]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/printers.c
Fix parentheses in cupsdCleanJobs.
[thirdparty/cups.git] / scheduler / printers.c
index dca09626a07886324d34d50bb3c99b3956dd133b..e4841c0713cd2580fe1345d3385be05ecd352b8c 100644 (file)
@@ -1,14 +1,11 @@
 /*
  * Printer routines for the CUPS scheduler.
  *
- * Copyright 2007-2017 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright © 2007-2019 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
- * missing or damaged, see the license at "http://www.cups.org/".
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
  */
 
 /*
@@ -48,8 +45,7 @@ static int    compare_printers(void *first, void *second, void *data);
 static void    delete_printer_filters(cupsd_printer_t *p);
 static void    dirty_printer(cupsd_printer_t *p);
 static void    load_ppd(cupsd_printer_t *p);
-static ipp_t   *new_media_col(pwg_size_t *size, const char *source,
-                              const char *type);
+static ipp_t   *new_media_col(pwg_size_t *size);
 static void    write_xml_string(cups_file_t *fp, const char *s);
 
 
@@ -152,8 +148,32 @@ cupsdCreateCommonData(void)
   struct statfs                spoolinfo;      /* FS info for spool directory */
   double               spoolsize;      /* FS size */
 #endif /* HAVE_STATVFS */
-  static const int nups[] =            /* number-up-supported values */
+  static const char * const page_delivery[] =
+               {                       /* page-delivery-supported values */
+                 "reverse-order",
+                 "same-order"
+               };
+  static const char * const print_scaling[] =
+               {                       /* print-scaling-supported values */
+                 "auto",
+                 "auto-fit",
+                 "fill",
+                 "fit",
+                 "none"
+               };
+  static const int number_up[] =               /* number-up-supported values */
                { 1, 2, 4, 6, 9, 16 };
+  static const char * const number_up_layout[] =
+               {                       /* number-up-layout-supported values */
+                 "btlr",
+                 "btrl",
+                 "lrbt",
+                 "lrtb",
+                 "rlbt",
+                 "rltb",
+                 "tblr",
+                 "tbrl"
+               };
   static const int orients[4] =/* orientation-requested-supported values */
                {
                  IPP_PORTRAIT,
@@ -294,6 +314,7 @@ cupsdCreateCommonData(void)
                {                       /* job-creation-attributes-supported */
                  "copies",
                  "finishings",
+                 "finishings-col",
                  "ipp-attribute-fidelity",
                  "job-hold-until",
                  "job-name",
@@ -303,11 +324,14 @@ cupsdCreateCommonData(void)
                  "media-col",
                  "multiple-document-handling",
                  "number-up",
-                 "output-bin",
+                 "number-up-layout",
                  "orientation-requested",
+                 "output-bin",
+                 "page-delivery",
                  "page-ranges",
                  "print-color-mode",
                  "print-quality",
+                 "print-scaling",
                  "printer-resolution",
                  "sides"
                };
@@ -605,7 +629,10 @@ cupsdCreateCommonData(void)
 
   /* number-up-supported */
   ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-                 "number-up-supported", sizeof(nups) / sizeof(nups[0]), nups);
+                 "number-up-supported", sizeof(number_up) / sizeof(number_up[0]), number_up);
+
+  /* number-up-layout-supported */
+  ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "number-up-layout-supported", sizeof(number_up_layout) / sizeof(number_up_layout[0]), NULL, number_up_layout);
 
   /* operations-supported */
   ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
@@ -615,6 +642,9 @@ cupsdCreateCommonData(void)
   ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
                  "orientation-requested-supported", 4, orients);
 
+  /* page-delivery-supported */
+  ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "page-delivery-supported", sizeof(page_delivery) / sizeof(page_delivery[0]), NULL, page_delivery);
+
   /* page-ranges-supported */
   ippAddBoolean(CommonData, IPP_TAG_PRINTER, "page-ranges-supported", 1);
 
@@ -632,6 +662,9 @@ cupsdCreateCommonData(void)
   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
                "pdl-override-supported", NULL, "attempted");
 
+  /* print-scaling-supported */
+  ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-scaling-supported", sizeof(print_scaling) / sizeof(print_scaling[0]), NULL, print_scaling);
+
   /* printer-get-attributes-supported */
   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "printer-get-attributes-supported", NULL, "document-format");
 
@@ -809,6 +842,7 @@ cupsdDeletePrinter(
   cupsdClearString(&p->port_monitor);
   cupsdClearString(&p->op_policy);
   cupsdClearString(&p->error_policy);
+  cupsdClearString(&p->strings);
 
   cupsdClearString(&p->alert);
   cupsdClearString(&p->alert_description);
@@ -929,8 +963,14 @@ cupsdLoadAllPrinters(void)
     * Decode the directive...
     */
 
-    if (!_cups_strcasecmp(line, "<Printer") ||
-        !_cups_strcasecmp(line, "<DefaultPrinter"))
+    if (!_cups_strcasecmp(line, "NextPrinterId"))
+    {
+      if (value && (i = atoi(value)) > 0)
+        NextPrinterId = i;
+      else
+        cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of printers.conf.", linenum);
+    }
+    else if (!_cups_strcasecmp(line, "<Printer") || !_cups_strcasecmp(line, "<DefaultPrinter"))
     {
      /*
       * <Printer name> or <DefaultPrinter name>
@@ -967,17 +1007,21 @@ cupsdLoadAllPrinters(void)
         * Close out the current printer...
        */
 
+        if (!p->printer_id)
+        {
+          p->printer_id = NextPrinterId ++;
+          cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
+       }
+
         cupsdSetPrinterAttrs(p);
 
-        if (strncmp(p->device_uri, "file:", 5) &&
-           p->state != IPP_PRINTER_STOPPED)
+        if (strncmp(p->device_uri, "file:", 5) && p->state != IPP_PRINTER_STOPPED)
        {
         /*
           * See if the backend exists...
          */
 
-         snprintf(line, sizeof(line), "%s/backend/%s", ServerBin,
-                  p->device_uri);
+         snprintf(line, sizeof(line), "%s/backend/%s", ServerBin, p->device_uri);
 
           if ((valueptr = strchr(line + strlen(ServerBin), ':')) != NULL)
            *valueptr = '\0';           /* Chop everything but URI scheme */
@@ -989,8 +1033,7 @@ cupsdLoadAllPrinters(void)
            */
 
            p->state = IPP_PRINTER_STOPPED;
-           snprintf(p->state_message, sizeof(p->state_message),
-                    "Backend %s does not exist!", line);
+           snprintf(p->state_message, sizeof(p->state_message), "Backend %s does not exist!", line);
          }
         }
 
@@ -1005,6 +1048,13 @@ cupsdLoadAllPrinters(void)
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "Syntax error on line %d of printers.conf.", linenum);
     }
+    else if (!_cups_strcasecmp(line, "PrinterId"))
+    {
+      if (value && (i = atoi(value)) > 0)
+        p->printer_id = i;
+      else
+        cupsdLogMessage(CUPSD_LOG_ERROR, "Bad PrinterId on line %d of printers.conf.", linenum);
+    }
     else if (!_cups_strcasecmp(line, "UUID"))
     {
       if (value && !strncmp(value, "urn:uuid:", 9))
@@ -1461,6 +1511,8 @@ cupsdSaveAllPrinters(void)
   cupsFilePrintf(fp, "# Written by cupsd on %s\n", temp);
   cupsFilePuts(fp, "# DO NOT EDIT THIS FILE WHEN CUPSD IS RUNNING\n");
 
+  cupsFilePrintf(fp, "NextPrinterId %d\n", NextPrinterId);
+
  /*
   * Write each local printer known to the system...
   */
@@ -1485,6 +1537,9 @@ cupsdSaveAllPrinters(void)
     else
       cupsFilePrintf(fp, "<Printer %s>\n", printer->name);
 
+    if (printer->printer_id)
+      cupsFilePrintf(fp, "PrinterId %d\n", printer->printer_id);
+
     cupsFilePrintf(fp, "UUID %s\n", printer->uuid);
 
     if (printer->num_auth_info_required > 0)
@@ -2204,9 +2259,6 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
                *filter;                /* Current filter */
 
 
-  DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
-                p->type));
-
  /*
   * Make sure that we have the common attributes defined...
   */
@@ -2271,6 +2323,8 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
                "uri-authentication-supported", NULL, auth_supported);
   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
                "uri-security-supported", NULL, "none");
+  if (p->printer_id)
+    ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "printer-id", p->printer_id);
   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-name", NULL,
                p->name);
   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
@@ -2535,9 +2589,6 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
 
   add_printer_formats(p);
 
-  DEBUG_printf(("cupsdSetPrinterAttrs: leaving name = %s, type = %x\n", p->name,
-                p->type));
-
  /*
   * Add name-default attributes...
   */
@@ -2979,9 +3030,6 @@ cupsdValidateDest(
   int                  port;           /* Port portion of URI */
 
 
-  DEBUG_printf(("cupsdValidateDest(uri=\"%s\", dtype=%p, printer=%p)\n", uri,
-                dtype, printer));
-
  /*
   * Initialize return values...
   */
@@ -3085,8 +3133,6 @@ cupsdValidateDest(
     }
   }
 
-  DEBUG_printf(("localized hostname is \"%s\"...\n", localname));
-
  /*
   * Find a matching printer or class...
   */
@@ -3317,16 +3363,17 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */
     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("document-format-default"));
     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("finishings-default"));
     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-account-id-default"));
-    cupsArrayAdd(CommonDefaults,
-                 _cupsStrAlloc("job-accounting-user-id-default"));
+    cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-accounting-user-id-default"));
     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-cancel-after-default"));
     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-hold-until-default"));
     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-priority-default"));
     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-sheets-default"));
     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("media-col-default"));
+    cupsArrayAdd(CommonDefaults, _cupsStrAlloc("notify-lease-duration-default"));
+    cupsArrayAdd(CommonDefaults, _cupsStrAlloc("notify-events-default"));
     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("number-up-default"));
-    cupsArrayAdd(CommonDefaults,
-                 _cupsStrAlloc("orientation-requested-default"));
+    cupsArrayAdd(CommonDefaults, _cupsStrAlloc("orientation-requested-default"));
+    cupsArrayAdd(CommonDefaults, _cupsStrAlloc("print-quality-default"));
   }
 
  /*
@@ -3369,7 +3416,7 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */
                 "document-format-default", NULL, "application/octet-stream");
 
   if (!cupsGetOption("job-cancel-after", p->num_options, p->options))
-    ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+    ippAddInteger(p->attrs, IPP_TAG_PRINTER, MaxJobTime > 0 ? IPP_TAG_INTEGER : IPP_TAG_NOVALUE,
                  "job-cancel-after-default", MaxJobTime);
 
   if (!cupsGetOption("job-hold-until", p->num_options, p->options))
@@ -3798,21 +3845,20 @@ dirty_printer(cupsd_printer_t *p)       /* I - Printer */
 static void
 load_ppd(cupsd_printer_t *p)           /* I - Printer */
 {
-  int          i, j, k;                /* Looping vars */
+  int          i, j;                   /* Looping vars */
   char         cache_name[1024];       /* Cache filename */
   struct stat  cache_info;             /* Cache file info */
   ppd_file_t   *ppd;                   /* PPD file */
   char         ppd_name[1024];         /* PPD filename */
   struct stat  ppd_info;               /* PPD file info */
-  int          num_media;              /* Number of media options */
+  char         strings_name[1024];     /* Strings filename */
+  int          num_media;              /* Number of media values */
   ppd_size_t   *size;                  /* Current PPD size */
   ppd_option_t *duplex,                /* Duplex option */
                *output_bin,            /* OutputBin option */
                *output_mode,           /* OutputMode option */
                *resolution;            /* (Set|JCL|)Resolution option */
-  ppd_choice_t *choice,                /* Current PPD choice */
-               *input_slot,            /* Current input slot */
-               *media_type;            /* Current media type */
+  ppd_choice_t *choice;                /* Current PPD choice */
   ppd_attr_t   *ppd_attr;              /* PPD attribute */
   int          xdpi,                   /* Horizontal resolution */
                ydpi;                   /* Vertical resolution */
@@ -3862,6 +3908,8 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
   if (stat(ppd_name, &ppd_info))
     ppd_info.st_mtime = 1;
 
+  snprintf(strings_name, sizeof(strings_name), "%s/%s.strings", CacheDir, p->name);
+
   ippDelete(p->ppd_attrs);
   p->ppd_attrs = NULL;
 
@@ -4033,6 +4081,14 @@ load_ppd(cupsd_printer_t *p)             /* I - Printer */
     ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
                 "printer-make-and-model", NULL, p->make_model);
 
+    if (p->pc && p->pc->strings)
+      _cupsMessageSave(strings_name, _CUPS_MESSAGE_STRINGS, p->pc->strings);
+
+    if (!access(strings_name, R_OK))
+      cupsdSetString(&p->strings, strings_name);
+    else
+      cupsdClearString(&p->strings);
+
    /*
     * Add media options from the PPD file...
     */
@@ -4072,20 +4128,8 @@ load_ppd(cupsd_printer_t *p)             /* I - Printer */
       {
         ipp_t  *col;                   /* Collection value */
 
-       input_slot = ppdFindMarkedChoice(ppd, "InputSlot");
-       media_type = ppdFindMarkedChoice(ppd, "MediaType");
-       col        = new_media_col(pwgsize,
-                                  input_slot ?
-                                      _ppdCacheGetSource(p->pc,
-                                                         input_slot->choice) :
-                                      NULL,
-                                  media_type ?
-                                      _ppdCacheGetType(p->pc,
-                                                       media_type->choice) :
-                                      NULL);
-
-       ippAddCollection(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-default",
-                        col);
+       col = new_media_col(pwgsize);
+       ippAddCollection(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-default", col);
         ippDelete(col);
       }
 
@@ -4279,89 +4323,19 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
       * media-col-database
       */
 
-      num_media = p->pc->num_sizes;
-      if (p->pc->num_sources)
+      if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-database", p->pc->num_sizes, NULL)) != NULL)
       {
-        if (p->pc->num_types > 0)
-         num_media += p->pc->num_sizes * p->pc->num_sources *
-                      p->pc->num_types;
-       else
-          num_media += p->pc->num_sizes * p->pc->num_sources;
-      }
-      else if (p->pc->num_types)
-        num_media += p->pc->num_sizes * p->pc->num_types;
+       /*
+       * Add each page size without source or type...
+       */
 
-      if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER,
-                                    "media-col-database", num_media,
-                                   NULL)) != NULL)
-      {
-        for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, val = attr->values;
-            i > 0;
-            i --, pwgsize ++)
+        for (i = 0, pwgsize = p->pc->sizes; i < p->pc->num_sizes; i ++, pwgsize ++)
        {
-        /*
-         * Start by adding the page size without source or type...
-         */
-
-         ppdMarkOption(ppd, "PageSize", pwgsize->map.ppd);
-
-          val->collection = new_media_col(pwgsize, NULL, NULL);
-         val ++;
+         ipp_t *col = new_media_col(pwgsize);
 
-         /*
-         * Then add the specific, supported combinations of size, source, and
-         * type...
-         */
-
-         if (p->pc->num_sources > 0)
-         {
-           for (j = p->pc->num_sources, pwgsource = p->pc->sources;
-                j > 0;
-                j --, pwgsource ++)
-           {
-             ppdMarkOption(ppd, "InputSlot", pwgsource->ppd);
-
-             if (p->pc->num_types > 0)
-             {
-               for (k = p->pc->num_types, pwgtype = p->pc->types;
-                    k > 0;
-                    k --, pwgtype ++)
-               {
-                 if (!ppdMarkOption(ppd, "MediaType", pwgtype->ppd))
-                 {
-                   val->collection = new_media_col(pwgsize, pwgsource->pwg,
-                                                   pwgtype->pwg);
-                   val ++;
-                 }
-               }
-             }
-             else if (!ppdConflicts(ppd))
-             {
-               val->collection = new_media_col(pwgsize, pwgsource->pwg, NULL);
-               val ++;
-             }
-           }
-         }
-         else if (p->pc->num_types > 0)
-         {
-           for (j = p->pc->num_types, pwgtype = p->pc->types;
-                j > 0;
-                j --, pwgtype ++)
-           {
-             if (!ppdMarkOption(ppd, "MediaType", pwgtype->ppd))
-             {
-               val->collection = new_media_col(pwgsize, NULL, pwgtype->pwg);
-               val ++;
-             }
-           }
-         }
+         ippSetCollection(p->ppd_attrs, &attr, i, col);
+         ippDelete(col);
        }
-
-       /*
-        * Update the number of media-col-database values...
-       */
-
-       attr->num_values = val - attr->values;
       }
     }
 
@@ -4675,6 +4649,22 @@ load_ppd(cupsd_printer_t *p)             /* I - Printer */
       }
     }
 
+    if (p->pc && p->pc->templates)
+    {
+      const char       *template;      /* Finishing template */
+      ipp_attribute_t  *fin_col_db;    /* finishings-col-database attribute */
+      ipp_t            *fin_col;       /* finishings-col value */
+
+      fin_col_db = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER, "finishings-col-database", cupsArrayCount(p->pc->templates), NULL);
+      for (i = 0, template = (const char *)cupsArrayFirst(p->pc->templates); template; i ++, template = (const char *)cupsArrayNext(p->pc->templates))
+      {
+        fin_col = ippNew();
+        ippAddString(fin_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "finishing-template", NULL, template);
+        ippSetCollection(p->ppd_attrs, &fin_col_db, i, fin_col);
+        ippDelete(fin_col);
+      }
+    }
+
     for (i = 0; i < ppd->num_sizes; i ++)
       if (ppd->sizes[i].length > 1728)
        p->type |= CUPS_PRINTER_LARGE;
@@ -5059,9 +5049,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
  */
 
 static ipp_t *                         /* O - Collection value */
-new_media_col(pwg_size_t *size,        /* I - media-size/margin values */
-              const char  *source,     /* I - media-source value */
-              const char  *type)       /* I - media-type value */
+new_media_col(pwg_size_t *size)                /* I - media-size/margin values */
 {
   ipp_t        *media_col,                     /* Collection value */
        *media_size;                    /* media-size value */
@@ -5070,29 +5058,15 @@ new_media_col(pwg_size_t *size, /* I - media-size/margin values */
   media_col = ippNew();
 
   media_size = ippNew();
-  ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-               "x-dimension", size->width);
-  ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-               "y-dimension", size->length);
+  ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "x-dimension", size->width);
+  ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "y-dimension", size->length);
   ippAddCollection(media_col, IPP_TAG_PRINTER, "media-size", media_size);
   ippDelete(media_size);
 
-  ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-               "media-bottom-margin", size->bottom);
-  ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-               "media-left-margin", size->left);
-  ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-               "media-right-margin", size->right);
-  ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
-               "media-top-margin", size->top);
-
-  if (source)
-    ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-source",
-                NULL, source);
-
-  if (type)
-    ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-type",
-                NULL, type);
+  ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-bottom-margin", size->bottom);
+  ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-left-margin", size->left);
+  ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-right-margin", size->right);
+  ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-top-margin", size->top);
 
   return (media_col);
 }