STR #3755, STR #3769)
- Configure script fixes (STR #3659, STR #3691)
- Compilation fixes (STR #3718, STR #3771, STR #3774)
+ - The scheduler did not always register the correct default ICC profile
+ on Mac OS X.
+ - The scheduler did not use the job owner when authorizing access for
+ the CUPS-Get-Document operation, preventing non-admins from accessing
+ their own jobs.
+ - CUPS did not work with some printers that incorrectly implemented the
+ HTTP/1.1 standard (STR #3778, STR #3791)
- The scheduler did not retry fax jobs properly.
- The scheduler now recognizes an empty cupsCommands PPD keyword as
meaning that CUPS commands are not supported for a printer (STR #3773)
-CHANGES.txt - 2011-01-10
+CHANGES.txt - 2011-01-21
------------------------
CHANGES IN CUPS V1.5b1
+ - The scheduler now provides default values for the pages-per-minute and
+ pages-per-minute-color attributes for PPD files that lack a
+ Throughput keyword.
+ - Email notifications did not work on Mac OS X.
- The cupstestppd program now shows an error for files missing a
CloseGroup keyword (STR #3668)
- Name resolution errors no longer cause queues to stop (STR #3719,
-L../scheduler @LDARCHFLAGS@ \
@LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
LEGACY_BACKENDS = @LEGACY_BACKENDS@
-LINKCUPS = @LINKCUPS@ $(SSLLIBS) $(DNSSDLIBS)
+LINKCUPS = @LINKCUPS@ $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(LIBZ)
LINKCUPSIMAGE = @LINKCUPSIMAGE@
LIBS = $(LINKCUPS) $(COMMONLIBS)
OPTIM = @OPTIM@
}
*valptr++ = '\n';
- *valptr++ = '\0';
+ *valptr = '\0';
fputs(value, stderr);
}
if (value[0])
{
*valptr++ = '\n';
- *valptr++ = '\0';
+ *valptr = '\0';
fputs(value, stderr);
}
if (isalnum(*ptr & 255) || *ptr == '_' || *ptr == '-' ||
*ptr == '.')
*option_ptr++ = *ptr;
- else if ((*ptr == ' ' || *ptr == '/') && option_ptr[-1] != '_')
+ else if ((*ptr == ' ' || *ptr == '/') && option_ptr > option &&
+ option_ptr[-1] != '_')
*option_ptr++ = '_';
else if (*ptr == '?' || *ptr == '(')
break;
/* Current resolver option */
reschoice[PPD_MAX_NAME],
/* Current resolver choice */
- *resptr; /* Pointer into option/choice */
+ *resptr, /* Pointer into option/choice */
+ firstpage[255]; /* AP_FIRSTPAGE_Keyword string */
const char *value; /* Selected option value */
int changed; /* Did we change anything? */
ppd_choice_t *marked; /* Marked choice */
* Is this the option we are changing?
*/
+ snprintf(firstpage, sizeof(firstpage), "AP_FIRSTPAGE_%s", resoption);
+
if (option &&
(!strcasecmp(resoption, option) ||
+ !strcasecmp(firstpage, option) ||
(!strcasecmp(option, "PageSize") &&
!strcasecmp(resoption, "PageRegion")) ||
+ (!strcasecmp(option, "AP_FIRSTPAGE_PageSize") &&
+ !strcasecmp(resoption, "PageSize")) ||
+ (!strcasecmp(option, "AP_FIRSTPAGE_PageSize") &&
+ !strcasecmp(resoption, "PageRegion")) ||
(!strcasecmp(option, "PageRegion") &&
- !strcasecmp(resoption, "PageSize"))))
+ !strcasecmp(resoption, "PageSize")) ||
+ (!strcasecmp(option, "AP_FIRSTPAGE_PageRegion") &&
+ !strcasecmp(resoption, "PageSize")) ||
+ (!strcasecmp(option, "AP_FIRSTPAGE_PageRegion") &&
+ !strcasecmp(resoption, "PageRegion"))))
continue;
/*
ppd_choice_t key, /* Search key */
*marked; /* Marked choice */
cups_array_t *active = NULL; /* Active constraints */
- const char *value; /* Current value */
+ const char *value, /* Current value */
+ *firstvalue; /* AP_FIRSTPAGE_Keyword value */
+ char firstpage[255]; /* AP_FIRSTPAGE_Keyword string */
DEBUG_printf(("7ppd_test_constraints(ppd=%p, option=\"%s\", choice=\"%s\", "
for (i = consts->num_constraints, constptr = consts->constraints;
i > 0;
i --, constptr ++)
+ {
if (!strcasecmp(constptr->option->keyword, option))
break;
+ if (!strncasecmp(option, "AP_FIRSTPAGE_", 13) &&
+ !strcasecmp(constptr->option->keyword, option + 13))
+ break;
+ }
+
if (!i)
continue;
}
if (value && !strncasecmp(value, "Custom.", 7))
value = "Custom";
- if (!value || strcasecmp(value, constptr->choice->choice))
+ if (option && choice &&
+ (!strcasecmp(option, "AP_FIRSTPAGE_PageSize") ||
+ !strcasecmp(option, "AP_FIRSTPAGE_PageRegion")))
+ {
+ firstvalue = choice;
+ }
+ else if ((firstvalue = cupsGetOption("AP_FIRSTPAGE_PageSize",
+ num_options, options)) == NULL)
+ firstvalue = cupsGetOption("AP_FIRSTPAGE_PageRegion", num_options,
+ options);
+
+ if (firstvalue && !strncasecmp(firstvalue, "Custom.", 7))
+ firstvalue = "Custom";
+
+ if ((!value || strcasecmp(value, constptr->choice->choice)) &&
+ (!firstvalue || strcasecmp(firstvalue, constptr->choice->choice)))
{
DEBUG_puts("9ppd_test_constraints: NO");
break;
}
else if (constptr->choice)
{
+ /*
+ * Compare against the constrained choice...
+ */
+
if (option && choice && !strcasecmp(option, constptr->option->keyword))
{
if (!strncasecmp(choice, "Custom.", 7))
value = "Custom";
else
value = choice;
-
- if (strcasecmp(value, constptr->choice->choice))
- {
- DEBUG_puts("9ppd_test_constraints: NO");
- break;
- }
}
else if ((value = cupsGetOption(constptr->option->keyword, num_options,
options)) != NULL)
{
if (!strncasecmp(value, "Custom.", 7))
value = "Custom";
+ }
+ else if (constptr->choice->marked)
+ value = constptr->choice->choice;
+ else
+ value = NULL;
- if (strcasecmp(value, constptr->choice->choice))
- {
- DEBUG_puts("9ppd_test_constraints: NO");
- break;
- }
+ /*
+ * Now check AP_FIRSTPAGE_option...
+ */
+
+ snprintf(firstpage, sizeof(firstpage), "AP_FIRSTPAGE_%s",
+ constptr->option->keyword);
+
+ if (option && choice && !strcasecmp(option, firstpage))
+ {
+ if (!strncasecmp(choice, "Custom.", 7))
+ firstvalue = "Custom";
+ else
+ firstvalue = choice;
+ }
+ else if ((firstvalue = cupsGetOption(firstpage, num_options,
+ options)) != NULL)
+ {
+ if (!strncasecmp(firstvalue, "Custom.", 7))
+ firstvalue = "Custom";
}
- else if (!constptr->choice->marked)
+ else
+ firstvalue = NULL;
+
+ DEBUG_printf(("9ppd_test_constraints: value=%s, firstvalue=%s", value,
+ firstvalue));
+
+ if ((!value || strcasecmp(value, constptr->choice->choice)) &&
+ (!firstvalue || strcasecmp(firstvalue, constptr->choice->choice)))
{
DEBUG_puts("9ppd_test_constraints: NO");
break;
!strcasecmp(choice, "False"))
{
DEBUG_puts("9ppd_test_constraints: NO");
- break;
+ break;
}
}
else if ((value = cupsGetOption(constptr->option->keyword, num_options,
- options)) != NULL)
+ options)) != NULL)
{
if (!strcasecmp(value, "None") || !strcasecmp(value, "Off") ||
!strcasecmp(value, "False"))
}
else
{
- key.option = constptr->option;
+ key.option = constptr->option;
if ((marked = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key))
- == NULL ||
+ == NULL ||
(!strcasecmp(marked->choice, "None") ||
!strcasecmp(marked->choice, "Off") ||
!strcasecmp(marked->choice, "False")))
size_t resolved_size, int log);
extern void _httpSetTimeout(http_t *http, double timeout,
_http_timeout_cb_t cb, void *user_data);
+extern int _httpUpdate(http_t *http, http_status_t *status);
extern int _httpWait(http_t *http, int msec, int usessl);
* _httpSetTimeout() - Set read/write timeouts and an optional
* callback.
* httpTrace() - Send an TRACE request to the server.
+ * _httpUpdate() - Update the current HTTP status for incoming
+ * data.
* httpUpdate() - Update the current HTTP state for incoming
* data.
* _httpWait() - Wait for data available on a connection (no
/*
- * 'httpUpdate()' - Update the current HTTP state for incoming data.
+ * '_httpUpdate()' - Update the current HTTP status for incoming data.
+ *
+ * Note: Unlike httpUpdate(), this function does not flush pending write data
+ * and only retrieves a single status line from the HTTP connection.
*/
-http_status_t /* O - HTTP status */
-httpUpdate(http_t *http) /* I - Connection to server */
+int /* O - 1 to continue, 0 to stop */
+_httpUpdate(http_t *http, /* I - Connection to server */
+ http_status_t *status) /* O - Current HTTP status */
{
char line[32768], /* Line from connection... */
*value; /* Pointer to value on line */
http_field_t field; /* Field index */
- int major, minor, /* HTTP version numbers */
- status; /* Request status */
+ int major, minor; /* HTTP version numbers */
- DEBUG_printf(("httpUpdate(http=%p), state=%s", http,
+ DEBUG_printf(("_httpUpdate(http=%p, status=%p), state=%s", http, status,
http_states[http->state]));
/*
- * Flush pending data, if any...
+ * Grab a single line from the connection...
*/
- if (http->wused)
+ if (!httpGets(line, sizeof(line), http))
{
- DEBUG_puts("2httpUpdate: flushing buffer...");
-
- if (httpFlushWrite(http) < 0)
- return (HTTP_ERROR);
+ *status = HTTP_ERROR;
+ return (0);
}
- /*
- * If we haven't issued any commands, then there is nothing to "update"...
- */
+ DEBUG_printf(("2_httpUpdate: Got \"%s\"", line));
- if (http->state == HTTP_WAITING)
- return (HTTP_CONTINUE);
-
- /*
- * Grab all of the lines we can from the connection...
- */
-
- while (httpGets(line, sizeof(line), http) != NULL)
+ if (line[0] == '\0')
{
- DEBUG_printf(("2httpUpdate: Got \"%s\"", line));
+ /*
+ * Blank line means the start of the data section (if any). Return
+ * the result code, too...
+ *
+ * If we get status 100 (HTTP_CONTINUE), then we *don't* change states.
+ * Instead, we just return HTTP_CONTINUE to the caller and keep on
+ * tryin'...
+ */
- if (line[0] == '\0')
+ if (http->status == HTTP_CONTINUE)
{
- /*
- * Blank line means the start of the data section (if any). Return
- * the result code, too...
- *
- * If we get status 100 (HTTP_CONTINUE), then we *don't* change states.
- * Instead, we just return HTTP_CONTINUE to the caller and keep on
- * tryin'...
- */
-
- if (http->status == HTTP_CONTINUE)
- return (http->status);
+ *status = http->status;
+ return (0);
+ }
- if (http->status < HTTP_BAD_REQUEST)
- http->digest_tries = 0;
+ if (http->status < HTTP_BAD_REQUEST)
+ http->digest_tries = 0;
#ifdef HAVE_SSL
- if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls)
+ if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls)
+ {
+ if (http_setup_ssl(http) != 0)
{
- if (http_setup_ssl(http) != 0)
- {
# ifdef WIN32
- closesocket(http->fd);
+ closesocket(http->fd);
# else
- close(http->fd);
+ close(http->fd);
# endif /* WIN32 */
- return (HTTP_ERROR);
- }
-
- return (HTTP_CONTINUE);
+ *status = http->status = HTTP_ERROR;
+ return (0);
}
+
+ *status = HTTP_CONTINUE;
+ return (0);
+ }
#endif /* HAVE_SSL */
- httpGetLength2(http);
+ httpGetLength2(http);
- switch (http->state)
- {
- case HTTP_GET :
- case HTTP_POST :
- case HTTP_POST_RECV :
- case HTTP_PUT :
- http->state ++;
- case HTTP_POST_SEND :
- case HTTP_HEAD :
- break;
+ switch (http->state)
+ {
+ case HTTP_GET :
+ case HTTP_POST :
+ case HTTP_POST_RECV :
+ case HTTP_PUT :
+ http->state ++;
+ case HTTP_POST_SEND :
+ case HTTP_HEAD :
+ break;
- default :
- http->state = HTTP_WAITING;
- break;
- }
+ default :
+ http->state = HTTP_WAITING;
+ break;
+ }
+
+ *status = http->status;
+ return (0);
+ }
+ else if (!strncmp(line, "HTTP/", 5))
+ {
+ /*
+ * Got the beginning of a response...
+ */
+
+ int intstatus; /* Status value as an integer */
- return (http->status);
+ if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &intstatus) != 3)
+ {
+ *status = http->status = HTTP_ERROR;
+ return (0);
}
- else if (!strncmp(line, "HTTP/", 5))
+
+ http->version = (http_version_t)(major * 100 + minor);
+ *status = http->status = (http_status_t)intstatus;
+ }
+ else if ((value = strchr(line, ':')) != NULL)
+ {
+ /*
+ * Got a value...
+ */
+
+ *value++ = '\0';
+ while (_cups_isspace(*value))
+ value ++;
+
+ /*
+ * Be tolerants of servers that send unknown attribute fields...
+ */
+
+ if (!strcasecmp(line, "expect"))
{
/*
- * Got the beginning of a response...
+ * "Expect: 100-continue" or similar...
*/
- if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &status) != 3)
- return (HTTP_ERROR);
-
- http->version = (http_version_t)(major * 100 + minor);
- http->status = (http_status_t)status;
+ http->expect = (http_status_t)atoi(value);
}
- else if ((value = strchr(line, ':')) != NULL)
+ else if (!strcasecmp(line, "cookie"))
{
/*
- * Got a value...
+ * "Cookie: name=value[; name=value ...]" - replaces previous cookies...
*/
- *value++ = '\0';
- while (_cups_isspace(*value))
- value ++;
+ httpSetCookie(http, value);
+ }
+ else if ((field = http_field(line)) != HTTP_FIELD_UNKNOWN)
+ httpSetField(http, field, value);
+#ifdef DEBUG
+ else
+ DEBUG_printf(("1_httpUpdate: unknown field %s seen!", line));
+#endif /* DEBUG */
+ }
+ else
+ {
+ DEBUG_printf(("1_httpUpdate: Bad response line \"%s\"!", line));
+ *status = http->status = HTTP_ERROR;
+ return (0);
+ }
- /*
- * Be tolerants of servers that send unknown attribute fields...
- */
+ return (1);
+}
- if (!strcasecmp(line, "expect"))
- {
- /*
- * "Expect: 100-continue" or similar...
- */
- http->expect = (http_status_t)atoi(value);
- }
- else if (!strcasecmp(line, "cookie"))
- {
- /*
- * "Cookie: name=value[; name=value ...]" - replaces previous cookies...
- */
+/*
+ * 'httpUpdate()' - Update the current HTTP state for incoming data.
+ */
- httpSetCookie(http, value);
- }
- else if ((field = http_field(line)) == HTTP_FIELD_UNKNOWN)
- {
- DEBUG_printf(("1httpUpdate: unknown field %s seen!", line));
- continue;
- }
- else
- httpSetField(http, field, value);
- }
- else
- {
- DEBUG_printf(("1httpUpdate: Bad response line \"%s\"!", line));
- http->status = HTTP_ERROR;
+http_status_t /* O - HTTP status */
+httpUpdate(http_t *http) /* I - Connection to server */
+{
+ http_status_t status; /* Request status */
+
+
+ DEBUG_printf(("httpUpdate(http=%p), state=%s", http,
+ http_states[http->state]));
+
+ /*
+ * Flush pending data, if any...
+ */
+
+ if (http->wused)
+ {
+ DEBUG_puts("2httpUpdate: flushing buffer...");
+
+ if (httpFlushWrite(http) < 0)
return (HTTP_ERROR);
- }
}
+ /*
+ * If we haven't issued any commands, then there is nothing to "update"...
+ */
+
+ if (http->state == HTTP_WAITING)
+ return (HTTP_CONTINUE);
+
+ /*
+ * Grab all of the lines we can from the connection...
+ */
+
+ while (_httpUpdate(http, &status));
+
/*
* See if there was an error...
*/
}
/*
- * If we haven't already returned, then there is nothing new...
+ * Return the current status...
*/
- return (HTTP_CONTINUE);
+ return (status);
}
http->data_encoding = HTTP_ENCODE_LENGTH;
http->data_remaining = 0;
}
-
- if (http->state == HTTP_POST_RECV)
- http->state ++;
- else if (http->state == HTTP_PUT_RECV)
- http->state = HTTP_STATUS;
- else
- http->state = HTTP_WAITING;
}
return (bytes);
*
* I18N/language support for CUPS.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
*
* Contents:
*
+ * _cupsAppleLanguage() - Get the Apple language identifier associated with
+ * a locale ID.
+ * _cupsEncodingName() - Return the character encoding name string for the
+ * given encoding enumeration.
+ * cupsLangDefault() - Return the default language.
+ * cupsLangEncoding() - Return the character encoding (us-ascii, etc.) for
+ * the given language.
+ * cupsLangFlush() - Flush all language data out of the cache.
+ * cupsLangFree() - Free language data.
+ * cupsLangGet() - Get a language.
+ * _cupsLangString() - Get a message string.
+ * _cupsMessageFree() - Free a messages array.
+ * _cupsMessageLoad() - Load a .po file into a messages array.
+ * _cupsMessageLookup() - Lookup a message string.
+ * appleLangDefault() - Get the default locale string.
+ * appleMessageLoad() - Load a message catalog from a localizable bundle.
+ * cups_cache_lookup() - Lookup a language in the cache...
+ * cups_message_compare() - Compare two messages.
+ * cups_message_free() - Free a message.
+ * cups_unquote() - Unquote characters in strings...
*/
/*
match->str = strdup(m);
cupsArrayAdd(a, match);
+
+ if (cfm)
+ CFRelease(cfm);
}
#endif /* __APPLE__ && CUPS_BUNDLEDIR */
# ifdef CUPS_BUNDLEDIR
+# ifndef CF_RETURNS_RETAINED
+# if __has_feature(attribute_cf_returns_retained)
+# define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+# else
+# define CF_RETURNS_RETAINED
+# endif /* __has_feature(attribute_cf_returns_retained) */
+# endif /* !CF_RETURNED_RETAINED */
+
/*
* 'appleMessageLoad()' - Load a message catalog from a localizable bundle.
*/
static cups_array_t * /* O - Message catalog */
appleMessageLoad(const char *locale) /* I - Locale ID */
+CF_RETURNS_RETAINED
{
char filename[1024], /* Path to cups.strings file */
applelang[256]; /* Apple language ID */
*
* IPP utilities for CUPS.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
if (!http)
if ((http = _cupsConnect()) == NULL)
+ {
+ ippDelete(request);
+
return (NULL);
+ }
/*
* See if we have a file to send...
{
if (httpCheck(http))
{
- if ((status = httpUpdate(http)) != HTTP_CONTINUE)
+ _httpUpdate(http, &status);
+
+ if (status >= HTTP_MULTIPLE_CHOICES)
break;
}
DEBUG_printf(("2cupsGetResponse: Update loop, http->status=%d...",
http->status));
- status = http->status;
- while (status == HTTP_CONTINUE)
+ do
+ {
status = httpUpdate(http);
+ }
+ while (http->state == HTTP_POST_RECV);
DEBUG_printf(("2cupsGetResponse: status=%d", status));
{
got_status = 1;
- if ((status = httpUpdate(http)) != HTTP_CONTINUE)
+ _httpUpdate(http, &status);
+ if (status >= HTTP_MULTIPLE_CHOICES)
break;
}
* Wait up to 1 second to get the 100-continue response as needed...
*/
- if (!got_status && expect == HTTP_CONTINUE)
+ if (!got_status)
{
- DEBUG_puts("2cupsSendRequest: Waiting for 100-continue...");
+ if (expect == HTTP_CONTINUE)
+ {
+ DEBUG_puts("2cupsSendRequest: Waiting for 100-continue...");
- if (httpWait(http, 1000))
- status = httpUpdate(http);
+ if (httpWait(http, 1000))
+ _httpUpdate(http, &status);
+ }
+ else if (httpCheck(http))
+ _httpUpdate(http, &status);
}
- else if (httpCheck(http))
- status = httpUpdate(http);
DEBUG_printf(("2cupsSendRequest: status=%d", status));
* Process the current HTTP status...
*/
- if (status >= HTTP_BAD_REQUEST)
+ if (status >= HTTP_MULTIPLE_CHOICES)
httpFlush(http);
switch (status)
if (_httpWait(http, 0, 1))
{
- http_status_t status; /* Status from httpUpdate */
+ http_status_t status; /* Status from _httpUpdate */
- if ((status = httpUpdate(http)) >= HTTP_BAD_REQUEST)
+ _httpUpdate(http, &status);
+ if (status >= HTTP_MULTIPLE_CHOICES)
{
_cupsSetHTTPError(status);
httpFlush(http);
/*
* "$Id: image-zoom.c 6649 2007-07-11 21:46:42Z mike $"
*
- * cupsImage zoom routines for the Common UNIX Printing System (CUPS).
+ * cupsImage zoom routines for CUPS.
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1993-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
z->ystep = z->height / z->ysize;
z->yincr = 1;
z->instep = z->xstep * z->depth;
- z->inincr = z->xincr * z->depth;
+ z->inincr = /* z->xincr * */ z->depth; /* z->xincr is always 1 */
if (z->width < img->ysize)
z->xmax = z->width;
z->ystep = z->height / z->ysize;
z->yincr = 1;
z->instep = z->xstep * z->depth;
- z->inincr = z->xincr * z->depth;
+ z->inincr = /* z->xincr * */ z->depth; /* z->xincr is always 1 */
if (z->width < img->xsize)
z->xmax = z->width;
*
* "mailto" notifier for CUPS.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* Include necessary headers...
*/
-#include <cups/cups.h>
-#include <cups/language-private.h>
-#include <cups/string-private.h>
+#include <cups/cups-private.h>
#include <sys/wait.h>
#include <signal.h>
cupsFileClose(fp);
- if (wait(&status))
- status = errno << 8;
+ while (wait(&status))
+ {
+ if (errno != EINTR)
+ {
+ fprintf(stderr, "DEBUG: Unable to get child status: %s\n",
+ strerror(errno));
+ status = 0;
+ break;
+ }
+ }
/*
* Report any non-zero status...
if ((fp = cupsFileOpen(line, "r")) == NULL)
{
- fprintf(stderr, "ERROR: Unable to open \"%s\" - %s\n", line,
- strerror(errno));
- return (1);
+ if (errno != ENOENT)
+ {
+ fprintf(stderr, "ERROR: Unable to open \"%s\" - %s\n", line,
+ strerror(errno));
+ return (1);
+ }
+ else
+ return (0);
}
linenum = 0;
print_attributes(ipp_t *ipp, /* I - IPP request */
int indent) /* I - Indentation */
{
- int i; /* Looping var */
ipp_tag_t group; /* Current group */
ipp_attribute_t *attr; /* Current attribute */
- ipp_value_t *val; /* Current value */
- static const char * const tags[] = /* Value/group tag strings */
- {
- "reserved-00",
- "operation-attributes-tag",
- "job-attributes-tag",
- "end-of-attributes-tag",
- "printer-attributes-tag",
- "unsupported-attributes-tag",
- "subscription-attributes-tag",
- "event-attributes-tag",
- "reserved-08",
- "reserved-09",
- "reserved-0A",
- "reserved-0B",
- "reserved-0C",
- "reserved-0D",
- "reserved-0E",
- "reserved-0F",
- "unsupported",
- "default",
- "unknown",
- "no-value",
- "reserved-14",
- "not-settable",
- "delete-attr",
- "admin-define",
- "reserved-18",
- "reserved-19",
- "reserved-1A",
- "reserved-1B",
- "reserved-1C",
- "reserved-1D",
- "reserved-1E",
- "reserved-1F",
- "reserved-20",
- "integer",
- "boolean",
- "enum",
- "reserved-24",
- "reserved-25",
- "reserved-26",
- "reserved-27",
- "reserved-28",
- "reserved-29",
- "reserved-2a",
- "reserved-2b",
- "reserved-2c",
- "reserved-2d",
- "reserved-2e",
- "reserved-2f",
- "octetString",
- "dateTime",
- "resolution",
- "rangeOfInteger",
- "begCollection",
- "textWithLanguage",
- "nameWithLanguage",
- "endCollection",
- "reserved-38",
- "reserved-39",
- "reserved-3a",
- "reserved-3b",
- "reserved-3c",
- "reserved-3d",
- "reserved-3e",
- "reserved-3f",
- "reserved-40",
- "textWithoutLanguage",
- "nameWithoutLanguage",
- "reserved-43",
- "keyword",
- "uri",
- "uriScheme",
- "charset",
- "naturalLanguage",
- "mimeMediaType",
- "memberName"
- };
+ char buffer[1024]; /* Value buffer */
for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next)
{
group = attr->group_tag;
- fprintf(stderr, "DEBUG: %*s%s:\n\n", indent - 4, "", tags[group]);
+ fprintf(stderr, "DEBUG: %*s%s:\n\n", indent - 4, "", ippTagString(group));
}
- fprintf(stderr, "DEBUG: %*s%s (", indent, "", attr->name);
- if (attr->num_values > 1)
- fputs("1setOf ", stderr);
- fprintf(stderr, "%s):", tags[attr->value_tag]);
+ _ippAttrString(attr, buffer, sizeof(buffer));
- switch (attr->value_tag)
- {
- case IPP_TAG_ENUM :
- case IPP_TAG_INTEGER :
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- fprintf(stderr, " %d", val->integer);
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_BOOLEAN :
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- fprintf(stderr, " %s", val->boolean ? "true" : "false");
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_RANGE :
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- fprintf(stderr, " %d-%d", val->range.lower, val->range.upper);
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_DATE :
- {
- time_t vtime; /* Date/Time value */
- struct tm *vdate; /* Date info */
- char vstring[256]; /* Formatted time */
-
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- {
- vtime = ippDateToTime(val->date);
- vdate = localtime(&vtime);
- strftime(vstring, sizeof(vstring), "%c", vdate);
- fprintf(stderr, " (%s)", vstring);
- }
- }
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_RESOLUTION :
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- fprintf(stderr, " %dx%d%s", val->resolution.xres,
- val->resolution.yres,
- val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc");
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_STRING :
- 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, val = attr->values; i < attr->num_values; i ++, val ++)
- fprintf(stderr, " \"%s\"", val->string.text);
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_BEGIN_COLLECTION :
- fputc('\n', stderr);
-
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- {
- if (i)
- fputc('\n', stderr);
- print_attributes(val->collection, indent + 4);
- }
- break;
-
- default :
- fprintf(stderr, "UNKNOWN (%d values)\n", attr->num_values);
- break;
- }
+ fprintf(stderr, "DEBUG: %*s%s (%s%s) %s", indent, "", attr->name,
+ attr->num_values > 1 ? "1setOf " : "",
+ ippTagString(attr->value_tag), buffer);
}
}
*
* Test notifier for CUPS.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* Include necessary headers...
*/
-#include <cups/cups.h>
-#include <cups/language.h>
-#include <cups/string-private.h>
+#include <cups/cups-private.h>
/*
print_attributes(ipp_t *ipp, /* I - IPP request */
int indent) /* I - Indentation */
{
- int i; /* Looping var */
ipp_tag_t group; /* Current group */
ipp_attribute_t *attr; /* Current attribute */
- ipp_value_t *val; /* Current value */
- static const char * const tags[] = /* Value/group tag strings */
- {
- "reserved-00",
- "operation-attributes-tag",
- "job-attributes-tag",
- "end-of-attributes-tag",
- "printer-attributes-tag",
- "unsupported-attributes-tag",
- "subscription-attributes-tag",
- "event-attributes-tag",
- "reserved-08",
- "reserved-09",
- "reserved-0A",
- "reserved-0B",
- "reserved-0C",
- "reserved-0D",
- "reserved-0E",
- "reserved-0F",
- "unsupported",
- "default",
- "unknown",
- "no-value",
- "reserved-14",
- "not-settable",
- "delete-attr",
- "admin-define",
- "reserved-18",
- "reserved-19",
- "reserved-1A",
- "reserved-1B",
- "reserved-1C",
- "reserved-1D",
- "reserved-1E",
- "reserved-1F",
- "reserved-20",
- "integer",
- "boolean",
- "enum",
- "reserved-24",
- "reserved-25",
- "reserved-26",
- "reserved-27",
- "reserved-28",
- "reserved-29",
- "reserved-2a",
- "reserved-2b",
- "reserved-2c",
- "reserved-2d",
- "reserved-2e",
- "reserved-2f",
- "octetString",
- "dateTime",
- "resolution",
- "rangeOfInteger",
- "begCollection",
- "textWithLanguage",
- "nameWithLanguage",
- "endCollection",
- "reserved-38",
- "reserved-39",
- "reserved-3a",
- "reserved-3b",
- "reserved-3c",
- "reserved-3d",
- "reserved-3e",
- "reserved-3f",
- "reserved-40",
- "textWithoutLanguage",
- "nameWithoutLanguage",
- "reserved-43",
- "keyword",
- "uri",
- "uriScheme",
- "charset",
- "naturalLanguage",
- "mimeMediaType",
- "memberName"
- };
+ char buffer[1024]; /* Value buffer */
for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next)
{
group = attr->group_tag;
- fprintf(stderr, "DEBUG: %*s%s:\n\n", indent - 4, "", tags[group]);
+ fprintf(stderr, "DEBUG: %*s%s:\n\n", indent - 4, "", ippTagString(group));
}
- fprintf(stderr, "DEBUG: %*s%s (", indent, "", attr->name);
- if (attr->num_values > 1)
- fputs("1setOf ", stderr);
- fprintf(stderr, "%s):", tags[attr->value_tag]);
+ _ippAttrString(attr, buffer, sizeof(buffer));
- switch (attr->value_tag)
- {
- case IPP_TAG_ENUM :
- case IPP_TAG_INTEGER :
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- fprintf(stderr, " %d", val->integer);
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_BOOLEAN :
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- fprintf(stderr, " %s", val->boolean ? "true" : "false");
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_RANGE :
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- fprintf(stderr, " %d-%d", val->range.lower, val->range.upper);
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_DATE :
- {
- time_t vtime; /* Date/Time value */
- struct tm *vdate; /* Date info */
- char vstring[256]; /* Formatted time */
-
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- {
- vtime = ippDateToTime(val->date);
- vdate = localtime(&vtime);
- strftime(vstring, sizeof(vstring), "%c", vdate);
- fprintf(stderr, " (%s)", vstring);
- }
- }
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_RESOLUTION :
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- fprintf(stderr, " %dx%d%s", val->resolution.xres,
- val->resolution.yres,
- val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc");
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_STRING :
- 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, val = attr->values; i < attr->num_values; i ++, val ++)
- fprintf(stderr, " \"%s\"", val->string.text);
- fputc('\n', stderr);
- break;
-
- case IPP_TAG_BEGIN_COLLECTION :
- fputc('\n', stderr);
-
- for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- {
- if (i)
- fputc('\n', stderr);
- print_attributes(val->collection, indent + 4);
- }
- break;
-
- default :
- fprintf(stderr, "UNKNOWN (%d values)\n", attr->num_values);
- break;
- }
+ fprintf(stderr, "DEBUG: %*s%s (%s%s) %s", indent, "", attr->name,
+ attr->num_values > 1 ? "1setOf " : "",
+ ippTagString(attr->value_tag), buffer);
}
}
return (1);
# elif defined(HAVE_CDSASSL)
- OSStatus error; /* Error code */
+ OSStatus error = 0; /* Error code */
+ CFArrayRef peerCerts; /* Peer certificates */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con,
con->http.fd);
- error = 0;
con->http.tls_credentials = get_cdsa_certificate(con);
if (!con->http.tls_credentials)
cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
con->http.hostname);
- CFArrayRef peerCerts; /* Peer certificates */
-
- if (!(error = SSLCopyPeerCertificates(con->http.tls, &peerCerts)) && peerCerts)
+ if (!SSLCopyPeerCertificates(con->http.tls, &peerCerts) && peerCerts)
{
cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates!",
(int)CFArrayGetCount(peerCerts));
servername = CFStringCreateWithCString(kCFAllocatorDefault, con->servername,
kCFStringEncodingUTF8);
- if ((policy = SecPolicyCreateSSL(1, servername)) == NULL)
+ policy = SecPolicyCreateSSL(1, servername);
+
+ if (servername)
+ CFRelease(servername);
+
+ if (!policy)
{
cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
goto cleanup;
}
- if (servername)
- CFRelease(servername);
-
if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks)))
CFRelease(policy);
- if ((policy = SecPolicyCreateSSL(1, servername)) == NULL)
+ policy = SecPolicyCreateSSL(1, servername);
+
+ if (servername)
+ CFRelease(servername);
+
+ if (!policy)
{
cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
goto cleanup;
}
- if (servername)
- CFRelease(servername);
-
CFDictionarySetValue(query, kSecMatchPolicy, policy);
err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
*
* Directory services routines for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
* Calculate the buffer size
*/
+ if (count <= 0)
+ return (NULL);
+
for (length = i = 0; i < count; i++)
length += 1 + strlen(keyvalue[i][0]) +
(keyvalue[i][1] ? 1 + strlen(keyvalue[i][1]) : 0);
return (buffer);
}
- return (NULL);
+ return ("none");
}
ppd_option_t *cm_option; /* Color model option */
ppd_choice_t *cm_choice; /* Color model choice */
int num_profiles; /* Number of profiles */
- CMError error = 0; /* Last error */
+ OSStatus error = 0; /* Last error */
unsigned device_id, /* Printer device ID */
profile_id, /* Profile ID */
default_profile_id = 0;
* See if this is the default profile...
*/
- if (!default_profile_id)
+ if (!default_profile_id && q1_choice && q2_choice && q3_choice)
{
- if (q2_choice)
- {
- if (q3_choice)
- {
- snprintf(selector, sizeof(selector), "%s.%s.%s",
- q1_choice, q2_choice, q3_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
+ snprintf(selector, sizeof(selector), "%s.%s.%s", q1_choice, q2_choice,
+ q3_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
- if (!default_profile_id)
- {
- snprintf(selector, sizeof(selector), "%s.%s.", q1_choice,
- q2_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
- }
+ if (!default_profile_id && q1_choice && q2_choice)
+ {
+ snprintf(selector, sizeof(selector), "%s.%s.", q1_choice, q2_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
- if (!default_profile_id && q3_choice)
- {
- snprintf(selector, sizeof(selector), "%s..%s", q1_choice,
- q3_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
+ if (!default_profile_id && q1_choice && q3_choice)
+ {
+ snprintf(selector, sizeof(selector), "%s..%s", q1_choice, q3_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
- if (!default_profile_id)
- {
- snprintf(selector, sizeof(selector), "%s..", q1_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
+ if (!default_profile_id && q1_choice)
+ {
+ snprintf(selector, sizeof(selector), "%s..", q1_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
+
+ if (!default_profile_id && q2_choice && q3_choice)
+ {
+ snprintf(selector, sizeof(selector), ".%s.%s", q2_choice, q3_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
+
+ if (!default_profile_id && q2_choice)
+ {
+ snprintf(selector, sizeof(selector), ".%s.", q2_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
+
+ if (!default_profile_id && q3_choice)
+ {
+ snprintf(selector, sizeof(selector), "..%s", q3_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
}
}
* Check policy...
*/
- if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
+ if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con,
+ job->username)) != HTTP_OK)
{
send_http_error(con, status, NULL);
return;
*
* Main loop for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
cupsArrayCount(PrintingJobs) > 0)
{
SleepJobs = 0;
- cupsdStopAllJobs(CUPSD_JOB_DEFAULT, 10);
+ cupsdStopAllJobs(CUPSD_JOB_DEFAULT, 5);
}
#endif /* __APPLE__ */
ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"pages-per-minute-color", ppd->throughput);
}
+ else
+ {
+ /*
+ * When there is no speed information, just say "1 page per minute".
+ */
+
+ ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "pages-per-minute", 1);
+ if (ppd->color_device)
+ ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "pages-per-minute-color", 1);
+ }
num_qualities = 0;
CGImageDestinationFinalize(destRef);
CFRelease(destRef);
}
+ }
+ if (imageRef)
CGImageRelease(imageRef);
- }
CFRelease(sourceRef);
- CFRelease(icnsFileUrl);
}
+ }
+ if (outUrl)
CFRelease(outUrl);
- }
+
+ if (icnsFileUrl)
+ CFRelease(icnsFileUrl);
}
#endif /* HAVE_APPLICATIONSERVICES_H */
*
* Process management routines for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
" #\"^/Library/Printers/PPD Plugins/\""
"))\n");
if (job_id)
+ {
+ /*
+ * Allow job filters to read the spool file(s)...
+ */
+
cupsFilePrintf(fp,
"(allow file-read-data file-read-metadata\n"
" (regex #\"^%s/([ac]%05d|d%05d-[0-9][0-9][0-9])$\"))\n",
request, job_id, job_id);
+ }
+ else
+ {
+ /*
+ * Allow email notifications from notifiers...
+ */
+
+ cupsFilePuts(fp,
+ "(allow process-exec\n"
+ " (literal \"/usr/sbin/sendmail\")\n"
+ " (with no-sandbox)\n"
+ ")\n");
+ }
cupsFileClose(fp);
int *pid) /* O - Process ID */
{
int i; /* Looping var */
+ const char *exec_path = command; /* Command to be exec'd */
char *real_argv[103], /* Real command-line arguments */
cups_exec[1024]; /* Path to "cups-exec" program */
int user; /* Command UID */
real_argv[i + 3] = NULL;
- argv = real_argv;
- command = cups_exec;
+ argv = real_argv;
+ exec_path = cups_exec;
}
/*
*/
if (envp)
- execve(command, argv, envp);
+ execve(exec_path, argv, envp);
else
- execv(command, argv);
+ execv(exec_path, argv);
perror(command);
{
proc->pid = *pid;
proc->job_id = job ? job->id : 0;
- strcpy(proc->name, command);
+ _cups_strcpy(proc->name, command);
cupsArrayAdd(process_array, proc);
}
* Send one last notification as the server shuts down.
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG,
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
"notify_post(\"com.apple.printerListChange\") last");
notify_post("com.apple.printerListChange");
#endif /* HAVE_NOTIFY_POST */
*
* System management functions for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
sysevent.powerNotificationID);
else
{
- LastSysEvent = sysevent;
- SleepJobs = time(NULL) + 15;
+ /*
+ * If there are active printers that don't have the connecting-to-device
+ * printer-state-reason then delay the sleep request (i.e. this reason
+ * indicates a job that is not yet connected to the printer)...
+ */
+
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
+ p;
+ p = (cupsd_printer_t *)cupsArrayNext(Printers))
+ {
+ if (p->job)
+ {
+ for (i = 0; i < p->num_reasons; i ++)
+ if (!strcmp(p->reasons[i], "connecting-to-device"))
+ break;
+
+ if (!p->num_reasons || i >= p->num_reasons)
+ break;
+ }
+ }
+
+ if (p)
+ {
+ LastSysEvent = sysevent;
+ SleepJobs = time(NULL) + 10;
+ }
+ else
+ {
+ IOAllowPowerChange(sysevent.powerKernelPort,
+ sysevent.powerNotificationID);
+ }
}
}
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
+#
+# ippserver-shared
+#
+
+ippserver-shared: ippserver.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ ippserver.o $(LIBS)
+
+
#
# ipptool
#
*
* Sample IPP/2.0 server for CUPS.
*
- * Copyright 2010 by Apple Inc.
+ * Copyright 2010-2011 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
_ipp_job_t *job, /* I - Job */
cups_array_t *ra) /* I - requested-attributes */
{
- copy_attributes(client->response, job->attrs, ra, 0, IPP_TAG_ZERO);
+ copy_attributes(client->response, job->attrs, ra, IPP_TAG_ZERO, 0);
if (!ra || cupsArrayFind(ra, "job-printer-up-time"))
ippAddInteger(client->response, IPP_TAG_JOB, IPP_TAG_INTEGER,
switch (job->state)
{
case IPP_JOB_PENDING :
- ippAddString(client->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "none");
+ ippAddString(client->response, IPP_TAG_JOB,
+ IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ NULL, "none");
break;
case IPP_JOB_HELD :
if (job->fd >= 0)
- ippAddString(client->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-incoming");
+ ippAddString(client->response, IPP_TAG_JOB,
+ IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ NULL, "job-incoming");
else if (ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_ZERO))
- ippAddString(client->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-hold-until-specified");
+ ippAddString(client->response, IPP_TAG_JOB,
+ IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ NULL, "job-hold-until-specified");
break;
case IPP_JOB_PROCESSING :
if (job->cancel)
- ippAddString(client->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "processing-to-stop-point");
+ ippAddString(client->response, IPP_TAG_JOB,
+ IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ NULL, "processing-to-stop-point");
else
- ippAddString(client->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-printing");
+ ippAddString(client->response, IPP_TAG_JOB,
+ IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ NULL, "job-printing");
break;
case IPP_JOB_STOPPED :
- ippAddString(client->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-stopped");
+ ippAddString(client->response, IPP_TAG_JOB,
+ IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ NULL, "job-stopped");
break;
case IPP_JOB_CANCELED :
- ippAddString(client->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-canceled-by-user");
+ ippAddString(client->response, IPP_TAG_JOB,
+ IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ NULL, "job-canceled-by-user");
break;
case IPP_JOB_ABORTED :
- ippAddString(client->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "aborted-by-system");
+ ippAddString(client->response, IPP_TAG_JOB,
+ IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ NULL, "aborted-by-system");
break;
case IPP_JOB_COMPLETED :
- ippAddString(client->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-completed-successfully");
+ ippAddString(client->response, IPP_TAG_JOB,
+ IPP_TAG_KEYWORD | IPP_TAG_COPY, "job-state-reasons",
+ NULL, "job-completed-successfully");
break;
}
}
attr->name = _cupsStrAlloc("job-originating-user-name");
}
else
- attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME,
+ attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME | IPP_TAG_COPY,
"job-originating-user-name", NULL, "anonymous");
if (attr)
ipp_value_t *media_col_value;
/* Current media-col-database value */
int k_supported; /* Maximum file size supported */
-#ifdef HAVE_STATFS
- struct statfs spoolinfo; /* FS info for spool directory */
- double spoolsize; /* FS size */
-#elif defined(HAVE_STATVFS)
+#ifdef HAVE_STATVFS
struct statvfs spoolinfo; /* FS info for spool directory */
double spoolsize; /* FS size */
-#endif /* HAVE_STATFS */
+#elif defined(HAVE_STATFS)
+ struct statfs spoolinfo; /* FS info for spool directory */
+ double spoolsize; /* FS size */
+#endif /* HAVE_STATVFS */
static const int orients[4] = /* orientation-requested-supported values */
{
IPP_PORTRAIT,
* or the filesystem is larger than 2TiB, always report INT_MAX.
*/
-#ifdef HAVE_STATFS
- if (statfs(printer->directory, &spoolinfo))
+#ifdef HAVE_STATVFS
+ if (statvfs(printer->directory, &spoolinfo))
k_supported = INT_MAX;
- else if ((spoolsize = (double)spoolinfo.f_bsize *
+ else if ((spoolsize = (double)spoolinfo.f_frsize *
spoolinfo.f_blocks / 1024) > INT_MAX)
k_supported = INT_MAX;
else
k_supported = (int)spoolsize;
-#elif defined(HAVE_STATVFS)
- if (statvfs(printer->directory, &spoolinfo))
+#elif defined(HAVE_STATFS)
+ if (statfs(printer->directory, &spoolinfo))
k_supported = INT_MAX;
- else if ((spoolsize = (double)spoolinfo.f_frsize *
+ else if ((spoolsize = (double)spoolinfo.f_bsize *
spoolinfo.f_blocks / 1024) > INT_MAX)
k_supported = INT_MAX;
else
#else
k_supported = INT_MAX;
-#endif /* HAVE_STATFS */
+#endif /* HAVE_STATVFS */
/*
* Create the printer attributes. This list of attributes is sorted to improve
ippAddRange(printer->attrs, IPP_TAG_PRINTER, "copies-supported", 1, 999);
/* document-format-default */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE | IPP_TAG_COPY,
- "document-format-default", NULL, "application/octet-stream");
+ ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
+ "document-format-default", NULL, defformat);
/* document-format-supported */
ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
"orientation-requested-supported", 4, orients);
/* output-bin-default */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
"output-bin-default", NULL, "face-down");
/* output-bin-supported */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
"output-bin-supported", NULL, "face-down");
/* pages-per-minute */
"sides-default", NULL, "one-sided");
/* sides-supported */
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
"sides-supported", duplex ? 3 : 1, NULL, sides_supported);
/* uri-authentication-supported */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
"uri-authentication-supported", NULL, "none");
/* uri-security-supported */
- ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
"uri-security-supported", NULL, "none");
/* which-jobs-supported */
if (!ra || cupsArrayFind(ra, "printer-state-reasons"))
{
if (printer->state_reasons == _IPP_PRINTER_NONE)
- ippAddString(client->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "printer-state-reasons", NULL, "none");
+ ippAddString(client->response, IPP_TAG_PRINTER,
+ IPP_TAG_KEYWORD | IPP_TAG_COPY, "printer-state-reasons",
+ NULL, "none");
else
{
int num_reasons = 0;/* Number of reasons */
cupsArrayAdd(ra, "job-uri");
copy_job_attributes(client, job, ra);
+ cupsArrayDelete(ra);
}
return (0);
}
+ /*
+ * Handle HTTP Expect...
+ */
+
+ if (client->http.expect &&
+ (client->operation == HTTP_POST || client->operation == HTTP_PUT))
+ {
+ if (client->http.expect == HTTP_CONTINUE)
+ {
+ /*
+ * Send 100-continue header...
+ */
+
+ if (!respond_http(client, HTTP_CONTINUE, NULL, 0))
+ return (0);
+ }
+ else
+ {
+ /*
+ * Send 417-expectation-failed header...
+ */
+
+ if (!respond_http(client, HTTP_EXPECTATION_FAILED, NULL, 0))
+ return (0);
+
+ httpPrintf(&(client->http), "Content-Length: 0\r\n");
+ httpPrintf(&(client->http), "\r\n");
+ httpFlushWrite(&(client->http));
+ client->http.data_encoding = HTTP_ENCODE_LENGTH;
+ }
+ }
+
/*
* Handle new transfers...
*/
if (!client->response->attrs)
{
- ippAddString(client->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
- ippAddString(client->response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, "en-US");
+ ippAddString(client->response, IPP_TAG_OPERATION,
+ IPP_TAG_CHARSET | IPP_TAG_COPY, "attributes-charset", NULL,
+ "utf-8");
+ ippAddString(client->response, IPP_TAG_OPERATION,
+ IPP_TAG_LANGUAGE | IPP_TAG_COPY, "attributes-natural-language",
+ NULL, "en-us");
}
if (message)
else
timeout = -1;
- if (poll(polldata, (int)(sizeof(polldata) / sizeof(polldata[0])),
- timeout) < 0 && errno != EINTR)
+ if (poll(polldata, num_fds, timeout) < 0 && errno != EINTR)
{
perror("poll() failed");
break;
ippTagString(attr->value_tag)); \
valid = 0; \
} \
- copy_attribute(client->response, attr, 0, IPP_TAG_UNSUPPORTED_GROUP)
+ copy_attribute(client->response, attr, IPP_TAG_UNSUPPORTED_GROUP, 0)
if ((attr = ippFindAttribute(client->request, "compression",
IPP_TAG_ZERO)) != NULL)
respond_unsupported(client, attr);
}
else
+ {
format = attr->values[0].string.text;
+
+ fprintf(stderr, "%s %s document-format=\"%s\"\n",
+ client->http.hostname,
+ ippOpString(client->request->request.op.operation_id), format);
+ }
}
else
format = "application/octet-stream";
"document-format-supported",
IPP_TAG_MIMETYPE)) != NULL)
{
- for (i = 0; i < attr->num_values; i ++)
- if (!strcasecmp(format, attr->values[i].string.text))
+ for (i = 0; i < supported->num_values; i ++)
+ if (!strcasecmp(format, supported->values[i].string.text))
break;
- if (i >= attr->num_values)
- {
+ if (i >= supported->num_values)
respond_unsupported(client, attr);
- }
}
/*
*
* ipptool command for CUPS.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
static char *get_variable(_cups_vars_t *vars, const char *name);
static char *iso_date(ipp_uchar_t *date);
static const char *password_cb(const char *prompt);
-static void print_attr(ipp_attribute_t *attr);
+static void print_attr(ipp_attribute_t *attr, ipp_tag_t *group);
static void print_col(ipp_t *col);
static void print_csv(ipp_attribute_t *attr, int num_displayed,
char **displayed, size_t *widths);
case IPP_TAG_INTEGER :
case IPP_TAG_ENUM :
- ippAddInteger(request, group, value, attr, atoi(token));
+ if (!strchr(token, ','))
+ ippAddInteger(request, group, value, attr,
+ strtol(token, &tokenptr, 0));
+ else
+ {
+ int values[100], /* Values */
+ num_values = 1; /* Number of values */
+
+ values[0] = strtol(token, &tokenptr, 10);
+ while (tokenptr && *tokenptr &&
+ num_values < (int)(sizeof(values) / sizeof(values[0])))
+ {
+ if (*tokenptr == ',')
+ tokenptr ++;
+ else if (!isdigit(*tokenptr & 255) && *tokenptr != '-')
+ break;
+
+ values[num_values] = strtol(tokenptr, &tokenptr, 0);
+ num_values ++;
+ }
+
+ ippAddIntegers(request, group, value, attr, num_values, values);
+ }
+
+ if (!tokenptr || *tokenptr)
+ {
+ print_fatal_error("Bad %s value \"%s\" on line %d.",
+ ippTagString(value), token, linenum);
+ pass = 0;
+ goto test_exit;
+ }
break;
case IPP_TAG_RESOLUTION :
}
if (ptr <= token || xres <= 0 || yres <= 0 || !ptr ||
- (strcasecmp(ptr, "dpi") && strcasecmp(ptr, "dpc") &&
- strcasecmp(ptr, "other")))
+ (strcasecmp(ptr, "dpi") && strcasecmp(ptr, "dpc") &&
+ strcasecmp(ptr, "other")))
{
print_fatal_error("Bad resolution value \"%s\" on line %d.",
token, linenum);
puts("<key>Operation</key>");
print_xml_string("string", ippOpString(op));
puts("<key>RequestAttributes</key>");
+ puts("<array>");
puts("<dict>");
- for (attrptr = request->attrs; attrptr; attrptr = attrptr->next)
- print_attr(attrptr);
+ for (attrptr = request->attrs, group = attrptr->group_tag;
+ attrptr;
+ attrptr = attrptr->next)
+ print_attr(attrptr, &group);
puts("</dict>");
+ puts("</array>");
}
else if (Output == _CUPS_OUTPUT_TEST)
{
printf(" %s:\n", ippOpString(op));
for (attrptr = request->attrs; attrptr; attrptr = attrptr->next)
- print_attr(attrptr);
+ print_attr(attrptr, NULL);
}
printf(" %-69.69s [", name);
puts("<key>StatusCode</key>");
print_xml_string("string", ippErrorString(cupsLastError()));
puts("<key>ResponseAttributes</key>");
+ puts("<array>");
puts("<dict>");
- for (attrptr = response ? response->attrs : NULL;
+ for (attrptr = response ? response->attrs : NULL,
+ group = attrptr ? attrptr->group_tag : IPP_TAG_ZERO;
attrptr;
attrptr = attrptr->next)
- print_attr(attrptr);
+ print_attr(attrptr, &group);
puts("</dict>");
+ puts("</array>");
}
else if (Output == _CUPS_OUTPUT_TEST)
{
attrptr != NULL;
attrptr = attrptr->next)
{
- print_attr(attrptr);
+ print_attr(attrptr, NULL);
}
}
}
{
if (!strcmp(displayed[i], attrptr->name))
{
- print_attr(attrptr);
+ print_attr(attrptr, NULL);
break;
}
}
if (i == num_statuses && num_statuses > 0)
{
- print_test_error("Bad status-code (%s)",
- ippErrorString(cupsLastError()));
- print_test_error("status-message=\"%s\"", cupsLastErrorString());
+ for (i = 0; i < num_statuses; i ++)
+ {
+ if (statuses[i].if_defined &&
+ !get_variable(vars, statuses[i].if_defined))
+ continue;
+
+ if (statuses[i].if_not_defined &&
+ get_variable(vars, statuses[i].if_not_defined))
+ continue;
+
+ print_test_error("EXPECTED: STATUS %s (got %s)",
+ ippErrorString(statuses[i].status),
+ ippErrorString(cupsLastError()));
+ }
+
+ if ((attrptr = ippFindAttribute(response, "status-message",
+ IPP_TAG_TEXT)) != NULL)
+ print_test_error("status-message=\"%s\"",
+ attrptr->values[0].string.text);
}
for (i = num_expects, expect = expects; i > 0; i --, expect ++)
*/
static void
-print_attr(ipp_attribute_t *attr) /* I - Attribute to print */
+print_attr(ipp_attribute_t *attr, /* I - Attribute to print */
+ ipp_tag_t *group) /* IO - Current group */
{
int i; /* Looping var */
ipp_attribute_t *colattr; /* Collection attribute */
if (Output == _CUPS_OUTPUT_PLIST)
{
- if (!attr->name)
+ if (!attr->name || (group && *group != attr->group_tag))
{
- printf("<key>%s</key>\n<true />\n", ippTagString(attr->group_tag));
- return;
+ puts("</dict>");
+ puts("<dict>");
+
+ if (group)
+ *group = attr->group_tag;
}
+ if (!attr->name)
+ return;
+
print_xml_string("key", attr->name);
if (attr->num_values > 1)
puts("<array>");
puts("</string></dict>");
}
else
- printf("\"%s\",%s ", attr->values[i].string.text,
+ printf("\"%s\"(%s) ", attr->values[i].string.text,
attr->values[i].string.charset);
break;
for (colattr = attr->values[i].collection->attrs;
colattr;
colattr = colattr->next)
- print_attr(colattr);
+ print_attr(colattr, NULL);
puts("</dict>");
}
else