From 409f54979f3dcd08d9b318e8d74d1d445e0cc520 Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Wed, 1 Nov 2017 14:48:06 -0400 Subject: [PATCH] Add support for "printer-id" attribute (Issue #4868) --- CHANGES.md | 1 + scheduler/classes.c | 12 ++++++++- scheduler/ipp.c | 27 ++++++++++++++++++- scheduler/printers.c | 39 ++++++++++++++++++++++------ scheduler/printers.h | 3 +++ test/get-printers-printer-id.test | 27 +++++++++++++++++++ xcode/CUPS.xcodeproj/project.pbxproj | 2 +- 7 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 test/get-printers-printer-id.test diff --git a/CHANGES.md b/CHANGES.md index 3d98a44f8..ff55182b5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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) diff --git a/scheduler/classes.c b/scheduler/classes.c index 57f9a8f44..99e39e3cb 100644 --- a/scheduler/classes.c +++ b/scheduler/classes.c @@ -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, "\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) diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 5cf980ab3..5213d8eca 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -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 || diff --git a/scheduler/printers.c b/scheduler/printers.c index bb99907ad..e8d6b2d97 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -929,8 +929,14 @@ cupsdLoadAllPrinters(void) * Decode the directive... */ - if (!_cups_strcasecmp(line, " 0) + NextPrinterId = i; + else + cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of printers.conf.", linenum); + } + else if (!_cups_strcasecmp(line, " or @@ -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, "\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", diff --git a/scheduler/printers.h b/scheduler/printers.h index e1d991016..b51a4e58a 100644 --- a/scheduler/printers.h +++ b/scheduler/printers.h @@ -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 index 000000000..52e0b132f --- /dev/null +++ b/test/get-printers-printer-id.test @@ -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 +} diff --git a/xcode/CUPS.xcodeproj/project.pbxproj b/xcode/CUPS.xcodeproj/project.pbxproj index 1f96704c7..9a8c27fd5 100644 --- a/xcode/CUPS.xcodeproj/project.pbxproj +++ b/xcode/CUPS.xcodeproj/project.pbxproj @@ -7215,7 +7215,7 @@ 72BF96371333042100B1EAD7 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0900; + LastUpgradeCheck = 0920; ORGANIZATIONNAME = "Apple Inc."; TargetAttributes = { 270695FD1CADF3E200FFE5FB = { -- 2.39.2