summaryrefslogtreecommitdiff
path: root/backend/ipp.c
diff options
context:
space:
mode:
Diffstat (limited to 'backend/ipp.c')
-rw-r--r--backend/ipp.c128
1 files changed, 94 insertions, 34 deletions
diff --git a/backend/ipp.c b/backend/ipp.c
index 91524a82..83074ebd 100644
--- a/backend/ipp.c
+++ b/backend/ipp.c
@@ -1,5 +1,5 @@
/*
- * "$Id: ipp.c 10509 2012-05-23 22:47:10Z mike $"
+ * "$Id: ipp.c 10548 2012-07-16 18:21:43Z mike $"
*
* IPP backend for CUPS.
*
@@ -45,8 +45,12 @@
# define kPMPrintUIToolAgent "com.apple.printuitool.agent"
# define kPMStartJob 100
# define kPMWaitForJob 101
+# ifdef HAVE_XPC_PRIVATE_H
+# include <xpc/private.h>
+# else
extern void xpc_connection_set_target_uid(xpc_connection_t connection,
uid_t uid);
+# endif /* HAVE_XPC_PRIVATE_H */
#endif /* HAVE_GSSAPI && HAVE_XPC */
@@ -165,7 +169,7 @@ static const char *password_cb(const char *);
static void report_attr(ipp_attribute_t *attr);
static void report_printer_state(ipp_t *ipp);
#if defined(HAVE_GSSAPI) && defined(HAVE_XPC)
-static int run_as_user(int argc, char *argv[], uid_t uid,
+static int run_as_user(char *argv[], uid_t uid,
const char *device_uri, int fd);
#endif /* HAVE_GSSAPI && HAVE_XPC */
static void sigterm_handler(int sig);
@@ -344,7 +348,7 @@ main(int argc, /* I - Number of command-line args */
if (uid > 0)
{
if (argc == 6)
- return (run_as_user(argc, argv, uid, device_uri, 0));
+ return (run_as_user(argv, uid, device_uri, 0));
else
{
int status = 0; /* Exit status */
@@ -353,7 +357,7 @@ main(int argc, /* I - Number of command-line args */
{
if ((fd = open(argv[i], O_RDONLY)) >= 0)
{
- status = run_as_user(argc, argv, uid, device_uri, fd);
+ status = run_as_user(argv, uid, device_uri, fd);
close(fd);
}
else
@@ -643,6 +647,9 @@ main(int argc, /* I - Number of command-line args */
update_reasons(NULL, "-connecting-to-device");
return (CUPS_BACKEND_STOP);
}
+
+ if (job_canceled)
+ return (CUPS_BACKEND_OK);
}
http = _httpCreate(hostname, port, addrlist, cupsEncryption(), AF_UNSPEC);
@@ -747,7 +754,7 @@ main(int argc, /* I - Number of command-line args */
case ECONNREFUSED :
default :
_cupsLangPrintFilter(stderr, "WARNING",
- _("The printer is busy."));
+ _("The printer is in use."));
break;
}
@@ -770,7 +777,9 @@ main(int argc, /* I - Number of command-line args */
}
while (http->fd < 0);
- if (job_canceled || !http)
+ if (job_canceled)
+ return (CUPS_BACKEND_OK);
+ else if (!http)
return (CUPS_BACKEND_FAILED);
update_reasons(NULL, "-connecting-to-device");
@@ -862,7 +871,7 @@ main(int argc, /* I - Number of command-line args */
return (CUPS_BACKEND_FAILED);
}
- _cupsLangPrintFilter(stderr, "INFO", _("The printer is busy."));
+ _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use."));
report_printer_state(supported);
@@ -880,14 +889,14 @@ main(int argc, /* I - Number of command-line args */
if (version >= 20)
{
_cupsLangPrintFilter(stderr, "INFO",
- _("Printer does not support IPP/%d.%d, trying "
+ _("The printer does not support IPP/%d.%d, trying "
"IPP/%s."), version / 10, version % 10, "1.1");
version = 11;
}
else
{
_cupsLangPrintFilter(stderr, "INFO",
- _("Printer does not support IPP/%d.%d, trying "
+ _("The printer does not support IPP/%d.%d, trying "
"IPP/%s."), version / 10, version % 10, "1.0");
version = 10;
}
@@ -968,7 +977,7 @@ main(int argc, /* I - Number of command-line args */
if (busy)
{
- _cupsLangPrintFilter(stderr, "INFO", _("The printer is busy."));
+ _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use."));
report_printer_state(supported);
@@ -1071,11 +1080,14 @@ main(int argc, /* I - Number of command-line args */
get_job_attrs = 1;
}
- if (!send_document)
+ if (create_job && !send_document)
{
fputs("DEBUG: Printer supports Create-Job but not Send-Document.\n",
stderr);
create_job = 0;
+
+ update_reasons(NULL, "+cups-ipp-conformance-failure-report,"
+ "cups-ipp-missing-send-document");
}
if (!validate_job)
@@ -1092,7 +1104,10 @@ main(int argc, /* I - Number of command-line args */
report_printer_state(supported);
}
- while (ipp_status > IPP_OK_CONFLICT);
+ while (!job_canceled && ipp_status > IPP_OK_CONFLICT);
+
+ if (job_canceled)
+ return (CUPS_BACKEND_OK);
/*
* See if the printer is accepting jobs and is not stopped; if either
@@ -1143,12 +1158,7 @@ main(int argc, /* I - Number of command-line args */
copies = atoi(argv[4]);
if (copies_sup || argc < 7)
- {
copies_remaining = 1;
-
- if (argc < 7 && !_cups_strncasecmp(final_content_type, "image/", 6))
- copies = 1;
- }
else
copies_remaining = copies;
@@ -1300,7 +1310,7 @@ main(int argc, /* I - Number of command-line args */
if (ipp_status == IPP_SERVICE_UNAVAILABLE || ipp_status == IPP_PRINTER_BUSY)
{
- _cupsLangPrintFilter(stderr, "INFO", _("The printer is busy."));
+ _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use."));
sleep(10);
}
else if (ipp_status == IPP_DOCUMENT_FORMAT)
@@ -1451,7 +1461,7 @@ main(int argc, /* I - Number of command-line args */
ipp_status == IPP_NOT_POSSIBLE ||
ipp_status == IPP_PRINTER_BUSY)
{
- _cupsLangPrintFilter(stderr, "INFO", _("The printer is busy."));
+ _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use."));
sleep(10);
if (num_files == 0)
@@ -1802,7 +1812,7 @@ main(int argc, /* I - Number of command-line args */
* Cancel the job as needed...
*/
- if (job_canceled && job_id)
+ if (job_canceled > 0 && job_id > 0)
cancel_job(http, uri, job_id, resource, argv[2], version);
/*
@@ -1874,23 +1884,22 @@ main(int argc, /* I - Number of command-line args */
else if (ipp_status == IPP_CONFLICT)
return (CUPS_BACKEND_FAILED);
else if (ipp_status == IPP_REQUEST_VALUE ||
- ipp_status == IPP_DOCUMENT_FORMAT)
+ ipp_status == IPP_DOCUMENT_FORMAT || job_canceled < 0)
{
if (ipp_status == IPP_REQUEST_VALUE)
_cupsLangPrintFilter(stderr, "ERROR", _("Print job too large."));
- else
+ else if (ipp_status == IPP_DOCUMENT_FORMAT)
_cupsLangPrintFilter(stderr, "ERROR",
_("Printer cannot print supplied content."));
+ else
+ _cupsLangPrintFilter(stderr, "ERROR", _("Print job canceled at printer."));
return (CUPS_BACKEND_CANCEL);
}
else if (ipp_status > IPP_OK_CONFLICT && ipp_status != IPP_ERROR_JOB_CANCELED)
return (CUPS_BACKEND_RETRY_CURRENT);
else
- {
- _cupsLangPrintFilter(stderr, "INFO", _("Ready to print."));
return (CUPS_BACKEND_OK);
- }
}
@@ -2153,7 +2162,7 @@ monitor_printer(
response = cupsDoRequest(http, request, monitor->resource);
- fprintf(stderr, "DEBUG: %s: %s (%s)\n", ippOpString(job_op),
+ fprintf(stderr, "DEBUG: (monitor) %s: %s (%s)\n", ippOpString(job_op),
ippErrorString(cupsLastError()), cupsLastErrorString());
if (cupsLastError() <= IPP_OK_CONFLICT)
@@ -2217,6 +2226,14 @@ monitor_printer(
ippDelete(response);
+ fprintf(stderr, "DEBUG: (monitor) job-state=%s\n",
+ ippEnumString("job-state", monitor->job_state));
+
+ if (!job_canceled &&
+ (monitor->job_state == IPP_JOB_CANCELED ||
+ monitor->job_state == IPP_JOB_ABORTED))
+ job_canceled = -1;
+
/*
* Disconnect from the printer - we'll reconnect on the next poll...
*/
@@ -2237,7 +2254,7 @@ monitor_printer(
* Cancel the job if necessary...
*/
- if (job_canceled && monitor->job_id > 0)
+ if (job_canceled > 0 && monitor->job_id > 0)
if (!httpReconnect(http))
cancel_job(http, monitor->uri, monitor->job_id, monitor->resource,
monitor->user, monitor->version);
@@ -2465,9 +2482,46 @@ new_request(
NULL, "two-sided-short-edge");
}
- if (doc_handling_sup &&
- (!format || _cups_strncasecmp(format, "image/", 6)) &&
- (keyword = cupsGetOption("collate", num_options, options)) != NULL)
+ if ((keyword = cupsGetOption("multiple-document-handling",
+ num_options, options)) != NULL)
+ {
+ if (strstr(keyword, "uncollated"))
+ keyword = "false";
+ else
+ keyword = "true";
+ }
+ else if ((keyword = cupsGetOption("collate", num_options,
+ options)) == NULL)
+ keyword = "true";
+
+ if (format)
+ {
+ if (!_cups_strcasecmp(format, "image/gif") ||
+ !_cups_strcasecmp(format, "image/jp2") ||
+ !_cups_strcasecmp(format, "image/jpeg") ||
+ !_cups_strcasecmp(format, "image/png") ||
+ !_cups_strcasecmp(format, "image/tiff") ||
+ !_cups_strncasecmp(format, "image/x-", 8))
+ {
+ /*
+ * Collation makes no sense for single page image formats...
+ */
+
+ keyword = "false";
+ }
+ else if (!_cups_strncasecmp(format, "image/", 6) ||
+ !_cups_strcasecmp(format, "application/vnd.cups-raster"))
+ {
+ /*
+ * Multi-page image formats will have copies applied by the upstream
+ * filters...
+ */
+
+ copies = 1;
+ }
+ }
+
+ if (doc_handling_sup)
{
if (!_cups_strcasecmp(keyword, "true"))
collate_str = "separate-documents-collated-copies";
@@ -2481,6 +2535,9 @@ new_request(
"multiple-document-handling", NULL, collate_str);
break;
}
+
+ if (i >= doc_handling_sup->num_values)
+ copies = 1;
}
/*
@@ -2529,7 +2586,7 @@ new_request(
cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB);
}
- if (copies > 1)
+ if (copies > 1 && (!pc || copies <= pc->max_copies))
ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies", copies);
}
@@ -2782,8 +2839,7 @@ report_printer_state(ipp_t *ipp) /* I - IPP response */
*/
static int /* O - Exit status */
-run_as_user(int argc, /* I - Number of command-line args */
- char *argv[], /* I - Command-line arguments */
+run_as_user(char *argv[], /* I - Command-line arguments */
uid_t uid, /* I - User ID */
const char *device_uri, /* I - Device URI */
int fd) /* I - File to print */
@@ -2974,6 +3030,8 @@ sigterm_handler(int sig) /* I - Signal */
{
(void)sig; /* remove compiler warnings... */
+ write(2, "DEBUG: Got SIGTERM.\n", 20);
+
#if defined(HAVE_GSSAPI) && defined(HAVE_XPC)
if (child_pid)
{
@@ -2988,6 +3046,8 @@ sigterm_handler(int sig) /* I - Signal */
* Flag that the job should be canceled...
*/
+ write(2, "DEBUG: job_canceled = 1.\n", 25);
+
job_canceled = 1;
return;
}
@@ -3217,5 +3277,5 @@ update_reasons(ipp_attribute_t *attr, /* I - printer-state-reasons or NULL */
}
/*
- * End of "$Id: ipp.c 10509 2012-05-23 22:47:10Z mike $".
+ * End of "$Id: ipp.c 10548 2012-07-16 18:21:43Z mike $".
*/