]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/classes.c
Fix source file header text duplication text duplication.
[thirdparty/cups.git] / scheduler / classes.c
index da828ce7497638f8d632ee247f855d54f2648beb..57f9a8f44ffd64790afc33b3c83d46d932280a1f 100644 (file)
@@ -1,30 +1,14 @@
 /*
- * "$Id: classes.c 7608 2008-05-21 01:37:21Z mike $"
+ * Printer class routines for the CUPS scheduler.
  *
- *   Printer class routines for the Common UNIX Printing System (CUPS).
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
- *   Copyright 2007 by Apple Inc.
- *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
- *
- *   These coded instructions, statements, and computer programs are the
- *   property of Apple Inc. and are protected by Federal copyright
- *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
- *   which should have been included with this file.  If this file is
- *   file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- *   cupsdAddClass()                 - Add a class to the system.
- *   cupsdAddPrinterToClass()        - Add a printer to a class...
- *   cupsdDeletePrinterFromClass()   - Delete a printer from a class.
- *   cupsdDeletePrinterFromClasses() - Delete a printer from all classes.
- *   cupsdDeleteAllClasses()         - Remove all classes from the system.
- *   cupsdFindAvailablePrinter()     - Find an available printer in a class.
- *   cupsdFindClass()                - Find the named class.
- *   cupsdLoadAllClasses()           - Load classes from the classes.conf file.
- *   cupsdSaveAllClasses()           - Save classes to the classes.conf file.
- *   cupsdUpdateImplicitClasses()    - Update the accepting state of implicit
- *                                     classes.
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file.  If this file is
+ * missing or damaged, see the license at "http://www.cups.org/".
  */
 
 /*
@@ -42,6 +26,7 @@ cupsd_printer_t *                     /* O - New class */
 cupsdAddClass(const char *name)                /* I - Name of class */
 {
   cupsd_printer_t      *c;             /* New class */
+  char                 uri[1024];      /* Class URI */
 
 
  /*
@@ -56,9 +41,11 @@ cupsdAddClass(const char *name)              /* I - Name of class */
 
     c->type = CUPS_PRINTER_CLASS;
 
-    cupsdSetStringf(&c->uri, "ipp://%s:%d/classes/%s", ServerName, LocalPort,
-                    name);
-    cupsdSetString(&c->error_policy, "retry-job");
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                    ServerName, RemotePort, "/classes/%s", name);
+    cupsdSetString(&c->uri, uri);
+
+    cupsdSetString(&c->error_policy, "retry-current-job");
   }
 
   return (c);
@@ -93,7 +80,7 @@ cupsdAddPrinterToClass(
   if (c->num_printers == 0)
     temp = malloc(sizeof(cupsd_printer_t *));
   else
-    temp = realloc(c->printers, sizeof(cupsd_printer_t *) * (c->num_printers + 1));
+    temp = realloc(c->printers, sizeof(cupsd_printer_t *) * (size_t)(c->num_printers + 1));
 
   if (temp == NULL)
   {
@@ -118,14 +105,12 @@ cupsdAddPrinterToClass(
  * 'cupsdDeletePrinterFromClass()' - Delete a printer from a class.
  */
 
-void
+int                                    /* O - 1 if class changed, 0 otherwise */
 cupsdDeletePrinterFromClass(
     cupsd_printer_t *c,                        /* I - Class to delete from */
     cupsd_printer_t *p)                        /* I - Printer to delete */
 {
-  int          i;                      /* Looping var */
-  cups_ptype_t type,                   /* Class type */
-               oldtype;                /* Old class type */
+  int  i;                              /* Looping var */
 
 
  /*
@@ -149,33 +134,18 @@ cupsdDeletePrinterFromClass(
     c->num_printers --;
     if (i < c->num_printers)
       memmove(c->printers + i, c->printers + i + 1,
-              (c->num_printers - i) * sizeof(cupsd_printer_t *));
+              (size_t)(c->num_printers - i) * sizeof(cupsd_printer_t *));
   }
   else
-    return;
+    return (0);
 
  /*
-  * Recompute the printer type mask as needed...
+  * Update the IPP attributes (have to do this for member-names)...
   */
 
-  if (c->num_printers > 0)
-  {
-    oldtype = c->type;
-    type    = c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT);
-    c->type = ~CUPS_PRINTER_REMOTE;
-
-    for (i = 0; i < c->num_printers; i ++)
-      c->type &= c->printers[i]->type;
+  cupsdSetPrinterAttrs(c);
 
-    c->type |= type;
-
-   /*
-    * Update the IPP attributes...
-    */
-
-    if (c->type != oldtype)
-      cupsdSetPrinterAttrs(c);
-  }
+  return (1);
 }
 
 
@@ -183,10 +153,11 @@ cupsdDeletePrinterFromClass(
  * 'cupsdDeletePrinterFromClasses()' - Delete a printer from all classes.
  */
 
-void
+int                                    /* O - 1 if class changed, 0 otherwise */
 cupsdDeletePrinterFromClasses(
     cupsd_printer_t *p)                        /* I - Printer to delete */
 {
+  int                  changed = 0;    /* Any class changed? */
   cupsd_printer_t      *c;             /* Pointer to current class */
 
 
@@ -195,43 +166,13 @@ cupsdDeletePrinterFromClasses(
   * from each class listed...
   */
 
-  for (c = (cupsd_printer_t *)cupsArrayFirst(Printers);
-       c;
-       c = (cupsd_printer_t *)cupsArrayNext(Printers))
-    if (c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
-      cupsdDeletePrinterFromClass(c, p);
-
- /*
-  * Then clean out any empty implicit classes...
-  */
-
-  for (c = (cupsd_printer_t *)cupsArrayFirst(ImplicitPrinters);
-       c;
-       c = (cupsd_printer_t *)cupsArrayNext(ImplicitPrinters))
-    if (c->num_printers == 0)
-    {
-      cupsdLogMessage(CUPSD_LOG_DEBUG, "Deleting implicit class \"%s\"...",
-                      c->name);
-      cupsdDeletePrinter(c, 0);
-    }
-}
-
-
-/*
- * 'cupsdDeleteAllClasses()' - Remove all classes from the system.
- */
-
-void
-cupsdDeleteAllClasses(void)
-{
-  cupsd_printer_t      *c;             /* Pointer to current printer/class */
-
-
   for (c = (cupsd_printer_t *)cupsArrayFirst(Printers);
        c;
        c = (cupsd_printer_t *)cupsArrayNext(Printers))
     if (c->type & CUPS_PRINTER_CLASS)
-      cupsdDeletePrinter(c, 0);
+      changed |= cupsdDeletePrinterFromClass(c, p);
+
+  return (changed);
 }
 
 
@@ -308,8 +249,7 @@ cupsdFindClass(const char *name)    /* I - Name of class */
   cupsd_printer_t      *c;             /* Current class/printer */
 
 
-  if ((c = cupsdFindDest(name)) != NULL &&
-      (c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)))
+  if ((c = cupsdFindDest(name)) != NULL && (c->type & CUPS_PRINTER_CLASS))
     return (c);
   else
     return (NULL);
@@ -323,9 +263,10 @@ cupsdFindClass(const char *name)   /* I - Name of class */
 void
 cupsdLoadAllClasses(void)
 {
+  int                  i;              /* Looping var */
   cups_file_t          *fp;            /* classes.conf file */
   int                  linenum;        /* Current line number */
-  char                 line[1024],     /* Line from file */
+  char                 line[4096],     /* Line from file */
                        *value,         /* Pointer to value */
                        *valueptr;      /* Pointer into value */
   cupsd_printer_t      *p,             /* Current printer class */
@@ -337,13 +278,8 @@ cupsdLoadAllClasses(void)
   */
 
   snprintf(line, sizeof(line), "%s/classes.conf", ServerRoot);
-  if ((fp = cupsFileOpen(line, "r")) == NULL)
-  {
-    if (errno != ENOENT)
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open %s - %s", line,
-                     strerror(errno));
+  if ((fp = cupsdOpenConfFile(line)) == NULL)
     return;
-  }
 
  /*
   * Read class configurations until we hit EOF...
@@ -358,8 +294,8 @@ cupsdLoadAllClasses(void)
     * Decode the directive...
     */
 
-    if (!strcasecmp(line, "<Class") ||
-        !strcasecmp(line, "<DefaultClass"))
+    if (!_cups_strcasecmp(line, "<Class") ||
+        !_cups_strcasecmp(line, "<DefaultClass"))
     {
      /*
       * <Class name> or <DefaultClass name>
@@ -387,17 +323,14 @@ cupsdLoadAllClasses(void)
        p->accepting = 1;
        p->state     = IPP_PRINTER_IDLE;
 
-        if (!strcasecmp(line, "<DefaultClass"))
+        if (!_cups_strcasecmp(line, "<DefaultClass"))
          DefaultPrinter = p;
       }
       else
-      {
         cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-        break;
-      }
     }
-    else if (!strcasecmp(line, "</Class>"))
+    else if (!_cups_strcasecmp(line, "</Class>") || !_cups_strcasecmp(line, "</DefaultClass>"))
     {
       if (p != NULL)
       {
@@ -405,36 +338,40 @@ cupsdLoadAllClasses(void)
         p = NULL;
       }
       else
-      {
         cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-        break;
-      }
     }
     else if (!p)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "Syntax error on line %d of classes.conf.", linenum);
-      break;
     }
-    else if (!strcasecmp(line, "AuthInfoRequired"))
+    else if (!_cups_strcasecmp(line, "UUID"))
+    {
+      if (value && !strncmp(value, "urn:uuid:", 9))
+        cupsdSetString(&(p->uuid), value);
+      else
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Bad UUID on line %d of classes.conf.", linenum);
+    }
+    else if (!_cups_strcasecmp(line, "AuthInfoRequired"))
     {
       if (!cupsdSetAuthInfoRequired(p, value, NULL))
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Bad AuthInfoRequired on line %d of classes.conf.",
                        linenum);
     }
-    else if (!strcasecmp(line, "Info"))
+    else if (!_cups_strcasecmp(line, "Info"))
     {
       if (value)
         cupsdSetString(&p->info, value);
     }
-    else if (!strcasecmp(line, "Location"))
+    else if (!_cups_strcasecmp(line, "Location"))
     {
       if (value)
         cupsdSetString(&p->location, value);
     }
-    else if (!strcasecmp(line, "Option") && value)
+    else if (!_cups_strcasecmp(line, "Option") && value)
     {
      /*
       * Option name value
@@ -453,13 +390,13 @@ cupsdLoadAllClasses(void)
                                       &(p->options));
       }
     }
-    else if (!strcasecmp(line, "Printer"))
+    else if (!_cups_strcasecmp(line, "Printer"))
     {
       if (!value)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-       break;
+        continue;
       }
       else if ((temp = cupsdFindPrinter(value)) == NULL)
       {
@@ -475,9 +412,8 @@ cupsdLoadAllClasses(void)
        {
          cupsdSetString(&temp->make_model, "Remote Printer on unknown");
 
-          temp->state       = IPP_PRINTER_STOPPED;
-         temp->type        |= CUPS_PRINTER_REMOTE;
-         temp->browse_time = 2147483647;
+          temp->state = IPP_PRINTER_STOPPED;
+         temp->type  |= CUPS_PRINTER_REMOTE;
 
          cupsdSetString(&temp->location, "Location Unknown");
          cupsdSetString(&temp->info, "No Information Available");
@@ -490,25 +426,35 @@ cupsdLoadAllClasses(void)
       if (temp)
         cupsdAddPrinterToClass(p, temp);
     }
-    else if (!strcasecmp(line, "State"))
+    else if (!_cups_strcasecmp(line, "State"))
     {
      /*
       * Set the initial queue state...
       */
 
-      if (!strcasecmp(value, "idle"))
+      if (!_cups_strcasecmp(value, "idle"))
         p->state = IPP_PRINTER_IDLE;
-      else if (!strcasecmp(value, "stopped"))
+      else if (!_cups_strcasecmp(value, "stopped"))
+      {
         p->state = IPP_PRINTER_STOPPED;
+
+        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,
                        "Syntax error on line %d of classes.conf.",
                        linenum);
-       break;
-      }
     }
-    else if (!strcasecmp(line, "StateMessage"))
+    else if (!_cups_strcasecmp(line, "StateMessage"))
     {
      /*
       * Set the initial queue state message...
@@ -517,7 +463,7 @@ cupsdLoadAllClasses(void)
       if (value)
        strlcpy(p->state_message, value, sizeof(p->state_message));
     }
-    else if (!strcasecmp(line, "StateTime"))
+    else if (!_cups_strcasecmp(line, "StateTime"))
     {
      /*
       * Set the state time...
@@ -526,55 +472,49 @@ cupsdLoadAllClasses(void)
       if (value)
         p->state_time = atoi(value);
     }
-    else if (!strcasecmp(line, "Accepting"))
+    else if (!_cups_strcasecmp(line, "Accepting"))
     {
      /*
       * Set the initial accepting state...
       */
 
       if (value &&
-          (!strcasecmp(value, "yes") ||
-           !strcasecmp(value, "on") ||
-           !strcasecmp(value, "true")))
+          (!_cups_strcasecmp(value, "yes") ||
+           !_cups_strcasecmp(value, "on") ||
+           !_cups_strcasecmp(value, "true")))
         p->accepting = 1;
       else if (value &&
-               (!strcasecmp(value, "no") ||
-               !strcasecmp(value, "off") ||
-               !strcasecmp(value, "false")))
+               (!_cups_strcasecmp(value, "no") ||
+               !_cups_strcasecmp(value, "off") ||
+               !_cups_strcasecmp(value, "false")))
         p->accepting = 0;
       else
-      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.",
                        linenum);
-       break;
-      }
     }
-    else if (!strcasecmp(line, "Shared"))
+    else if (!_cups_strcasecmp(line, "Shared"))
     {
      /*
       * Set the initial shared state...
       */
 
       if (value &&
-          (!strcasecmp(value, "yes") ||
-           !strcasecmp(value, "on") ||
-           !strcasecmp(value, "true")))
+          (!_cups_strcasecmp(value, "yes") ||
+           !_cups_strcasecmp(value, "on") ||
+           !_cups_strcasecmp(value, "true")))
         p->shared = 1;
       else if (value &&
-               (!strcasecmp(value, "no") ||
-               !strcasecmp(value, "off") ||
-               !strcasecmp(value, "false")))
+               (!_cups_strcasecmp(value, "no") ||
+               !_cups_strcasecmp(value, "off") ||
+               !_cups_strcasecmp(value, "false")))
         p->shared = 0;
       else
-      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.",
                        linenum);
-       break;
-      }
     }
-    else if (!strcasecmp(line, "JobSheets"))
+    else if (!_cups_strcasecmp(line, "JobSheets"))
     {
      /*
       * Set the initial job sheets...
@@ -607,74 +547,56 @@ cupsdLoadAllClasses(void)
        }
       }
       else
-      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-       break;
-      }
     }
-    else if (!strcasecmp(line, "AllowUser"))
+    else if (!_cups_strcasecmp(line, "AllowUser"))
     {
       if (value)
       {
         p->deny_users = 0;
-        cupsdAddPrinterUser(p, value);
+        cupsdAddString(&(p->users), value);
       }
       else
-      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-       break;
-      }
     }
-    else if (!strcasecmp(line, "DenyUser"))
+    else if (!_cups_strcasecmp(line, "DenyUser"))
     {
       if (value)
       {
         p->deny_users = 1;
-        cupsdAddPrinterUser(p, value);
+        cupsdAddString(&(p->users), value);
       }
       else
-      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-       break;
-      }
     }
-    else if (!strcasecmp(line, "QuotaPeriod"))
+    else if (!_cups_strcasecmp(line, "QuotaPeriod"))
     {
       if (value)
         p->quota_period = atoi(value);
       else
-      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-       break;
-      }
     }
-    else if (!strcasecmp(line, "PageLimit"))
+    else if (!_cups_strcasecmp(line, "PageLimit"))
     {
       if (value)
         p->page_limit = atoi(value);
       else
-      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-       break;
-      }
     }
-    else if (!strcasecmp(line, "KLimit"))
+    else if (!_cups_strcasecmp(line, "KLimit"))
     {
       if (value)
         p->k_limit = atoi(value);
       else
-      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-       break;
-      }
     }
-    else if (!strcasecmp(line, "OpPolicy"))
+    else if (!_cups_strcasecmp(line, "OpPolicy"))
     {
       if (value)
       {
@@ -692,22 +614,21 @@ cupsdLoadAllClasses(void)
                          value, linenum);
       }
       else
-      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-       break;
-      }
     }
-    else if (!strcasecmp(line, "ErrorPolicy"))
+    else if (!_cups_strcasecmp(line, "ErrorPolicy"))
     {
       if (value)
-        cupsdSetString(&p->error_policy, value);
-      else
       {
+        if (strcmp(value, "retry-current-job") && strcmp(value, "retry-job"))
+         cupsdLogMessage(CUPSD_LOG_WARN,
+                         "ErrorPolicy %s ignored on line %d of classes.conf",
+                         value, linenum);
+      }
+      else
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
-       break;
-      }
     }
     else
     {
@@ -733,49 +654,27 @@ void
 cupsdSaveAllClasses(void)
 {
   cups_file_t          *fp;            /* classes.conf file */
-  char                 temp[1024];     /* Temporary string */
-  char                 backup[1024];   /* classes.conf.O file */
+  char                 filename[1024], /* classes.conf filename */
+                       temp[1024],     /* Temporary string */
+                       value[2048],    /* Value string */
+                       *name;          /* Current user name */
   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 */
 
 
  /*
   * Create the classes.conf file...
   */
 
-  snprintf(temp, sizeof(temp), "%s/classes.conf", ServerRoot);
-  snprintf(backup, sizeof(backup), "%s/classes.conf.O", ServerRoot);
-
-  if (rename(temp, backup))
-  {
-    if (errno != ENOENT)
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to backup classes.conf - %s",
-                      strerror(errno));
-  }
-
-  if ((fp = cupsFileOpen(temp, "w")) == NULL)
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to save classes.conf - %s",
-                    strerror(errno));
+  snprintf(filename, sizeof(filename), "%s/classes.conf", ServerRoot);
 
-    if (rename(backup, temp))
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to restore classes.conf - %s",
-                      strerror(errno));
+  if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm)) == NULL)
     return;
-  }
-  else
-    cupsdLogMessage(CUPSD_LOG_INFO, "Saving classes.conf...");
 
- /*
-  * Restrict access to the file...
-  */
-
-  fchown(cupsFileNumber(fp), RunUser, Group);
-  fchmod(cupsFileNumber(fp), 0600);
+  cupsdLogMessage(CUPSD_LOG_INFO, "Saving classes.conf...");
 
  /*
   * Write a small header to the file...
@@ -787,6 +686,7 @@ cupsdSaveAllClasses(void)
 
   cupsFilePuts(fp, "# Class 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 class known to the system...
@@ -801,7 +701,6 @@ cupsdSaveAllClasses(void)
     */
 
     if ((pclass->type & CUPS_PRINTER_REMOTE) ||
-        (pclass->type & CUPS_PRINTER_IMPLICIT) ||
         !(pclass->type & CUPS_PRINTER_CLASS))
       continue;
 
@@ -814,55 +713,42 @@ cupsdSaveAllClasses(void)
     else
       cupsFilePrintf(fp, "<Class %s>\n", pclass->name);
 
-    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');
-    }
+    cupsFilePrintf(fp, "UUID %s\n", pclass->uuid);
 
-    if (pclass->info)
+    if (pclass->num_auth_info_required > 0)
     {
-      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");
 
@@ -878,84 +764,40 @@ cupsdSaveAllClasses(void)
     else
       cupsFilePuts(fp, "Shared No\n");
 
-    cupsFilePrintf(fp, "JobSheets %s %s\n", pclass->job_sheets[0],
-                   pclass->job_sheets[1]);
+    snprintf(value, sizeof(value), "%s %s", pclass->job_sheets[0],
+             pclass->job_sheets[1]);
+    cupsFilePutConf(fp, "JobSheets", value);
 
-    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]);
-    }
+    for (i = 0; i < pclass->num_printers; i ++)
+      cupsFilePrintf(fp, "Printer %s\n", pclass->printers[i]->name);
 
     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]);
+    for (name = (char *)cupsArrayFirst(pclass->users);
+         name;
+        name = (char *)cupsArrayNext(pclass->users))
+      cupsFilePutConf(fp, pclass->deny_users ? "DenyUser" : "AllowUser", name);
 
-    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");
+    if (pclass == DefaultPrinter)
+      cupsFilePuts(fp, "</DefaultClass>\n");
+    else
+      cupsFilePuts(fp, "</Class>\n");
   }
 
-  cupsFileClose(fp);
-}
-
-
-/*
- * 'cupsdUpdateImplicitClasses()' - Update the accepting state of implicit
- *                                  classes.
- */
-
-void
-cupsdUpdateImplicitClasses(void)
-{
-  int                  i;              /* Looping var */
-  cupsd_printer_t      *pclass;        /* Current class */
-  int                  accepting;      /* printer-is-accepting-jobs value */
-
-
-  for (pclass = (cupsd_printer_t *)cupsArrayFirst(ImplicitPrinters);
-       pclass;
-       pclass = (cupsd_printer_t *)cupsArrayNext(ImplicitPrinters))
-  {
-   /*
-    * Loop through the printers to come up with a composite state...
-    */
-
-    for (i = 0, accepting = 0; i < pclass->num_printers; i ++)
-      if ((accepting = pclass->printers[i]->accepting) != 0)
-       break;
-
-    pclass->accepting = accepting;
-  }
+  cupsdCloseCreatedConfFile(fp, filename);
 }
-
-
-/*
- * End of "$Id: classes.c 7608 2008-05-21 01:37:21Z mike $".
- */