]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/printers.c
Merge changes from CUPS 1.4svn-r7614.
[thirdparty/cups.git] / scheduler / printers.c
index 640f02ac287f01b4f9d156690c7fd01dabd7f2a2..3a63fc2e668b80f792abfb5989521fec35af40d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: printers.c 6970 2007-09-17 23:58:28Z mike $"
+ * "$Id: printers.c 7608 2008-05-21 01:37:21Z mike $"
  *
  *   Printer routines for the Common UNIX Printing System (CUPS).
  *
@@ -1236,6 +1236,26 @@ cupsdLoadAllPrinters(void)
        break;
       }
     }
+    else if (!strcasecmp(line, "Attribute") && value)
+    {
+      for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
+
+      if (!*valueptr)
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Syntax error on line %d of printers.conf.", linenum);
+      else
+      {
+        for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0');
+
+        if (!p->attrs)
+         cupsdSetPrinterAttrs(p);
+
+        cupsdSetPrinterAttr(p, value, valueptr);
+
+       if (!strncmp(value, "marker-", 7))
+         p->marker_time = time(NULL);
+      }
+    }
     else
     {
      /*
@@ -1320,6 +1340,7 @@ cupsdSaveAllPrinters(void)
   struct tm            *curdate;       /* Current date */
   cups_option_t                *option;        /* Current option */
   const char           *ptr;           /* Pointer into info/location */
+  ipp_attribute_t      *marker;        /* Current marker attribute */
 
 
  /*
@@ -1470,8 +1491,24 @@ cupsdSaveAllPrinters(void)
     cupsFilePrintf(fp, "KLimit %d\n", printer->k_limit);
 
     for (i = 0; i < printer->num_users; i ++)
-      cupsFilePrintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow",
-              printer->users[i]);
+    {
+      if ((ptr = strchr(printer->users[i], '#')) != NULL)
+      {
+       /*
+        * Need to quote the first # in the user string...
+       */
+
+        cupsFilePrintf(fp, "%sUser ", printer->deny_users ? "Deny" : "Allow");
+       cupsFileWrite(fp, printer->users[i], ptr - printer->users[i]);
+       cupsFilePutChar(fp, '\\');
+       cupsFilePuts(fp, ptr);
+       cupsFilePutChar(fp, '\n');
+      }
+      else
+        cupsFilePrintf(fp, "%sUser %s\n",
+                      printer->deny_users ? "Deny" : "Allow",
+                       printer->users[i]);
+    }
 
     if (printer->op_policy)
       cupsFilePrintf(fp, "OpPolicy %s\n", printer->op_policy);
@@ -1481,7 +1518,104 @@ cupsdSaveAllPrinters(void)
     for (i = printer->num_options, option = printer->options;
          i > 0;
         i --, option ++)
-      cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+    {
+      if ((ptr = strchr(option->value, '#')) != NULL)
+      {
+       /*
+        * Need to quote the first # in the option string...
+       */
+
+        cupsFilePrintf(fp, "Option %s ", option->name);
+       cupsFileWrite(fp, option->value, ptr - option->value);
+       cupsFilePutChar(fp, '\\');
+       cupsFilePuts(fp, ptr);
+       cupsFilePutChar(fp, '\n');
+      }
+      else
+        cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+    }
+
+    if ((marker = ippFindAttribute(printer->attrs, "marker-colors",
+                                   IPP_TAG_NAME)) != NULL)
+    {
+      cupsFilePrintf(fp, "Attribute %s ", marker->name);
+
+      for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+      {
+        if (i)
+         cupsFilePutChar(fp, ',');
+
+        if (!ptr && (ptr = strchr(marker->values[i].string.text, '#')) != NULL)
+       {
+         cupsFileWrite(fp, marker->values[i].string.text,
+                       ptr - marker->values[i].string.text);
+         cupsFilePutChar(fp, '\\');
+         cupsFilePuts(fp, ptr);
+       }
+       else
+          cupsFilePuts(fp, marker->values[i].string.text);
+      }
+
+      cupsFilePuts(fp, "\n");
+    }
+
+    if ((marker = ippFindAttribute(printer->attrs, "marker-levels",
+                                   IPP_TAG_INTEGER)) != NULL)
+    {
+      cupsFilePrintf(fp, "Attribute %s %d", marker->name,
+                     marker->values[0].integer);
+      for (i = 1; i < marker->num_values; i ++)
+        cupsFilePrintf(fp, ",%d", marker->values[i].integer);
+      cupsFilePuts(fp, "\n");
+    }
+
+    if ((marker = ippFindAttribute(printer->attrs, "marker-names",
+                                   IPP_TAG_NAME)) != NULL)
+    {
+      cupsFilePrintf(fp, "Attribute %s ", marker->name);
+
+      for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+      {
+        if (i)
+         cupsFilePutChar(fp, ',');
+
+        if (!ptr && (ptr = strchr(marker->values[i].string.text, '#')) != NULL)
+       {
+         cupsFileWrite(fp, marker->values[i].string.text,
+                       ptr - marker->values[i].string.text);
+         cupsFilePutChar(fp, '\\');
+         cupsFilePuts(fp, ptr);
+       }
+       else
+          cupsFilePuts(fp, marker->values[i].string.text);
+      }
+
+      cupsFilePuts(fp, "\n");
+    }
+
+    if ((marker = ippFindAttribute(printer->attrs, "marker-types",
+                                   IPP_TAG_KEYWORD)) != NULL)
+    {
+      cupsFilePrintf(fp, "Attribute %s ", marker->name);
+
+      for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+      {
+        if (i)
+         cupsFilePutChar(fp, ',');
+
+        if (!ptr && (ptr = strchr(marker->values[i].string.text, '#')) != NULL)
+       {
+         cupsFileWrite(fp, marker->values[i].string.text,
+                       ptr - marker->values[i].string.text);
+         cupsFilePutChar(fp, '\\');
+         cupsFilePuts(fp, ptr);
+       }
+       else
+          cupsFilePuts(fp, marker->values[i].string.text);
+      }
+
+      cupsFilePuts(fp, "\n");
+    }
 
     cupsFilePuts(fp, "</Printer>\n");
 
@@ -1762,6 +1896,8 @@ cupsdSetPrinterAttr(
         value = ptr;
     }
   }
+
+  cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
 }
 
 
@@ -1790,6 +1926,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
                *media_quality,         /* EFMediaQualityMode options */
                *duplex;                /* Duplex options */
   ppd_attr_t   *ppdattr;               /* PPD attribute */
+  ipp_t                *oldattrs;              /* Old printer attributes */
   ipp_attribute_t *attr;               /* Attribute data */
   ipp_value_t  *val;                   /* Attribute value */
   int          num_finishings;         /* Number of finishings */
@@ -1816,6 +1953,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
                {                       /* No authentication */
                  "none"
                };
+  static const char * const standard_commands[] =
+               {                       /* Standard CUPS commands */
+                 "AutoConfigure",
+                 "Clean",
+                 "PrintSelfTestPage",
+                 "ReportLevels"
+               };
 
 
   DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
@@ -1904,9 +2048,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
   * Create the required IPP attributes for a printer...
   */
 
-  if (p->attrs)
-    ippDelete(p->attrs);
-
+  oldattrs = p->attrs;
   p->attrs = ippNew();
 
   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
@@ -2307,6 +2449,110 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
 
           p->type |= CUPS_PRINTER_COMMANDS;
         }
+       else if (!(p->type & CUPS_PRINTER_COMMANDS))
+       {
+        /*
+         * See if this is a PostScript device without a command filter...
+         */
+
+         for (i = 0; i < ppd->num_filters; i ++)
+           if (!strncasecmp(ppd->filters[i],
+                            "application/vnd.cups-postscript", 31))
+             break;
+
+          if (i < ppd->num_filters)
+         {
+          /*
+           * Add the generic PostScript command filter...
+           */
+
+           add_printer_filter(p, p->filetype,
+                              "application/vnd.cups-command 0 commandtops");
+           p->type |= CUPS_PRINTER_COMMANDS;
+         }
+       }
+
+        if (p->type & CUPS_PRINTER_COMMANDS)
+       {
+         char  *commands,              /* Copy of commands */
+               *start,                 /* Start of name */
+               *end;                   /* End of name */
+          int  count;                  /* Number of commands */
+
+
+          if ((ppdattr = ppdFindAttr(ppd, "cupsCommands", NULL)) != NULL &&
+             ppdattr->value && ppdattr->value[0])
+         {
+           for (count = 0, start = ppdattr->value; *start; count ++)
+           {
+             while (isspace(*start & 255))
+               start ++;
+
+             if (!*start)
+               break;
+
+             while (*start && !isspace(*start & 255))
+               start ++;
+           }
+         }
+         else
+           count = 0;
+
+          if (count > 0)
+         {
+          /*
+           * Make a copy of the commands string and count how many ...
+           */
+
+           attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                                "printer-commands", count, NULL, NULL);
+
+           commands = strdup(ppdattr->value);
+
+           for (count = 0, start = commands; *start; count ++)
+           {
+             while (isspace(*start & 255))
+               start ++;
+
+             if (!*start)
+               break;
+
+              end = start;
+             while (*end && !isspace(*end & 255))
+               end ++;
+
+              if (*end)
+               *end++ = '\0';
+
+              attr->values[count].string.text = _cupsStrAlloc(start);
+
+              start = end;
+           }
+
+           free(commands);
+          }
+         else
+         {
+          /*
+           * Add the standard list of commands...
+           */
+
+           ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                         "printer-commands",
+                         (int)(sizeof(standard_commands) /
+                               sizeof(standard_commands[0])), NULL,
+                         standard_commands);
+         }
+       }
+       else
+       {
+        /*
+         * No commands supported...
+         */
+
+         ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                      "printer-commands", NULL, "none");
+        }
 
        /*
        * Show current and available port monitors for this printer...
@@ -2469,6 +2715,69 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
     }
   }
 
+ /*
+  * Copy marker attributes as needed...
+  */
+
+  if (oldattrs)
+  {
+    ipp_attribute_t *oldattr;          /* Old attribute */
+
+
+    if ((oldattr = ippFindAttribute(oldattrs, "marker-colors",
+                                    IPP_TAG_NAME)) != NULL)
+    {
+      if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+                                "marker-colors", oldattr->num_values, NULL,
+                               NULL)) != NULL)
+      {
+       for (i = 0; i < oldattr->num_values; i ++)
+         attr->values[i].string.text =
+             _cupsStrAlloc(oldattr->values[i].string.text);
+      }
+    }
+
+    if ((oldattr = ippFindAttribute(oldattrs, "marker-levels",
+                                    IPP_TAG_INTEGER)) != NULL)
+    {
+      if ((attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+                                 "marker-levels", oldattr->num_values,
+                                NULL)) != NULL)
+      {
+       for (i = 0; i < oldattr->num_values; i ++)
+         attr->values[i].integer = oldattr->values[i].integer;
+      }
+    }
+
+    if ((oldattr = ippFindAttribute(oldattrs, "marker-names",
+                                    IPP_TAG_NAME)) != NULL)
+    {
+      if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+                                "marker-names", oldattr->num_values, NULL,
+                               NULL)) != NULL)
+      {
+       for (i = 0; i < oldattr->num_values; i ++)
+         attr->values[i].string.text =
+             _cupsStrAlloc(oldattr->values[i].string.text);
+      }
+    }
+
+    if ((oldattr = ippFindAttribute(oldattrs, "marker-types",
+                                    IPP_TAG_KEYWORD)) != NULL)
+    {
+      if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                                "marker-types", oldattr->num_values, NULL,
+                               NULL)) != NULL)
+      {
+       for (i = 0; i < oldattr->num_values; i ++)
+         attr->values[i].string.text =
+             _cupsStrAlloc(oldattr->values[i].string.text);
+      }
+    }
+
+    ippDelete(oldattrs);
+  }
+
  /*
   * Force sharing off for remote queues...
   */
@@ -4011,5 +4320,5 @@ write_irix_state(cupsd_printer_t *p)      /* I - Printer to update */
 
 
 /*
- * End of "$Id: printers.c 6970 2007-09-17 23:58:28Z mike $".
+ * End of "$Id: printers.c 7608 2008-05-21 01:37:21Z mike $".
  */