/*
* IPP backend for CUPS.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
#define _CUPS_JSR_ACCOUNT_LIMIT_REACHED 0x08
#define _CUPS_JSR_JOB_PASSWORD_WAIT 0x10
#define _CUPS_JSR_JOB_RELEASE_WAIT 0x20
+#define _CUPS_JSR_DOCUMENT_FORMAT_ERROR 0x40
+#define _CUPS_JSR_DOCUMENT_UNPRINTABLE 0x80
/*
http_encryption_t encryption; /* Use encryption? */
ipp_jstate_t job_state; /* Current job state */
ipp_pstate_t printer_state; /* Current printer state */
+ int retryable; /* Is this a job that should be retried? */
} _cups_monitor_t;
* that way.
*/
- if (!getuid() && (value = getenv("AUTH_UID")) != NULL &&
- !getenv("AUTH_PASSWORD"))
+ if (!getuid() && (value = getenv("AUTH_UID")) != NULL)
{
uid_t uid = (uid_t)atoi(value);
/* User ID */
# else /* No XPC, just try to run as the user ID */
if (uid > 0)
- seteuid(uid);
+ setuid(uid);
# endif /* HAVE_XPC */
}
#endif /* HAVE_GSSAPI */
fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(errno));
- if (errno == ECONNREFUSED || errno == EHOSTDOWN ||
- errno == EHOSTUNREACH)
+ if (errno == ECONNREFUSED || errno == EHOSTDOWN || errno == EHOSTUNREACH || errno == ETIMEDOUT || errno == ENOTCONN)
{
if (contimeout && (time(NULL) - start_time) > contimeout)
{
break;
case EHOSTUNREACH :
+ default :
_cupsLangPrintFilter(stderr, "WARNING",
_("The printer is unreachable at this "
"time."));
break;
case ECONNREFUSED :
- default :
_cupsLangPrintFilter(stderr, "WARNING",
_("The printer is in use."));
break;
copies_sup = NULL; /* No */
}
- cups_version = ippFindAttribute(supported, "cups-version", IPP_TAG_TEXT);
+ if ((cups_version = ippFindAttribute(supported, "cups-version", IPP_TAG_TEXT)) != NULL)
+ {
+ const char *version = ippGetString(cups_version, 0, NULL);
+
+ fprintf(stderr, "DEBUG: cups-version = \"%s\"\n", version);
+ if (!strcmp(version, "cups-version"))
+ cups_version = NULL; /* Bogus cups-version value returned by buggy printers! */
+ }
encryption_sup = ippFindAttribute(supported, "job-password-encryption-supported", IPP_TAG_KEYWORD);
monitor.encryption = cupsEncryption();
monitor.job_state = IPP_JOB_PENDING;
monitor.printer_state = IPP_PRINTER_IDLE;
+ monitor.retryable = argc == 6 && document_format && strcmp(document_format, "image/pwg-raster") && strcmp(document_format, "image/urf");
if (create_job)
{
for (i = 0; i < attr->num_values; i ++)
{
- if (!strcmp(attr->values[i].string.text,
- "account-authorization-failed"))
+ if (!strcmp(attr->values[i].string.text, "account-authorization-failed"))
new_reasons |= _CUPS_JSR_ACCOUNT_AUTHORIZATION_FAILED;
else if (!strcmp(attr->values[i].string.text, "account-closed"))
new_reasons |= _CUPS_JSR_ACCOUNT_CLOSED;
else if (!strcmp(attr->values[i].string.text, "account-info-needed"))
new_reasons |= _CUPS_JSR_ACCOUNT_INFO_NEEDED;
- else if (!strcmp(attr->values[i].string.text,
- "account-limit-reached"))
+ else if (!strcmp(attr->values[i].string.text, "account-limit-reached"))
new_reasons |= _CUPS_JSR_ACCOUNT_LIMIT_REACHED;
else if (!strcmp(attr->values[i].string.text, "job-password-wait"))
new_reasons |= _CUPS_JSR_JOB_PASSWORD_WAIT;
else if (!strcmp(attr->values[i].string.text, "job-release-wait"))
new_reasons |= _CUPS_JSR_JOB_RELEASE_WAIT;
- if (!job_canceled &&
- (!strncmp(attr->values[i].string.text, "job-canceled-", 13) || !strcmp(attr->values[i].string.text, "aborted-by-system")))
+ else if (!strcmp(attr->values[i].string.text, "document-format-error"))
+ new_reasons |= _CUPS_JSR_DOCUMENT_FORMAT_ERROR;
+ else if (!strcmp(attr->values[i].string.text, "document-unprintable"))
+ new_reasons |= _CUPS_JSR_DOCUMENT_UNPRINTABLE;
+
+ if (!job_canceled && (!strncmp(attr->values[i].string.text, "job-canceled-", 13) || !strcmp(attr->values[i].string.text, "aborted-by-system")))
job_canceled = 1;
}
fputs("JOBSTATE: job-password-wait\n", stderr);
else if (new_reasons & _CUPS_JSR_JOB_RELEASE_WAIT)
fputs("JOBSTATE: job-release-wait\n", stderr);
+ else if (new_reasons & (_CUPS_JSR_DOCUMENT_FORMAT_ERROR | _CUPS_JSR_DOCUMENT_UNPRINTABLE))
+ {
+ if (monitor->retryable)
+ {
+ /*
+ * Can't print this, so retry as raster...
+ */
+
+ job_canceled = 1;
+ fputs("JOBSTATE: cups-retry-as-raster\n", stderr);
+ }
+ else if (new_reasons & _CUPS_JSR_DOCUMENT_FORMAT_ERROR)
+ {
+ fputs("JOBSTATE: document-format-error\n", stderr);
+ }
+ else
+ {
+ fputs("JOBSTATE: document-unprintable\n", stderr);
+ }
+ }
else
fputs("JOBSTATE: job-printing\n", stderr);
char phone[1024], /* Phone number string */
*ptr, /* Pointer into string */
tel_uri[1024]; /* tel: URI */
- static const char * const allowed = "0123456789#*-+.()";
+ static const char * const allowed = "0123456789#*-+.()pw";
/* Allowed characters */
destination = ippNew();
_httpDecodeURI(phone, keyword, sizeof(phone));
for (ptr = phone; *ptr;)
{
- if (!strchr(allowed, *ptr))
+ if (*ptr == ',')
+ *ptr = 'p';
+ else if (!strchr(allowed, *ptr))
_cups_strcpy(ptr, ptr + 1);
else
ptr ++;