/*
* "$Id: ipp.c 7944 2008-09-16 22:32:42Z mike $"
*
- * IPP routines for the Common UNIX Printing System (CUPS) scheduler.
+ * IPP routines for the CUPS scheduler.
*
- * Copyright 2007-2009 by Apple Inc.
+ * Copyright 2007-2010 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
* printer.
* apply_printer_defaults() - Apply printer default options to a job.
* authenticate_job() - Set job authentication info.
- * cancel_all_jobs() - Cancel all print jobs.
+ * cancel_all_jobs() - Cancel all or selected print jobs.
* cancel_job() - Cancel a print job.
* cancel_subscription() - Cancel a subscription.
- * check_quotas() - Check quotas for a printer and user.
* check_rss_recipient() - Check that we do not have a duplicate RSS
* feed URI.
+ * check_quotas() - Check quotas for a printer and user.
+ * close_job() - Close a multi-file job.
* copy_attribute() - Copy a single attribute.
* copy_attrs() - Copy attributes from one request to another.
* copy_banner() - Copy a banner file to the requests directory
* get_ppds() - Get the list of PPD files on the local
* system.
* get_printer_attrs() - Get printer attributes.
+ * get_printer_supported() - Get printer supported values.
* get_printers() - Get a list of printers or classes.
* get_subscription_attrs() - Get subscription attributes.
* get_subscriptions() - Get subscriptions.
* get_username() - Get the username associated with a request.
* hold_job() - Hold a print job.
+ * hold_new_jobs() - Hold pending/new jobs on a printer or class.
* move_job() - Move a job to a new destination.
* ppd_parse_line() - Parse a PPD default line.
* print_job() - Print a file to a printer or class.
* read_job_ticket() - Read a job ticket embedded in a print file.
* reject_jobs() - Reject print jobs to a printer.
+ * release_held_new_jobs() - Release pending/new jobs on a printer or
+ * class.
* release_job() - Release a held print job.
* renew_subscription() - Renew an existing subscription...
* restart_job() - Restart an old print job.
static int check_quotas(cupsd_client_t *con, cupsd_printer_t *p);
static ipp_attribute_t *copy_attribute(ipp_t *to, ipp_attribute_t *attr,
int quickcopy);
+static void close_job(cupsd_client_t *con, ipp_attribute_t *uri);
static void copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra,
ipp_tag_t group, int quickcopy);
static int copy_banner(cupsd_client_t *con, cupsd_job_t *job,
con->request->request.any.version[1]);
send_ipp_status(con, IPP_VERSION_NOT_SUPPORTED,
- _("Bad request version number %d.%d!"),
+ _("Bad request version number %d.%d"),
con->request->request.any.version[0],
con->request->request.any.version[1]);
}
IPP_BAD_REQUEST, con->http.hostname,
con->request->request.any.request_id);
- send_ipp_status(con, IPP_BAD_REQUEST, _("Bad request ID %d!"),
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Bad request ID %d"),
con->request->request.any.request_id);
}
else if (!con->request->attrs)
"%04X %s No attributes in request",
IPP_BAD_REQUEST, con->http.hostname);
- send_ipp_status(con, IPP_BAD_REQUEST, _("No attributes in request!"));
+ send_ipp_status(con, IPP_BAD_REQUEST, _("No attributes in request"));
}
else
{
IPP_BAD_REQUEST, con->http.hostname);
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Attribute groups are out of order (%x < %x)!"),
+ _("Attribute groups are out of order (%x < %x)"),
attr->group_tag, group);
break;
}
charset->values[0].string.text);
else
ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, DefaultCharset);
+ "attributes-charset", NULL, "utf-8");
if (language)
ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
* Bad character set...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unsupported character set \"%s\"!",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unsupported character set \"%s\"",
charset->values[0].string.text);
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Unsupported attributes-charset value \"%s\"",
IPP_CHARSET, con->http.hostname,
charset->values[0].string.text);
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Unsupported character set \"%s\"!"),
+ _("Unsupported character set \"%s\""),
charset->values[0].string.text);
}
else if (!charset || !language ||
if (!charset)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Missing attributes-charset attribute!");
+ "Missing attributes-charset attribute");
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Missing attributes-charset attribute",
if (!language)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Missing attributes-natural-language attribute!");
+ "Missing attributes-natural-language attribute");
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Missing attributes-natural-language attribute",
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Missing printer-uri, job-uri, or ppd-name "
- "attribute!");
+ "attribute");
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Missing printer-uri, job-uri, or ppd-name "
cupsdLogMessage(CUPSD_LOG_DEBUG, "End of attributes...");
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Missing required attributes!"));
+ _("Missing required attributes"));
}
else
{
break;
case IPP_PURGE_JOBS :
+ case IPP_CANCEL_JOBS :
+ case IPP_CANCEL_MY_JOBS :
cancel_all_jobs(con, uri);
break;
release_held_new_jobs(con, uri);
break;
+ case IPP_CLOSE_JOB :
+ close_job(con, uri);
+ break;
+
case CUPS_GET_DEFAULT :
get_default(con);
break;
ippOpString(con->request->request.op.operation_id));
send_ipp_status(con, IPP_OPERATION_NOT_SUPPORTED,
- _("%s not supported!"),
+ _("%s not supported"),
ippOpString(
con->request->request.op.operation_id));
break;
* See if we need to add the ending sheet...
*/
+ if (!cupsdLoadJob(job))
+ return (-1);
+
printer = cupsdFindDest(job->dest);
attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
cupsdAddPrinterHistory(printer);
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
+ "Now accepting jobs.");
+
if (dtype & CUPS_PRINTER_CLASS)
{
cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
*/
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("A printer named \"%s\" already exists!"),
+ _("A printer named \"%s\" already exists"),
resource + 9);
return;
}
cupsdSetString(&pclass->info, attr->values[0].string.text);
if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs",
- IPP_TAG_BOOLEAN)) != NULL)
+ IPP_TAG_BOOLEAN)) != NULL &&
+ attr->values[0].boolean != pclass->accepting)
{
cupsdLogMessage(CUPSD_LOG_INFO,
"Setting %s printer-is-accepting-jobs to %d (was %d.)",
pclass->accepting = attr->values[0].boolean;
cupsdAddPrinterHistory(pclass);
+
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, pclass, NULL, "%s accepting jobs.",
+ pclass->accepting ? "Now" : "No longer");
}
if ((attr = ippFindAttribute(con->request, "printer-is-shared",
attr->values[0].integer != IPP_PRINTER_STOPPED)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Attempt to set %s printer-state to bad value %d!"),
+ _("Attempt to set %s printer-state to bad value %d"),
pclass->name, attr->values[0].integer);
return;
}
strlcpy(pclass->state_message, attr->values[0].string.text,
sizeof(pclass->state_message));
cupsdAddPrinterHistory(pclass);
+
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, pclass, NULL, "%s",
+ pclass->state_message);
}
if ((attr = ippFindAttribute(con->request, "member-uris",
IPP_TAG_URI)) != NULL)
_("The printer or class was not found."));
return;
}
+ else if (dtype & CUPS_PRINTER_CLASS)
+ {
+ send_ipp_status(con, IPP_BAD_REQUEST,
+ _("Nested classes are not allowed"));
+ return;
+ }
/*
* Add it to the class...
if (modify)
{
- cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, pclass, NULL,
- "Class \"%s\" modified by \"%s\".", pclass->name,
- get_username(con));
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED,
+ pclass, NULL, "Class \"%s\" modified by \"%s\".",
+ pclass->name, get_username(con));
cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" modified by \"%s\".",
pclass->name, get_username(con));
{
cupsdAddPrinterHistory(pclass);
- cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, pclass, NULL,
- "New class \"%s\" added by \"%s\".", pclass->name,
- get_username(con));
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED,
+ pclass, NULL, "New class \"%s\" added by \"%s\".",
+ pclass->name, get_username(con));
cupsdLogMessage(CUPSD_LOG_INFO, "New class \"%s\" added by \"%s\".",
pclass->name, get_username(con));
if (con)
send_ipp_status(con, IPP_INTERNAL_ERROR,
- _("Unable to allocate memory for file types!"));
+ _("Unable to allocate memory for file types"));
return (-1);
}
*auth_info; /* auth-info attribute */
const char *val; /* Default option value */
int priority; /* Job priority */
- char *title; /* Job name/title */
cupsd_job_t *job; /* Current job */
char job_uri[HTTP_MAX_URI]; /* Job URI */
int kbytes; /* Size of print file */
int i; /* Looping var */
int lowerpagerange; /* Page range bound */
+ int exact; /* Did we have an exact match? */
+ ipp_attribute_t *media_col, /* media-col attribute */
+ *media_margin; /* media-*-margin attribute */
+ ipp_t *unsup_col; /* media-col in unsupported response */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
strcasecmp(con->http.hostname, ServerName))
{
send_ipp_status(con, IPP_NOT_AUTHORIZED,
- _("The printer or class is not shared!"));
+ _("The printer or class is not shared"));
return (NULL);
}
filetype->type);
send_ipp_status(con, IPP_DOCUMENT_FORMAT,
- _("Unsupported format \'%s\'!"), mimetype);
+ _("Unsupported format \'%s\'"), mimetype);
ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
"document-format", NULL, mimetype);
if (attr->value_tag != IPP_TAG_KEYWORD &&
attr->value_tag != IPP_TAG_NAME)
{
- send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value type!"));
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value type"));
return (NULL);
}
if (attr->num_values > 2)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Too many job-sheets values (%d > 2)!"),
+ _("Too many job-sheets values (%d > 2)"),
attr->num_values);
return (NULL);
}
if (strcmp(attr->values[i].string.text, "none") &&
!cupsdFindBanner(attr->values[i].string.text))
{
- send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value \"%s\"!"),
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value \"%s\""),
attr->values[i].string.text);
return (NULL);
}
}
}
+ /*
+ * Do media selection as needed...
+ */
+
+ if (!ippFindAttribute(con->request, "PageRegion", IPP_TAG_ZERO) &&
+ !ippFindAttribute(con->request, "PageSize", IPP_TAG_ZERO) &&
+ _pwgGetPageSize(printer->pwg, con->request, NULL, &exact))
+ {
+ if (!exact &&
+ (media_col = ippFindAttribute(con->request, "media-col",
+ IPP_TAG_BEGIN_COLLECTION)) != NULL)
+ {
+ send_ipp_status(con, IPP_OK_SUBST, _("Unsupported margins."));
+
+ unsup_col = ippNew();
+ if ((media_margin = ippFindAttribute(media_col->values[0].collection,
+ "media-bottom-margin",
+ IPP_TAG_INTEGER)) != NULL)
+ ippAddInteger(unsup_col, IPP_TAG_ZERO, IPP_TAG_INTEGER,
+ "media-bottom-margin", media_margin->values[0].integer);
+
+ if ((media_margin = ippFindAttribute(media_col->values[0].collection,
+ "media-left-margin",
+ IPP_TAG_INTEGER)) != NULL)
+ ippAddInteger(unsup_col, IPP_TAG_ZERO, IPP_TAG_INTEGER,
+ "media-left-margin", media_margin->values[0].integer);
+
+ if ((media_margin = ippFindAttribute(media_col->values[0].collection,
+ "media-right-margin",
+ IPP_TAG_INTEGER)) != NULL)
+ ippAddInteger(unsup_col, IPP_TAG_ZERO, IPP_TAG_INTEGER,
+ "media-right-margin", media_margin->values[0].integer);
+
+ if ((media_margin = ippFindAttribute(media_col->values[0].collection,
+ "media-top-margin",
+ IPP_TAG_INTEGER)) != NULL)
+ ippAddInteger(unsup_col, IPP_TAG_ZERO, IPP_TAG_INTEGER,
+ "media-top-margin", media_margin->values[0].integer);
+
+ ippAddCollection(con->response, IPP_TAG_UNSUPPORTED_GROUP, "media-col",
+ unsup_col);
+ ippDelete(unsup_col);
+ }
+ }
+
/*
* Make sure we aren't over our limit...
*/
priority);
}
- if ((attr = ippFindAttribute(con->request, "job-name",
- IPP_TAG_NAME)) != NULL)
- title = attr->values[0].string.text;
- else
+ if (!ippFindAttribute(con->request, "job-name", IPP_TAG_NAME))
ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
- title = "Untitled");
+ "Untitled");
if ((job = cupsdAddJob(priority, printer->name)) == NULL)
{
send_ipp_status(con, IPP_INTERNAL_ERROR,
- _("Unable to add job for destination \"%s\"!"),
+ _("Unable to add job for destination \"%s\""),
printer->name);
return (NULL);
}
"job-media-sheets-completed", 0);
ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL,
printer->uri);
- ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
- title);
if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
IPP_TAG_INTEGER)) != NULL)
attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
"job-hold-until", NULL, val);
}
- if (attr && strcmp(attr->values[0].string.text, "no-hold") &&
- !(printer->type & CUPS_PRINTER_REMOTE))
+ if (attr && strcmp(attr->values[0].string.text, "no-hold"))
{
/*
* Hold job until specified time...
resource, sizeof(resource)) < HTTP_URI_OK)
{
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("Bad notify-recipient-uri URI \"%s\"!"), recipient);
+ _("Bad notify-recipient-uri URI \"%s\""), recipient);
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
"notify-status-code", IPP_URI_SCHEME);
return;
{
send_ipp_status(con, IPP_NOT_POSSIBLE,
_("notify-recipient-uri URI \"%s\" uses unknown "
- "scheme!"), recipient);
+ "scheme"), recipient);
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
"notify-status-code", IPP_URI_SCHEME);
return;
if (!strcmp(scheme, "rss") && !check_rss_recipient(recipient))
{
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("notify-recipient-uri URI \"%s\" is already used!"),
+ _("notify-recipient-uri URI \"%s\" is already used"),
recipient);
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
"notify-status-code", IPP_ATTRIBUTES);
if (strcmp(pullmethod, "ippget"))
{
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("Bad notify-pull-method \"%s\"!"), pullmethod);
+ _("Bad notify-pull-method \"%s\""), pullmethod);
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
"notify-status-code", IPP_ATTRIBUTES);
return;
strcmp(attr->values[0].string.text, "utf-8"))
{
send_ipp_status(con, IPP_CHARSET,
- _("Character set \"%s\" not supported!"),
+ _("Character set \"%s\" not supported"),
attr->values[0].string.text);
return;
}
strcmp(attr->values[0].string.text, DefaultLanguage)))
{
send_ipp_status(con, IPP_CHARSET,
- _("Language \"%s\" not supported!"),
+ _("Language \"%s\" not supported"),
attr->values[0].string.text);
return;
}
{
send_ipp_status(con, IPP_REQUEST_VALUE,
_("The notify-user-data value is too large "
- "(%d > 63 octets)!"),
+ "(%d > 63 octets)"),
attr->values[0].unknown.length);
return;
}
ippAddSeparator(con->response);
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
"notify-subscription-id", sub->id);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription %d for job %d",
+ sub->id, job->id);
}
if (attr)
dstfile[1024]; /* Destination Script/PPD file */
int modify; /* Non-zero if we are modifying */
char newname[IPP_MAX_NAME]; /* New printer name */
- int need_restart_job; /* Need to restart job? */
- int set_device_uri, /* Did we set the device URI? */
+ int changed_driver, /* Changed the PPD/interface script? */
+ need_restart_job, /* Need to restart job? */
+ set_device_uri, /* Did we set the device URI? */
set_port_monitor; /* Did we set the port monitor? */
*/
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("A class named \"%s\" already exists!"),
+ _("A class named \"%s\" already exists"),
resource + 10);
return;
}
* Look for attributes and copy them over as needed...
*/
+ changed_driver = 0;
need_restart_job = 0;
if ((attr = ippFindAttribute(con->request, "printer-location",
if (uri_status < HTTP_URI_OK)
{
- send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\"!"),
+ send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\""),
attr->values[0].string.text);
cupsdLogMessage(CUPSD_LOG_DEBUG,
"add_printer: httpSeparateURI returned %d", uri_status);
* Could not find device in list!
*/
- send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri scheme \"%s\"!"),
+ send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri scheme \"%s\""),
scheme);
return;
}
if (!supported || i >= supported->num_values)
{
- send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\"!"),
+ send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\""),
attr->values[0].string.text);
return;
}
}
if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs",
- IPP_TAG_BOOLEAN)) != NULL)
+ IPP_TAG_BOOLEAN)) != NULL &&
+ attr->values[0].boolean != printer->accepting)
{
cupsdLogMessage(CUPSD_LOG_INFO,
"Setting %s printer-is-accepting-jobs to %d (was %d.)",
printer->accepting = attr->values[0].boolean;
cupsdAddPrinterHistory(printer);
+
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
+ "%s accepting jobs.",
+ printer->accepting ? "Now" : "No longer");
}
if ((attr = ippFindAttribute(con->request, "printer-is-shared",
if (attr->values[0].integer != IPP_PRINTER_IDLE &&
attr->values[0].integer != IPP_PRINTER_STOPPED)
{
- send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d!"),
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d"),
attr->values[0].integer);
return;
}
strlcpy(printer->state_message, attr->values[0].string.text,
sizeof(printer->state_message));
cupsdAddPrinterHistory(printer);
+
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL, "%s",
+ printer->state_message);
}
if ((attr = ippFindAttribute(con->request, "printer-state-reasons",
(int)(sizeof(printer->reasons) / sizeof(printer->reasons[0])))
{
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("Too many printer-state-reasons values (%d > %d)!"),
+ _("Too many printer-state-reasons values (%d > %d)"),
attr->num_values,
(int)(sizeof(printer->reasons) /
sizeof(printer->reasons[0])));
if (PrintcapFormat == PRINTCAP_PLIST)
cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
+
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
+ "Printer \"%s\" state changed.", printer->name);
}
set_printer_defaults(con, printer);
if (con->filename)
{
need_restart_job = 1;
+ changed_driver = 1;
strlcpy(srcfile, con->filename, sizeof(srcfile));
if (copy_file(srcfile, dstfile))
{
send_ipp_status(con, IPP_INTERNAL_ERROR,
- _("Unable to copy interface script - %s!"),
+ _("Unable to copy interface script - %s"),
strerror(errno));
return;
}
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Copied interface script successfully!");
+ "Copied interface script successfully");
chmod(dstfile, 0755);
}
if (copy_file(srcfile, dstfile))
{
send_ipp_status(con, IPP_INTERNAL_ERROR,
- _("Unable to copy PPD file - %s!"),
+ _("Unable to copy PPD file - %s"),
strerror(errno));
return;
}
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Copied PPD file successfully!");
+ "Copied PPD file successfully");
chmod(dstfile, 0644);
-
-#ifdef __APPLE__
- /*
- * (Re)register color profiles...
- */
-
- if (!RunUser)
- {
- apple_unregister_profiles(printer);
- apple_register_profiles(printer);
- }
-#endif /* __APPLE__ */
}
else
{
IPP_TAG_NAME)) != NULL)
{
need_restart_job = 1;
+ changed_driver = 1;
if (!strcmp(attr->values[0].string.text, "raw"))
{
if (copy_model(con, attr->values[0].string.text, dstfile))
{
- send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file!"));
+ send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file"));
return;
}
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Copied PPD file successfully!");
+ "Copied PPD file successfully");
chmod(dstfile, 0644);
+ }
+ }
+
+ if (changed_driver)
+ {
+ /*
+ * If we changed the PPD/interface script, then remove the printer's cache
+ * file and clear the printer-state-reasons...
+ */
+
+ char cache_name[1024]; /* Cache filename for printer attrs */
+
+ snprintf(cache_name, sizeof(cache_name), "%s/%s.ipp4", CacheDir,
+ printer->name);
+ unlink(cache_name);
+
+ snprintf(cache_name, sizeof(cache_name), "%s/%s.pwg3", CacheDir,
+ printer->name);
+ unlink(cache_name);
+
+ cupsdSetPrinterReasons(printer, "none");
#ifdef __APPLE__
- /*
- * (Re)register color profiles...
- */
+ /*
+ * (Re)register color profiles...
+ */
- if (!RunUser)
- {
- apple_unregister_profiles(printer);
- apple_register_profiles(printer);
- }
-#endif /* __APPLE__ */
+ if (!RunUser)
+ {
+ apple_unregister_profiles(printer);
+ apple_register_profiles(printer);
}
+#endif /* __APPLE__ */
}
/*
if (modify)
{
- cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, printer, NULL,
- "Printer \"%s\" modified by \"%s\".", printer->name,
- get_username(con));
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED,
+ printer, NULL, "Printer \"%s\" modified by \"%s\".",
+ printer->name, get_username(con));
cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" modified by \"%s\".",
printer->name, get_username(con));
{
cupsdAddPrinterHistory(printer);
- cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, printer, NULL,
- "New printer \"%s\" added by \"%s\".", printer->name,
- get_username(con));
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED,
+ printer, NULL, "New printer \"%s\" added by \"%s\".",
+ printer->name, get_username(con));
cupsdLogMessage(CUPSD_LOG_INFO, "New printer \"%s\" added by \"%s\".",
printer->name, get_username(con));
num_profiles ++;
}
-
+
/*
* If we have profiles, add them...
*/
snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
q2_attr = ppdFindAttr(ppd, q_keyword, NULL);
}
- else
+ else
q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL);
if (q2_attr && q2_attr->value && q2_attr->value[0])
snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
q3_attr = ppdFindAttr(ppd, q_keyword, NULL);
}
- else
+ else
q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL);
if (q3_attr && q3_attr->value && q3_attr->value[0])
if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for %d profiles!",
+ "Unable to allocate memory for %d profiles",
num_profiles);
ppdClose(ppd);
return;
if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for %d profiles!",
+ "Unable to allocate memory for %d profiles",
num_profiles);
ppdClose(ppd);
return;
attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL);
num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2;
-
+
if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for %d profiles!",
+ "Unable to allocate memory for %d profiles",
num_profiles);
ppdClose(ppd);
return;
IPP_TAG_INTEGER)) == NULL)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Got a printer-uri attribute but no job-id!"));
+ _("Got a printer-uri attribute but no job-id"));
return;
}
* Not a valid URI!
*/
- send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri attribute \"%s\"!"),
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri attribute \"%s\""),
uri->values[0].string.text);
return;
}
*/
send_ipp_status(con, IPP_NOT_FOUND,
- _("Job #%d does not exist!"), jobid);
+ _("Job #%d does not exist"), jobid);
return;
}
*/
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("Job #%d is not held for authentication!"),
+ _("Job #%d is not held for authentication"),
jobid);
return;
}
send_http_error(con, HTTP_UNAUTHORIZED, printer);
else
send_ipp_status(con, IPP_NOT_AUTHORIZED,
- _("No authentication information provided!"));
+ _("No authentication information provided"));
return;
}
/*
- * 'cancel_all_jobs()' - Cancel all print jobs.
+ * 'cancel_all_jobs()' - Cancel all or selected print jobs.
*/
static void
cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */
ipp_attribute_t *uri) /* I - Job or Printer URI */
{
+ int i; /* Looping var */
http_status_t status; /* Policy status */
cups_ptype_t dtype; /* Destination type */
char scheme[HTTP_MAX_URI], /* Scheme portion of URI */
resource[HTTP_MAX_URI]; /* Resource portion of URI */
int port; /* Port portion of URI */
ipp_attribute_t *attr; /* Attribute in request */
- const char *username; /* Username */
- cupsd_jobaction_t purge; /* Purge? */
+ const char *username = NULL; /* Username */
+ cupsd_jobaction_t purge = CUPSD_JOB_DEFAULT;
+ /* Purge? */
cupsd_printer_t *printer; /* Printer */
+ ipp_attribute_t *job_ids; /* job-ids attribute */
+ cupsd_job_t *job; /* Job */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_all_jobs(%p[%d], %s)", con,
con->http.fd, uri->values[0].string.text);
/*
- * See if we have a printer URI...
+ * Get the jobs to cancel/purge...
*/
- if (strcmp(uri->name, "printer-uri"))
+ switch (con->request->request.op.operation_id)
{
- send_ipp_status(con, IPP_BAD_REQUEST,
- _("The printer-uri attribute is required!"));
- return;
- }
+ case IPP_PURGE_JOBS :
+ /*
+ * Get the username (if any) for the jobs we want to cancel (only if
+ * "my-jobs" is specified...
+ */
- /*
- * Get the username (if any) for the jobs we want to cancel (only if
- * "my-jobs" is specified...
- */
+ if ((attr = ippFindAttribute(con->request, "my-jobs",
+ IPP_TAG_BOOLEAN)) != NULL &&
+ attr->values[0].boolean)
+ {
+ if ((attr = ippFindAttribute(con->request, "requesting-user-name",
+ IPP_TAG_NAME)) != NULL)
+ username = attr->values[0].string.text;
+ else
+ {
+ send_ipp_status(con, IPP_BAD_REQUEST,
+ _("Missing requesting-user-name attribute"));
+ return;
+ }
+ }
- if ((attr = ippFindAttribute(con->request, "my-jobs",
- IPP_TAG_BOOLEAN)) != NULL &&
- attr->values[0].boolean)
- {
- if ((attr = ippFindAttribute(con->request, "requesting-user-name",
- IPP_TAG_NAME)) != NULL)
- username = attr->values[0].string.text;
- else
- {
- send_ipp_status(con, IPP_BAD_REQUEST,
- _("Missing requesting-user-name attribute!"));
- return;
- }
+ /*
+ * Look for the "purge-jobs" attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "purge-jobs",
+ IPP_TAG_BOOLEAN)) != NULL)
+ purge = attr->values[0].boolean ? CUPSD_JOB_PURGE : CUPSD_JOB_DEFAULT;
+ else
+ purge = CUPSD_JOB_PURGE;
+ break;
+
+ case IPP_CANCEL_MY_JOBS :
+ if (con->username[0])
+ username = con->username;
+ else if ((attr = ippFindAttribute(con->request, "requesting-user-name",
+ IPP_TAG_NAME)) != NULL)
+ username = attr->values[0].string.text;
+ else
+ {
+ send_ipp_status(con, IPP_BAD_REQUEST,
+ _("Missing requesting-user-name attribute"));
+ return;
+ }
+
+ default :
+ break;
}
- else
- username = NULL;
+
+ job_ids = ippFindAttribute(con->request, "job-ids", IPP_TAG_INTEGER);
/*
- * Look for the "purge-jobs" attribute...
+ * See if we have a printer URI...
*/
- if ((attr = ippFindAttribute(con->request, "purge-jobs",
- IPP_TAG_BOOLEAN)) != NULL)
- purge = attr->values[0].boolean ? CUPSD_JOB_PURGE : CUPSD_JOB_DEFAULT;
- else
- purge = CUPSD_JOB_PURGE;
+ if (strcmp(uri->name, "printer-uri"))
+ {
+ send_ipp_status(con, IPP_BAD_REQUEST,
+ _("The printer-uri attribute is required"));
+ return;
+ }
/*
* And if the destination is valid...
return;
}
- /*
- * Cancel all jobs on all printers...
- */
+ if (job_ids)
+ {
+ for (i = 0; i < job_ids->num_values; i ++)
+ {
+ if (!cupsdFindJob(job_ids->values[i].integer))
+ break;
+ }
+
+ if (i < job_ids->num_values)
+ {
+ send_ipp_status(con, IPP_NOT_FOUND, _("job-id %d not found."),
+ job_ids->values[i].integer);
+ return;
+ }
+
+ for (i = 0; i < job_ids->num_values; i ++)
+ {
+ job = cupsdFindJob(job_ids->values[i].integer);
+
+ cupsdSetJobState(job, IPP_JOB_CANCELED, purge,
+ purge == CUPSD_JOB_PURGE ? "Job purged by user." :
+ "Job canceled by user.");
+ }
- cupsdCancelJobs(NULL, username, purge);
+ cupsdLogMessage(CUPSD_LOG_INFO, "Selected jobs were %s by \"%s\".",
+ purge == CUPSD_JOB_PURGE ? "purged" : "canceled",
+ get_username(con));
+ }
+ else
+ {
+ /*
+ * Cancel all jobs on all printers...
+ */
- cupsdLogMessage(CUPSD_LOG_INFO, "All jobs were %s by \"%s\".",
- purge == CUPSD_JOB_PURGE ? "purged" : "canceled",
- get_username(con));
+ cupsdCancelJobs(NULL, username, purge);
+
+ cupsdLogMessage(CUPSD_LOG_INFO, "All jobs were %s by \"%s\".",
+ purge == CUPSD_JOB_PURGE ? "purged" : "canceled",
+ get_username(con));
+ }
}
else
{
return;
}
- /*
- * Cancel all of the jobs on the named printer...
- */
+ if (job_ids)
+ {
+ for (i = 0; i < job_ids->num_values; i ++)
+ {
+ if ((job = cupsdFindJob(job_ids->values[i].integer)) == NULL ||
+ strcasecmp(job->dest, printer->name))
+ break;
+ }
+
+ if (i < job_ids->num_values)
+ {
+ send_ipp_status(con, IPP_NOT_FOUND, _("job-id %d not found."),
+ job_ids->values[i].integer);
+ return;
+ }
+
+ for (i = 0; i < job_ids->num_values; i ++)
+ {
+ job = cupsdFindJob(job_ids->values[i].integer);
+
+ cupsdSetJobState(job, IPP_JOB_CANCELED, purge,
+ purge == CUPSD_JOB_PURGE ? "Job purged by user." :
+ "Job canceled by user.");
+ }
+
+ cupsdLogMessage(CUPSD_LOG_INFO, "Selected jobs were %s by \"%s\".",
+ purge == CUPSD_JOB_PURGE ? "purged" : "canceled",
+ get_username(con));
+ }
+ else
+ {
+ /*
+ * Cancel all of the jobs on the named printer...
+ */
- cupsdCancelJobs(printer->name, username, purge);
+ cupsdCancelJobs(printer->name, username, purge);
- cupsdLogMessage(CUPSD_LOG_INFO, "All jobs on \"%s\" were %s by \"%s\".",
- printer->name,
- purge == CUPSD_JOB_PURGE ? "purged" : "canceled",
- get_username(con));
+ cupsdLogMessage(CUPSD_LOG_INFO, "All jobs on \"%s\" were %s by \"%s\".",
+ printer->name,
+ purge == CUPSD_JOB_PURGE ? "purged" : "canceled",
+ get_username(con));
+ }
}
con->response->request.status.status_code = IPP_OK;
IPP_TAG_INTEGER)) == NULL)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Got a printer-uri attribute but no job-id!"));
+ _("Got a printer-uri attribute but no job-id"));
return;
}
jobid = job->id;
else
{
- send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s!"),
+ send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s"),
printer->name);
return;
}
*/
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Bad job-uri attribute \"%s\"!"),
+ _("Bad job-uri attribute \"%s\""),
uri->values[0].string.text);
return;
}
* Nope - return a "not found" error...
*/
- send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
return;
}
*/
send_ipp_status(con, IPP_NOT_FOUND,
- _("notify-subscription-id %d no good!"), sub_id);
+ _("notify-subscription-id %d no good"), sub_id);
return;
}
* Check quotas...
*/
-#ifdef __APPLE__
- if (AppleQuotas && (q = cupsdFindQuota(p, username)) != NULL)
- {
- /*
- * TODO: Define these special page count values as constants!
- */
-
- if (q->page_count == -4) /* special case: unlimited user */
- {
- cupsdLogMessage(CUPSD_LOG_INFO,
- "User \"%s\" request approved for printer %s (%s): "
- "unlimited quota.",
- username, p->name, p->info);
- q->page_count = 0; /* allow user to print */
- return (1);
- }
- else if (q->page_count == -3) /* quota exceeded */
- {
- cupsdLogMessage(CUPSD_LOG_INFO,
- "User \"%s\" request denied for printer %s (%s): "
- "quota limit exceeded.",
- username, p->name, p->info);
- q->page_count = 2; /* force quota exceeded failure */
- return (-1);
- }
- else if (q->page_count == -2) /* quota disabled for user */
- {
- cupsdLogMessage(CUPSD_LOG_INFO,
- "User \"%s\" request denied for printer %s (%s): "
- "printing disabled for user.",
- username, p->name, p->info);
- q->page_count = 2; /* force quota exceeded failure */
- return (-1);
- }
- else if (q->page_count == -1) /* quota access error */
- {
- cupsdLogMessage(CUPSD_LOG_INFO,
- "User \"%s\" request denied for printer %s (%s): "
- "unable to determine quota limit.",
- username, p->name, p->info);
- q->page_count = 2; /* force quota exceeded failure */
- return (-1);
- }
- else if (q->page_count < 0) /* user not found or other error */
- {
- cupsdLogMessage(CUPSD_LOG_INFO,
- "User \"%s\" request denied for printer %s (%s): "
- "user disabled / missing quota.",
- username, p->name, p->info);
- q->page_count = 2; /* force quota exceeded failure */
- return (-1);
- }
- else /* page within user limits */
- {
- q->page_count = 0; /* allow user to print */
- return (1);
- }
- }
- else
-#endif /* __APPLE__ */
if (p->k_limit || p->page_limit)
{
if ((q = cupsdUpdateQuota(p, username, 0, 0)) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate quota data for user \"%s\"!",
+ "Unable to allocate quota data for user \"%s\"",
username);
return (-1);
}
}
+/*
+ * 'close_job()' - Close a multi-file job.
+ */
+
+static void
+close_job(cupsd_client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ cupsd_job_t *job; /* Job */
+ ipp_attribute_t *attr; /* Attribute */
+ char job_uri[HTTP_MAX_URI],
+ /* Job URI */
+ username[256]; /* User name */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "close_job(%p[%d], %s)", con,
+ con->http.fd, uri->values[0].string.text);
+
+ /*
+ * See if we have a job URI or a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri"))
+ {
+ /*
+ * job-uri is not supported by Close-Job!
+ */
+
+ send_ipp_status(con, IPP_BAD_REQUEST,
+ _("Close-Job doesn't support the job-uri attribute."));
+ return;
+ }
+
+ /*
+ * Got a printer URI; see if we also have a job-id attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-id",
+ IPP_TAG_INTEGER)) == NULL)
+ {
+ send_ipp_status(con, IPP_BAD_REQUEST,
+ _("Got a printer-uri attribute but no job-id"));
+ return;
+ }
+
+ if ((job = cupsdFindJob(attr->values[0].integer)) == NULL)
+ {
+ /*
+ * Nope - return a "not found" error...
+ */
+
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"),
+ attr->values[0].integer);
+ return;
+ }
+
+ /*
+ * See if the job is owned by the requesting user...
+ */
+
+ if (!validate_user(job, con, job->username, username, sizeof(username)))
+ {
+ send_http_error(con, con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED,
+ cupsdFindDest(job->dest));
+ return;
+ }
+
+ /*
+ * Add any ending sheet...
+ */
+
+ if (cupsdTimeoutJob(job))
+ return;
+
+ if (job->state_value == IPP_JOB_STOPPED)
+ {
+ job->state->values[0].integer = IPP_JOB_PENDING;
+ job->state_value = IPP_JOB_PENDING;
+ }
+ else if (job->state_value == IPP_JOB_HELD)
+ {
+ if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
+ IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+
+ if (!attr || !strcmp(attr->values[0].string.text, "no-hold"))
+ {
+ job->state->values[0].integer = IPP_JOB_PENDING;
+ job->state_value = IPP_JOB_PENDING;
+ }
+ }
+
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+
+ /*
+ * Fill in the response info...
+ */
+
+ snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName,
+ LocalPort, job->id);
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL,
+ job_uri);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
+ job->state_value);
+
+ add_job_state_reasons(con, job);
+
+ con->response->request.status.status_code = IPP_OK;
+
+ /*
+ * Start the job if necessary...
+ */
+
+ cupsdCheckJobs();
+}
+
+
/*
* 'copy_attribute()' - Copy a single attribute.
*/
for (i = 0; i < attr->num_values; i ++)
{
- toattr->values[i].collection = ippNew();
- copy_attrs(toattr->values[i].collection, attr->values[i].collection,
- NULL, IPP_TAG_ZERO, 0);
+ toattr->values[i].collection = attr->values[i].collection;
+ attr->values[i].collection->use ++;
}
break;
{
/*
* Don't send collection attributes by default to IPP/1.x clients
- * since many do not support collections...
+ * since many do not support collections. Also don't send
+ * media-col-database unless specifically requested by the client.
*/
if (fromattr->value_tag == IPP_TAG_BEGIN_COLLECTION &&
- !ra && to->request.status.version[0] == 1)
+ !ra &&
+ (to->request.status.version[0] == 1 ||
+ !strcmp(fromattr->name, "media-col-database")))
continue;
copy_attribute(to, fromattr, quickcopy);
int i; /* Looping var */
char option[PPD_MAX_NAME], /* Option name */
choice[PPD_MAX_NAME]; /* Choice name */
+ ppd_size_t *size; /* Default size */
int num_defaults; /* Number of default options */
cups_option_t *defaults; /* Default options */
char cups_protocol[PPD_MAX_LINE];
* No data from cups-deviced...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR, "copy_model: empty PPD file!");
+ cupsdLogMessage(CUPSD_LOG_ERROR, "copy_model: empty PPD file");
unlink(tempfile);
return (-1);
}
cupsFileClose(dst);
}
- else if (ppdPageSize(ppd, DefaultPaperSize))
+ else if ((size = ppdPageSize(ppd, DefaultPaperSize)) != NULL)
{
/*
* Add the default media sizes...
*/
- num_defaults = cupsAddOption("PageSize", DefaultPaperSize,
+ num_defaults = cupsAddOption("PageSize", size->name,
num_defaults, &defaults);
- num_defaults = cupsAddOption("PageRegion", DefaultPaperSize,
+ num_defaults = cupsAddOption("PageRegion", size->name,
num_defaults, &defaults);
- num_defaults = cupsAddOption("PaperDimension", DefaultPaperSize,
+ num_defaults = cupsAddOption("PaperDimension", size->name,
num_defaults, &defaults);
- num_defaults = cupsAddOption("ImageableArea", DefaultPaperSize,
+ num_defaults = cupsAddOption("ImageableArea", size->name,
num_defaults, &defaults);
}
{
char printer_uri[HTTP_MAX_URI];
/* Printer URI */
+ char printer_icons[HTTP_MAX_URI];
+ /* Printer icons */
time_t curtime; /* Current time */
int i; /* Looping var */
ipp_attribute_t *history; /* History collection */
curtime = time(NULL);
-#ifdef __APPLE__
- if ((!ra || cupsArrayFind(ra, "com.apple.print.recoverable-message")) &&
- printer->recoverable)
- ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
- "com.apple.print.recoverable-message", NULL,
- printer->recoverable);
-#endif /* __APPLE__ */
-
if (!ra || cupsArrayFind(ra, "marker-change-time"))
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"marker-change-time", printer->marker_time);
sizeof(errors) / sizeof(errors[0]), NULL, errors);
}
+ if (!ra || cupsArrayFind(ra, "printer-icons"))
+ {
+ httpAssembleURIf(HTTP_URI_CODING_ALL, printer_icons, sizeof(printer_icons),
+ "http", NULL, con->servername, con->serverport,
+ "/icons/%s.png", printer->name);
+ ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-icons",
+ NULL, printer_icons);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-icons=\"%s\"", printer_icons);
+ }
+
if (!ra || cupsArrayFind(ra, "printer-is-accepting-jobs"))
ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs",
printer->accepting);
if (!attr)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("No subscription attributes in request!"));
+ _("No subscription attributes in request"));
return;
}
resource, sizeof(resource)) < HTTP_URI_OK)
{
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("Bad notify-recipient-uri URI \"%s\"!"), recipient);
+ _("Bad notify-recipient-uri URI \"%s\""), recipient);
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
"notify-status-code", IPP_URI_SCHEME);
return;
{
send_ipp_status(con, IPP_NOT_POSSIBLE,
_("notify-recipient-uri URI \"%s\" uses unknown "
- "scheme!"), recipient);
+ "scheme"), recipient);
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
"notify-status-code", IPP_URI_SCHEME);
return;
if (!strcmp(scheme, "rss") && !check_rss_recipient(recipient))
{
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("notify-recipient-uri URI \"%s\" is already used!"),
+ _("notify-recipient-uri URI \"%s\" is already used"),
recipient);
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
"notify-status-code", IPP_ATTRIBUTES);
if (strcmp(pullmethod, "ippget"))
{
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("Bad notify-pull-method \"%s\"!"), pullmethod);
+ _("Bad notify-pull-method \"%s\""), pullmethod);
ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
"notify-status-code", IPP_ATTRIBUTES);
return;
strcmp(attr->values[0].string.text, "utf-8"))
{
send_ipp_status(con, IPP_CHARSET,
- _("Character set \"%s\" not supported!"),
+ _("Character set \"%s\" not supported"),
attr->values[0].string.text);
return;
}
strcmp(attr->values[0].string.text, DefaultLanguage)))
{
send_ipp_status(con, IPP_CHARSET,
- _("Language \"%s\" not supported!"),
+ _("Language \"%s\" not supported"),
attr->values[0].string.text);
return;
}
{
send_ipp_status(con, IPP_REQUEST_VALUE,
_("The notify-user-data value is too large "
- "(%d > 63 octets)!"),
+ "(%d > 63 octets)"),
attr->values[0].unknown.length);
return;
}
else
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("notify-events not specified!"));
+ _("notify-events not specified"));
return;
}
}
{
if ((job = cupsdFindJob(jobid)) == NULL)
{
- send_ipp_status(con, IPP_NOT_FOUND, _("Job %d not found!"), jobid);
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job %d not found"), jobid);
return;
}
}
printer->name);
unlink(filename);
- snprintf(filename, sizeof(filename), "%s/%s.ipp", CacheDir, printer->name);
+ snprintf(filename, sizeof(filename), "%s/%s.ipp4", CacheDir, printer->name);
+ unlink(filename);
+
+ snprintf(filename, sizeof(filename), "%s/%s.png", CacheDir, printer->name);
+ unlink(filename);
+
+ snprintf(filename, sizeof(filename), "%s/%s.pwg3", CacheDir, printer->name);
unlink(filename);
#ifdef __APPLE__
cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" deleted by \"%s\".",
printer->name, get_username(con));
- cupsdDeletePrinter(printer, 0);
+ if (cupsdDeletePrinter(printer, 0))
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
+
cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
}
"%d+%d+%d+%d+%s%s%s%s%s",
con->request->request.op.request_id,
limit ? limit->values[0].integer : 0,
- timeout ? timeout->values[0].integer : 10,
+ timeout ? timeout->values[0].integer : 15,
(int)User,
requested_str,
exclude_str[0] ? "%20" : "", exclude_str,
IPP_TAG_INTEGER)) == NULL)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Got a printer-uri attribute but no job-id!"));
+ _("Got a printer-uri attribute but no job-id"));
return;
}
*/
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Bad job-uri attribute \"%s\"!"),
+ _("Bad job-uri attribute \"%s\""),
uri->values[0].string.text);
return;
}
* Nope - return a "not found" error...
*/
- send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
return;
}
IPP_TAG_INTEGER)) == NULL)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Missing document-number attribute!"));
+ _("Missing document-number attribute"));
return;
}
"Unable to open document %d in job %d - %s", docnum, jobid,
strerror(errno));
send_ipp_status(con, IPP_NOT_FOUND,
- _("Unable to open document %d in job %d!"), docnum, jobid);
+ _("Unable to open document %d in job %d"), docnum, jobid);
return;
}
ipp_attribute_t *attr; /* Current attribute */
int jobid; /* Job ID */
cupsd_job_t *job; /* Current job */
+ cupsd_printer_t *printer; /* Current printer */
char scheme[HTTP_MAX_URI], /* Method portion of URI */
username[HTTP_MAX_URI], /* Username portion of URI */
host[HTTP_MAX_URI], /* Host portion of URI */
IPP_TAG_INTEGER)) == NULL)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Got a printer-uri attribute but no job-id!"));
+ _("Got a printer-uri attribute but no job-id"));
return;
}
*/
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Bad job-uri attribute \"%s\"!"),
+ _("Bad job-uri attribute \"%s\""),
uri->values[0].string.text);
return;
}
* Nope - return a "not found" error...
*/
- send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
return;
}
* Check policy...
*/
- if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
+ if ((printer = job->printer) == NULL)
+ printer = cupsdFindDest(job->dest);
+
+ if (printer)
+ {
+ if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con,
+ NULL)) != HTTP_OK)
+ {
+ send_http_error(con, status, printer);
+ return;
+ }
+ }
+ else if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
{
send_http_error(con, status, NULL);
return;
host[HTTP_MAX_URI], /* Host portion of URI */
resource[HTTP_MAX_URI]; /* Resource portion of URI */
int port; /* Port portion of URI */
- int completed; /* Completed jobs? */
+ int job_comparison; /* Job comparison */
+ ipp_jstate_t job_state; /* job-state value */
int first_job_id; /* First job ID */
int limit; /* Maximum number of jobs to return */
int count; /* Number of jobs that match */
+ ipp_attribute_t *job_ids; /* job-ids attribute */
cupsd_job_t *job; /* Current job pointer */
cupsd_printer_t *printer; /* Printer */
cups_array_t *list; /* Which job list... */
if (strcmp(uri->name, "printer-uri"))
{
- send_ipp_status(con, IPP_BAD_REQUEST, _("No printer-uri in request!"));
+ send_ipp_status(con, IPP_BAD_REQUEST, _("No printer-uri in request"));
return;
}
return;
}
+ job_ids = ippFindAttribute(con->request, "job-ids", IPP_TAG_INTEGER);
+
/*
* See if the "which-jobs" attribute have been specified...
*/
if ((attr = ippFindAttribute(con->request, "which-jobs",
- IPP_TAG_KEYWORD)) != NULL &&
- !strcmp(attr->values[0].string.text, "completed"))
+ IPP_TAG_KEYWORD)) != NULL && job_ids)
+ {
+ send_ipp_status(con, IPP_CONFLICT,
+ _("The %s attribute cannot be provided with job-ids."),
+ "which-jobs");
+ return;
+ }
+ else if (!attr || !strcmp(attr->values[0].string.text, "not-completed"))
+ {
+ job_comparison = -1;
+ job_state = IPP_JOB_STOPPED;
+ list = Jobs;
+ }
+ else if (!strcmp(attr->values[0].string.text, "completed"))
{
- completed = 1;
- list = Jobs;
+ job_comparison = 1;
+ job_state = IPP_JOB_CANCELED;
+ list = Jobs;
}
- else if (attr && !strcmp(attr->values[0].string.text, "all"))
+ else if (!strcmp(attr->values[0].string.text, "aborted"))
{
- completed = 0;
- list = Jobs;
+ job_comparison = 0;
+ job_state = IPP_JOB_ABORTED;
+ list = Jobs;
}
- else if (attr && !strcmp(attr->values[0].string.text, "processing"))
+ else if (!strcmp(attr->values[0].string.text, "all"))
{
- completed = 0;
- list = PrintingJobs;
+ job_comparison = 1;
+ job_state = IPP_JOB_PENDING;
+ list = Jobs;
+ }
+ else if (!strcmp(attr->values[0].string.text, "canceled"))
+ {
+ job_comparison = 0;
+ job_state = IPP_JOB_CANCELED;
+ list = Jobs;
+ }
+ else if (!strcmp(attr->values[0].string.text, "pending"))
+ {
+ job_comparison = 0;
+ job_state = IPP_JOB_PENDING;
+ list = ActiveJobs;
+ }
+ else if (!strcmp(attr->values[0].string.text, "pending-held"))
+ {
+ job_comparison = 0;
+ job_state = IPP_JOB_HELD;
+ list = ActiveJobs;
+ }
+ else if (!strcmp(attr->values[0].string.text, "processing"))
+ {
+ job_comparison = 0;
+ job_state = IPP_JOB_PROCESSING;
+ list = PrintingJobs;
+ }
+ else if (!strcmp(attr->values[0].string.text, "processing-stopped"))
+ {
+ job_comparison = 0;
+ job_state = IPP_JOB_STOPPED;
+ list = ActiveJobs;
}
else
{
- completed = 0;
- list = ActiveJobs;
+ send_ipp_status(con, IPP_ATTRIBUTES,
+ _("The which-jobs value \"%s\" is not supported."),
+ attr->values[0].string.text);
+ ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
+ "which-jobs", NULL, attr->values[0].string.text);
+ return;
}
/*
if ((attr = ippFindAttribute(con->request, "limit",
IPP_TAG_INTEGER)) != NULL)
+ {
+ if (job_ids)
+ {
+ send_ipp_status(con, IPP_CONFLICT,
+ _("The %s attribute cannot be provided with job-ids."),
+ "limit");
+ return;
+ }
+
limit = attr->values[0].integer;
+ }
else
limit = 0;
if ((attr = ippFindAttribute(con->request, "first-job-id",
IPP_TAG_INTEGER)) != NULL)
+ {
+ if (job_ids)
+ {
+ send_ipp_status(con, IPP_CONFLICT,
+ _("The %s attribute cannot be provided with job-ids."),
+ "first-job-id");
+ return;
+ }
+
first_job_id = attr->values[0].integer;
+ }
else
first_job_id = 1;
*/
if ((attr = ippFindAttribute(con->request, "my-jobs",
- IPP_TAG_BOOLEAN)) != NULL &&
- attr->values[0].boolean)
+ IPP_TAG_BOOLEAN)) != NULL && job_ids)
+ {
+ send_ipp_status(con, IPP_CONFLICT,
+ _("The %s attribute cannot be provided with job-ids."),
+ "my-jobs");
+ return;
+ }
+ else if (attr && attr->values[0].boolean)
strlcpy(username, get_username(con), sizeof(username));
else
username[0] = '\0';
- ra = create_requested_array(con->request);
+ if ((ra = create_requested_array(con->request)) == NULL &&
+ !ippFindAttribute(con->request, "requested-attributes", IPP_TAG_KEYWORD))
+ {
+ /*
+ * IPP conformance - Get-Jobs has a default requested-attributes value of
+ * "job-id" and "job-uri".
+ */
+
+ ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
+ cupsArrayAdd(ra, "job-id");
+ cupsArrayAdd(ra, "job-uri");
+ }
/*
* OK, build a list of jobs for this printer...
*/
- for (count = 0, job = (cupsd_job_t *)cupsArrayFirst(list);
- (limit <= 0 || count < limit) && job;
- job = (cupsd_job_t *)cupsArrayNext(list))
+ if (job_ids)
{
- /*
- * Filter out jobs that don't match...
- */
+ int i; /* Looping var */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "get_jobs: job->id=%d, dest=\"%s\", username=\"%s\", "
- "state_value=%d, attrs=%p", job->id, job->dest,
- job->username, job->state_value, job->attrs);
+ for (i = 0; i < job_ids->num_values; i ++)
+ {
+ if (!cupsdFindJob(job_ids->values[i].integer))
+ break;
+ }
- if (!job->dest || !job->username)
- cupsdLoadJob(job);
+ if (i < job_ids->num_values)
+ {
+ send_ipp_status(con, IPP_NOT_FOUND, _("job-id %d not found."),
+ job_ids->values[i].integer);
+ return;
+ }
- if (!job->dest || !job->username)
- continue;
+ for (i = 0; i < job_ids->num_values; i ++)
+ {
+ job = cupsdFindJob(job_ids->values[i].integer);
- if ((dest && strcmp(job->dest, dest)) &&
- (!job->printer || !dest || strcmp(job->printer->name, dest)))
- continue;
- if ((job->dtype & dmask) != dtype &&
- (!job->printer || (job->printer->type & dmask) != dtype))
- continue;
- if (completed && job->state_value <= IPP_JOB_STOPPED)
- continue;
+ cupsdLoadJob(job);
- if (job->id < first_job_id)
- continue;
+ if (!job->attrs)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d",
+ job->id);
+ continue;
+ }
- cupsdLoadJob(job);
+ if (i > 0)
+ ippAddSeparator(con->response);
- if (!job->attrs)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d!",
- job->id);
- continue;
+ copy_job_attrs(con, job, ra);
}
+ }
+ else
+ {
+ for (count = 0, job = (cupsd_job_t *)cupsArrayFirst(list);
+ (limit <= 0 || count < limit) && job;
+ job = (cupsd_job_t *)cupsArrayNext(list))
+ {
+ /*
+ * Filter out jobs that don't match...
+ */
- if (username[0] && strcasecmp(username, job->username))
- continue;
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "get_jobs: job->id=%d, dest=\"%s\", username=\"%s\", "
+ "state_value=%d, attrs=%p", job->id, job->dest,
+ job->username, job->state_value, job->attrs);
- if (count > 0)
- ippAddSeparator(con->response);
+ if (!job->dest || !job->username)
+ cupsdLoadJob(job);
- count ++;
+ if (!job->dest || !job->username)
+ continue;
- copy_job_attrs(con, job, ra);
- }
+ if ((dest && strcmp(job->dest, dest)) &&
+ (!job->printer || !dest || strcmp(job->printer->name, dest)))
+ continue;
+ if ((job->dtype & dmask) != dtype &&
+ (!job->printer || (job->printer->type & dmask) != dtype))
+ continue;
+
+ if ((job_comparison < 0 && job->state_value > job_state) ||
+ (job_comparison == 0 && job->state_value != job_state) ||
+ (job_comparison > 0 && job->state_value < job_state))
+ continue;
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: count=%d", count);
+ if (job->id < first_job_id)
+ continue;
+
+ cupsdLoadJob(job);
+
+ if (!job->attrs)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d",
+ job->id);
+ continue;
+ }
+
+ if (username[0] && strcasecmp(username, job->username))
+ continue;
+
+ if (count > 0)
+ ippAddSeparator(con->response);
+
+ count ++;
+
+ copy_job_attrs(con, job, ra);
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: count=%d", count);
+ }
cupsArrayDelete(ra);
if (!ids)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Missing notify-subscription-ids attribute!"));
+ _("Missing notify-subscription-ids attribute"));
return;
}
*/
send_ipp_status(con, IPP_NOT_FOUND,
- _("notify-subscription-id %d no good!"),
+ _("notify-subscription-id %d no good"),
ids->values[i].integer);
return;
}
*/
send_ipp_status(con, IPP_NOT_FOUND,
- _("notify-subscription-id %d no good!"), sub_id);
+ _("notify-subscription-id %d no good"), sub_id);
return;
}
if (!job)
{
- send_ipp_status(con, IPP_NOT_FOUND, _("Job #%s does not exist!"),
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%s does not exist"),
resource + 6);
return;
}
if (!job)
{
- send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"),
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"),
attr->values[0].integer);
return;
}
IPP_TAG_INTEGER)) == NULL)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Got a printer-uri attribute but no job-id!"));
+ _("Got a printer-uri attribute but no job-id"));
return;
}
*/
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Bad job-uri attribute \"%s\"!"),
+ _("Bad job-uri attribute \"%s\""),
uri->values[0].string.text);
return;
}
* Nope - return a "not found" error...
*/
- send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
return;
}
*/
send_ipp_status(con, IPP_BAD_REQUEST,
- _("job-printer-uri attribute missing!"));
+ _("job-printer-uri attribute missing"));
return;
}
*/
send_ipp_status(con, IPP_NOT_FOUND,
- _("Job #%d does not exist!"), attr->values[0].integer);
+ _("Job #%d does not exist"), attr->values[0].integer);
return;
}
else
*/
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Bad job-uri attribute \"%s\"!"),
+ _("Bad job-uri attribute \"%s\""),
uri->values[0].string.text);
return;
}
*/
send_ipp_status(con, IPP_NOT_FOUND,
- _("Job #%d does not exist!"), jobid);
+ _("Job #%d does not exist"), jobid);
return;
}
else
*/
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("Job #%d is finished and cannot be altered!"),
+ _("Job #%d is finished and cannot be altered"),
job->id);
return;
}
* Read the option name...
*/
- for (line += 8, olen --; isalnum(*line & 255); line ++)
+ for (line += 8, olen --;
+ *line > ' ' && *line < 0x7f && *line != ':' && *line != '/';
+ line ++)
if (olen > 0)
{
*option++ = *line;
while (isspace(*line & 255))
line ++;
- for (clen --; isalnum(*line & 255); line ++)
+ for (clen --;
+ *line > ' ' && *line < 0x7f && *line != ':' && *line != '/';
+ line ++)
if (clen > 0)
{
*choice++ = *line;
)
{
send_ipp_status(con, IPP_ATTRIBUTES,
- _("Unsupported compression \"%s\"!"),
+ _("Unsupported compression \"%s\""),
attr->values[0].string.text);
ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
"compression", NULL, attr->values[0].string.text);
if (!con->filename)
{
- send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?!"));
+ send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?"));
return;
}
type) != 2)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Could not scan type \"%s\"!"),
+ _("Bad document-format \"%s\""),
format->values[0].string.text);
return;
}
if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Could not scan type \"%s\"!"),
+ _("Bad document-format \"%s\""),
default_format);
return;
}
else if (!filetype)
{
send_ipp_status(con, IPP_DOCUMENT_FORMAT,
- _("Unsupported format \'%s/%s\'!"), super, type);
+ _("Unsupported document-format \"%s\""),
+ format ? format->values[0].string.text :
+ "application/octet-stream");
cupsdLogMessage(CUPSD_LOG_INFO,
"Hint: Do you have the raw file printing rules enabled?");
cupsdAddPrinterHistory(printer);
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
+ "No longer accepting jobs.");
+
if (dtype & CUPS_PRINTER_CLASS)
{
cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
IPP_TAG_INTEGER)) == NULL)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Got a printer-uri attribute but no job-id!"));
+ _("Got a printer-uri attribute but no job-id"));
return;
}
*/
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Bad job-uri attribute \"%s\"!"),
+ _("Bad job-uri attribute \"%s\""),
uri->values[0].string.text);
return;
}
* Nope - return a "not found" error...
*/
- send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
return;
}
* Nope - return a "not possible" error...
*/
- send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not held!"), jobid);
+ send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not held"), jobid);
return;
}
*/
send_ipp_status(con, IPP_NOT_FOUND,
- _("notify-subscription-id %d no good!"), sub_id);
+ _("notify-subscription-id %d no good"), sub_id);
return;
}
*/
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("Job subscriptions cannot be renewed!"));
+ _("Job subscriptions cannot be renewed"));
return;
}
IPP_TAG_INTEGER)) == NULL)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Got a printer-uri attribute but no job-id!"));
+ _("Got a printer-uri attribute but no job-id"));
return;
}
*/
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Bad job-uri attribute \"%s\"!"),
+ _("Bad job-uri attribute \"%s\""),
uri->values[0].string.text);
return;
}
* Nope - return a "not found" error...
*/
- send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
return;
}
* Nope - return a "not possible" error...
*/
- send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not complete!"),
+ send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not complete"),
jobid);
return;
}
*/
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("Job #%d cannot be restarted - no files!"), jobid);
+ _("Job #%d cannot be restarted - no files"), jobid);
return;
}
* Write a random number of newlines to the end of the file...
*/
- for (i = (rand() % 1024); i >= 0; i --)
+ for (i = (CUPS_RAND() % 1024); i >= 0; i --)
cupsFilePutChar(fp, '\n');
/*
IPP_TAG_INTEGER)) == NULL)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Got a printer-uri attribute but no job-id!"));
+ _("Got a printer-uri attribute but no job-id"));
return;
}
*/
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Bad job-uri attribute \"%s\"!"),
+ _("Bad job-uri attribute \"%s\""),
uri->values[0].string.text);
return;
}
* Nope - return a "not found" error...
*/
- send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
return;
}
#endif /* HAVE_LIBZ */
)
{
- send_ipp_status(con, IPP_ATTRIBUTES, _("Unsupported compression \"%s\"!"),
+ send_ipp_status(con, IPP_ATTRIBUTES, _("Unsupported compression \"%s\""),
attr->values[0].string.text);
ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
"compression", NULL, attr->values[0].string.text);
if (!con->filename)
{
- send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?!"));
+ /*
+ * Check for an empty request with "last-document" set to true, which is
+ * used to close an "open" job by RFC 2911, section 3.3.2.
+ */
+
+ if (job->num_files > 0 &&
+ (attr = ippFindAttribute(con->request, "last-document",
+ IPP_TAG_BOOLEAN)) != NULL &&
+ attr->values[0].boolean)
+ goto last_document;
+
+ send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?"));
return;
}
if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]",
super, type) != 2)
{
- send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"!"),
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\""),
format->values[0].string.text);
return;
}
if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Could not scan type \"%s\"!"),
+ _("Could not scan type \"%s\""),
default_format);
return;
}
else if (!filetype)
{
send_ipp_status(con, IPP_DOCUMENT_FORMAT,
- _("Unsupported format \'%s/%s\'!"), super, type);
+ _("Unsupported format \'%s/%s\'"), super, type);
cupsdLogMessage(CUPSD_LOG_INFO,
"Hint: Do you have the raw file printing rules enabled?");
filetype->type);
send_ipp_status(con, IPP_DOCUMENT_FORMAT,
- _("Unsupported format \'%s\'!"), mimetype);
+ _("Unsupported format \'%s\'"), mimetype);
ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
"document-format", NULL, mimetype);
* Start the job if this is the last document...
*/
+ last_document:
+
if ((attr = ippFindAttribute(con->request, "last-document",
IPP_TAG_BOOLEAN)) != NULL &&
attr->values[0].boolean)
if (ippFindAttribute(con->response, "attributes-charset",
IPP_TAG_ZERO) == NULL)
ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, DefaultCharset);
+ "attributes-charset", NULL, "utf-8");
if (ippFindAttribute(con->response, "attributes-natural-language",
IPP_TAG_ZERO) == NULL)
IPP_TAG_INTEGER)) == NULL)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Got a printer-uri attribute but no job-id!"));
+ _("Got a printer-uri attribute but no job-id"));
return;
}
*/
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Bad job-uri attribute \"%s\"!"),
+ _("Bad job-uri attribute \"%s\""),
uri->values[0].string.text);
return;
}
* Nope - return a "not found" error...
*/
- send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
return;
}
*/
send_ipp_status(con, IPP_NOT_POSSIBLE,
- _("Job #%d is finished and cannot be altered!"), jobid);
+ _("Job #%d is finished and cannot be altered"), jobid);
return;
}
if (attr->value_tag != IPP_TAG_INTEGER)
{
- send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-priority value!"));
+ send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-priority value"));
if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL)
attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
if (attr->value_tag != IPP_TAG_ENUM)
{
- send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-state value!"));
+ send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-state value"));
if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL)
attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
while (*s && bufptr < bufend)
{
- if (*s == ' ' || *s == '%')
+ if (*s == ' ' || *s == '%' || *s == '+')
{
if (bufptr >= (bufend - 2))
break;
ipp_attribute_t *uri) /* I - Printer URI */
{
http_status_t status; /* Policy status */
- ipp_attribute_t *attr; /* Current attribute */
+ ipp_attribute_t *attr, /* Current attribute */
+ *auth_info; /* auth-info attribute */
ipp_attribute_t *format; /* Document-format attribute */
cups_ptype_t dtype; /* Destination type (printer/class) */
char super[MIME_MAX_SUPER],
*/
if ((attr = ippFindAttribute(con->request, "compression",
- IPP_TAG_KEYWORD)) != NULL &&
- !strcmp(attr->values[0].string.text, "none"))
+ IPP_TAG_KEYWORD)) != NULL)
{
- send_ipp_status(con, IPP_ATTRIBUTES,
- _("Unsupported compression attribute %s!"),
- attr->values[0].string.text);
- ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
- "compression", NULL, attr->values[0].string.text);
- return;
+ if (strcmp(attr->values[0].string.text, "none")
+#ifdef HAVE_LIBZ
+ && strcmp(attr->values[0].string.text, "gzip")
+#endif /* HAVE_LIBZ */
+ )
+ {
+ send_ipp_status(con, IPP_ATTRIBUTES,
+ _("Unsupported compression \"%s\""),
+ attr->values[0].string.text);
+ ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
+ "compression", NULL, attr->values[0].string.text);
+ return;
+ }
}
/*
if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]",
super, type) != 2)
{
- send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"!"),
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\""),
format->values[0].string.text);
return;
}
cupsdLogMessage(CUPSD_LOG_INFO,
"Hint: Do you have the raw file printing rules enabled?");
send_ipp_status(con, IPP_DOCUMENT_FORMAT,
- _("Unsupported format \"%s\"!"),
+ _("Unsupported document-format \"%s\""),
format->values[0].string.text);
ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
"document-format", NULL, format->values[0].string.text);
* Check policy...
*/
+ auth_info = ippFindAttribute(con->request, "auth-info", IPP_TAG_TEXT);
+
if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK)
{
send_http_error(con, status, printer);
return;
}
+ else if (printer->num_auth_info_required == 1 &&
+ !strcmp(printer->auth_info_required[0], "negotiate") &&
+ !con->username[0])
+ {
+ send_http_error(con, HTTP_UNAUTHORIZED, printer);
+ return;
+ }
+#ifdef HAVE_SSL
+ else if (auth_info && !con->http.tls &&
+ !httpAddrLocalhost(con->http.hostaddr))
+ {
+ /*
+ * Require encryption of auth-info over non-local connections...
+ */
+
+ send_http_error(con, HTTP_UPGRADE_REQUIRED, printer);
+ return;
+ }
+#endif /* HAVE_SSL */
/*
* Everything was ok, so return OK status...