summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2016-02-18 20:32:13 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2016-02-18 20:32:13 +0000
commitc585706d00357dec95a60ce9e3e258775189ed6c (patch)
tree487f104bd6c389a9ccfffacf8a757739bc958509
parent4db7fceecfefe00824281a2a25e9c0c794a4e6a8 (diff)
Implement more of testdest unit test.
Fix mapping of CUPS-Create-Local-Printer operation code. Add logging to background thread. git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@13105 a1ca3aef-8c08-0410-bb20-df032aa958be
-rw-r--r--cups/dest.c39
-rw-r--r--cups/ipp-support.c4
-rw-r--r--cups/testdest.c199
-rw-r--r--scheduler/ipp.c26
4 files changed, 242 insertions, 26 deletions
diff --git a/cups/dest.c b/cups/dest.c
index bc9d71141..1682346b4 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -826,11 +826,10 @@ _cupsCreateDest(const char *name, /* I - Printer name */
ipp_t *request, /* CUPS-Create-Local-Printer request */
*response; /* CUPS-Create-Local-Printer response */
ipp_attribute_t *attr; /* printer-uri-supported attribute */
+ ipp_pstate_t state = IPP_PSTATE_STOPPED;
+ /* printer-state value */
- (void)info;
- (void)device_id;
-
if (!name || !device_uri || !uri || urisize < 32)
return (NULL);
@@ -851,14 +850,40 @@ _cupsCreateDest(const char *name, /* I - Printer name */
response = cupsDoRequest(http, request, "/");
- httpClose(http);
-
if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
strlcpy(uri, ippGetString(attr, 0, NULL), urisize);
+ else
+ {
+ ippDelete(response);
+ httpClose(http);
+ return (NULL);
+ }
+
+ if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
+ state = (ipp_pstate_t)ippGetInteger(attr, 0);
+
+ while (state == IPP_PSTATE_STOPPED && cupsLastError() == IPP_STATUS_OK)
+ {
+ sleep(1);
+ ippDelete(response);
+
+ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "printer-state");
+
+ response = cupsDoRequest(http, request, "/");
+
+ if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
+ state = (ipp_pstate_t)ippGetInteger(attr, 0);
+ }
ippDelete(response);
- return (attr ? uri : NULL);
+ httpClose(http);
+
+ return (uri);
}
@@ -3498,7 +3523,7 @@ cups_dnssd_resolve(
if (cb)
(*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_RESOLVING, dest);
- if ((uri = _httpResolveURI(uri, tempuri, sizeof(tempuri), _HTTP_RESOLVE_FQDN, cups_dnssd_resolve_cb, &resolve)) == NULL)
+ if ((uri = _httpResolveURI(uri, tempuri, sizeof(tempuri), _HTTP_RESOLVE_DEFAULT, cups_dnssd_resolve_cb, &resolve)) == NULL)
{
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to resolve printer-uri."), 1);
diff --git a/cups/ipp-support.c b/cups/ipp-support.c
index 9928a91d4..40c01eb60 100644
--- a/cups/ipp-support.c
+++ b/cups/ipp-support.c
@@ -2051,8 +2051,8 @@ ippOpString(ipp_op_t op) /* I - Operation ID */
return ("windows-ext");
else if (op >= IPP_OP_CUPS_GET_DEFAULT && op <= IPP_OP_CUPS_GET_PPD)
return (ipp_cups_ops[op - IPP_OP_CUPS_GET_DEFAULT]);
- else if (op == IPP_OP_CUPS_GET_DOCUMENT)
- return (ipp_cups_ops2[0]);
+ else if (op >= IPP_OP_CUPS_GET_DOCUMENT && op <= IPP_OP_CUPS_CREATE_LOCAL_PRINTER)
+ return (ipp_cups_ops2[op - IPP_OP_CUPS_GET_DOCUMENT]);
/*
* No, build an "0xxxxx" operation string...
diff --git a/cups/testdest.c b/cups/testdest.c
index 74cdd6555..50835eceb 100644
--- a/cups/testdest.c
+++ b/cups/testdest.c
@@ -1,7 +1,7 @@
/*
* CUPS destination API test program for CUPS.
*
- * Copyright 2016 by Apple Inc.
+ * Copyright 2012-2016 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -17,6 +17,7 @@
*/
#include <stdio.h>
+#include <errno.h>
#include "cups.h"
@@ -149,9 +150,14 @@ main(int argc, /* I - Number of command-line arguments */
{
show_default(http, dest, dinfo, argv[3]);
}
- else if (!strcmp(argv[2], "localize") && argc > 3 && argc < 6)
+ else if (!strcmp(argv[2], "localize") && argc < 6)
{
- localize(http, dest, dinfo, argv[3], argv[4]);
+ if (argc > 3)
+ localize(http, dest, dinfo, argv[3], argv[4]);
+ else if (argc > 2)
+ localize(http, dest, dinfo, argv[3], NULL);
+ else
+ localize(http, dest, dinfo, NULL, NULL);
}
else if (!strcmp(argv[2], "media"))
{
@@ -234,11 +240,128 @@ localize(http_t *http, /* I - Connection to destination */
const char *option, /* I - Option */
const char *value) /* I - Value, if any */
{
- (void)http;
- (void)dest;
- (void)dinfo;
- (void)option;
- (void)value;
+ ipp_attribute_t *attr; /* Attribute */
+ int i, /* Looping var */
+ count; /* Number of values */
+
+
+ if (!option)
+ {
+ attr = cupsFindDestSupported(http, dest, dinfo, "job-creation-attributes");
+ if (attr)
+ {
+ count = ippGetCount(attr);
+ for (i = 0; i < count; i ++)
+ localize(http, dest, dinfo, ippGetString(attr, i, NULL), NULL);
+ }
+ else
+ {
+ static const char * const options[] =
+ { /* List of standard options */
+ CUPS_COPIES,
+ CUPS_FINISHINGS,
+ CUPS_MEDIA,
+ CUPS_NUMBER_UP,
+ CUPS_ORIENTATION,
+ CUPS_PRINT_COLOR_MODE,
+ CUPS_PRINT_QUALITY,
+ CUPS_SIDES
+ };
+
+ puts("No job-creation-attributes-supported attribute, probing instead.");
+
+ for (i = 0; i < (int)(sizeof(options) / sizeof(options[0])); i ++)
+ if (cupsCheckDestSupported(http, dest, dinfo, options[i], NULL))
+ localize(http, dest, dinfo, options[i], NULL);
+ }
+ }
+ else if (!value)
+ {
+ printf("%s (%s)\n", option, cupsLocalizeDestOption(http, dest, dinfo, option));
+
+ if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL)
+ {
+ count = ippGetCount(attr);
+
+ switch (ippGetValueTag(attr))
+ {
+ case IPP_TAG_INTEGER :
+ for (i = 0; i < count; i ++)
+ printf(" %d\n", ippGetInteger(attr, i));
+ break;
+
+ case IPP_TAG_ENUM :
+ for (i = 0; i < count; i ++)
+ printf(" %s\n", ippEnumString(option, ippGetInteger(attr, i)));
+ break;
+
+ case IPP_TAG_RANGE :
+ for (i = 0; i < count; i ++)
+ {
+ int upper, lower = ippGetRange(attr, i, &upper);
+
+ printf(" %d-%d\n", lower, upper);
+ }
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ for (i = 0; i < count; i ++)
+ {
+ int xres, yres;
+ ipp_res_t units;
+ xres = ippGetResolution(attr, i, &yres, &units);
+
+ if (xres == yres)
+ printf(" %d%s\n", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
+ else
+ printf(" %dx%d%s\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
+ }
+ break;
+
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ for (i = 0; i < count; i ++)
+ printf(" %s (%s)\n", ippGetString(attr, i, NULL), cupsLocalizeDestValue(http, dest, dinfo, option, ippGetString(attr, i, NULL)));
+ break;
+
+ case IPP_TAG_STRING :
+ for (i = 0; i < count; i ++)
+ {
+ int j, len;
+ unsigned char *data = ippGetOctetString(attr, i, &len);
+
+ fputs(" ", stdout);
+ for (j = 0; j < len; j ++)
+ {
+ if (data[j] < ' ' || data[j] >= 0x7f)
+ printf("<%02X>", data[j]);
+ else
+ putchar(data[j]);
+ }
+ putchar('\n');
+ }
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ break;
+
+ default :
+ printf(" %s\n", ippTagString(ippGetValueTag(attr)));
+ break;
+ }
+ }
+
+ }
+ else
+ puts(cupsLocalizeDestValue(http, dest, dinfo, option, value));
}
@@ -254,12 +377,59 @@ print_file(http_t *http, /* I - Connection to destination */
int num_options, /* I - Number of options */
cups_option_t *options) /* I - Options */
{
- (void)http;
- (void)dest;
- (void)dinfo;
- (void)filename;
- (void)num_options;
- (void)options;
+ cups_file_t *fp; /* File to print */
+ int job_id; /* Job ID */
+ ipp_status_t status; /* Submission status */
+ const char *title; /* Title of job */
+ char buffer[32768]; /* File buffer */
+ ssize_t bytes; /* Bytes read/to write */
+
+
+ if ((fp = cupsFileOpen(filename, "r")) == NULL)
+ {
+ printf("Unable to open \"%s\": %s\n", filename, strerror(errno));
+ return;
+ }
+
+ if ((title = strrchr(filename, '/')) != NULL)
+ title ++;
+ else
+ title = filename;
+
+ if ((status = cupsCreateDestJob(http, dest, dinfo, &job_id, title, num_options, options)) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
+ {
+ printf("Unable to create job: %s\n", cupsLastErrorString());
+ cupsFileClose(fp);
+ return;
+ }
+
+ printf("Created job ID: %d\n", job_id);
+
+ if (cupsStartDestDocument(http, dest, dinfo, job_id, title, CUPS_FORMAT_AUTO, 0, NULL, 1) != HTTP_STATUS_CONTINUE)
+ {
+ printf("Unable to send document: %s\n", cupsLastErrorString());
+ cupsFileClose(fp);
+ return;
+ }
+
+ while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
+ {
+ if (cupsWriteRequestData(http, buffer, (size_t)bytes) != HTTP_STATUS_CONTINUE)
+ {
+ printf("Unable to write document data: %s\n", cupsLastErrorString());
+ break;
+ }
+ }
+
+ cupsFileClose(fp);
+
+ if ((status = cupsFinishDestDocument(http, dest, dinfo)) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
+ {
+ printf("Unable to send document: %s\n", cupsLastErrorString());
+ return;
+ }
+
+ puts("Job queued.");
}
@@ -510,7 +680,6 @@ show_supported(http_t *http, /* I - Connection to destination */
puts("YES");
else
puts("NO");
-
}
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index 8c266c7c9..6ccdc6889 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -5229,8 +5229,13 @@ create_local_bg_thread(
* Try connecting to the printer...
*/
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Generating PPD file from \"%s\"...", printer->name, printer->device_uri);
+
if (httpSeparateURI(HTTP_URI_CODING_ALL, printer->device_uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Bad device URI \"%s\".", printer->name, printer->device_uri);
return (NULL);
+ }
if (!strcmp(scheme, "ipps") || port == 443)
encryption = HTTP_ENCRYPTION_ALWAYS;
@@ -5238,18 +5243,25 @@ create_local_bg_thread(
encryption = HTTP_ENCRYPTION_IF_REQUESTED;
if ((http = httpConnect2(host, port, NULL, AF_UNSPEC, encryption, 1, 30000, NULL)) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to connect to %s:%d: %s", printer->name, host, port, cupsLastErrorString());
return (NULL);
+ }
/*
* Query the printer for its capabilities...
*/
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Connected to %s:%d, sending Get-Printer-Attributes request...", printer->name, host, port);
+
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer->device_uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "all");
response = cupsDoRequest(http, request, resource);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Get-Printer-Attributes returned %s", printer->name, ippErrorString(cupsLastError()));
+
// TODO: Grab printer icon file...
httpClose(http);
@@ -5269,11 +5281,15 @@ create_local_bg_thread(
cupsdSetString(&printer->geo_location, ippGetString(attr, 0, NULL));
if ((from = cupsFileOpen(fromppd, "r")) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to read generated PPD: %s", printer->name, strerror(errno));
return (NULL);
+ }
snprintf(toppd, sizeof(toppd), "%s/ppd/%s.ppd", ServerRoot, printer->name);
if ((to = cupsdCreateConfFile(toppd, ConfigFilePerm)) == NULL)
{
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to create PPD for printer: %s", printer->name, strerror(errno));
cupsFileClose(from);
return (NULL);
}
@@ -5284,12 +5300,18 @@ create_local_bg_thread(
cupsFileClose(from);
if (!cupsdCloseCreatedConfFile(to, toppd))
{
- printer->state = IPP_PSTATE_IDLE;
- printer->accepting = 1;
+ printer->config_time = time(NULL);
+ printer->state = IPP_PSTATE_IDLE;
+ printer->accepting = 1;
cupsdSetPrinterAttrs(printer);
+
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_CONFIG, printer, NULL, "Printer \"%s\" is now available.", printer->name);
+ cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" is now available.", printer->name);
}
}
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: PPD creation failed.", printer->name);
return (NULL);
}