summaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2012-01-19 16:53:50 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2012-01-19 16:53:50 +0000
commitdcb445bcf3e9ec2efd56550263052aca70beb08e (patch)
tree9a0d2260f2bbfdc8a6aa561c138baca1a58f8228 /backend
parent9c80ffa289171a48b10cbda2098289ed0c7b96cc (diff)
Merge changes from CUPS 1.6svn-r10188, including changes for <rdar://problem/10127258> CUPS 1.6: New printer/printing APIs
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@3618 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'backend')
-rw-r--r--backend/ipp.c255
-rw-r--r--backend/network.c2
-rw-r--r--backend/testbackend.c25
3 files changed, 230 insertions, 52 deletions
diff --git a/backend/ipp.c b/backend/ipp.c
index 99df346ae..21eacde39 100644
--- a/backend/ipp.c
+++ b/backend/ipp.c
@@ -3,7 +3,7 @@
*
* IPP backend for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -63,6 +63,7 @@ typedef struct _cups_monitor_s /**** Monitoring data ****/
int port, /* Port number */
version, /* IPP version */
job_id; /* Job ID for submitted job */
+ const char *job_name; /* Job name for submitted job */
http_encryption_t encryption; /* Use encryption? */
ipp_jstate_t job_state; /* Current job state */
ipp_pstate_t printer_state; /* Current printer state */
@@ -82,6 +83,8 @@ static const char * const jattrs[] = /* Job attributes we want */
{
"job-impressions-completed",
"job-media-sheets-completed",
+ "job-name",
+ "job-originating-user-name",
"job-state",
"job-state-reasons"
};
@@ -205,6 +208,7 @@ main(int argc, /* I - Number of command-line args */
int port; /* Port number (not used) */
char portname[255]; /* Port name */
char uri[HTTP_MAX_URI]; /* Updated URI without user/pass */
+ char print_job_name[1024]; /* Update job-name for Print-Job */
http_status_t http_status; /* Status of HTTP request */
ipp_status_t ipp_status; /* Status of IPP request */
http_t *http; /* HTTP connection */
@@ -231,7 +235,9 @@ main(int argc, /* I - Number of command-line args */
ipp_attribute_t *doc_handling_sup; /* multiple-document-handling-supported */
ipp_attribute_t *printer_state; /* printer-state attribute */
ipp_attribute_t *printer_accepting; /* printer-is-accepting-jobs */
- int validate_job; /* Does printer support Validate-Job? */
+ int create_job = 0, /* Does printer support Create-Job? */
+ send_document = 0, /* Does printer support Send-Document? */
+ validate_job = 0; /* Does printer support Validate-Job? */
int copies, /* Number of copies for job */
copies_remaining; /* Number of copies remaining */
const char *content_type, /* CONTENT_TYPE environment variable */
@@ -789,7 +795,6 @@ main(int argc, /* I - Number of command-line args */
supported = NULL;
operations_sup = NULL;
doc_handling_sup = NULL;
- validate_job = 0;
do
{
@@ -1042,11 +1047,21 @@ main(int argc, /* I - Number of command-line args */
"cups-ipp-missing-get-printer-attributes");
for (i = 0; i < operations_sup->num_values; i ++)
+ {
if (operations_sup->values[i].integer == IPP_VALIDATE_JOB)
- {
validate_job = 1;
- break;
- }
+ else if (operations_sup->values[i].integer == IPP_CREATE_JOB)
+ create_job = 1;
+ else if (operations_sup->values[i].integer == IPP_SEND_DOCUMENT)
+ send_document = 1;
+ }
+
+ if (!send_document)
+ {
+ fputs("DEBUG: Printer supports Create-Job but not Send-Document.\n",
+ stderr);
+ create_job = 0;
+ }
if (!validate_job)
update_reasons(NULL, "+cups-ipp-conformance-failure-report,"
@@ -1116,7 +1131,7 @@ main(int argc, /* I - Number of command-line args */
{
copies_remaining = 1;
- if (argc < 7 && !send_options)
+ if (argc < 7 && !_cups_strncasecmp(final_content_type, "image/", 6))
copies = 1;
}
else
@@ -1220,6 +1235,17 @@ main(int argc, /* I - Number of command-line args */
monitor.job_state = IPP_JOB_PENDING;
monitor.printer_state = IPP_PRINTER_IDLE;
+ if (create_job)
+ {
+ monitor.job_name = argv[3];
+ }
+ else
+ {
+ snprintf(print_job_name, sizeof(print_job_name), "%s - %s", argv[1],
+ argv[3]);
+ monitor.job_name = print_job_name;
+ }
+
_cupsThreadCreate((_cups_thread_func_t)monitor_printer, &monitor);
/*
@@ -1228,8 +1254,8 @@ main(int argc, /* I - Number of command-line args */
while (!job_canceled && validate_job)
{
- request = new_request(IPP_VALIDATE_JOB, version, uri, argv[2], argv[3],
- num_options, options, compression,
+ request = new_request(IPP_VALIDATE_JOB, version, uri, argv[2],
+ monitor.job_name, num_options, options, compression,
copies_sup ? copies : 1, document_format, pc,
media_col_sup, doc_handling_sup);
@@ -1306,16 +1332,17 @@ main(int argc, /* I - Number of command-line args */
if (job_canceled)
break;
- request = new_request(num_files > 1 ? IPP_CREATE_JOB : IPP_PRINT_JOB,
- version, uri, argv[2], argv[3], num_options, options,
- compression, copies_sup ? copies : 1, document_format,
- pc, media_col_sup, doc_handling_sup);
+ request = new_request((num_files > 1 || create_job) ? IPP_CREATE_JOB :
+ IPP_PRINT_JOB,
+ version, uri, argv[2], monitor.job_name, num_options,
+ options, compression, copies_sup ? copies : 1,
+ document_format, pc, media_col_sup, doc_handling_sup);
/*
* Do the request...
*/
- if (num_files > 1)
+ if (num_files > 1 || create_job)
response = cupsDoRequest(http, request, resource);
else
{
@@ -1333,7 +1360,13 @@ main(int argc, /* I - Number of command-line args */
if (http_status == HTTP_CONTINUE && request->state == IPP_DATA)
{
if (num_files == 1)
- fd = open(files[0], O_RDONLY);
+ {
+ if ((fd = open(files[0], O_RDONLY)) < 0)
+ {
+ _cupsLangPrintError("ERROR", _("Unable to open print file"));
+ return (CUPS_BACKEND_FAILED);
+ }
+ }
else
{
fd = 0;
@@ -1382,7 +1415,7 @@ main(int argc, /* I - Number of command-line args */
ipp_status = cupsLastError();
fprintf(stderr, "DEBUG: %s: %s (%s)\n",
- num_files > 1 ? "Create-Job" : "Print-Job",
+ (num_files > 1 || create_job) ? "Create-Job" : "Print-Job",
ippErrorString(ipp_status), cupsLastErrorString());
if (ipp_status > IPP_OK_CONFLICT)
@@ -1466,14 +1499,15 @@ main(int argc, /* I - Number of command-line args */
_("Print file accepted - job ID %d."), job_id);
}
+ fprintf(stderr, "DEBUG: job-id=%d\n", job_id);
ippDelete(response);
if (job_canceled)
break;
- if (job_id && num_files > 1)
+ if (job_id && (num_files > 1 || create_job))
{
- for (i = 0; i < num_files; i ++)
+ for (i = 0; num_files == 0 || i < num_files; i ++)
{
/*
* Check for side-channel requests...
@@ -1499,16 +1533,34 @@ main(int argc, /* I - Number of command-line args */
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requesting-user-name", NULL, argv[2]);
- if ((i + 1) == num_files)
+ if ((i + 1) >= num_files)
ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
- "document-format", NULL, content_type);
+ "document-format", NULL, document_format);
fprintf(stderr, "DEBUG: Sending file %d using chunking...\n", i + 1);
http_status = cupsSendRequest(http, request, resource, 0);
- if (http_status == HTTP_CONTINUE && request->state == IPP_DATA &&
- (fd = open(files[i], O_RDONLY)) >= 0)
+ if (http_status == HTTP_CONTINUE && request->state == IPP_DATA)
+ {
+ if (num_files == 0)
+ {
+ fd = 0;
+ http_status = cupsWriteRequestData(http, buffer, bytes);
+ }
+ else
+ {
+ if ((fd = open(files[i], O_RDONLY)) < 0)
+ {
+ _cupsLangPrintError("ERROR", _("Unable to open print file"));
+ return (CUPS_BACKEND_FAILED);
+ }
+ }
+ }
+ else
+ fd = -1;
+
+ if (fd >= 0)
{
while (!job_canceled &&
(bytes = read(fd, buffer, sizeof(buffer))) > 0)
@@ -1525,7 +1577,8 @@ main(int argc, /* I - Number of command-line args */
}
}
- close(fd);
+ if (fd > 0)
+ close(fd);
}
ippDelete(cupsGetResponse(http, resource));
@@ -1542,6 +1595,8 @@ main(int argc, /* I - Number of command-line args */
_("Unable to add document to print job."));
break;
}
+ else if (num_files == 0 || fd < 0)
+ break;
}
}
@@ -1972,6 +2027,11 @@ monitor_printer(
ipp_attribute_t *attr; /* Attribute in response */
int delay, /* Current delay */
prev_delay; /* Previous delay */
+ ipp_op_t job_op; /* Operation to use */
+ int job_id; /* Job ID */
+ const char *job_name; /* Job name */
+ ipp_jstate_t job_state; /* Job state */
+ const char *job_user; /* Job originating user name */
/*
@@ -2006,47 +2066,96 @@ monitor_printer(
monitor->user,
monitor->version);
- if (monitor->job_id > 0)
- {
- /*
- * Check the status of the job itself...
- */
+ /*
+ * Check the status of the job itself...
+ */
- request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES);
- request->request.op.version[0] = monitor->version / 10;
- request->request.op.version[1] = monitor->version % 10;
+ job_op = monitor->job_id > 0 ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS;
+ request = ippNewRequest(job_op);
+ request->request.op.version[0] = monitor->version / 10;
+ request->request.op.version[1] = monitor->version % 10;
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, monitor->uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, monitor->uri);
+ if (job_op == IPP_GET_JOB_ATTRIBUTES)
ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
- monitor->job_id);
+ monitor->job_id);
- if (monitor->user && monitor->user[0])
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requesting-user-name", NULL, monitor->user);
+ if (monitor->user && monitor->user[0])
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, monitor->user);
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes",
- (int)(sizeof(jattrs) / sizeof(jattrs[0])), NULL, jattrs);
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes",
+ (int)(sizeof(jattrs) / sizeof(jattrs[0])), NULL, jattrs);
- /*
- * Do the request...
- */
+ /*
+ * Do the request...
+ */
- response = cupsDoRequest(http, request, monitor->resource);
+ response = cupsDoRequest(http, request, monitor->resource);
- fprintf(stderr, "DEBUG: Get-Job-Attributes: %s (%s)\n",
- ippErrorString(cupsLastError()), cupsLastErrorString());
+ fprintf(stderr, "DEBUG: %s: %s (%s)\n", ippOpString(job_op),
+ ippErrorString(cupsLastError()), cupsLastErrorString());
+ if (job_op == IPP_GET_JOB_ATTRIBUTES)
+ {
if ((attr = ippFindAttribute(response, "job-state",
IPP_TAG_ENUM)) != NULL)
monitor->job_state = (ipp_jstate_t)attr->values[0].integer;
else
monitor->job_state = IPP_JOB_COMPLETED;
+ }
+ else
+ {
+ for (attr = response->attrs; attr; attr = attr->next)
+ {
+ job_id = 0;
+ job_name = NULL;
+ job_state = IPP_JOB_PENDING;
+ job_user = NULL;
+
+ while (attr && attr->group_tag != IPP_TAG_JOB)
+ attr = attr->next;
- ippDelete(response);
+ if (!attr)
+ break;
+
+ while (attr && attr->group_tag == IPP_TAG_JOB)
+ {
+ if (!strcmp(attr->name, "job-id") &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ job_id = attr->values[0].integer;
+ else if (!strcmp(attr->name, "job-name") &&
+ (attr->value_tag == IPP_TAG_NAME ||
+ attr->value_tag == IPP_TAG_NAMELANG))
+ job_name = attr->values[0].string.text;
+ else if (!strcmp(attr->name, "job-state") &&
+ attr->value_tag == IPP_TAG_ENUM)
+ job_state = attr->values[0].integer;
+ else if (!strcmp(attr->name, "job-originating-user-name") &&
+ (attr->value_tag == IPP_TAG_NAME ||
+ attr->value_tag == IPP_TAG_NAMELANG))
+ job_user = attr->values[0].string.text;
+
+ attr = attr->next;
+ }
+
+ if (job_id > 0 && job_name && !strcmp(job_name, monitor->job_name) &&
+ job_user && monitor->user && !strcmp(job_user, monitor->user))
+ {
+ monitor->job_id = job_id;
+ monitor->job_state = job_state;
+ break;
+ }
+
+ if (!attr)
+ break;
+ }
}
+ ippDelete(response);
+
/*
* Disconnect from the printer - we'll reconnect on the next poll...
*/
@@ -2064,6 +2173,15 @@ monitor_printer(
}
/*
+ * Cancel the job if necessary...
+ */
+
+ if (job_canceled && monitor->job_id > 0)
+ if (!httpReconnect(http))
+ cancel_job(http, monitor->uri, monitor->job_id, monitor->resource,
+ monitor->user, monitor->version);
+
+ /*
* Cleanup and return...
*/
@@ -2088,7 +2206,7 @@ new_request(
cups_option_t *options, /* I - Options to send */
const char *compression, /* I - compression value or NULL */
int copies, /* I - copies value or 0 */
- const char *format, /* I - documet-format value or NULL */
+ const char *format, /* I - document-format value or NULL */
_ppd_cache_t *pc, /* I - PPD cache and mapping data */
ipp_attribute_t *media_col_sup, /* I - media-col-supported values */
ipp_attribute_t *doc_handling_sup) /* I - multiple-document-handling-supported values */
@@ -2163,6 +2281,9 @@ new_request(
{
if (pc)
{
+ int num_finishings = 0, /* Number of finishing values */
+ finishings[10]; /* Finishing enum values */
+
/*
* Send standard IPP attributes...
*/
@@ -2284,6 +2405,7 @@ new_request(
}
if (doc_handling_sup &&
+ (!format || _cups_strncasecmp(format, "image/", 6)) &&
(keyword = cupsGetOption("collate", num_options, options)) != NULL)
{
if (!_cups_strcasecmp(keyword, "true"))
@@ -2299,6 +2421,43 @@ new_request(
break;
}
}
+
+ /*
+ * Map finishing options...
+ */
+
+ num_finishings = _ppdCacheGetFinishingValues(pc, num_options, options,
+ (int)(sizeof(finishings) /
+ sizeof(finishings[0])),
+ finishings);
+ if (num_finishings > 0)
+ ippAddIntegers(request, IPP_TAG_JOB, IPP_TAG_ENUM, "finishings",
+ num_finishings, finishings);
+
+ /*
+ * Map FaxOut options...
+ */
+
+ if ((keyword = cupsGetOption("phone", num_options, options)) != NULL)
+ {
+ ipp_t *destination; /* destination collection */
+ char tel_uri[1024]; /* tel: URI */
+
+ destination = ippNew();
+
+ httpAssembleURI(HTTP_URI_CODING_ALL, tel_uri, sizeof(tel_uri), "tel",
+ NULL, NULL, 0, keyword);
+ ippAddString(destination, IPP_TAG_JOB, IPP_TAG_URI, "destination-uri",
+ NULL, tel_uri);
+
+ if ((keyword = cupsGetOption("faxPrefix", num_options,
+ options)) != NULL && *keyword)
+ ippAddString(destination, IPP_TAG_JOB, IPP_TAG_TEXT,
+ "pre-dial-string", NULL, keyword);
+
+ ippAddCollection(request, IPP_TAG_JOB, "destination-uris", destination);
+ ippDelete(destination);
+ }
}
else
{
diff --git a/backend/network.c b/backend/network.c
index fb42f791f..6dbdca03b 100644
--- a/backend/network.c
+++ b/backend/network.c
@@ -71,7 +71,7 @@ backendNetworkSideCB(
{
cups_sc_command_t command; /* Request command */
cups_sc_status_t status; /* Request/response status */
- char data[2048]; /* Request/response data */
+ char data[65536]; /* Request/response data */
int datalen; /* Request/response data size */
const char *device_id; /* 1284DEVICEID env var */
diff --git a/backend/testbackend.c b/backend/testbackend.c
index cdb9a6695..6182471d1 100644
--- a/backend/testbackend.c
+++ b/backend/testbackend.c
@@ -3,7 +3,7 @@
*
* Backend test program for CUPS.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -57,7 +57,7 @@ static void walk_cb(const char *oid, const char *data, int datalen,
*
* Usage:
*
- * betest [-s] [-t] device-uri job-id user title copies options [file]
+ * testbackend [-s] [-t] device-uri job-id user title copies options [file]
*/
int /* O - Exit status */
@@ -75,7 +75,9 @@ main(int argc, /* I - Number of command-line args */
const char *oid = ".1.3.6.1.2.1.43.10.2.1.4.1.1";
/* OID to lookup or walk */
char scheme[255], /* Scheme in URI == backend */
- backend[1024]; /* Backend path */
+ backend[1024], /* Backend path */
+ libpath[1024], /* Path for libcups */
+ *ptr; /* Pointer into path */
const char *serverbin; /* CUPS_SERVERBIN environment variable */
int fd, /* Temporary file descriptor */
back_fds[2], /* Back-channel pipe */
@@ -88,6 +90,23 @@ main(int argc, /* I - Number of command-line args */
/*
+ * Get the current directory and point the run-time linker at the "cups"
+ * subdirectory...
+ */
+
+ if (getcwd(libpath, sizeof(libpath)) &&
+ (ptr = strrchr(libpath, '/')) != NULL && !strcmp(ptr, "/backend"))
+ {
+ strlcpy(ptr, "/cups", sizeof(libpath) - (ptr - libpath));
+ if (access(libpath, 0))
+#ifdef __APPLE__
+ setenv("DYLD_LIBRARY_PATH", libpath, 1);
+#else
+ setenv("LD_LIBRARY_PATH", libpath, 1);
+#endif /* __APPLE__ */
+ }
+
+ /*
* See if we have side-channel tests to do...
*/