/*
- * "$Id: ipp.c 9759 2011-05-11 03:24:33Z mike $"
+ * "$Id: ipp.c 11495 2013-12-22 05:29:16Z msweet $"
*
- * IPP backend for CUPS.
+ * IPP backend for CUPS.
*
- * Copyright 2007-2013 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2013 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * "LICENSE" which should have been included with this file. If this
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
- * This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- * main() - Send a file to the printer or server.
- * cancel_job() - Cancel a print job.
- * check_printer_state() - Check the printer state.
- * monitor_printer() - Monitor the printer state.
- * new_request() - Create a new print creation or validation
- * request.
- * password_cb() - Disable the password prompt for
- * cupsDoFileRequest().
- * quote_string() - Quote a string value.
- * report_attr() - Report an IPP attribute value.
- * report_printer_state() - Report the printer state.
- * run_as_user() - Run the IPP backend as the printing user.
- * sigterm_handler() - Handle 'terminate' signals that stop the backend.
- * timeout_cb() - Handle HTTP timeouts.
- * update_reasons() - Update the printer-state-reasons values.
+ * This file is subject to the Apple OS-Developed Software exception.
*/
/*
/* Username for device URI */
*password = NULL;
/* Password for device URI */
-static int password_tries = 0;
- /* Password tries */
static const char * const pattrs[] = /* Printer attributes we want */
{
#ifdef HAVE_LIBZ
"media-col-supported",
"multiple-document-handling-supported",
"operations-supported",
+ "print-color-mode-supported",
"printer-alert",
"printer-alert-description",
"printer-is-accepting-jobs",
ppd_file_t *ppd,
ipp_attribute_t *media_col_sup,
ipp_attribute_t *doc_handling_sup,
- int print_color_mode);
+ ipp_attribute_t *print_color_mode_sup);
static const char *password_cb(const char *prompt, http_t *http,
const char *method, const char *resource,
- void *user_data);
+ int *user_data);
static const char *quote_string(const char *s, char *q, size_t qsize);
static void report_attr(ipp_attribute_t *attr);
static void report_printer_state(ipp_t *ipp);
*name, /* Name of option */
*value, /* Value of option */
sep; /* Separator character */
+ int password_tries = 0; /* Password tries */
http_addrlist_t *addrlist; /* Address of printer */
int snmp_enabled = 1; /* Is SNMP enabled? */
int snmp_fd, /* SNMP socket */
ipp_attribute_t *copies_sup; /* copies-supported */
ipp_attribute_t *cups_version; /* cups-version */
ipp_attribute_t *format_sup; /* document-format-supported */
+ ipp_attribute_t *job_auth; /* job-authorization-uri */
ipp_attribute_t *media_col_sup; /* media-col-supported */
ipp_attribute_t *operations_sup; /* operations-supported */
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 */
+ ipp_attribute_t *print_color_mode_sup;/* Does printer support print-color-mode? */
int create_job = 0, /* Does printer support Create-Job? */
get_job_attrs = 0, /* Does printer support Get-Job-Attributes? */
send_document = 0, /* Does printer support Send-Document? */
validate_job = 0, /* Does printer support Validate-Job? */
- print_color_mode = 0; /* Does printer support print-color-mode? */
- int copies, /* Number of copies for job */
+ copies, /* Number of copies for job */
copies_remaining; /* Number of copies remaining */
const char *content_type, /* CONTENT_TYPE environment variable */
*final_content_type, /* FINAL_CONTENT_TYPE environment var */
* that way.
*/
- if (!getuid() && (value = getenv("AUTH_UID")) != NULL)
+ if (!getuid() && (value = getenv("AUTH_UID")) != NULL &&
+ !getenv("AUTH_PASSWORD"))
{
uid_t uid = (uid_t)atoi(value);
/* User ID */
if (!port)
port = IPP_PORT; /* Default to port 631 */
- if (!strcmp(scheme, "https"))
+ if (!strcmp(scheme, "https") || !strcmp(scheme, "ipps"))
cupsSetEncryption(HTTP_ENCRYPT_ALWAYS);
else
cupsSetEncryption(HTTP_ENCRYPT_IF_REQUESTED);
* Set the authentication info, if any...
*/
- cupsSetPasswordCB2(password_cb, NULL);
+ cupsSetPasswordCB2((cups_password_cb2_t)password_cb, &password_tries);
if (username[0])
{
delay = _cupsNextDelay(delay, &prev_delay);
ippDelete(supported);
- supported = NULL;
+ supported = NULL;
+ ipp_status = IPP_STATUS_ERROR_BUSY;
continue;
}
}
media_col_sup->values[i].string.text);
}
- print_color_mode = ippFindAttribute(supported,
- "print-color-mode-supported",
- IPP_TAG_KEYWORD) != NULL;
+ print_color_mode_sup = ippFindAttribute(supported, "print-color-mode-supported", IPP_TAG_KEYWORD);
if ((operations_sup = ippFindAttribute(supported, "operations-supported",
IPP_TAG_ENUM)) != NULL)
request = new_request(IPP_VALIDATE_JOB, version, uri, argv[2],
monitor.job_name, num_options, options, compression,
copies_sup ? copies : 1, document_format, pc, ppd,
- media_col_sup, doc_handling_sup, print_color_mode);
+ media_col_sup, doc_handling_sup, print_color_mode_sup);
- ippDelete(cupsDoRequest(http, request, resource));
+ response = cupsDoRequest(http, request, resource);
ipp_status = cupsLastError();
fprintf(stderr, "DEBUG: Validate-Job: %s (%s)\n",
ippErrorString(ipp_status), cupsLastErrorString());
+ if ((job_auth = ippFindAttribute(response, "job-authorization-uri",
+ IPP_TAG_URI)) != NULL)
+ num_options = cupsAddOption("job-authorization-uri",
+ ippGetString(job_auth, 0, NULL), num_options,
+ &options);
+
+ ippDelete(response);
+
if (job_canceled)
break;
version, uri, argv[2], monitor.job_name, num_options,
options, compression, copies_sup ? copies : 1,
document_format, pc, ppd, media_col_sup,
- doc_handling_sup, print_color_mode);
+ doc_handling_sup, print_color_mode_sup);
/*
* Do the request...
}
else if (ipp_status == IPP_STATUS_ERROR_JOB_CANCELED ||
ipp_status == IPP_STATUS_ERROR_NOT_AUTHORIZED ||
+ ipp_status == IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES ||
ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_INFO_NEEDED ||
ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_CLOSED ||
ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_LIMIT_REACHED ||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requesting-user-name", NULL, argv[2]);
- if ((i + 1) >= num_files)
- ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);
+ ippAddBoolean(request, IPP_TAG_OPERATION, "last-document",
+ (i + 1) >= num_files);
if (document_format)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
check_printer_state(http, uri, resource, argv[2], version);
+ if (cupsLastError() <= IPP_OK_CONFLICT)
+ password_tries = 0;
+
/*
* Build an IPP_GET_JOB_ATTRIBUTES request...
*/
check_printer_state(http, uri, resource, argv[2], version);
+ if (cupsLastError() <= IPP_OK_CONFLICT)
+ password_tries = 0;
+
/*
* Collect the final page count as needed...
*/
if (have_supplies &&
- !backendSNMPSupplies(snmp_fd, http->hostaddr, &page_count, NULL) &&
+ !backendSNMPSupplies(snmp_fd, &(http->addrlist->addr), &page_count,
+ NULL) &&
page_count > start_count)
fprintf(stderr, "PAGE: total %d\n", page_count - start_count);
fputs("JOBSTATE: account-authorization-failed\n", stderr);
if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN ||
- ipp_status == IPP_AUTHENTICATION_CANCELED ||
- ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_INFO_NEEDED ||
- ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_CLOSED ||
- ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_LIMIT_REACHED ||
- ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_AUTHORIZATION_FAILED)
+ ipp_status == IPP_AUTHENTICATION_CANCELED)
return (CUPS_BACKEND_AUTH_REQUIRED);
+ else if (ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_LIMIT_REACHED ||
+ ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_INFO_NEEDED ||
+ ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_CLOSED ||
+ ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_AUTHORIZATION_FAILED)
+ return (CUPS_BACKEND_HOLD);
else if (ipp_status == IPP_INTERNAL_ERROR)
return (CUPS_BACKEND_STOP);
else if (ipp_status == IPP_CONFLICT)
return (CUPS_BACKEND_FAILED);
else if (ipp_status == IPP_REQUEST_VALUE ||
+ ipp_status == IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES ||
ipp_status == IPP_DOCUMENT_FORMAT || job_canceled < 0)
{
if (ipp_status == IPP_REQUEST_VALUE)
else if (ipp_status == IPP_DOCUMENT_FORMAT)
_cupsLangPrintFilter(stderr, "ERROR",
_("Printer cannot print supplied content."));
+ else if (ipp_status == IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES)
+ _cupsLangPrintFilter(stderr, "ERROR",
+ _("Printer cannot print with supplied options."));
else
_cupsLangPrintFilter(stderr, "ERROR", _("Print job canceled at printer."));
fprintf(stderr, "DEBUG: Get-Printer-Attributes: %s (%s)\n",
ippErrorString(cupsLastError()), cupsLastErrorString());
- if (cupsLastError() <= IPP_OK_CONFLICT)
- password_tries = 0;
-
/*
* Return the printer-state value...
*/
const char *job_name; /* Job name */
ipp_jstate_t job_state; /* Job state */
const char *job_user; /* Job originating user name */
+ int password_tries = 0; /* Password tries */
/*
httpSetTimeout(http, 30.0, timeout_cb, NULL);
if (username[0])
cupsSetUser(username);
- cupsSetPasswordCB2(password_cb, NULL);
+
+ cupsSetPasswordCB2((cups_password_cb2_t)password_cb, &password_tries);
/*
* Loop until the job is canceled, aborted, or completed.
monitor->resource,
monitor->user,
monitor->version);
+ if (cupsLastError() <= IPP_OK_CONFLICT)
+ password_tries = 0;
/*
* Check the status of the job itself...
ppd_file_t *ppd, /* I - PPD file data */
ipp_attribute_t *media_col_sup, /* I - media-col-supported values */
ipp_attribute_t *doc_handling_sup, /* I - multiple-document-handling-supported values */
- int print_color_mode) /* I - Printer supports print-color-mode */
+ ipp_attribute_t *print_color_mode_sup)
+ /* I - Printer supports print-color-mode */
{
int i; /* Looping var */
ipp_t *request; /* Request data */
"job-password-encryption", NULL, keyword);
}
- if (pc->account_id &&
- (keyword = cupsGetOption("job-account-id", num_options,
- options)) != NULL)
- ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-account-id",
- NULL, keyword);
+ if (pc->account_id)
+ {
+ if ((keyword = cupsGetOption("job-account-id", num_options,
+ options)) == NULL)
+ keyword = cupsGetOption("job-billing", num_options, options);
- if (pc->account_id &&
- (keyword = cupsGetOption("job-accounting-user-id", num_options,
- options)) != NULL)
- ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME,
- "job-accounting-user-id", NULL, keyword);
+ if (keyword)
+ ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-account-id",
+ NULL, keyword);
+ }
+
+ if (pc->accounting_user_id)
+ {
+ if ((keyword = cupsGetOption("job-accounting-user-id", num_options,
+ options)) == NULL)
+ keyword = user;
+
+ if (keyword)
+ ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME,
+ "job-accounting-user-id", NULL, keyword);
+ }
for (mandatory = (char *)cupsArrayFirst(pc->mandatory);
mandatory;
strlen(keyword));
break;
default :
+ if (!strcmp(mandatory, "print-color-mode") && !strcmp(keyword, "monochrome"))
+ {
+ if (ippContainsString(print_color_mode_sup, "auto-monochrome"))
+ keyword = "auto-monochrome";
+ else if (ippContainsString(print_color_mode_sup, "process-monochrome") && !ippContainsString(print_color_mode_sup, "monochrome"))
+ keyword = "process-monochrome";
+ }
+
ippAddString(request, IPP_TAG_JOB, value_tag, mandatory,
NULL, keyword);
break;
ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "output-bin",
NULL, keyword);
- color_attr_name = print_color_mode ? "print-color-mode" : "output-mode";
+ color_attr_name = print_color_mode_sup ? "print-color-mode" : "output-mode";
if ((keyword = cupsGetOption("print-color-mode", num_options,
- options)) != NULL)
- ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, color_attr_name,
- NULL, keyword);
- else if ((choice = ppdFindMarkedChoice(ppd, "ColorModel")) != NULL)
+ options)) == NULL)
{
- if (!_cups_strcasecmp(choice->choice, "Gray"))
- ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- color_attr_name, NULL, "monochrome");
- else
- ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- color_attr_name, NULL, "color");
+ if ((choice = ppdFindMarkedChoice(ppd, "ColorModel")) != NULL)
+ {
+ if (!_cups_strcasecmp(choice->choice, "Gray"))
+ keyword = "monochrome";
+ else
+ keyword = "color";
+ }
+ }
+
+ if (keyword && !strcmp(keyword, "monochrome"))
+ {
+ if (ippContainsString(print_color_mode_sup, "auto-monochrome"))
+ keyword = "auto-monochrome";
+ else if (ippContainsString(print_color_mode_sup, "process-monochrome") && !ippContainsString(print_color_mode_sup, "monochrome"))
+ keyword = "process-monochrome";
}
+ if (keyword)
+ ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, color_attr_name,
+ NULL, keyword);
+
if ((keyword = cupsGetOption("print-quality", num_options,
options)) != NULL)
ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality",
http_t *http, /* I - Connection */
const char *method, /* I - Request method (not used) */
const char *resource, /* I - Resource path (not used) */
- void *user_data) /* I - User data (not used) */
+ int *password_tries) /* I - Password tries */
{
char def_username[HTTP_MAX_VALUE]; /* Default username */
- fprintf(stderr, "DEBUG: password_cb(prompt=\"%s\"), password=%p, "
- "password_tries=%d\n", prompt, password, password_tries);
+ fprintf(stderr, "DEBUG: password_cb(prompt=\"%s\", http=%p, method=\"%s\", "
+ "resource=\"%s\", password_tries=%p(%d)), password=%p\n",
+ prompt, http, method, resource, password_tries, *password_tries,
+ password);
(void)prompt;
(void)method;
(void)resource;
- (void)user_data;
/*
* Remember that we need to authenticate...
quote_string(def_username, quoted, sizeof(quoted)));
}
- if (password && *password && password_tries < 3)
+ if (password && *password && *password_tries < 3)
{
- password_tries ++;
+ (*password_tries) ++;
return (password);
}
{
if (*s == '\\' || *s == '\"' || *s == '\'')
{
- if (q < (qend - 3))
+ if (qptr < (qend - 4))
{
*qptr++ = '\\';
*qptr++ = '\\';
if (conn)
{
- xpc_connection_suspend(conn);
xpc_connection_cancel(conn);
xpc_release(conn);
}
}
/*
- * End of "$Id: ipp.c 9759 2011-05-11 03:24:33Z mike $".
+ * End of "$Id: ipp.c 11495 2013-12-22 05:29:16Z msweet $".
*/