]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/printers.c
Merge changes from CUPS 1.5svn-r9000.
[thirdparty/cups.git] / scheduler / printers.c
index ba1be9b03f72cd10ff6f924ae4a93c22dcb3cfa4..876231d45e9001baf9794602063633afa1794d06 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Printer routines for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007-2009 by Apple Inc.
+ *   Copyright 2007-2010 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -205,11 +205,6 @@ cupsdAddPrinterHistory(
   ippAddBoolean(history, IPP_TAG_PRINTER, "printer-is-shared", p->shared);
   ippAddString(history, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-state-message",
                NULL, p->state_message);
-#ifdef __APPLE__
-  if (p->recoverable)
-    ippAddString(history, IPP_TAG_PRINTER, IPP_TAG_TEXT,
-                 "com.apple.print.recoverable-message", NULL, p->recoverable);
-#endif /* __APPLE__ */
   if (p->num_reasons == 0)
     ippAddString(history, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
                  "printer-state-reasons", NULL, "none");
@@ -435,7 +430,7 @@ cupsdCreateCommonData(void)
 
   /* charset-configured */
   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_CHARSET | IPP_TAG_COPY,
-               "charset-configured", NULL, DefaultCharset);
+               "charset-configured", NULL, "utf-8");
 
   /* charset-supported */
   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_CHARSET | IPP_TAG_COPY,
@@ -455,8 +450,8 @@ cupsdCreateCommonData(void)
   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_TEXT | IPP_TAG_COPY,
                "cups-version", NULL, CUPS_SVERSION + 6);
 
-  /* generated-natural-language-supported */
-  ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE | IPP_TAG_COPY,
+  /* generated-natural-language-supported (no IPP_TAG_COPY) */
+  ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
                "generated-natural-language-supported", NULL, DefaultLanguage);
 
   /* ipp-versions-supported */
@@ -539,8 +534,8 @@ cupsdCreateCommonData(void)
   ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                 "multiple-operation-time-out", MultipleOperationTimeout);
 
-  /* natural-language-configured */
-  ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE | IPP_TAG_COPY,
+  /* natural-language-configured (no IPP_TAG_COPY) */
+  ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
                "natural-language-configured", NULL, DefaultLanguage);
 
   /* notify-attributes-supported */
@@ -649,7 +644,10 @@ cupsdDeleteAllPrinters(void)
   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
        p;
        p = (cupsd_printer_t *)cupsArrayNext(Printers))
+  {
+    p->op_policy_ptr = DefaultPolicyPtr;
     cupsdDeletePrinter(p, 0);
+  }
 }
 
 
@@ -657,12 +655,13 @@ cupsdDeleteAllPrinters(void)
  * 'cupsdDeletePrinter()' - Delete a printer from the system.
  */
 
-void
+int                                    /* O - 1 if classes affected, 0 otherwise */
 cupsdDeletePrinter(
     cupsd_printer_t *p,                        /* I - Printer to delete */
     int             update)            /* I - Update printers.conf? */
 {
-  int  i;                              /* Looping var */
+  int  i,                              /* Looping var */
+       changed = 0;                    /* Class changed? */
 #ifdef __sgi
   char filename[1024];                 /* Interface script filename */
 #endif /* __sgi */
@@ -773,7 +772,7 @@ cupsdDeletePrinter(
 
   if (!(p->type & CUPS_PRINTER_IMPLICIT))
   {
-    cupsdDeletePrinterFromClasses(p);
+    changed = cupsdDeletePrinterFromClasses(p);
 
    /*
     * Deregister from any browse protocols...
@@ -841,10 +840,6 @@ cupsdDeletePrinter(
   if (p->browse_attrs)
     free(p->browse_attrs);
 
-#ifdef __APPLE__
-  cupsdClearString(&p->recoverable);
-#endif /* __APPLE__ */
-
   cupsFreeOptions(p->num_options, p->options);
 
   free(p);
@@ -854,6 +849,8 @@ cupsdDeletePrinter(
   */
 
   cupsArrayRestore(Printers);
+
+  return (changed);
 }
 
 
@@ -1094,7 +1091,6 @@ cupsdLoadAllPrinters(void)
     else if (!strcasecmp(line, "Reason"))
     {
       if (value &&
-          strcmp(value, "com.apple.print.recoverable-warning") &&
           strcmp(value, "connecting-to-device") &&
           strcmp(value, "cups-insecure-filter-warning") &&
           strcmp(value, "cups-missing-filter-warning"))
@@ -1125,7 +1121,17 @@ cupsdLoadAllPrinters(void)
       else if (value && !strcasecmp(value, "stopped"))
       {
         p->state = IPP_PRINTER_STOPPED;
-       cupsdSetPrinterReasons(p, "+paused");
+
+        for (i = 0 ; i < p->num_reasons; i ++)
+         if (!strcmp("paused", p->reasons[i]))
+           break;
+
+        if (i >= p->num_reasons &&
+           p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
+       {
+         p->reasons[p->num_reasons] = _cupsStrAlloc("paused");
+         p->num_reasons ++;
+       }
       }
       else
        cupsdLogMessage(CUPSD_LOG_ERROR,
@@ -1508,6 +1514,7 @@ cupsdSaveAllPrinters(void)
 
   cupsFilePuts(fp, "# Printer configuration file for " CUPS_SVERSION "\n");
   cupsFilePrintf(fp, "# Written by cupsd on %s\n", temp);
+  cupsFilePuts(fp, "# DO NOT EDIT THIS FILE WHEN CUPSD IS RUNNING\n");
 
  /*
   * Write each local printer known to the system...
@@ -1588,8 +1595,7 @@ cupsdSaveAllPrinters(void)
     cupsFilePrintf(fp, "StateTime %d\n", (int)printer->state_time);
 
     for (i = 0; i < printer->num_reasons; i ++)
-      if (strcmp(printer->reasons[i], "com.apple.print.recoverable-warning") &&
-          strcmp(printer->reasons[i], "connecting-to-device") &&
+      if (strcmp(printer->reasons[i], "connecting-to-device") &&
           strcmp(printer->reasons[i], "cups-insecure-filter-warning") &&
           strcmp(printer->reasons[i], "cups-missing-filter-warning"))
         cupsFilePutConf(fp, "Reason", printer->reasons[i]);
@@ -2137,21 +2143,15 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
   ipp_attribute_t *attr;               /* Attribute data */
   cups_option_t        *option;                /* Current printer option */
   char         *filter;                /* Current filter */
+  static const char * const air_none[] =
+               {                       /* No authentication */
+                 "none"
+               };
   static const char * const air_userpass[] =
                {                       /* Basic/Digest authentication */
                  "username",
                  "password"
                };
-#ifdef HAVE_GSSAPI
-  static const char * const air_negotiate[] =
-               {                       /* Kerberos authentication */
-                 "negotiate"
-               };
-#endif /* HAVE_GSSAPI */
-  static const char * const air_none[] =
-               {                       /* No authentication */
-                 "none"
-               };
 
 
   DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
@@ -2182,65 +2182,50 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
   {
     num_air = p->num_auth_info_required;
     air     = p->auth_info_required;
-
-    if (!strcmp(air[0], "username"))
-      auth_supported = "basic";
-    else
-      auth_supported = "negotiate";
   }
-  else if (!(p->type & CUPS_PRINTER_DISCOVERED))
+  else if ((p->type & CUPS_PRINTER_AUTHENTICATED) &&
+           (p->type & CUPS_PRINTER_DISCOVERED))
   {
-    if (p->type & CUPS_PRINTER_CLASS)
-      snprintf(resource, sizeof(resource), "/classes/%s", p->name);
-    else
-      snprintf(resource, sizeof(resource), "/printers/%s", p->name);
+    num_air = 2;
+    air     = air_userpass;
+  }
 
-    if ((auth = cupsdFindBest(resource, HTTP_POST)) == NULL ||
-        auth->type == CUPSD_AUTH_NONE)
-      auth = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB);
+  if (p->type & CUPS_PRINTER_CLASS)
+    snprintf(resource, sizeof(resource), "/classes/%s", p->name);
+  else
+    snprintf(resource, sizeof(resource), "/printers/%s", p->name);
 
-    if (auth)
-    {
-      int      auth_type;              /* Authentication type */
+  if ((auth = cupsdFindBest(resource, HTTP_POST)) == NULL ||
+      auth->type == CUPSD_AUTH_NONE)
+    auth = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB);
 
+  if (auth)
+  {
+    int        auth_type;              /* Authentication type */
 
-      if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT)
-        auth_type = DefaultAuthType;
 
-      if (auth_type == CUPSD_AUTH_BASIC || auth_type == CUPSD_AUTH_BASICDIGEST)
-      {
-       auth_supported = "basic";
-       num_air        = 2;
-       air            = air_userpass;
-      }
-      else if (auth_type == CUPSD_AUTH_DIGEST)
-      {
-       auth_supported = "digest";
-       num_air        = 2;
-       air            = air_userpass;
-      }
+    if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT)
+      auth_type = DefaultAuthType;
+
+    if (auth_type == CUPSD_AUTH_BASIC || auth_type == CUPSD_AUTH_BASICDIGEST)
+      auth_supported = "basic";
+    else if (auth_type == CUPSD_AUTH_DIGEST)
+      auth_supported = "digest";
 #ifdef HAVE_GSSAPI
-      else if (auth_type == CUPSD_AUTH_NEGOTIATE)
-      {
-       auth_supported = "negotiate";
-       num_air        = 1;
-       air            = air_negotiate;
-      }
+    else if (auth_type == CUPSD_AUTH_NEGOTIATE)
+      auth_supported = "negotiate";
 #endif /* HAVE_GSSAPI */
 
+    if (!(p->type & CUPS_PRINTER_DISCOVERED))
+    {
       if (auth_type != CUPSD_AUTH_NONE)
-        p->type |= CUPS_PRINTER_AUTHENTICATED;
+       p->type |= CUPS_PRINTER_AUTHENTICATED;
       else
-        p->type &= ~CUPS_PRINTER_AUTHENTICATED;
+       p->type &= ~CUPS_PRINTER_AUTHENTICATED;
     }
-    else
-      p->type &= ~CUPS_PRINTER_AUTHENTICATED;
-  }
-  else if (p->type & CUPS_PRINTER_AUTHENTICATED)
-  {
-    num_air = 2;
-    air     = air_userpass;
   }
+  else if (!(p->type & CUPS_PRINTER_DISCOVERED))
+    p->type &= ~CUPS_PRINTER_AUTHENTICATED;
 
  /*
   * Create the required IPP attributes for a printer...
@@ -2550,14 +2535,6 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
     if (BrowseLocalOptions)
       length += 12 + strlen(BrowseLocalOptions);
 
-    if (p->num_auth_info_required > 0)
-    {
-      length += 18;                    /* auth-info-required */
-
-      for (i = 0; i < p->num_auth_info_required; i ++)
-        length += strlen(p->auth_info_required[i]) + 1;
-    }
-
    /*
     * Allocate the new string...
     */
@@ -2603,21 +2580,6 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
          }
        }
       }
-
-      if (p->num_auth_info_required > 0)
-      {
-        strcpy(attrptr, "auth-info-required");
-       attrptr += 18;
-
-       for (i = 0; i < p->num_auth_info_required; i ++)
-       {
-         *attrptr++ = i ? ',' : '=';
-         strcpy(attrptr, p->auth_info_required[i]);
-         attrptr += strlen(attrptr);
-       }
-      }
-      else
-       *attrptr = '\0';
     }
   }
 
@@ -2750,11 +2712,12 @@ cupsdSetPrinterReasons(
            cupsdSetPrinterState(p, IPP_PRINTER_IDLE, 1);
 
           if (strcmp(reason, "connecting-to-device"))
+         {
            cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
 
-         if (PrintcapFormat == PRINTCAP_PLIST)
-           cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
-
+           if (PrintcapFormat == PRINTCAP_PLIST)
+             cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
+          }
          break;
        }
     }
@@ -2786,10 +2749,12 @@ cupsdSetPrinterReasons(
          cupsdSetPrinterState(p, IPP_PRINTER_STOPPED, 1);
 
        if (strcmp(reason, "connecting-to-device"))
+       {
          cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
 
-       if (PrintcapFormat == PRINTCAP_PLIST)
-         cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
+         if (PrintcapFormat == PRINTCAP_PLIST)
+           cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
+       }
       }
     }
   }
@@ -2809,6 +2774,12 @@ cupsdSetPrinterState(
     int             update)            /* I - Update printers.conf? */
 {
   ipp_pstate_t old_state;              /* Old printer state */
+  static const char * const printer_states[] =
+  {                                    /* State strings */
+    "idle",
+    "processing",
+    "stopped"
+  };
 
 
  /*
@@ -2832,9 +2803,9 @@ cupsdSetPrinterState(
   {
     cupsdAddEvent(s == IPP_PRINTER_STOPPED ? CUPSD_EVENT_PRINTER_STOPPED :
                       CUPSD_EVENT_PRINTER_STATE, p, NULL,
-                 "%s \"%s\" state changed.",
+                 "%s \"%s\" state changed to %s.",
                  (p->type & CUPS_PRINTER_CLASS) ? "Class" : "Printer",
-                 p->name);
+                 p->name, printer_states[p->state]);
 
    /*
     * Let the browse code know this needs to be updated...
@@ -3271,6 +3242,8 @@ cupsdWritePrintcap(void)
   if (!Printcap || !*Printcap)
     return;
 
+  cupsdLogMessage(CUPSD_LOG_INFO, "Generating printcap %s...", Printcap);
+
  /*
   * Open the printcap file...
   */
@@ -3595,11 +3568,12 @@ add_printer_filter(
     if (!RunUser)
     {
      /*
-      * Only use filters that are owned by root and do not have world write
-      * permissions.
+      * Only use filters that are owned by root and do not have group or world
+      * write permissions.
       */
 
-      if (fileinfo.st_uid || (fileinfo.st_mode & (S_ISUID | S_IWOTH)) != 0)
+      if (fileinfo.st_uid ||
+          (fileinfo.st_mode & (S_ISUID | S_IWGRP | S_IWOTH)) != 0)
       {
        if (fileinfo.st_uid)
          snprintf(p->state_message, sizeof(p->state_message),
@@ -3626,7 +3600,7 @@ add_printer_filter(
 
        if (!stat(filename, &fileinfo) &&
            (fileinfo.st_uid ||
-            (fileinfo.st_mode & (S_ISUID | S_IWOTH)) != 0))
+            (fileinfo.st_mode & (S_ISUID | S_IWGRP | S_IWOTH)) != 0))
        {
          if (fileinfo.st_uid)
            snprintf(p->state_message, sizeof(p->state_message),
@@ -3728,10 +3702,6 @@ add_printer_formats(cupsd_printer_t *p)  /* I - Printer */
                       p->name, mimetype);
   }
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                  "add_printer_formats: %s: %d supported types",
-                 p->name, cupsArrayCount(p->filetypes) + 1);
-
  /*
   * Add the file formats that can be filtered...
   */
@@ -3742,9 +3712,13 @@ add_printer_formats(cupsd_printer_t *p)  /* I - Printer */
   else
     i = 0;
 
+  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                  "add_printer_formats: %s: %d supported types",
+                  p->name, cupsArrayCount(p->filetypes) + i);
+
   attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
                        "document-format-supported",
-                      cupsArrayCount(p->filetypes) + 1, NULL, NULL);
+                       cupsArrayCount(p->filetypes) + i, NULL, NULL);
 
   if (i)
     attr->values[0].string.text = _cupsStrAlloc("application/octet-stream");
@@ -3783,7 +3757,7 @@ add_printer_formats(cupsd_printer_t *p)   /* I - Printer */
         filter;
         filter = (mime_filter_t *)cupsArrayNext(MimeDatabase->filters))
     {
-      if (filter->dst == p->filetype && filter->filter && 
+      if (filter->dst == p->filetype && filter->filter &&
          strstr(filter->filter, "PrintJobMgr"))
        break;
     }
@@ -3863,7 +3837,7 @@ delete_printer_filters(
   for (filter = mimeFirstFilter(MimeDatabase);
        filter;
        filter = mimeNextFilter(MimeDatabase))
-    if (filter->dst == p->filetype)
+    if (filter->dst == p->filetype || filter->dst == p->prefiltertype)
     {
      /*
       * Delete the current filter...
@@ -4171,7 +4145,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
       }
 
       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
-                  "output-bin-default", NULL, output_bin->defchoice);
+                  "output-bin-default", NULL, output_bin->defchoice);
     }
 
    /*