/*
* Job management routines for the CUPS scheduler.
*
- * Copyright 2007-2017 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
*
- * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
+ * Licensed under Apache License v2.0. See the file "LICENSE" for more
+ * information.
*/
/*
if (!job->impressions)
job->impressions = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-impressions-completed", 0);
+ if (!job->sheets)
+ job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-media-sheets-completed", 0);
if (!job->priority)
{
cupsdStatBufDelete(job->status_buffer);
job->status_buffer = NULL;
+ /*
+ * Log the final impression (page) count...
+ */
+
+ snprintf(buffer, sizeof(buffer), "total %d", ippGetInteger(job->impressions, 0));
+ cupsdLogPage(job, buffer);
+
/*
* Process the exit status...
*/
job_state == IPP_JOB_COMPLETED)
{
job_state = IPP_JOB_ABORTED;
- message = "Job aborted due to backend errors; please consult "
- "the error_log file for details.";
+
+ if (ErrorLog)
+ {
+ snprintf(buffer, sizeof(buffer), "Job aborted due to backend errors; please consult the %s file for details.", ErrorLog);
+ message = buffer;
+ }
+ else
+ message = "Job aborted due to backend errors.";
ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system");
}
{
job_state = IPP_JOB_PENDING;
printer_state = IPP_PRINTER_STOPPED;
- message = "Printer stopped due to backend errors; please "
- "consult the error_log file for details.";
+
+ if (ErrorLog)
+ {
+ snprintf(buffer, sizeof(buffer), "Printer stopped due to backend errors; please consult the %s file for details.", ErrorLog);
+ message = buffer;
+ }
+ else
+ message = "Printer stopped due to backend errors.";
ippSetString(job->attrs, &job->reasons, 0, "none");
}
ippSetString(job->attrs, &job->reasons, 0,
"job-hold-until-specified");
- message = "Job held indefinitely due to backend errors; please "
- "consult the error_log file for details.";
+
+ if (ErrorLog)
+ {
+ snprintf(buffer, sizeof(buffer), "Job held indefinitely due to backend errors; please consult the %s file for details.", ErrorLog);
+ message = buffer;
+ }
+ else
+ message = "Job held indefinitely due to backend errors.";
}
else if (!strcmp(reason, "account-info-needed"))
{
cupsdSetJobHoldUntil(job, "indefinite", 0);
- message = "Job held indefinitely - account information is "
- "required.";
+ message = "Job held indefinitely - account information is required.";
}
else if (!strcmp(reason, "account-closed"))
{
{
cupsdSetJobHoldUntil(job, "indefinite", 0);
- message = "Job held indefinitely - account limit has been "
- "reached.";
+ message = "Job held indefinitely - account limit has been reached.";
}
else
{
*/
printer_state = IPP_PRINTER_STOPPED;
- message = "Printer stopped due to backend errors; please "
- "consult the error_log file for details.";
+
+ if (ErrorLog)
+ {
+ snprintf(buffer, sizeof(buffer), "Printer stopped due to backend errors; please consult the %s file for details.", ErrorLog);
+ message = buffer;
+ }
+ else
+ message = "Printer stopped due to backend errors.";
if (job_state == IPP_JOB_COMPLETED)
{
if (job_state == IPP_JOB_COMPLETED)
{
job_state = IPP_JOB_STOPPED;
- message = "Job stopped due to filter errors; please consult the "
- "error_log file for details.";
+
+ if (ErrorLog)
+ {
+ snprintf(buffer, sizeof(buffer), "Job stopped due to filter errors; please consult the %s file for details.", ErrorLog);
+ message = buffer;
+ }
+ else
+ message = "Job stopped due to filter errors.";
if (WIFSIGNALED(job->status))
ippSetString(job->attrs, &job->reasons, 0, "cups-filter-crashed");
cupsdLogJob(job, CUPSD_LOG_DEBUG2, "After mapping finishings %s=%s", pwgppd->name, pwgppd->value);
}
+ /*
+ * Map page-delivery values...
+ */
+
+ if ((attr = ippFindAttribute(job->attrs, "page-delivery", IPP_TAG_KEYWORD)) != NULL && !ippFindAttribute(job->attrs, "outputorder", IPP_TAG_ZERO))
+ {
+ const char *page_delivery = ippGetString(attr, 0, NULL);
+
+ if (!strncmp(page_delivery, "same-order", 10))
+ num_pwgppds = cupsAddOption("OutputOrder", "Normal", num_pwgppds, &pwgppds);
+ else if (!strncmp(page_delivery, "reverse-order", 13))
+ num_pwgppds = cupsAddOption("OutputOrder", "Reverse", num_pwgppds, &pwgppds);
+ }
+
/*
* Figure out how much room we need...
*/
job->profile = cupsdCreateProfile(job->id, 0);
job->bprofile = cupsdCreateProfile(job->id, 1);
+#ifdef HAVE_SANDBOX_H
+ if ((!job->profile || !job->bprofile) && UseSandboxing && Sandboxing != CUPSD_SANDBOXING_OFF)
+ {
+ /*
+ * Failure to create the sandbox profile means something really bad has
+ * happened and we need to shutdown immediately.
+ */
+
+ return;
+ }
+#endif /* HAVE_SANDBOX_H */
+
/*
* Create the status pipes and buffer...
*/
update_job(cupsd_job_t *job) /* I - Job to check */
{
int i; /* Looping var */
- int copies; /* Number of copies printed */
char message[CUPSD_SB_BUFFER_SIZE],
/* Message text */
*ptr; /* Pointer update... */
if (loglevel == CUPSD_LOG_PAGE)
{
+ int impressions = ippGetInteger(job->impressions, 0);
+ /* Number of impressions printed */
+ int delta; /* Number of impressions added */
+
/*
* Page message; send the message to the page_log file and update the
* job sheet count...
cupsdLogJob(job, CUPSD_LOG_DEBUG, "PAGE: %s", message);
- if (job->impressions)
+ if (!_cups_strncasecmp(message, "total ", 6))
{
- if (!_cups_strncasecmp(message, "total ", 6))
- {
- /*
- * Got a total count of pages from a backend or filter...
- */
+ /*
+ * Got a total count of pages from a backend or filter...
+ */
- copies = atoi(message + 6);
- copies -= ippGetInteger(job->impressions, 0); /* Just track the delta */
+ int total = atoi(message + 6); /* Total impressions */
+
+ if (total > impressions)
+ {
+ delta = total - impressions;
+ impressions = total;
}
- else if (!sscanf(message, "%*d%d", &copies))
+ else
+ delta = 0;
+ }
+ else
+ {
+ /*
+ * Add the number of copies to the impression count...
+ */
+
+ int copies; /* Number of copies */
+
+ if (!sscanf(message, "%*d%d", &copies) || copies <= 0)
copies = 1;
- ippSetInteger(job->attrs, &job->impressions, 0, ippGetInteger(job->impressions, 0) + copies);
- job->dirty = 1;
- cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+ delta = copies;
+ impressions += copies;
}
+ if (job->impressions)
+ ippSetInteger(job->attrs, &job->impressions, 0, impressions);
+
if (job->sheets)
{
- if (!_cups_strncasecmp(message, "total ", 6))
- {
- /*
- * Got a total count of pages from a backend or filter...
- */
+ const char *sides = ippGetString(ippFindAttribute(job->attrs, "sides", IPP_TAG_KEYWORD), 0, NULL);
- copies = atoi(message + 6);
- copies -= ippGetInteger(job->sheets, 0); /* Just track the delta */
- }
- else if (!sscanf(message, "%*d%d", &copies))
- copies = 1;
-
- ippSetInteger(job->attrs, &job->sheets, 0, ippGetInteger(job->sheets, 0) + copies);
- job->dirty = 1;
- cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+ if (sides && strcmp(sides, "one-sided"))
+ ippSetInteger(job->attrs, &job->sheets, 0, impressions / 2);
+ else
+ ippSetInteger(job->attrs, &job->sheets, 0, impressions);
- if (job->printer->page_limit)
- cupsdUpdateQuota(job->printer, job->username, copies, 0);
+ cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job, "Printed %d page(s).", ippGetInteger(job->sheets, 0));
}
- cupsdLogPage(job, message);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
- if (job->sheets)
- cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job, "Printed %d page(s).", ippGetInteger(job->sheets, 0));
+ if (job->printer->page_limit)
+ cupsdUpdateQuota(job->printer, job->username, delta, 0);
}
else if (loglevel == CUPSD_LOG_JOBSTATE)
{