]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Add support for "printer-id" attribute (Issue #4868)
authorMichael R Sweet <michaelrsweet@gmail.com>
Wed, 1 Nov 2017 18:48:06 +0000 (14:48 -0400)
committerMichael R Sweet <michaelrsweet@gmail.com>
Wed, 1 Nov 2017 18:48:06 +0000 (14:48 -0400)
CHANGES.md
scheduler/classes.c
scheduler/ipp.c
scheduler/printers.c
scheduler/printers.h
test/get-printers-printer-id.test [new file with mode: 0644]
xcode/CUPS.xcodeproj/project.pbxproj

index 3d98a44f8dc9ea7423ba75c20a5ddb743d0018b8..ff55182b5532a3748c5c905cd884a58dea8700cd 100644 (file)
@@ -6,6 +6,7 @@ Changes in CUPS v2.3b1
 ----------------------
 
 - The lpstat command now reports when new jobs are being held (Issue #4761)
+- The scheduler now supports the "printer-id" attribute (Issue #4868)
 - No longer support backslash, question mark, or quotes in printer names
   (Issue #4966)
 - Dropped RSS subscription management from the web interface (Issue #5012)
index 57f9a8f44ffd64790afc33b3c83d46d932280a1f..99e39e3cbf6fbc7fa63722b7f969949a471e8a8e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Printer class routines for the CUPS scheduler.
  *
- * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2007-2017 by Apple Inc.
  * Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  * These coded instructions, statements, and computer programs are the
@@ -346,6 +346,13 @@ cupsdLoadAllClasses(void)
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "Syntax error on line %d of classes.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 classes.conf.", linenum);
+    }
     else if (!_cups_strcasecmp(line, "UUID"))
     {
       if (value && !strncmp(value, "urn:uuid:", 9))
@@ -713,6 +720,9 @@ cupsdSaveAllClasses(void)
     else
       cupsFilePrintf(fp, "<Class %s>\n", pclass->name);
 
+    if (pclass->printer_id)
+      cupsFilePrintf(fp, "PrinterId %d\n", pclass->printer_id);
+
     cupsFilePrintf(fp, "UUID %s\n", pclass->uuid);
 
     if (pclass->num_auth_info_required > 0)
index 5cf980ab3213b587347a488063324291f6efc4ae..5213d8eca778053446611ef948ccde6f49258736 100644 (file)
@@ -952,6 +952,8 @@ add_class(cupsd_client_t  *con,             /* I - Client connection */
 
     pclass = cupsdAddClass(resource + 9);
     modify = 0;
+
+    pclass->printer_id = NextPrinterId ++;
   }
   else if ((status = cupsdCheckPolicy(pclass->op_policy_ptr, con,
                                       NULL)) != HTTP_OK)
@@ -2341,6 +2343,8 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
 
     printer = cupsdAddPrinter(resource + 10);
     modify  = 0;
+
+    printer->printer_id = NextPrinterId ++;
   }
   else if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con,
                                       NULL)) != HTTP_OK)
@@ -2841,9 +2845,15 @@ add_printer(cupsd_client_t  *con,        /* I - Client connection */
   * Update the printer attributes and return...
   */
 
-  cupsdSetPrinterAttrs(printer);
   if (!printer->temporary)
+  {
+    if (!printer->printer_id)
+      printer->printer_id = NextPrinterId ++;
+
     cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
+  }
+
+  cupsdSetPrinterAttrs(printer);
 
   if (need_restart_job && printer->job)
   {
@@ -7462,6 +7472,7 @@ get_printers(cupsd_client_t *con, /* I - Client connection */
   ipp_attribute_t *attr;               /* Current attribute */
   int          limit;                  /* Max number of printers to return */
   int          count;                  /* Number of printers that match */
+  int          printer_id;             /* Printer we are interested in */
   cupsd_printer_t *printer;            /* Current printer pointer */
   cups_ptype_t printer_type,           /* printer-type attribute */
                printer_mask;           /* printer-type-mask attribute */
@@ -7515,6 +7526,17 @@ get_printers(cupsd_client_t *con,        /* I - Client connection */
   * Support filtering...
   */
 
+  if ((attr = ippFindAttribute(con->request, "printer-id", IPP_TAG_INTEGER)) != NULL)
+  {
+    if ((printer_id = ippGetInteger(attr, 0)) <= 0)
+    {
+      send_ipp_status(con, IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, _("Bad \"printer-id\" value %d."), printer_id);
+      return;
+    }
+  }
+  else
+    printer_id = 0;
+
   if ((attr = ippFindAttribute(con->request, "printer-type",
                                IPP_TAG_ENUM)) != NULL)
     printer_type = (cups_ptype_t)attr->values[0].integer;
@@ -7564,6 +7586,9 @@ get_printers(cupsd_client_t *con, /* I - Client connection */
     if (!local && !printer->shared)
       continue;
 
+    if (printer_id && printer->printer_id != printer_id)
+      continue;
+
     if ((!type || (printer->type & CUPS_PRINTER_CLASS) == type) &&
         (printer->type & printer_mask) == printer_type &&
        (!location ||
index bb99907ad3dcd08e4d567cb0d7145c73a69b9e04..e8d6b2d9720699eade7be7d2c60088edb320a1ca 100644 (file)
@@ -929,8 +929,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 +973,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 +999,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 +1014,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 +1477,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 +1503,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)
@@ -2271,6 +2292,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",
index e1d991016a7849deb1fbb2b77d201b09b532eaa7..b51a4e58af0402d1480fd1d8c5fbf1e0d24588f6 100644 (file)
@@ -58,6 +58,7 @@ typedef struct cupsd_job_s cupsd_job_t;
 struct cupsd_printer_s
 {
   _cups_rwlock_t lock;                 /* Concurrency lock for background updates */
+  int          printer_id;             /* Printer ID */
   char         *uri,                   /* Printer URI */
                *uuid,                  /* Printer UUID */
                *hostname,              /* Host printer resides on */
@@ -137,6 +138,8 @@ VAR ipp_t           *CommonData     VALUE(NULL);
                                        /* Common printer object attrs */
 VAR cups_array_t       *CommonDefaults VALUE(NULL);
                                        /* Common -default option names */
+VAR int                        NextPrinterId   VALUE(1);
+                                       /* Next printer-id value */
 VAR cups_array_t       *Printers       VALUE(NULL);
                                        /* Printer list */
 VAR cupsd_printer_t    *DefaultPrinter VALUE(NULL);
diff --git a/test/get-printers-printer-id.test b/test/get-printers-printer-id.test
new file mode 100644 (file)
index 0000000..52e0b13
--- /dev/null
@@ -0,0 +1,27 @@
+# Get printer attributes using CUPS-Get-Printers
+#
+# Usage:
+#
+#   ipptool -t -d printer_id=N ipp://localhost:port/ get-printers-printer-id.test
+#
+{
+       # The name of the test...
+       NAME "CUPS-Get-Printers w/printer-id"
+
+       # The resource to use for the POST
+       # RESOURCE /admin
+
+       # The operation to use
+       OPERATION CUPS-Get-Printers
+
+       # Attributes, starting in the operation group...
+       GROUP operation
+       ATTR charset attributes-charset utf-8
+       ATTR language attributes-natural-language en
+       ATTR integer printer-id $printer_id
+
+       # What statuses are OK?
+       STATUS successful-ok
+       EXPECT printer-name
+       DISPLAY printer-name
+}
index 1f96704c7db5258facdd4e9ebb9cf0e680b6ad34..9a8c27fd5134bd71fd87bbab8fcd82d8528de01e 100644 (file)
                72BF96371333042100B1EAD7 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0900;
+                               LastUpgradeCheck = 0920;
                                ORGANIZATIONNAME = "Apple Inc.";
                                TargetAttributes = {
                                        270695FD1CADF3E200FFE5FB = {