]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
First half of PPD/attributes caching (STR #1293)
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Wed, 8 Oct 2008 04:26:38 +0000 (04:26 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Wed, 8 Oct 2008 04:26:38 +0000 (04:26 +0000)
git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@8026 7a7537e8-13f0-0310-91df-b6672ffda945

cups/file.c
cups/file.h
cups/libcups.exp
doc/help/ref-printers-conf.html
scheduler/classes.c
scheduler/cupsd.h
scheduler/dirsvc.c
scheduler/printers.c
scheduler/printers.h

index c07c6cc72e07f0eb3f033fcec6a3244be7a0d914..5c981148987f5776326be6e83ef1e996df3a89dc 100644 (file)
@@ -1253,6 +1253,67 @@ cupsFilePutChar(cups_file_t *fp, /* I - CUPS file */
 }
 
 
+/*
+ * 'cupsFilePutConf()' - Write a configuration line.
+ *
+ * This function handles any comment escaping of the value.
+ *
+ * @since CUPS 1.4@
+ */
+
+ssize_t                                        /* O - Number of bytes written or -1 on error */
+cupsFilePutConf(cups_file_t *fp,       /* I - CUPS file */
+                const char *directive, /* I - Directive */
+               const char *value)      /* I - Value */
+{
+  ssize_t      bytes,                  /* Number of bytes written */
+               temp;                   /* Temporary byte count */
+  const char   *ptr;                   /* Pointer into value */
+
+
+  if (!fp || !directive || !*directive)
+    return (-1);
+
+  if ((bytes = cupsFilePuts(fp, directive)) < 0)
+    return (-1);
+
+  if (cupsFilePutChar(fp, ' ') < 0)
+    return (-1);
+  bytes ++;
+
+  if (value && *value)
+  {
+    if ((ptr = strchr(value, '#')) != NULL)
+    {
+     /*
+      * Need to quote the first # in the info string...
+      */
+
+      if ((temp = cupsFileWrite(fp, value, ptr - value)) < 0)
+        return (-1);
+      bytes += temp;
+
+      if (cupsFilePutChar(fp, '\\') < 0)
+        return (-1);
+      bytes ++;
+
+      if ((temp = cupsFilePuts(fp, ptr)) < 0)
+        return (-1);
+      bytes += temp;
+    }
+    else if ((temp = cupsFilePuts(fp, value)) < 0)
+      return (-1);
+    else
+      bytes += temp;
+  }
+
+  if (cupsFilePutChar(fp, '\n') < 0)
+    return (-1);
+  else
+    return (bytes + 1);
+}
+
+
 /*
  * 'cupsFilePuts()' - Write a string.
  *
index 805aae3976a108a28bfc3162d1f80177bee04208..770d173a035dd8d11201fa720d790965d5d3486f 100644 (file)
@@ -8,7 +8,7 @@
  *   our own file functions allows us to provide transparent support of
  *   gzip'd print files, PPD files, etc.
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -87,6 +87,8 @@ __attribute__ ((__format__ (__printf__, 2, 3)))
 #endif /* __GNUC__ */
 _CUPS_API_1_2;
 extern int             cupsFilePutChar(cups_file_t *fp, int c) _CUPS_API_1_2;
+extern ssize_t         cupsFilePutConf(cups_file_t *fp, const char *directive,
+                                       const char *value) _CUPS_API_1_4;
 extern int             cupsFilePuts(cups_file_t *fp, const char *s) _CUPS_API_1_2;
 extern ssize_t         cupsFileRead(cups_file_t *fp, char *buf, size_t bytes) _CUPS_API_1_2;
 extern off_t           cupsFileRewind(cups_file_t *fp) _CUPS_API_1_2;
index 4908e8bbc322f9545ae44a94fd83cb75a4d297b3..92d2f9c91d8366ba06cde96be11fa81691a2ed02 100644 (file)
@@ -120,6 +120,7 @@ _cupsFileOpenFd
 _cupsFilePeekChar
 _cupsFilePrintf
 _cupsFilePutChar
+_cupsFilePutConf
 _cupsFilePuts
 _cupsFileRead
 _cupsFileRewind
index 33397e8b0717ffa5c34e4c6be6db1680f3955e10..e3fb078404ddc2b231a72acc565020ac4591d444 100644 (file)
@@ -37,12 +37,12 @@ active.</P>
 
 <P>The <CODE>Accepting</CODE> directive defines the initial state
 of the <VAR>printer-is-accepting-jobs</VAR> attribute. This state
-is also set by the <CODE>accept(8)</CODE> and
-<CODE>reject(8)</CODE> commands:</P>
+is also set by the <CODE>cupsaccept(8)</CODE> and
+<CODE>cupsreject(8)</CODE> commands:</P>
 
 <PRE CLASS="command">
-<KBD>/usr/sbin/accept printername
-/usr/sbin/reject printername</KBD>
+<KBD>/usr/sbin/cupsaccept printername
+/usr/sbin/cupsreject printername</KBD>
 </PRE>
 
 <P>This directive must appear inside a <A
@@ -211,6 +211,27 @@ HREF="#DefaultPrinter"><CODE>DefaultPrinter</CODE></A>
 section.</P>
 
 
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.4</SPAN><A NAME="Filter">Filter</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+&lt;Printer name&gt;
+  ...
+  Filter mime/type 100 program
+&lt;/Printer&gt;
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>Filter</CODE> directive lists a single filter program as defined
+in the printer's PPD file.</P>
+
+<P>This directive must appear inside a
+<A HREF="#Printer"><CODE>Printer</CODE></A> or
+<A HREF="#DefaultPrinter"><CODE>DefaultPrinter</CODE></A> section.</P>
+
+
 <H2 CLASS="title"><A NAME="Info">Info</A></H2>
 
 <H3>Examples</H3>
@@ -482,6 +503,27 @@ HREF="#DefaultPrinter"><CODE>DefaultPrinter</CODE></A>
 section.</P>
 
 
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.4</SPAN><A NAME="PreFilter">PreFilter</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+&lt;Printer name&gt;
+  ...
+  PreFilter mime/type 100 program
+&lt;/Printer&gt;
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>PreFilter</CODE> directive lists a single pre-filter program as
+defined in the printer's PPD file.</P>
+
+<P>This directive must appear inside a
+<A HREF="#Printer"><CODE>Printer</CODE></A> or
+<A HREF="#DefaultPrinter"><CODE>DefaultPrinter</CODE></A> section.</P>
+
+
 <H2 CLASS="title"><A NAME="Printer">Printer</A></H2>
 
 <H3>Examples</H3>
@@ -503,6 +545,27 @@ command:
 </PRE>
 
 
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.4</SPAN><A NAME="Product">Product</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+&lt;Printer name&gt;
+  ...
+  Product Acme PaperWriter
+&lt;/Printer&gt;
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>Product</CODE> directive defines the main product string from the
+printer's PPD file and is used when advertising the queue via DNS-SD.</P>
+
+<P>This directive must appear inside a
+<A HREF="#Printer"><CODE>Printer</CODE></A> or
+<A HREF="#DefaultPrinter"><CODE>DefaultPrinter</CODE></A> section.</P>
+
+
 <H2 CLASS="title"><A NAME="QuotaPeriod">QuotaPeriod</A></H2>
 
 <H3>Examples</H3>
index 07b3381385ea08438aac2e91fd183b8c3da96833..5bc4783d5bc6748599b256c0c8e1d0fceccc5893 100644 (file)
@@ -674,14 +674,14 @@ void
 cupsdSaveAllClasses(void)
 {
   cups_file_t          *fp;            /* classes.conf file */
-  char                 temp[1024];     /* Temporary string */
-  char                 backup[1024];   /* classes.conf.O file */
+  char                 temp[1024],     /* Temporary string */
+                       backup[1024],   /* printers.conf.O file */
+                       value[2048];    /* Value string */
   cupsd_printer_t      *pclass;        /* Current printer class */
   int                  i;              /* Looping var */
   time_t               curtime;        /* Current time */
   struct tm            *curdate;       /* Current date */
   cups_option_t                *option;        /* Current option */
-  const char           *ptr;           /* Pointer into info/location */
 
 
  /*
@@ -757,53 +757,38 @@ cupsdSaveAllClasses(void)
 
     if (pclass->num_auth_info_required > 0)
     {
-      cupsFilePrintf(fp, "AuthInfoRequired %s", pclass->auth_info_required[0]);
-      for (i = 1; i < pclass->num_auth_info_required; i ++)
-        cupsFilePrintf(fp, ",%s", pclass->auth_info_required[i]);
-      cupsFilePutChar(fp, '\n');
-    }
-
-    if (pclass->info)
-    {
-      if ((ptr = strchr(pclass->info, '#')) != NULL)
+      switch (pclass->num_auth_info_required)
       {
-       /*
-        * Need to quote the first # in the info string...
-       */
-
-        cupsFilePuts(fp, "Info ");
-       cupsFileWrite(fp, pclass->info, ptr - pclass->info);
-       cupsFilePutChar(fp, '\\');
-       cupsFilePuts(fp, ptr);
-       cupsFilePutChar(fp, '\n');
+        case 1 :
+            strlcpy(value, pclass->auth_info_required[0], sizeof(value));
+           break;
+
+        case 2 :
+            snprintf(value, sizeof(value), "%s,%s",
+                    pclass->auth_info_required[0],
+                    pclass->auth_info_required[1]);
+           break;
+
+        case 3 :
+       default :
+            snprintf(value, sizeof(value), "%s,%s,%s",
+                    pclass->auth_info_required[0],
+                    pclass->auth_info_required[1],
+                    pclass->auth_info_required[2]);
+           break;
       }
-      else
-        cupsFilePrintf(fp, "Info %s\n", pclass->info);
+
+      cupsFilePutConf(fp, "AuthInfoRequired", value);
     }
 
-    if (pclass->location)
-    {
-      if ((ptr = strchr(pclass->info, '#')) != NULL)
-      {
-       /*
-        * Need to quote the first # in the location string...
-       */
+    if (pclass->info)
+      cupsFilePutConf(fp, "Info", pclass->info);
 
-        cupsFilePuts(fp, "Location ");
-       cupsFileWrite(fp, pclass->location, ptr - pclass->location);
-       cupsFilePutChar(fp, '\\');
-       cupsFilePuts(fp, ptr);
-       cupsFilePutChar(fp, '\n');
-      }
-      else
-        cupsFilePrintf(fp, "Location %s\n", pclass->location);
-    }
+    if (pclass->location)
+      cupsFilePutConf(fp, "Location", pclass->location);
 
     if (pclass->state == IPP_PRINTER_STOPPED)
-    {
       cupsFilePuts(fp, "State Stopped\n");
-      cupsFilePrintf(fp, "StateMessage %s\n", pclass->state_message);
-    }
     else
       cupsFilePuts(fp, "State Idle\n");
 
@@ -819,46 +804,30 @@ cupsdSaveAllClasses(void)
     else
       cupsFilePuts(fp, "Shared No\n");
 
-    cupsFilePrintf(fp, "JobSheets %s %s\n", pclass->job_sheets[0],
-                   pclass->job_sheets[1]);
-
-    for (i = 0; i < pclass->num_users; i ++)
-    {
-      if ((ptr = strchr(pclass->users[i], '#')) != NULL)
-      {
-       /*
-        * Need to quote the first # in the user string...
-       */
-
-        cupsFilePrintf(fp, "%sUser ", pclass->deny_users ? "Deny" : "Allow");
-       cupsFileWrite(fp, pclass->users[i], ptr - pclass->users[i]);
-       cupsFilePutChar(fp, '\\');
-       cupsFilePuts(fp, ptr);
-       cupsFilePutChar(fp, '\n');
-      }
-      else
-        cupsFilePrintf(fp, "%sUser %s\n",
-                      pclass->deny_users ? "Deny" : "Allow",
-                       pclass->users[i]);
-    }
+    snprintf(value, sizeof(value), "%s %s", pclass->job_sheets[0],
+             pclass->job_sheets[1]);
+    cupsFilePutConf(fp, "JobSheets", value);
 
     cupsFilePrintf(fp, "QuotaPeriod %d\n", pclass->quota_period);
     cupsFilePrintf(fp, "PageLimit %d\n", pclass->page_limit);
     cupsFilePrintf(fp, "KLimit %d\n", pclass->k_limit);
 
     for (i = 0; i < pclass->num_users; i ++)
-      cupsFilePrintf(fp, "%sUser %s\n", pclass->deny_users ? "Deny" : "Allow",
-                    pclass->users[i]);
+      cupsFilePutConf(fp, pclass->deny_users ? "DenyUser" : "AllowUser",
+                      pclass->users[i]);
 
-    if (pclass->op_policy)
-      cupsFilePrintf(fp, "OpPolicy %s\n", pclass->op_policy);
+     if (pclass->op_policy)
+      cupsFilePutConf(fp, "OpPolicy", pclass->op_policy);
     if (pclass->error_policy)
-      cupsFilePrintf(fp, "ErrorPolicy %s\n", pclass->error_policy);
+      cupsFilePutConf(fp, "ErrorPolicy", pclass->error_policy);
 
     for (i = pclass->num_options, option = pclass->options;
          i > 0;
         i --, option ++)
-      cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+    {
+      snprintf(value, sizeof(value), "%s %s", option->name, option->value);
+      cupsFilePutConf(fp, "Option", value);
+    }
 
     cupsFilePuts(fp, "</Class>\n");
   }
index 6f83204004ca9a5b17aa61c0a12c32061fac9dbd..6093eb3d5d133e4082edc54b08476e7ce68d1197 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Main header file for the Common UNIX Printing System (CUPS) scheduler.
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -235,6 +235,7 @@ extern void cupsdStopSelect(void);
 
 extern int     cupsdRemoveFile(const char *filename);
 
+
 /*
  * End of "$Id$".
  */
index bd8228d5c37d18175451b1fccfbdc2cf3b6bd6c2..2894d7969d4ff31d10303a5551b98438425d3acd 100644 (file)
@@ -696,7 +696,8 @@ cupsdSaveRemoteCache(void)
 {
   int                  i;              /* Looping var */
   cups_file_t          *fp;            /* printers.conf file */
-  char                 temp[1024];     /* Temporary string */
+  char                 temp[1024],     /* Temporary string */
+                       value[2048];    /* Value string */
   cupsd_printer_t      *printer;       /* Current printer class */
   time_t               curtime;        /* Current time */
   struct tm            *curdate;       /* Current date */
@@ -765,48 +766,49 @@ cupsdSaveRemoteCache(void)
     else
       cupsFilePrintf(fp, "Printer %s>\n", printer->name);
 
-    cupsFilePrintf(fp, "Type %d\n", printer->type);
-
     cupsFilePrintf(fp, "BrowseTime %d\n", (int)printer->browse_expire);
 
     if (printer->info)
-      cupsFilePrintf(fp, "Info %s\n", printer->info);
-
-    if (printer->make_model)
-      cupsFilePrintf(fp, "MakeModel %s\n", printer->make_model);
+      cupsFilePutConf(fp, "Info", printer->info);
 
     if (printer->location)
-      cupsFilePrintf(fp, "Location %s\n", printer->location);
+      cupsFilePutConf(fp, "Location", printer->location);
+
+    if (printer->make_model)
+      cupsFilePutConf(fp, "MakeModel", printer->make_model);
 
-    cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri);
+    cupsFilePutConf(fp, "DeviceURI", printer->device_uri);
 
     if (printer->state == IPP_PRINTER_STOPPED)
-    {
       cupsFilePuts(fp, "State Stopped\n");
-      cupsFilePrintf(fp, "StateMessage %s\n", printer->state_message);
-    }
     else
       cupsFilePuts(fp, "State Idle\n");
 
     for (i = 0; i < printer->num_reasons; i ++)
-      cupsFilePrintf(fp, "Reason %s\n", printer->reasons[i]);
+      cupsFilePutConf(fp, "Reason", printer->reasons[i]);
+
+    cupsFilePrintf(fp, "Type %d\n", printer->type);
 
     if (printer->accepting)
       cupsFilePuts(fp, "Accepting Yes\n");
     else
       cupsFilePuts(fp, "Accepting No\n");
 
-    cupsFilePrintf(fp, "JobSheets %s %s\n", printer->job_sheets[0],
-            printer->job_sheets[1]);
+    snprintf(value, sizeof(value), "%s %s", printer->job_sheets[0],
+             printer->job_sheets[1]);
+    cupsFilePutConf(fp, "JobSheets", value);
 
     for (i = 0; i < printer->num_users; i ++)
-      cupsFilePrintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow",
-              printer->users[i]);
+      cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser",
+                      printer->users[i]);
 
     for (i = printer->num_options, option = printer->options;
          i > 0;
         i --, option ++)
-      cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+    {
+      snprintf(value, sizeof(value), "%s %s", option->name, option->value);
+      cupsFilePutConf(fp, "Option", value);
+    }
 
     if (printer->type & CUPS_PRINTER_CLASS)
       cupsFilePuts(fp, "</Class>\n");
index 681a4c0d7800557fe7d5c81cff7dbf8cdc0d6fa6..492c5a88cd9de4e997b38a70f210fa6658afe62e 100644 (file)
@@ -1005,6 +1005,11 @@ cupsdLoadAllPrinters(void)
       if (value)
        cupsdSetString(&p->info, value);
     }
+    else if (!strcasecmp(line, "MakeModel"))
+    {
+      if (value)
+       cupsdSetString(&p->make_model, value);
+    }
     else if (!strcasecmp(line, "Location"))
     {
       if (value)
@@ -1111,6 +1116,52 @@ cupsdLoadAllPrinters(void)
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of printers.conf.", linenum);
     }
+    else if (!strcasecmp(line, "Type"))
+    {
+      if (value)
+        p->type = atoi(value);
+      else
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Syntax error on line %d of printers.conf.", linenum);
+    }
+    else if (!strcasecmp(line, "Product"))
+    {
+      if (value)
+      {
+#ifdef HAVE_DNSSD
+        p->product = _cupsStrAlloc(value);
+#endif /* HAVE_DNSSD */
+      }
+      else
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Syntax error on line %d of printers.conf.", linenum);
+    }
+    else if (!strcasecmp(line, "Filter"))
+    {
+      if (value)
+      {
+        if (!p->filters)
+         p->filters = cupsArrayNew(NULL, NULL);
+
+       cupsArrayAdd(p->filters, _cupsStrAlloc(value));
+      }
+      else
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Syntax error on line %d of printers.conf.", linenum);
+    }
+    else if (!strcasecmp(line, "PreFilter"))
+    {
+      if (value)
+      {
+        if (!p->pre_filters)
+         p->pre_filters = cupsArrayNew(NULL, NULL);
+
+       cupsArrayAdd(p->pre_filters, _cupsStrAlloc(value));
+      }
+      else
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Syntax error on line %d of printers.conf.", linenum);
+    }
     else if (!strcasecmp(line, "Shared"))
     {
      /*
@@ -1349,13 +1400,14 @@ cupsdSaveAllPrinters(void)
 {
   int                  i;              /* Looping var */
   cups_file_t          *fp;            /* printers.conf file */
-  char                 temp[1024];     /* Temporary string */
-  char                 backup[1024];   /* printers.conf.O file */
+  char                 temp[1024],     /* Temporary string */
+                       backup[1024],   /* printers.conf.O file */
+                       value[2048],    /* Value string */
+                       *ptr;           /* Pointer into value */
   cupsd_printer_t      *printer;       /* Current printer class */
   time_t               curtime;        /* Current time */
   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 */
 
 
@@ -1432,56 +1484,50 @@ cupsdSaveAllPrinters(void)
 
     if (printer->num_auth_info_required > 0)
     {
-      cupsFilePrintf(fp, "AuthInfoRequired %s", printer->auth_info_required[0]);
-      for (i = 1; i < printer->num_auth_info_required; i ++)
-        cupsFilePrintf(fp, ",%s", printer->auth_info_required[i]);
-      cupsFilePutChar(fp, '\n');
-    }
-
-    if (printer->info)
-    {
-      if ((ptr = strchr(printer->info, '#')) != NULL)
+      switch (printer->num_auth_info_required)
       {
-       /*
-        * Need to quote the first # in the info string...
-       */
-
-        cupsFilePuts(fp, "Info ");
-       cupsFileWrite(fp, printer->info, ptr - printer->info);
-       cupsFilePutChar(fp, '\\');
-       cupsFilePuts(fp, ptr);
-       cupsFilePutChar(fp, '\n');
+        case 1 :
+            strlcpy(value, printer->auth_info_required[0], sizeof(value));
+           break;
+
+        case 2 :
+            snprintf(value, sizeof(value), "%s,%s",
+                    printer->auth_info_required[0],
+                    printer->auth_info_required[1]);
+           break;
+
+        case 3 :
+       default :
+            snprintf(value, sizeof(value), "%s,%s,%s",
+                    printer->auth_info_required[0],
+                    printer->auth_info_required[1],
+                    printer->auth_info_required[2]);
+           break;
       }
-      else
-        cupsFilePrintf(fp, "Info %s\n", printer->info);
+
+      cupsFilePutConf(fp, "AuthInfoRequired", value);
     }
 
+    if (printer->info)
+      cupsFilePutConf(fp, "Info", printer->info);
+
     if (printer->location)
-    {
-      if ((ptr = strchr(printer->info, '#')) != NULL)
-      {
-       /*
-        * Need to quote the first # in the location string...
-       */
+      cupsFilePutConf(fp, "Location", printer->location);
 
-        cupsFilePuts(fp, "Location ");
-       cupsFileWrite(fp, printer->location, ptr - printer->location);
-       cupsFilePutChar(fp, '\\');
-       cupsFilePuts(fp, ptr);
-       cupsFilePutChar(fp, '\n');
-      }
-      else
-        cupsFilePrintf(fp, "Location %s\n", printer->location);
-    }
-    cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri);
+    if (printer->make_model)
+      cupsFilePutConf(fp, "MakeModel", printer->make_model);
+
+    cupsFilePutConf(fp, "DeviceURI", printer->device_uri);
 
     if (printer->port_monitor)
-      cupsFilePrintf(fp, "PortMonitor %s\n", printer->port_monitor);
+      cupsFilePutConf(fp, "PortMonitor", printer->port_monitor);
 
     if (printer->state == IPP_PRINTER_STOPPED)
     {
       cupsFilePuts(fp, "State Stopped\n");
-      cupsFilePrintf(fp, "StateMessage %s\n", printer->state_message);
+
+      if (printer->state_message)
+        cupsFilePutConf(fp, "StateMessage", printer->state_message);
     }
     else
       cupsFilePuts(fp, "State Idle\n");
@@ -1489,7 +1535,24 @@ cupsdSaveAllPrinters(void)
     cupsFilePrintf(fp, "StateTime %d\n", (int)printer->state_time);
 
     for (i = 0; i < printer->num_reasons; i ++)
-      cupsFilePrintf(fp, "Reason %s\n", printer->reasons[i]);
+      cupsFilePutConf(fp, "Reason", printer->reasons[i]);
+
+    cupsFilePrintf(fp, "Type %d", printer->type);
+
+#ifdef HAVE_DNSSD
+    if (printer->product)
+      cupsFilePutConf(fp, "Product", printer->product);
+#endif /* HAVE_DNSSD */
+
+    for (ptr = (char *)cupsArrayFirst(printer->filters);
+         ptr;
+        ptr = (char *)cupsArrayNext(printer->filters))
+      cupsFilePutConf(fp, "Filter", ptr);
+
+    for (ptr = (char *)cupsArrayFirst(printer->pre_filters);
+         ptr;
+        ptr = (char *)cupsArrayNext(printer->pre_filters))
+      cupsFilePutConf(fp, "PreFilter", ptr);
 
     if (printer->accepting)
       cupsFilePuts(fp, "Accepting Yes\n");
@@ -1501,80 +1564,50 @@ cupsdSaveAllPrinters(void)
     else
       cupsFilePuts(fp, "Shared No\n");
 
-    cupsFilePrintf(fp, "JobSheets %s %s\n", printer->job_sheets[0],
-            printer->job_sheets[1]);
+    snprintf(value, sizeof(value), "%s %s", printer->job_sheets[0],
+             printer->job_sheets[1]);
+    cupsFilePutConf(fp, "JobSheets", value);
 
     cupsFilePrintf(fp, "QuotaPeriod %d\n", printer->quota_period);
     cupsFilePrintf(fp, "PageLimit %d\n", printer->page_limit);
     cupsFilePrintf(fp, "KLimit %d\n", printer->k_limit);
 
     for (i = 0; i < printer->num_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]);
-    }
+      cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser",
+                      printer->users[i]);
 
     if (printer->op_policy)
-      cupsFilePrintf(fp, "OpPolicy %s\n", printer->op_policy);
+      cupsFilePutConf(fp, "OpPolicy", printer->op_policy);
     if (printer->error_policy)
-      cupsFilePrintf(fp, "ErrorPolicy %s\n", printer->error_policy);
+      cupsFilePutConf(fp, "ErrorPolicy", printer->error_policy);
 
     for (i = printer->num_options, option = printer->options;
          i > 0;
         i --, option ++)
     {
-      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);
+      snprintf(value, sizeof(value), "%s %s", option->name, option->value);
+      cupsFilePutConf(fp, "Option", value);
     }
 
     if ((marker = ippFindAttribute(printer->attrs, "marker-colors",
                                    IPP_TAG_NAME)) != NULL)
     {
-      cupsFilePrintf(fp, "Attribute %s ", marker->name);
+      snprintf(value, sizeof(value), "%s ", marker->name);
 
-      for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+      for (i = 0, ptr = value + strlen(value);
+           i < marker->num_values && ptr < (value + sizeof(value) - 1);
+          i ++)
       {
         if (i)
-         cupsFilePutChar(fp, ',');
+         *ptr++ = ',';
 
-        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);
+        strlcpy(ptr, marker->values[i].string.text,
+               value + sizeof(value) - ptr);
+        ptr += strlen(ptr);
       }
 
-      cupsFilePuts(fp, "\n");
+      *ptr = '\0';
+      cupsFilePutConf(fp, "Attribute", value);
     }
 
     if ((marker = ippFindAttribute(printer->attrs, "marker-levels",
@@ -1590,67 +1623,52 @@ cupsdSaveAllPrinters(void)
     if ((marker = ippFindAttribute(printer->attrs, "marker-message",
                                    IPP_TAG_TEXT)) != NULL)
     {
-      cupsFilePrintf(fp, "Attribute %s ", marker->name);
+      snprintf(value, sizeof(value), "%s %s", marker->name,
+               marker->values[0].string.text);
 
-      if ((ptr = strchr(marker->values[0].string.text, '#')) != NULL)
-      {
-       cupsFileWrite(fp, marker->values[0].string.text,
-                     ptr - marker->values[0].string.text);
-       cupsFilePutChar(fp, '\\');
-       cupsFilePuts(fp, ptr);
-      }
-      else
-       cupsFilePuts(fp, marker->values[0].string.text);
-
-      cupsFilePuts(fp, "\n");
+      cupsFilePutConf(fp, "Attribute", value);
     }
 
     if ((marker = ippFindAttribute(printer->attrs, "marker-names",
                                    IPP_TAG_NAME)) != NULL)
     {
-      cupsFilePrintf(fp, "Attribute %s ", marker->name);
+      snprintf(value, sizeof(value), "%s ", marker->name);
 
-      for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+      for (i = 0, ptr = value + strlen(value);
+           i < marker->num_values && ptr < (value + sizeof(value) - 1);
+          i ++)
       {
         if (i)
-         cupsFilePutChar(fp, ',');
+         *ptr++ = ',';
 
-        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);
+        strlcpy(ptr, marker->values[i].string.text,
+               value + sizeof(value) - ptr);
+        ptr += strlen(ptr);
       }
 
-      cupsFilePuts(fp, "\n");
+      *ptr = '\0';
+      cupsFilePutConf(fp, "Attribute", value);
     }
 
     if ((marker = ippFindAttribute(printer->attrs, "marker-types",
                                    IPP_TAG_KEYWORD)) != NULL)
     {
-      cupsFilePrintf(fp, "Attribute %s ", marker->name);
+      snprintf(value, sizeof(value), "%s ", marker->name);
 
-      for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+      for (i = 0, ptr = value + strlen(value);
+           i < marker->num_values && ptr < (value + sizeof(value) - 1);
+          i ++)
       {
         if (i)
-         cupsFilePutChar(fp, ',');
+         *ptr++ = ',';
 
-        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);
+        strlcpy(ptr, marker->values[i].string.text,
+               value + sizeof(value) - ptr);
+        ptr += strlen(ptr);
       }
 
-      cupsFilePuts(fp, "\n");
+      *ptr = '\0';
+      cupsFilePutConf(fp, "Attribute", value);
     }
 
     cupsFilePuts(fp, "</Printer>\n");
index 3f76edc722e011144aae0bbe221c1ea3f25e4d72..1c4b49f002d495cf2ad1542869dd2bbf2d00ce77 100644 (file)
@@ -88,6 +88,8 @@ typedef struct cupsd_printer_s
   char         *alert,                 /* PSX printer-alert value */
                *alert_description;     /* PSX printer-alert-description value */
   time_t       marker_time;            /* Last time marker attributes were updated */
+  cups_array_t *filters,               /* Filters for queue */
+               *pre_filters;           /* Pre-filters for queue */
 
 #ifdef __APPLE__
   char         *recoverable;           /* com.apple.print.recoverable-message */