]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/classes.c
Update svn:keyword properties.
[thirdparty/cups.git] / scheduler / classes.c
index d346976001221a2e6c9779aaff3fe7dbd76c9405..5ced554f599e1e195a5a12bfe620026ba816cb04 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * "$Id: classes.c 7724 2008-07-14 06:06:06Z mike $"
+ * "$Id$"
  *
- *   Printer class routines for the Common UNIX Printing System (CUPS).
+ *   Printer class routines for the CUPS scheduler.
  *
- *   Copyright 2007-2009 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -22,8 +22,6 @@
  *   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.
  */
 
 /*
@@ -41,6 +39,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 */
 
 
  /*
@@ -55,9 +54,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);
@@ -117,7 +118,7 @@ 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 */
@@ -149,13 +150,15 @@ cupsdDeletePrinterFromClass(
               (c->num_printers - i) * sizeof(cupsd_printer_t *));
   }
   else
-    return;
+    return (0);
 
  /*
   * Update the IPP attributes (have to do this for member-names)...
   */
 
   cupsdSetPrinterAttrs(c);
+
+  return (1);
 }
 
 
@@ -163,10 +166,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 */
 
 
@@ -178,22 +182,10 @@ cupsdDeletePrinterFromClasses(
   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...
-  */
+    if (c->type & CUPS_PRINTER_CLASS)
+      changed |= cupsdDeletePrinterFromClass(c, p);
 
-  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);
-    }
+  return (changed);
 }
 
 
@@ -270,8 +262,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);
@@ -285,6 +276,7 @@ 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[4096],     /* Line from file */
@@ -299,13 +291,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...
@@ -320,8 +307,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>
@@ -349,14 +336,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);
     }
-    else if (!strcasecmp(line, "</Class>"))
+    else if (!_cups_strcasecmp(line, "</Class>"))
     {
       if (p != NULL)
       {
@@ -372,24 +359,32 @@ cupsdLoadAllClasses(void)
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "Syntax error on line %d of classes.conf.", linenum);
     }
-    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
@@ -408,7 +403,7 @@ cupsdLoadAllClasses(void)
                                       &(p->options));
       }
     }
-    else if (!strcasecmp(line, "Printer"))
+    else if (!_cups_strcasecmp(line, "Printer"))
     {
       if (!value)
       {
@@ -430,9 +425,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");
@@ -445,25 +439,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;
-       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,
                        "Syntax error on line %d of classes.conf.",
                        linenum);
     }
-    else if (!strcasecmp(line, "StateMessage"))
+    else if (!_cups_strcasecmp(line, "StateMessage"))
     {
      /*
       * Set the initial queue state message...
@@ -472,7 +476,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...
@@ -481,49 +485,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);
     }
-    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);
     }
-    else if (!strcasecmp(line, "JobSheets"))
+    else if (!_cups_strcasecmp(line, "JobSheets"))
     {
      /*
       * Set the initial job sheets...
@@ -559,29 +563,29 @@ cupsdLoadAllClasses(void)
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
     }
-    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);
     }
-    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);
     }
-    else if (!strcasecmp(line, "QuotaPeriod"))
+    else if (!_cups_strcasecmp(line, "QuotaPeriod"))
     {
       if (value)
         p->quota_period = atoi(value);
@@ -589,7 +593,7 @@ cupsdLoadAllClasses(void)
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
     }
-    else if (!strcasecmp(line, "PageLimit"))
+    else if (!_cups_strcasecmp(line, "PageLimit"))
     {
       if (value)
         p->page_limit = atoi(value);
@@ -597,7 +601,7 @@ cupsdLoadAllClasses(void)
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
     }
-    else if (!strcasecmp(line, "KLimit"))
+    else if (!_cups_strcasecmp(line, "KLimit"))
     {
       if (value)
         p->k_limit = atoi(value);
@@ -605,7 +609,7 @@ cupsdLoadAllClasses(void)
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
     }
-    else if (!strcasecmp(line, "OpPolicy"))
+    else if (!_cups_strcasecmp(line, "OpPolicy"))
     {
       if (value)
       {
@@ -626,10 +630,15 @@ cupsdLoadAllClasses(void)
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of classes.conf.", linenum);
     }
-    else if (!strcasecmp(line, "ErrorPolicy"))
+    else if (!_cups_strcasecmp(line, "ErrorPolicy"))
     {
       if (value)
-        cupsdSetString(&p->error_policy, value);
+      {
+        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);
@@ -658,9 +667,10 @@ void
 cupsdSaveAllClasses(void)
 {
   cups_file_t          *fp;            /* classes.conf file */
-  char                 temp[1024],     /* Temporary string */
-                       backup[1024],   /* printers.conf.O file */
-                       value[2048];    /* Value string */
+  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 */
@@ -672,35 +682,12 @@ cupsdSaveAllClasses(void)
   * 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...
@@ -712,6 +699,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...
@@ -726,7 +714,6 @@ cupsdSaveAllClasses(void)
     */
 
     if ((pclass->type & CUPS_PRINTER_REMOTE) ||
-        (pclass->type & CUPS_PRINTER_IMPLICIT) ||
         !(pclass->type & CUPS_PRINTER_CLASS))
       continue;
 
@@ -739,6 +726,8 @@ cupsdSaveAllClasses(void)
     else
       cupsFilePrintf(fp, "<Class %s>\n", pclass->name);
 
+    cupsFilePrintf(fp, "UUID %s\n", pclass->uuid);
+
     if (pclass->num_auth_info_required > 0)
     {
       switch (pclass->num_auth_info_required)
@@ -799,9 +788,10 @@ cupsdSaveAllClasses(void)
     cupsFilePrintf(fp, "PageLimit %d\n", pclass->page_limit);
     cupsFilePrintf(fp, "KLimit %d\n", pclass->k_limit);
 
-    for (i = 0; i < pclass->num_users; i ++)
-      cupsFilePutConf(fp, pclass->deny_users ? "DenyUser" : "AllowUser",
-                      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)
       cupsFilePutConf(fp, "OpPolicy", pclass->op_policy);
@@ -819,40 +809,10 @@ cupsdSaveAllClasses(void)
     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 7724 2008-07-14 06:06:06Z mike $".
+ * End of "$Id$".
  */