----------------------
- 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)
/*
* 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
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))
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)
pclass = cupsdAddClass(resource + 9);
modify = 0;
+
+ pclass->printer_id = NextPrinterId ++;
}
else if ((status = cupsdCheckPolicy(pclass->op_policy_ptr, con,
NULL)) != HTTP_OK)
printer = cupsdAddPrinter(resource + 10);
modify = 0;
+
+ printer->printer_id = NextPrinterId ++;
}
else if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con,
NULL)) != HTTP_OK)
* 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)
{
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 */
* 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;
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 ||
* 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>
* 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 */
*/
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);
}
}
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))
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...
*/
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)
"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",
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 */
/* 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);
--- /dev/null
+# 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
+}
72BF96371333042100B1EAD7 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 0920;
ORGANIZATIONNAME = "Apple Inc.";
TargetAttributes = {
270695FD1CADF3E200FFE5FB = {