diff options
56 files changed, 1813 insertions, 625 deletions
diff --git a/CHANGES-1.5.txt b/CHANGES-1.5.txt index f97e843e3..3250d60aa 100644 --- a/CHANGES-1.5.txt +++ b/CHANGES-1.5.txt @@ -3,11 +3,12 @@ CHANGES-1.5.txt CHANGES IN CUPS V1.5.3 + - The cups-driverd program could temporarily "forget" a PPD file if it + was updated in place. + - The dnssd backend now prefers IPPS over IPP. - The USB backend now uses and requires LIBUSB 1.0 or later (STR #3477) - The LIBUSB-based USB backend now supports the back-channel (STR #2890) - Changed how timeouts are implemented in the LPD backend (STR #4013) - - The IPP backend no longer specifies the document-format for auto- - detect unless required (STR #3986) - Added more supported color names for SNMP supplies (STR #3981) - The default InputSlot setting was never used (STR #3957) - POSIX ACLs are now set properly on certificate files (STR #3970) diff --git a/CHANGES.txt b/CHANGES.txt index 454e98dc9..0528f3c3d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,8 +1,21 @@ -CHANGES.txt - 1.6b1 - 2012-01-30 +CHANGES.txt - 1.6b1 - 2012-02-15 -------------------------------- CHANGES IN CUPS V1.6b1 + - Documentation updates (STR #3927, STR #3980, STR #4010) + - CUPS now supports a User directive in client.conf and the CUPS_USER + environment variable for overriding the default username (STR #3114) + - Now set the PJL USERNAME variable as needed (STR #3100) + - Added support for usernames and passwords longer than 32 characters + (STR #2856) + - Added a new MaxHoldTime directive to automatically cancel jobs that + have been held indefinitely after a specific number of seconds + (STR #2291) + - The LPD backend now uses the originating host name when it is not the + local system (STR #2053) + - CUPS now prefers the suffix "dpcm" when reporting resolution in dots- + per-centimeter (STR #4006) - The configure script and build system no longer support building of separate 32-bit and 64-bit libraries. - The "brightness", "columns", "fitplot", "gamma", "hue", diff --git a/backend/dnssd.c b/backend/dnssd.c index fd86e0814..12571b15c 100644 --- a/backend/dnssd.c +++ b/backend/dnssd.c @@ -3,7 +3,7 @@ * * DNS-SD discovery backend for CUPS. * - * Copyright 2008-2011 by Apple Inc. + * Copyright 2008-2012 by Apple Inc. * * These coded instructions, statements, and computer programs are the * property of Apple Inc. and are protected by Federal copyright @@ -43,8 +43,8 @@ typedef enum { CUPS_DEVICE_PRINTER = 0, /* lpd://... */ - CUPS_DEVICE_IPP, /* ipp://... */ CUPS_DEVICE_IPPS, /* ipps://... */ + CUPS_DEVICE_IPP, /* ipp://... */ CUPS_DEVICE_FAX_IPP, /* ipp://... */ CUPS_DEVICE_PDL_DATASTREAM, /* socket://... */ CUPS_DEVICE_RIOUSBPRINT /* riousbprint://... */ diff --git a/backend/ipp.c b/backend/ipp.c index 68c05e954..20391f8a2 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -90,7 +90,9 @@ static const char * const jattrs[] = /* Job attributes we want */ }; static int job_canceled = 0; /* Job cancelled? */ -static char *password = NULL; +static char username[256] = "", + /* Username for device URI */ + *password = NULL; /* Password for device URI */ static int password_tries = 0; /* Password tries */ @@ -98,7 +100,6 @@ static const char * const pattrs[] = /* Printer attributes we want */ { "copies-supported", "cups-version", - "document-format-default", "document-format-supported", "marker-colors", "marker-high-levels", @@ -190,7 +191,6 @@ main(int argc, /* I - Number of command-line args */ const char *device_uri; /* Device URI */ char scheme[255], /* Scheme in URI */ hostname[1024], /* Hostname */ - username[255], /* Username info */ resource[1024], /* Resource info (printer name) */ addrname[256], /* Address name */ *optptr, /* Pointer to URI options */ @@ -230,7 +230,6 @@ main(int argc, /* I - Number of command-line args */ ipp_attribute_t *job_state; /* job-state */ ipp_attribute_t *copies_sup; /* copies-supported */ ipp_attribute_t *cups_version; /* cups-version */ - ipp_attribute_t *format_dflt; /* document-format-default */ ipp_attribute_t *format_sup; /* document-format-supported */ ipp_attribute_t *media_col_sup; /* media-col-supported */ ipp_attribute_t *operations_sup; /* operations-supported */ @@ -612,7 +611,10 @@ main(int argc, /* I - Number of command-line args */ const char *ptr = getenv("AUTH_USERNAME"); if (ptr) + { + strlcpy(username, ptr, sizeof(username)); cupsSetUser(ptr); + } password = getenv("AUTH_PASSWORD"); } @@ -841,7 +843,9 @@ main(int argc, /* I - Number of command-line args */ fprintf(stderr, "DEBUG: Get-Printer-Attributes: %s (%s)\n", ippErrorString(ipp_status), cupsLastErrorString()); - if (ipp_status > IPP_OK_CONFLICT) + if (ipp_status <= IPP_OK_CONFLICT) + password_tries = 0; + else { fprintf(stderr, "DEBUG: Get-Printer-Attributes returned %s.\n", ippErrorString(ipp_status)); @@ -898,7 +902,8 @@ main(int argc, /* I - Number of command-line args */ return (CUPS_BACKEND_STOP); } - else if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN) + else if (ipp_status == IPP_FORBIDDEN || + ipp_status == IPP_AUTHENTICATION_CANCELED) { const char *www_auth = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE); /* WWW-Authenticate field value */ @@ -911,7 +916,7 @@ main(int argc, /* I - Number of command-line args */ fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required); return (CUPS_BACKEND_AUTH_REQUIRED); } - else + else if (ipp_status != IPP_NOT_AUTHORIZED) { _cupsLangPrintFilter(stderr, "ERROR", _("Unable to get printer status.")); @@ -997,16 +1002,6 @@ main(int argc, /* I - Number of command-line args */ cups_version = ippFindAttribute(supported, "cups-version", IPP_TAG_TEXT); - if ((format_dflt = ippFindAttribute(supported, "document-format-default", - IPP_TAG_MIMETYPE)) != NULL) - { - fprintf(stderr, "DEBUG: document-format-default (%d values)\n", - format_dflt->num_values); - for (i = 0; i < format_dflt->num_values; i ++) - fprintf(stderr, "DEBUG: [%d] = \"%s\"\n", i, - format_dflt->values[i].string.text); - } - if ((format_sup = ippFindAttribute(supported, "document-format-supported", IPP_TAG_MIMETYPE)) != NULL) { @@ -1184,21 +1179,17 @@ main(int argc, /* I - Number of command-line args */ if (format_sup != NULL) { for (i = 0; i < format_sup->num_values; i ++) - if (!_cups_strcasecmp(final_content_type, - format_sup->values[i].string.text)) + if (!_cups_strcasecmp(final_content_type, format_sup->values[i].string.text)) { document_format = final_content_type; break; } - if (!document_format && - (!format_dflt || - _cups_strcasecmp(format_dflt->values[0].string.text, - "application/octet-stream"))) + if (!document_format) { for (i = 0; i < format_sup->num_values; i ++) if (!_cups_strcasecmp("application/octet-stream", - format_sup->values[i].string.text)) + format_sup->values[i].string.text)) { document_format = "application/octet-stream"; break; @@ -1303,7 +1294,7 @@ main(int argc, /* I - Number of command-line args */ _cupsLangPrintFilter(stderr, "INFO", _("The printer is busy.")); sleep(10); } - else if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN || + else if (ipp_status == IPP_FORBIDDEN || ipp_status == IPP_AUTHENTICATION_CANCELED) { const char *www_auth = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE); @@ -1463,6 +1454,8 @@ main(int argc, /* I - Number of command-line args */ } else if (ipp_status == IPP_ERROR_JOB_CANCELED) goto cleanup; + else if (ipp_status == IPP_NOT_AUTHORIZED) + continue; else { /* @@ -1472,11 +1465,12 @@ main(int argc, /* I - Number of command-line args */ _cupsLangPrintFilter(stderr, "ERROR", _("Print file was not accepted.")); - if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN) + if (ipp_status == IPP_FORBIDDEN || + ipp_status == IPP_AUTHENTICATION_CANCELED) { const char *www_auth = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE); /* WWW-Authenticate field value */ - + if (!strncmp(www_auth, "Negotiate", 9)) auth_info_required = "negotiate"; else if (www_auth[0]) @@ -1515,6 +1509,7 @@ main(int argc, /* I - Number of command-line args */ } else { + password_tries = 0; monitor.job_id = job_id = job_id_attr->values[0].integer; _cupsLangPrintFilter(stderr, "INFO", _("Print file accepted - job ID %d."), job_id); @@ -1616,8 +1611,13 @@ 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; + else + { + password_tries = 0; + + if (num_files == 0 || fd < 0) + break; + } } } @@ -1705,7 +1705,9 @@ main(int argc, /* I - Number of command-line args */ fprintf(stderr, "DEBUG: Get-Job-Attributes: %s (%s)\n", ippErrorString(ipp_status), cupsLastErrorString()); - if (ipp_status > IPP_OK_CONFLICT) + if (ipp_status <= IPP_OK_CONFLICT) + password_tries = 0; + else { if (ipp_status != IPP_SERVICE_UNAVAILABLE && ipp_status != IPP_NOT_POSSIBLE && @@ -1966,6 +1968,9 @@ check_printer_state( 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... */ @@ -2073,6 +2078,8 @@ monitor_printer( http = _httpCreate(monitor->hostname, monitor->port, NULL, monitor->encryption, AF_UNSPEC); httpSetTimeout(http, 30.0, timeout_cb, NULL); + if (username[0]) + cupsSetUser(username); cupsSetPasswordCB(password_cb); /* @@ -2130,6 +2137,9 @@ monitor_printer( fprintf(stderr, "DEBUG: %s: %s (%s)\n", ippOpString(job_op), ippErrorString(cupsLastError()), cupsLastErrorString()); + if (cupsLastError() <= IPP_OK_CONFLICT) + password_tries = 0; + if (job_op == IPP_GET_JOB_ATTRIBUTES) { if ((attr = ippFindAttribute(response, "job-state", @@ -2452,6 +2462,9 @@ new_request( "multiple-document-handling", NULL, collate_str); break; } + + if (i >= doc_handling_sup->num_values) + copies = 1; } /* @@ -2500,7 +2513,7 @@ new_request( cupsEncodeOptions(request, num_options, options); } - if (copies > 1) + if (copies > 1 && copies <= pc->max_copies) ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies", copies); } @@ -2515,6 +2528,9 @@ new_request( static const char * /* O - Password */ password_cb(const char *prompt) /* I - Prompt (not used) */ { + fprintf(stderr, "DEBUG: password_cb(prompt=\"%s\"), password=%p, " + "password_tries=%d\n", prompt, password, password_tries); + (void)prompt; /* diff --git a/backend/lpd.c b/backend/lpd.c index 0dabfd766..3e3cbfc90 100644 --- a/backend/lpd.c +++ b/backend/lpd.c @@ -92,7 +92,7 @@ static int lpd_queue(const char *hostname, http_addrlist_t *addrlist, int mode, const char *user, const char *title, int copies, int banner, int format, int order, int reserve, int manual_copies, int timeout, - int contimeout); + int contimeout, const char *orighost); static int lpd_write(int lpd_fd, char *buffer, int length); #ifndef HAVE_RRESVPORT_AF static int rresvport_af(int *port, int family); @@ -144,6 +144,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + int num_jobopts; /* Number of job options */ + cups_option_t *jobopts = NULL; /* Job options */ /* @@ -191,6 +193,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ return (CUPS_BACKEND_FAILED); } + num_jobopts = cupsParseOptions(argv[5], 0, &jobopts); + /* * Extract the hostname and printer name from the URI... */ @@ -525,7 +529,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode, username, title, copies, banner, format, order, reserve, - manual_copies, timeout, contimeout); + manual_copies, timeout, contimeout, + cupsGetOption("job-originating-host-name", num_jobopts, + jobopts)); if (!status) fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4])); @@ -533,7 +539,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ else status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode, username, title, 1, banner, format, order, reserve, 1, - timeout, contimeout); + timeout, contimeout, + cupsGetOption("job-originating-host-name", num_jobopts, + jobopts)); /* * Remove the temporary file if necessary... @@ -638,7 +646,8 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ int reserve, /* I - Reserve ports? */ int manual_copies,/* I - Do copies by hand... */ int timeout, /* I - Timeout... */ - int contimeout) /* I - Connection timeout */ + int contimeout, /* I - Connection timeout */ + const char *orighost) /* I - job-originating-host-name */ { char localhost[255]; /* Local host name */ int error; /* Error number */ @@ -927,7 +936,10 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ return (CUPS_BACKEND_FAILED); } - httpGetHostname(NULL, localhost, sizeof(localhost)); + if (orighost) + strlcpy(localhost, orighost, sizeof(localhost)); + else + httpGetHostname(NULL, localhost, sizeof(localhost)); snprintf(control, sizeof(control), "H%.31s\n" /* RFC 1179, Section 7.2 - host name <= 31 chars */ diff --git a/backend/snmp-supplies.c b/backend/snmp-supplies.c index 601bc979d..0eaba065d 100644 --- a/backend/snmp-supplies.c +++ b/backend/snmp-supplies.c @@ -149,7 +149,7 @@ static const int prtMarkerSuppliesType[] = static const backend_state_t const printer_states[] = { - { CUPS_TC_lowPaper, "media-low-report" }, + /* { CUPS_TC_lowPaper, "media-low-report" }, */ { CUPS_TC_noPaper | CUPS_TC_inputTrayEmpty, "media-empty-warning" }, /* { CUPS_TC_lowToner, "toner-low-report" }, */ /* now use prtMarkerSupplies */ /* { CUPS_TC_noToner, "toner-empty-warning" }, */ /* now use prtMarkerSupplies */ diff --git a/backend/testbackend.c b/backend/testbackend.c index 6182471d1..a3a7d97e6 100644 --- a/backend/testbackend.c +++ b/backend/testbackend.c @@ -98,12 +98,18 @@ main(int argc, /* I - Number of command-line args */ (ptr = strrchr(libpath, '/')) != NULL && !strcmp(ptr, "/backend")) { strlcpy(ptr, "/cups", sizeof(libpath) - (ptr - libpath)); - if (access(libpath, 0)) + if (!access(libpath, 0)) + { #ifdef __APPLE__ + fprintf(stderr, "Setting DYLD_LIBRARY_PATH to \"%s\".\n", libpath); setenv("DYLD_LIBRARY_PATH", libpath, 1); #else + fprintf(stderr, "Setting LD_LIBRARY_PATH to \"%s\".\n", libpath); setenv("LD_LIBRARY_PATH", libpath, 1); #endif /* __APPLE__ */ + } + else + perror(libpath); } /* diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c index 31d34d7fd..6c432a9d6 100644 --- a/cgi-bin/ipp-var.c +++ b/cgi-bin/ipp-var.c @@ -3,7 +3,7 @@ * * CGI <-> IPP variable routines for CUPS. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -1219,7 +1219,7 @@ cgiSetIPPObjectVars( "%dx%d%s", attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); break; case IPP_TAG_URI : diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4 index 04e700eb5..9b8ac80aa 100644 --- a/config-scripts/cups-common.m4 +++ b/config-scripts/cups-common.m4 @@ -225,24 +225,20 @@ AC_ARG_ENABLE(libusb, [ --enable-libusb use libusb for USB printing]) LIBUSB="" AC_SUBST(LIBUSB) -if test x$enable_libusb = xyes; then - check_libusb=yes -elif test x$enable_libusb != xno -a $uname != Darwin; then - check_libusb=yes -else - check_libusb=no -fi - -if test $check_libusb = yes -a "x$PKGCONFIG" != x; then - AC_MSG_CHECKING(for libusb-1.0) - if $PKGCONFIG --exists libusb-1.0; then - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_LIBUSB) - CFLAGS="$CFLAGS `$PKGCONFIG --cflags libusb-1.0`" - LIBUSB="`$PKGCONFIG --libs libusb-1.0`" - else - AC_MSG_RESULT(no) +if test "x$PKGCONFIG" != x; then + if test x$enable_libusb = xyes -o $uname != Darwin; then + AC_MSG_CHECKING(for libusb-1.0) + if $PKGCONFIG --exists libusb-1.0; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_LIBUSB) + CFLAGS="$CFLAGS `$PKGCONFIG --cflags libusb-1.0`" + LIBUSB="`$PKGCONFIG --libs libusb-1.0`" + else + AC_MSG_RESULT(no) + fi fi +elif x$enable_libusb = xyes; then + AC_MSG_ERROR(Need pkg-config to enable libusb support.) fi dnl See if we have libwrap for TCP wrappers support... @@ -353,12 +349,6 @@ case $uname in dnl Check for dynamic store function... AC_CHECK_FUNCS(SCDynamicStoreCopyComputerName) - dnl Check for new ColorSync APIs... - SAVELIBS="$LIBS" - LIBS="$LIBS -framework ApplicationServices" - AC_CHECK_FUNCS(ColorSyncRegisterDevice) - LIBS="$SAVELIBS" - dnl Check for the new membership functions in MacOSX 10.4... AC_CHECK_HEADER(membership.h,AC_DEFINE(HAVE_MEMBERSHIP_H)) AC_CHECK_HEADER(membershipPriv.h,AC_DEFINE(HAVE_MEMBERSHIPPRIV_H)) diff --git a/config-scripts/cups-dnssd.m4 b/config-scripts/cups-dnssd.m4 index 1999be3ff..3ed91f79b 100644 --- a/config-scripts/cups-dnssd.m4 +++ b/config-scripts/cups-dnssd.m4 @@ -3,7 +3,7 @@ dnl "$Id: cups-dnssd.m4 7890 2008-08-29 22:19:39Z mike $" dnl dnl DNS Service Discovery (aka Bonjour) stuff for CUPS. dnl -dnl Copyright 2007-2011 by Apple Inc. +dnl Copyright 2007-2012 by Apple Inc. dnl dnl These coded instructions, statements, and computer programs are the dnl property of Apple Inc. and are protected by Federal copyright @@ -12,7 +12,8 @@ dnl which should have been included with this file. If this file is dnl file is missing or damaged, see the license at "http://www.cups.org/". dnl -AC_ARG_ENABLE(dnssd, [ --disable-dnssd disable DNS Service Discovery support]) +AC_ARG_ENABLE(avahi, [ --disable-avahi disable DNS Service Discovery support using Avahi]) +AC_ARG_ENABLE(dnssd, [ --disable-dnssd disable DNS Service Discovery support using mDNSResponder]) AC_ARG_WITH(dnssd-libs, [ --with-dnssd-libs set directory for DNS Service Discovery library], LDFLAGS="-L$withval $LDFLAGS" DSOFLAGS="-L$withval $DSOFLAGS",) @@ -23,7 +24,20 @@ AC_ARG_WITH(dnssd-includes, [ --with-dnssd-includes set directory for DNS Ser DNSSDLIBS="" DNSSD_BACKEND="" -if test x$enable_dnssd != xno; then +if test "x$PKGCONFIG" != x -a x$enable_avahi != xno; then + AC_MSG_CHECKING(for Avahi) + if $PKGCONFIG --exists avahi-client; then + AC_MSG_RESULT(yes) + CFLAGS="$CFLAGS `$PKGCONFIG --cflags avahi-client`" + DNSSDLIBS="`$PKGCONFIG --libs avahi-client`" + DNSSD_BACKEND="dnssd" + AC_DEFINE(HAVE_AVAHI) + else + AC_MSG_RESULT(no) + fi +fi + +if test "x$DNSSD_BACKEND" = x -a x$enable_dnssd != xno; then AC_CHECK_HEADER(dns_sd.h, [ case "$uname" in Darwin*) diff --git a/config.h.in b/config.h.in index e5f383e15..9c1faf9ab 100644 --- a/config.h.in +++ b/config.h.in @@ -379,13 +379,20 @@ /* - * Do we have DNS Service Discovery (aka Bonjour)? + * Do we have mDNSResponder for DNS Service Discovery (aka Bonjour)? */ #undef HAVE_DNSSD /* + * Do we have Avahi for DNS Service Discovery (aka Bonjour)? + */ + +#undef HAVE_AVAHI + + +/* * Do we have <sys/ioctl.h>? */ @@ -724,13 +731,6 @@ /* - * Do we have the ColorSyncRegisterDevice function? - */ - -#undef HAVE_COLORSYNCREGISTERDEVICE - - -/* * Do we have XPC? */ diff --git a/cups/auth.c b/cups/auth.c index bea62b797..7e091bee0 100644 --- a/cups/auth.c +++ b/cups/auth.c @@ -124,7 +124,8 @@ cupsDoAuthentication( const char *method, /* I - Request method ("GET", "POST", "PUT") */ const char *resource) /* I - Resource path */ { - const char *password; /* Password string */ + const char *password, /* Password string */ + *www_auth; /* WWW-Authenticate header */ char prompt[1024], /* Prompt for user */ realm[HTTP_MAX_VALUE], /* realm="xyz" string */ nonce[HTTP_MAX_VALUE]; /* nonce="xyz" string */ @@ -179,9 +180,11 @@ cupsDoAuthentication( * Nope, see if we should retry the current username:password... */ + www_auth = http->fields[HTTP_FIELD_WWW_AUTHENTICATE]; + if ((http->digest_tries > 1 || !http->userpass[0]) && - (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) || - !strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Digest", 6))) + (!_cups_strncasecmp(www_auth, "Basic", 5) || + !_cups_strncasecmp(www_auth, "Digest", 6))) { /* * Nope - get a new password from the user... @@ -197,8 +200,7 @@ cupsDoAuthentication( cupsUser(), http->hostname[0] == '/' ? "localhost" : http->hostname); - http->digest_tries = _cups_strncasecmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], - "Digest", 5) != 0; + http->digest_tries = _cups_strncasecmp(www_auth, "Digest", 6) != 0; http->userpass[0] = '\0'; if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL) @@ -227,7 +229,7 @@ cupsDoAuthentication( */ #ifdef HAVE_GSSAPI - if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9)) + if (!_cups_strncasecmp(www_auth, "Negotiate", 9)) { /* * Kerberos authentication... @@ -241,7 +243,7 @@ cupsDoAuthentication( } else #endif /* HAVE_GSSAPI */ - if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5)) + if (!_cups_strncasecmp(www_auth, "Basic", 5)) { /* * Basic authentication... @@ -254,7 +256,7 @@ cupsDoAuthentication( (int)strlen(http->userpass)); httpSetAuthString(http, "Basic", encode); } - else if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Digest", 6)) + else if (!_cups_strncasecmp(www_auth, "Digest", 6)) { /* * Digest authentication... @@ -277,7 +279,7 @@ cupsDoAuthentication( else { DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"", - http->fields[HTTP_FIELD_WWW_AUTHENTICATE])); + www_auth)); http->status = HTTP_AUTHORIZATION_CANCELED; return (-1); } diff --git a/cups/dest-options.c b/cups/dest-options.c index eff70dcb0..af5a26256 100644 --- a/cups/dest-options.c +++ b/cups/dest-options.c @@ -187,7 +187,7 @@ cupsCheckDestSupported( if (!strcmp(temp, "dpi")) units_value = IPP_RES_PER_INCH; - else if (!strcmp(temp, "dpc")) + else if (!strcmp(temp, "dpc") || !strcmp(temp, "dpcm")) units_value = IPP_RES_PER_CM; else return (0); diff --git a/cups/emit.c b/cups/emit.c index 23e0c2800..e322bfe1a 100644 --- a/cups/emit.c +++ b/cups/emit.c @@ -3,7 +3,7 @@ * * PPD code emission routines 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 @@ -519,15 +519,27 @@ ppdEmitJCL(ppd_file_t *ppd, /* I - PPD file record */ */ if (display && strcmp(display->value, "job")) - { fprintf(fp, "@PJL JOB NAME = \"%s\"\n", temp); - - if (display && !strcmp(display->value, "rdymsg")) - fprintf(fp, "@PJL RDYMSG DISPLAY = \"%s\"\n", displaymsg); - } + else if (display && !strcmp(display->value, "rdymsg")) + fprintf(fp, "@PJL RDYMSG DISPLAY = \"%s\"\n", displaymsg); else fprintf(fp, "@PJL JOB NAME = \"%s\" DISPLAY = \"%s\"\n", temp, displaymsg); + + /* + * Replace double quotes with single quotes and UTF-8 characters with + * question marks so that the user does not cause a PJL syntax error. + */ + + strlcpy(temp, user, sizeof(temp)); + + for (ptr = temp; *ptr; ptr ++) + if (*ptr == '\"') + *ptr = '\''; + else if (!charset && (*ptr & 128)) + *ptr = '?'; + + fprintf(fp, "@PJL SET USERNAME = \"%s\"\n", temp); } else fputs(ppd->jcl_begin, fp); diff --git a/cups/encode.c b/cups/encode.c index 91a37ecd8..2226e1950 100644 --- a/cups/encode.c +++ b/cups/encode.c @@ -3,7 +3,7 @@ * * Option encoding routines for CUPS. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -539,7 +539,8 @@ cupsEncodeOptions2( else attr->values[j].resolution.yres = attr->values[j].resolution.xres; - if (!_cups_strcasecmp(s, "dpc")) + if (!_cups_strcasecmp(s, "dpc") || + !_cups_strcasecmp(s, "dpcm")) attr->values[j].resolution.units = IPP_RES_PER_CM; else attr->values[j].resolution.units = IPP_RES_PER_INCH; diff --git a/cups/http-support.c b/cups/http-support.c index 0d1f2b211..b886515bd 100644 --- a/cups/http-support.c +++ b/cups/http-support.c @@ -757,10 +757,13 @@ httpGetDateString2(time_t t, /* I - UNIX time */ tdate = gmtime(&t); - snprintf(s, slen, "%s, %02d %s %d %02d:%02d:%02d GMT", - http_days[tdate->tm_wday], tdate->tm_mday, - http_months[tdate->tm_mon], tdate->tm_year + 1900, - tdate->tm_hour, tdate->tm_min, tdate->tm_sec); + if (tdate) + snprintf(s, slen, "%s, %02d %s %d %02d:%02d:%02d GMT", + http_days[tdate->tm_wday], tdate->tm_mday, + http_months[tdate->tm_mon], tdate->tm_year + 1900, + tdate->tm_hour, tdate->tm_min, tdate->tm_sec); + else + s[0] = '\0'; return (s); } @@ -1504,15 +1507,19 @@ _httpResolveURI( if (DNSServiceCreateConnection(&ref) == kDNSServiceErr_NoError) { localref = ref; - if (DNSServiceResolve(&localref, kDNSServiceFlagsShareConnection, 0, - hostname, regtype, "local.", http_resolve_cb, + if (DNSServiceResolve(&localref, + kDNSServiceFlagsShareConnection | + kDNSServiceFlagsTimeout, 0, hostname, regtype, + "local.", http_resolve_cb, &uribuf) == kDNSServiceErr_NoError) { int fds; /* Number of ready descriptors */ time_t timeout, /* Poll timeout */ - start_time = time(NULL);/* Start time */ + start_time = time(NULL),/* Start time */ + end_time = start_time + 90; + /* End time */ - for (;;) + while (time(NULL) < end_time) { if (options & _HTTP_RESOLVE_STDERR) _cupsLangPrintFilter(stderr, "INFO", _("Looking for printer.")); @@ -1524,27 +1531,27 @@ _httpResolveURI( } /* - * For the first minute (or forever if we have a callback), wakeup - * every 2 seconds to emit a "looking for printer" message... + * Wakeup every 2 seconds to emit a "looking for printer" message... */ - timeout = (time(NULL) < (start_time + 60) || cb) ? 2000 : -1; + if ((timeout = end_time - time(NULL)) > 2) + timeout = 2; #ifdef HAVE_POLL polldata.fd = DNSServiceRefSockFD(ref); polldata.events = POLLIN; - fds = poll(&polldata, 1, timeout); + fds = poll(&polldata, 1, 1000 * timeout); #else /* select() */ FD_ZERO(&input_set); FD_SET(DNSServiceRefSockFD(ref), &input_set); - stimeout.tv_sec = ((int)timeout) / 1000; - stimeout.tv_usec = ((int)(timeout) * 1000) % 1000000; + stimeout.tv_sec = timeout; + stimeout.tv_usec = 0; fds = select(DNSServiceRefSockFD(ref)+1, &input_set, NULL, NULL, - timeout < 0.0 ? NULL : &stimeout); + &stimeout); #endif /* HAVE_POLL */ if (fds < 0) @@ -1562,7 +1569,7 @@ _httpResolveURI( * comes in, do an additional domain resolution... */ - if (domainsent == 0 && (domain && _cups_strcasecmp(domain, "local."))) + if (domainsent == 0 && domain && _cups_strcasecmp(domain, "local.")) { if (options & _HTTP_RESOLVE_STDERR) fprintf(stderr, @@ -1571,10 +1578,12 @@ _httpResolveURI( domain ? domain : ""); domainref = ref; - if (DNSServiceResolve(&domainref, kDNSServiceFlagsShareConnection, + if (DNSServiceResolve(&domainref, + kDNSServiceFlagsShareConnection | + kDNSServiceFlagsTimeout, 0, hostname, regtype, domain, - http_resolve_cb, &uribuf) - == kDNSServiceErr_NoError) + http_resolve_cb, + &uribuf) == kDNSServiceErr_NoError) domainsent = 1; } @@ -1612,11 +1621,15 @@ _httpResolveURI( if (options & _HTTP_RESOLVE_STDERR) { if (uri) + { fprintf(stderr, "DEBUG: Resolved as \"%s\"...\n", uri); + fputs("STATE: -connecting-to-device,offline-report\n", stderr); + } else + { fputs("DEBUG: Unable to resolve URI\n", stderr); - - fputs("STATE: -connecting-to-device,offline-report\n", stderr); + fputs("STATE: -connecting-to-device\n", stderr); + } } #else diff --git a/cups/http.c b/cups/http.c index 16351ef0d..1f2d826dd 100644 --- a/cups/http.c +++ b/cups/http.c @@ -1668,6 +1668,8 @@ _httpPeek(http_t *http, /* I - Connection to server */ * Buffer small reads for better performance... */ + ssize_t buflen; /* Length of read for buffer */ + if (!http->blocking) { while (!httpWait(http, http->wait_value)) @@ -1680,48 +1682,69 @@ _httpPeek(http_t *http, /* I - Connection to server */ } if (http->data_remaining > sizeof(http->buffer)) - bytes = sizeof(http->buffer); + buflen = sizeof(http->buffer); else - bytes = http->data_remaining; + buflen = http->data_remaining; + + DEBUG_printf(("2_httpPeek: Reading %d bytes into buffer.", (int)buflen)); + do + { #ifdef HAVE_SSL - if (http->tls) - bytes = http_read_ssl(http, http->buffer, bytes); - else + if (http->tls) + bytes = http_read_ssl(http, http->buffer, buflen); + else #endif /* HAVE_SSL */ - { - DEBUG_printf(("2_httpPeek: reading %d bytes from socket into buffer...", - (int)bytes)); - - bytes = recv(http->fd, http->buffer, bytes, 0); - - DEBUG_printf(("2_httpPeek: read %d bytes from socket into buffer...", - (int)bytes)); - } + bytes = recv(http->fd, http->buffer, buflen, 0); - if (bytes > 0) - http->used = bytes; - else if (bytes < 0) - { -#ifdef WIN32 - if (WSAGetLastError() != WSAEINTR && WSAGetLastError() != WSAEWOULDBLOCK) + if (bytes < 0) { - http->error = WSAGetLastError(); - return (-1); - } +#ifdef WIN32 + if (WSAGetLastError() != WSAEINTR) + { + http->error = WSAGetLastError(); + return (-1); + } + else if (WSAGetLastError() == WSAEWOULDBLOCK) + { + if (!http->timeout_cb || + !(*http->timeout_cb)(http, http->timeout_data)) + { + http->error = WSAEWOULDBLOCK; + return (-1); + } + } #else - if (errno != EINTR && errno != EAGAIN) - { - http->error = errno; - return (-1); - } + if (errno == EWOULDBLOCK || errno == EAGAIN) + { + if (http->timeout_cb && !(*http->timeout_cb)(http, http->timeout_data)) + { + http->error = errno; + return (-1); + } + else if (!http->timeout_cb && errno != EAGAIN) + { + http->error = errno; + return (-1); + } + } + else if (errno != EINTR) + { + http->error = errno; + return (-1); + } #endif /* WIN32 */ + } } - else - { - http->error = EPIPE; - return (0); - } + while (bytes < 0); + + DEBUG_printf(("2_httpPeek: Read " CUPS_LLFMT " bytes into buffer.", + CUPS_LLCAST bytes)); +#ifdef DEBUG + http_debug_hex("_httpPeek", http->buffer, (int)bytes); +#endif /* DEBUG */ + + http->used = bytes; } if (http->used > 0) diff --git a/cups/ipp-support.c b/cups/ipp-support.c index ec4c2c998..362321a55 100644 --- a/cups/ipp-support.c +++ b/cups/ipp-support.c @@ -3,7 +3,7 @@ * * Internet Printing Protocol support functions 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 @@ -487,12 +487,12 @@ ippAttributeString( bufptr += snprintf(bufptr, bufend - bufptr + 1, "%dx%d%s", val->resolution.xres, val->resolution.yres, val->resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); else bufptr += snprintf(temp, sizeof(temp), "%dx%d%s", val->resolution.xres, val->resolution.yres, val->resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); break; case IPP_TAG_DATE : diff --git a/cups/ipp.c b/cups/ipp.c index 96361abdc..6b88d71de 100644 --- a/cups/ipp.c +++ b/cups/ipp.c @@ -3673,7 +3673,11 @@ ippSetString(ipp_t *ipp, /* IO - IPP message */ * Range check input... */ - if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_INTEGER || + if (!ipp || !attr || !*attr || + ((*attr)->value_tag != IPP_TAG_TEXTLANG && + (*attr)->value_tag != IPP_TAG_NAMELANG && + ((*attr)->value_tag < IPP_TAG_TEXT || + (*attr)->value_tag > IPP_TAG_MIMETYPE)) || element < 0 || element > (*attr)->num_values || !strvalue) return (0); diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c index c9ee6af2d..cf34a00bd 100644 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@ -171,6 +171,8 @@ _ppdCacheCreateWithFile( goto create_error; } + pc->max_copies = 9999; + /* * Read the file... */ @@ -553,6 +555,8 @@ _ppdCacheCreateWithFile( cupsArrayAdd(pc->finishings, finishings); } + else if (!_cups_strcasecmp(line, "MaxCopies")) + pc->max_copies = atoi(value); else { DEBUG_printf(("_ppdCacheCreateWithFile: Unknown %s on line %d.", line, @@ -1349,6 +1353,17 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ } /* + * Max copies... + */ + + if ((ppd_attr = ppdFindAttr(ppd, "cupsMaxCopies", NULL)) != NULL) + pc->max_copies = atoi(ppd_attr->value); + else if (ppd->manual_copies) + pc->max_copies = 1; + else + pc->max_copies = 9999; + + /* * Return the cache data... */ @@ -2334,6 +2349,12 @@ _ppdCacheWriteFile( } /* + * Max copies... + */ + + cupsFilePrintf(fp, "MaxCopies %d\n", pc->max_copies); + + /* * IPP attributes, if any... */ diff --git a/cups/ppd-private.h b/cups/ppd-private.h index bc6a0f8b9..426c74ff8 100644 --- a/cups/ppd-private.h +++ b/cups/ppd-private.h @@ -49,7 +49,7 @@ extern "C" { * Constants... */ -# define _PPD_CACHE_VERSION 2 /* Version number in cache file */ +# define _PPD_CACHE_VERSION 3 /* Version number in cache file */ /* @@ -141,6 +141,7 @@ struct _ppd_cache_s /**** PPD cache and PWG conversion data ****/ *prefilters; /* cupsPreFilter values */ int single_file; /* cupsSingleFile value */ cups_array_t *finishings; /* cupsIPPFinishings values */ + int max_copies; /* cupsMaxCopies value */ }; diff --git a/cups/testipp.c b/cups/testipp.c index 70c83bf4b..5655b6be2 100644 --- a/cups/testipp.c +++ b/cups/testipp.c @@ -3,7 +3,7 @@ * * IPP test program for CUPS. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2005 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -901,7 +901,7 @@ print_attributes(ipp_t *ipp, /* I - IPP request */ case IPP_TAG_RESOLUTION : for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) printf(" %dx%d%s", val->resolution.xres, val->resolution.yres, - val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc"); + val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm"); putchar('\n'); break; diff --git a/cups/usersys.c b/cups/usersys.c index dfd5cb21c..0fcd86e57 100644 --- a/cups/usersys.c +++ b/cups/usersys.c @@ -66,6 +66,7 @@ static void cups_read_client_conf(cups_file_t *fp, _cups_globals_t *cg, const char *cups_encryption, const char *cups_server, + const char *cups_user, #ifdef HAVE_GSSAPI const char *cups_gssservicename, #endif /* HAVE_GSSAPI */ @@ -435,55 +436,11 @@ cupsSetUser(const char *user) /* I - User name */ const char * /* O - User name */ cupsUser(void) { - const char *user; /* USER environment variable */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ if (!cg->user[0]) - { -#ifdef WIN32 - /* - * Get the current user name from the OS... - */ - - DWORD size; /* Size of string */ - - size = sizeof(cg->user); - if (!GetUserName(cg->user, &size)) -#else - /* - * Get the user name corresponding to the current UID... - */ - - struct passwd *pwd; /* User/password entry */ - - setpwent(); - if ((pwd = getpwuid(getuid())) != NULL) - { - /* - * Found a match! - */ - - strlcpy(cg->user, pwd->pw_name, sizeof(cg->user)); - } - else -#endif /* WIN32 */ - if ((user = getenv("USER")) != NULL) - { - /* - * Use the username from the "USER" environment variable... - */ - strlcpy(cg->user, user, sizeof(cg->user)); - } - else - { - /* - * Use the default "unknown" user name... - */ - - strcpy(cg->user, "unknown"); - } - } + _cupsSetDefaults(); return (cg->user); } @@ -791,6 +748,7 @@ _cupsSetDefaults(void) const char *home, /* Home directory of user */ *cups_encryption, /* CUPS_ENCRYPTION env var */ *cups_server, /* CUPS_SERVER env var */ + *cups_user, /* CUPS_USER/USER env var */ #ifdef HAVE_GSSAPI *cups_gssservicename, /* CUPS_GSSSERVICENAME env var */ #endif /* HAVE_GSSAPI */ @@ -816,13 +774,16 @@ _cupsSetDefaults(void) cups_expiredroot = getenv("CUPS_EXPIREDROOT"); cups_expiredcerts = getenv("CUPS_EXPIREDCERTS"); + if ((cups_user = getenv("CUPS_USER")) == NULL) + cups_user = getenv("USER"); + /* * Then, if needed, read the ~/.cups/client.conf or /etc/cups/client.conf * files to get the default values... */ if (cg->encryption == (http_encryption_t)-1 || !cg->server[0] || - !cg->ipp_port) + !cg->user[0] || !cg->ipp_port) { if ((home = getenv("HOME")) != NULL) { @@ -852,7 +813,7 @@ _cupsSetDefaults(void) * functions handle NULL cups_file_t pointers... */ - cups_read_client_conf(fp, cg, cups_encryption, cups_server, + cups_read_client_conf(fp, cg, cups_encryption, cups_server, cups_user, #ifdef HAVE_GSSAPI cups_gssservicename, #endif /* HAVE_GSSAPI */ @@ -873,6 +834,7 @@ cups_read_client_conf( _cups_globals_t *cg, /* I - Global data */ const char *cups_encryption, /* I - CUPS_ENCRYPTION env var */ const char *cups_server, /* I - CUPS_SERVER env var */ + const char *cups_user, /* I - CUPS_USER env var */ #ifdef HAVE_GSSAPI const char *cups_gssservicename, /* I - CUPS_GSSSERVICENAME env var */ @@ -888,6 +850,7 @@ cups_read_client_conf( #ifndef __APPLE__ server_name[1024], /* ServerName value */ #endif /* !__APPLE__ */ + user[256], /* User value */ any_root[1024], /* AllowAnyRoot value */ expired_root[1024], /* AllowExpiredRoot value */ expired_certs[1024]; /* AllowExpiredCerts value */ @@ -921,6 +884,11 @@ cups_read_client_conf( cups_server = server_name; } #endif /* !__APPLE__ */ + else if (!cups_user && !_cups_strcasecmp(line, "User") && value) + { + strlcpy(user, value, sizeof(user)); + cups_user = user; + } else if (!cups_anyroot && !_cups_strcasecmp(line, "AllowAnyRoot") && value) { strlcpy(any_root, value, sizeof(any_root)); @@ -1029,6 +997,49 @@ cups_read_client_conf( cg->ipp_port = CUPS_DEFAULT_IPP_PORT; } + if (!cg->user[0]) + { + if (cups_user) + strlcpy(cg->user, cups_user, sizeof(cg->user)); + else + { +#ifdef WIN32 + /* + * Get the current user name from the OS... + */ + + DWORD size; /* Size of string */ + + size = sizeof(cg->user); + if (!GetUserName(cg->user, &size)) +#else + /* + * Get the user name corresponding to the current UID... + */ + + struct passwd *pwd; /* User/password entry */ + + setpwent(); + if ((pwd = getpwuid(getuid())) != NULL) + { + /* + * Found a match! + */ + + strlcpy(cg->user, pwd->pw_name, sizeof(cg->user)); + } + else +#endif /* WIN32 */ + { + /* + * Use the default "unknown" user name... + */ + + strcpy(cg->user, "unknown"); + } + } + } + #ifdef HAVE_GSSAPI if (!cups_gssservicename) cups_gssservicename = CUPS_DEFAULT_GSSSERVICENAME; diff --git a/doc/help/api-cups.html b/doc/help/api-cups.html index 5ebd932dc..bda8ad661 100644 --- a/doc/help/api-cups.html +++ b/doc/help/api-cups.html @@ -400,8 +400,13 @@ div.contents ul.subcontents li { <li><a href="#cupsAdminSetServerSettings" title="Set settings on the server.">cupsAdminSetServerSettings</a></li> <li><a href="#cupsCancelJob" title="Cancel a print job on the default server.">cupsCancelJob</a></li> <li><a href="#cupsCancelJob2" title="Cancel or purge a print job.">cupsCancelJob2</a></li> + <li><a href="#cupsConnectDest" title="Connect to the server for a destination.">cupsConnectDest</a></li> + <li><a href="#cupsConnectDestBlock" title="Connect to the server for a destination.">cupsConnectDestBlock</a></li> + <li><a href="#cupsCopyDest" title="Callback block">cupsCopyDest</a></li> <li><a href="#cupsCreateJob" title="Create an empty job for streaming.">cupsCreateJob</a></li> <li><a href="#cupsEncryption" title="Get the current encryption settings.">cupsEncryption</a></li> + <li><a href="#cupsEnumDests" title="Enumerate available destinations with a callback function.">cupsEnumDests</a></li> + <li><a href="#cupsEnumDestsBlock" title="Enumerate available destinations with a block.">cupsEnumDestsBlock</a></li> <li><a href="#cupsFinishDocument" title="Finish sending a document.">cupsFinishDocument</a></li> <li><a href="#cupsFreeDests" title="Free the memory used by the list of destinations.">cupsFreeDests</a></li> <li><a href="#cupsFreeJobs" title="Free memory used by job data.">cupsFreeJobs</a></li> @@ -463,27 +468,40 @@ connections.">cupsSetCredentials</a></li> <li><a href="#cupsUser" title="Return the current user's name.">cupsUser</a></li> </ul></li> <li><a href="#TYPES">Data Types</a><ul class="code"> - <li><a href="#cups_client_cert_cb_t" title="Client credentials callback ">cups_client_cert_cb_t</a></li> + <li><a href="#cups_client_cert_cb_t" title="Client credentials callback +">cups_client_cert_cb_t</a></li> + <li><a href="#cups_dest_block_t" title="Destination enumeration block +">cups_dest_block_t</a></li> + <li><a href="#cups_dest_cb_t" title="Destination enumeration callback +">cups_dest_cb_t</a></li> <li><a href="#cups_dest_t" title="Destination">cups_dest_t</a></li> - <li><a href="#cups_device_cb_t" title="Device callback ">cups_device_cb_t</a></li> + <li><a href="#cups_device_cb_t" title="Device callback +">cups_device_cb_t</a></li> + <li><a href="#cups_dinfo_t" title="Destination capability and status +information ">cups_dinfo_t</a></li> <li><a href="#cups_job_t" title="Job">cups_job_t</a></li> <li><a href="#cups_option_t" title="Printer Options">cups_option_t</a></li> - <li><a href="#cups_password_cb2_t" title="New password callback ">cups_password_cb2_t</a></li> + <li><a href="#cups_password_cb2_t" title="New password callback +">cups_password_cb2_t</a></li> <li><a href="#cups_password_cb_t" title="Password callback">cups_password_cb_t</a></li> <li><a href="#cups_ptype_t" title="Printer type/capability bits">cups_ptype_t</a></li> - <li><a href="#cups_server_cert_cb_t" title="Server credentials callback ">cups_server_cert_cb_t</a></li> + <li><a href="#cups_server_cert_cb_t" title="Server credentials callback +">cups_server_cert_cb_t</a></li> + <li><a href="#cups_size_t" title="Media Size ">cups_size_t</a></li> </ul></li> <li><a href="#STRUCTURES">Structures</a><ul class="code"> <li><a href="#cups_dest_s" title="Destination">cups_dest_s</a></li> <li><a href="#cups_job_s" title="Job">cups_job_s</a></li> <li><a href="#cups_option_s" title="Printer Options">cups_option_s</a></li> + <li><a href="#cups_size_s" title="Media Size ">cups_size_s</a></li> </ul></li> <li><a href="#VARIABLES">Variables</a><ul class="code"> <li><a href="#CF_RETURNS_RETAINED" title="Get the Apple language identifier associated with a locale ID.">CF_RETURNS_RETAINED</a></li> </ul></li> <li><a href="#ENUMERATIONS">Constants</a><ul class="code"> - <li><a href="#cups_ptype_e" title="Printer type/capability bit constants">cups_ptype_e</a></li> + <li><a href="#cups_ptype_e" title="Printer type/capability bit +constants">cups_ptype_e</a></li> </ul></li> </ul> <!-- @@ -1152,6 +1170,108 @@ Use the <a href="#cupsLastError"><code>cupsLastError</code></a> and <a href="#cu the cause of any failure. </p> +<h3 class="function"><span class="info"> CUPS 1.6 </span><a name="cupsConnectDest">cupsConnectDest</a></h3> +<p class="description">Connect to the server for a destination.</p> +<p class="code"> +http_t *cupsConnectDest (<br> + <a href="#cups_dest_t">cups_dest_t</a> *dest,<br> + unsigned flags,<br> + int msec,<br> + int *cancel,<br> + char *resource,<br> + size_t resourcesize,<br> + <a href="#cups_dest_cb_t">cups_dest_cb_t</a> cb,<br> + void *user_data<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>dest</dt> +<dd class="description">Destination</dd> +<dt>flags</dt> +<dd class="description">Connection flags</dd> +<dt>msec</dt> +<dd class="description">Timeout in milliseconds</dd> +<dt>cancel</dt> +<dd class="description">Pointer to "cancel" variable</dd> +<dt>resource</dt> +<dd class="description">Resource buffer</dd> +<dt>resourcesize</dt> +<dd class="description">Size of resource buffer</dd> +<dt>cb</dt> +<dd class="description">Callback function</dd> +<dt>user_data</dt> +<dd class="description">User data pointer</dd> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">Connection to server or <code>NULL</code></p> +<h4 class="discussion">Discussion</h4> +<p class="discussion">Connect to the destination, returning a new http_t connection object and +optionally the resource path to use for the destination. These calls will +block until a connection is made, the timeout expires, the integer pointed +to by "cancel" is non-zero, or the callback function (or block) returns 0, +The caller is responsible for calling httpClose() on the returned object. + +</p> +<h3 class="function"><span class="info"> CUPS 1.6 </span><a name="cupsConnectDestBlock">cupsConnectDestBlock</a></h3> +<p class="description">Connect to the server for a destination.</p> +<p class="code"> +http_t *cupsConnectDestBlock (<br> + <a href="#cups_dest_t">cups_dest_t</a> *dest,<br> + unsigned flags,<br> + int msec,<br> + int *cancel,<br> + char *resource,<br> + size_t resourcesize,<br> + <a href="#cups_dest_block_t">cups_dest_block_t</a> block<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>dest</dt> +<dd class="description">Destination</dd> +<dt>flags</dt> +<dd class="description">Connection flags</dd> +<dt>msec</dt> +<dd class="description">Timeout in milliseconds</dd> +<dt>cancel</dt> +<dd class="description">Pointer to "cancel" variable</dd> +<dt>resource</dt> +<dd class="description">Resource buffer</dd> +<dt>resourcesize</dt> +<dd class="description">Size of resource buffer</dd> +<dt>block</dt> +<dd class="description">Callback block</dd> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">Connection to server or <code>NULL</code></p> +<h4 class="discussion">Discussion</h4> +<p class="discussion">Connect to the destination, returning a new http_t connection object and +optionally the resource path to use for the destination. These calls will +block until a connection is made, the timeout expires, the integer pointed +to by "cancel" is non-zero, or the callback function (or block) returns 0, +The caller is responsible for calling httpClose() on the returned object. + +</p> +<h3 class="function"><a name="cupsCopyDest">cupsCopyDest</a></h3> +<p class="description">Callback block</p> +<p class="code"> +int cupsCopyDest (<br> + <a href="#cups_dest_t">cups_dest_t</a> *dest,<br> + int num_dests,<br> + <a href="#cups_dest_t">cups_dest_t</a> **dests<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>dest</dt> +<dt>num_dests</dt> +<dt>dests</dt> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">Copy a destination.</p> +<p class="discussion">Make a copy of the destination to an array of destinations (or just a single +copy) - for use with the cupsEnumDests* functions. The caller is responsible +for calling cupsFreeDests() on the returned object(s). + +</p> <h3 class="function"><span class="info"> CUPS 1.4/Mac OS X 10.6 </span><a name="cupsCreateJob">cupsCreateJob</a></h3> <p class="description">Create an empty job for streaming.</p> <p class="code"> @@ -1201,6 +1321,86 @@ Note: The current encryption setting is tracked separately for each thread in a program. Multi-threaded programs that override the setting via the <a href="#cupsSetEncryption"><code>cupsSetEncryption</code></a> function need to do so in each thread for the same setting to be used.</p> +<h3 class="function"><span class="info"> CUPS 1.6 </span><a name="cupsEnumDests">cupsEnumDests</a></h3> +<p class="description">Enumerate available destinations with a callback function.</p> +<p class="code"> +int cupsEnumDests (<br> + unsigned flags,<br> + int msec,<br> + int *cancel,<br> + <a href="#cups_ptype_t">cups_ptype_t</a> type,<br> + <a href="#cups_ptype_t">cups_ptype_t</a> mask,<br> + <a href="#cups_dest_cb_t">cups_dest_cb_t</a> cb,<br> + void *user_data<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>flags</dt> +<dd class="description">Enumeration flags</dd> +<dt>msec</dt> +<dd class="description">Timeout in milliseconds, +-1 for indefinite</dd> +<dt>cancel</dt> +<dd class="description">Pointer to "cancel" variable</dd> +<dt>type</dt> +<dd class="description">Printer type bits</dd> +<dt>mask</dt> +<dd class="description">Mask for printer type bits</dd> +<dt>cb</dt> +<dd class="description">Callback function</dd> +<dt>user_data</dt> +<dd class="description">User data</dd> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">1 on success, 0 on failure</p> +<h4 class="discussion">Discussion</h4> +<p class="discussion">Destinations are enumerated from one or more sources. The callback function +receives the <code>user_data</code> pointer, destination name, instance, number of +options, and options which can be used as input to the <a href="#cupsAddDest"><code>cupsAddDest</code></a> +function. The function must return 1 to continue enumeration or 0 to stop.<br> +<br> +Enumeration happens on the current thread and does not return until all +destinations have been enumerated or the callback function returns 0. + +</p> +<h3 class="function"><span class="info"> CUPS 1.6 </span><a name="cupsEnumDestsBlock">cupsEnumDestsBlock</a></h3> +<p class="description">Enumerate available destinations with a block.</p> +<p class="code"> +int cupsEnumDestsBlock (<br> + unsigned flags,<br> + int timeout,<br> + int *cancel,<br> + <a href="#cups_ptype_t">cups_ptype_t</a> type,<br> + <a href="#cups_ptype_t">cups_ptype_t</a> mask,<br> + <a href="#cups_dest_block_t">cups_dest_block_t</a> block<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>flags</dt> +<dd class="description">Enumeration flags</dd> +<dt>timeout</dt> +<dd class="description">Timeout in milliseconds, 0 for indefinite</dd> +<dt>cancel</dt> +<dd class="description">Pointer to "cancel" variable</dd> +<dt>type</dt> +<dd class="description">Printer type bits</dd> +<dt>mask</dt> +<dd class="description">Mask for printer type bits</dd> +<dt>block</dt> +<dd class="description">Block</dd> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">1 on success, 0 on failure</p> +<h4 class="discussion">Discussion</h4> +<p class="discussion">Destinations are enumerated from one or more sources. The block receives the +destination name, instance, number of options, and options which can be used +as input to the <a href="#cupsAddDest"><code>cupsAddDest</code></a> function. The block must return 1 to +continue enumeration or 0 to stop.<br> +<br> +Enumeration happens on the current thread and does not return until all +destinations have been enumerated or the block returns 0. + +</p> <h3 class="function"><span class="info"> CUPS 1.4/Mac OS X 10.6 </span><a name="cupsFinishDocument">cupsFinishDocument</a></h3> <p class="description">Finish sending a document.</p> <p class="code"> @@ -2332,20 +2532,40 @@ program. Multi-threaded programs that override the user name with the name to be used.</p> <h2 class="title"><a name="TYPES">Data Types</a></h2> <h3 class="typedef"><span class="info"> CUPS 1.5/Mac OS X 10.7 </span><a name="cups_client_cert_cb_t">cups_client_cert_cb_t</a></h3> -<p class="description">Client credentials callback </p> +<p class="description">Client credentials callback +</p> <p class="code"> typedef int (*cups_client_cert_cb_t)(http_t *http, void *tls, cups_array_t *distinguished_names, void *user_data); </p> +<h3 class="typedef"><span class="info"> CUPS 1.6 </span><a name="cups_dest_block_t">cups_dest_block_t</a></h3> +<p class="description">Destination enumeration block +</p> +<p class="code"> +typedef int (*cups_dest_block_t(unsigned flags, <a href="#cups_dest_t">cups_dest_t</a> *dest); +</p> +<h3 class="typedef"><span class="info"> CUPS 1.6 </span><a name="cups_dest_cb_t">cups_dest_cb_t</a></h3> +<p class="description">Destination enumeration callback +</p> +<p class="code"> +typedef int (*cups_dest_cb_t)(void *user_data, unsigned flags, <a href="#cups_dest_t">cups_dest_t</a> *dest); +</p> <h3 class="typedef"><a name="cups_dest_t">cups_dest_t</a></h3> <p class="description">Destination</p> <p class="code"> typedef struct <a href="#cups_dest_s">cups_dest_s</a> cups_dest_t; </p> <h3 class="typedef"><span class="info"> CUPS 1.4/Mac OS X 10.6 </span><a name="cups_device_cb_t">cups_device_cb_t</a></h3> -<p class="description">Device callback </p> +<p class="description">Device callback +</p> <p class="code"> typedef void (*cups_device_cb_t)(const char *device_class, const char *device_id, const char *device_info, const char *device_make_and_model, const char *device_uri, const char *device_location, void *user_data); </p> +<h3 class="typedef"><span class="info"> CUPS 1.6 </span><a name="cups_dinfo_t">cups_dinfo_t</a></h3> +<p class="description">Destination capability and status +information </p> +<p class="code"> +typedef struct _cups_dinfo_s cups_dinfo_t; +</p> <h3 class="typedef"><a name="cups_job_t">cups_job_t</a></h3> <p class="description">Job</p> <p class="code"> @@ -2357,7 +2577,8 @@ typedef struct <a href="#cups_job_s">cups_job_s</a> cups_job_t; typedef struct <a href="#cups_option_s">cups_option_s</a> cups_option_t; </p> <h3 class="typedef"><span class="info"> CUPS 1.4/Mac OS X 10.6 </span><a name="cups_password_cb2_t">cups_password_cb2_t</a></h3> -<p class="description">New password callback </p> +<p class="description">New password callback +</p> <p class="code"> typedef const char *(*cups_password_cb2_t)(const char *prompt, http_t *http, const char *method, const char *resource, void *user_data); </p> @@ -2372,10 +2593,16 @@ typedef const char *(*cups_password_cb_t)(const char *prompt); typedef unsigned cups_ptype_t; </p> <h3 class="typedef"><span class="info"> CUPS 1.5/Mac OS X 10.7 </span><a name="cups_server_cert_cb_t">cups_server_cert_cb_t</a></h3> -<p class="description">Server credentials callback </p> +<p class="description">Server credentials callback +</p> <p class="code"> typedef int (*cups_server_cert_cb_t)(http_t *http, void *tls, cups_array_t *certs, void *user_data); </p> +<h3 class="typedef"><span class="info"> CUPS 1.6 </span><a name="cups_size_t">cups_size_t</a></h3> +<p class="description">Media Size </p> +<p class="code"> +typedef struct <a href="#cups_size_s">cups_size_s</a> cups_size_t; +</p> <h2 class="title"><a name="STRUCTURES">Structures</a></h2> <h3 class="struct"><a name="cups_dest_s">cups_dest_s</a></h3> <p class="description">Destination</p> @@ -2449,6 +2676,20 @@ typedef int (*cups_server_cert_cb_t)(http_t *http, void *tls, cups_array_t *cert <dt>value </dt> <dd class="description">Value of option</dd> </dl> +<h3 class="struct"><span class="info"> CUPS 1.6 </span><a name="cups_size_s">cups_size_s</a></h3> +<p class="description">Media Size </p> +<p class="code">struct cups_size_s {<br> + char media[128];<br> + int width, length, bottom, left, right, top;<br> +};</p> +<h4 class="members">Members</h4> +<dl> +<dt>media[128] </dt> +<dd class="description">Media name to use</dd> +<dt>top </dt> +<dd class="description">Top margin in hundredths of +millimeters</dd> +</dl> <h2 class="title"><a name="VARIABLES">Variables</a></h2> <h3 class="variable"><a name="CF_RETURNS_RETAINED">CF_RETURNS_RETAINED</a></h3> <p class="description">Get the Apple language identifier associated with a @@ -2456,11 +2697,13 @@ locale ID.</p> <p class="code">const char *locale) CF_RETURNS_RETAINED;</p> <h2 class="title"><a name="ENUMERATIONS">Constants</a></h2> <h3 class="enumeration"><a name="cups_ptype_e">cups_ptype_e</a></h3> -<p class="description">Printer type/capability bit constants</p> +<p class="description">Printer type/capability bit +constants</p> <h4 class="constants">Constants</h4> <dl> <dt>CUPS_PRINTER_AUTHENTICATED <span class="info"> CUPS 1.2/Mac OS X 10.5 </span></dt> -<dd class="description">Printer requires authentication </dd> +<dd class="description">Printer requires authentication +</dd> <dt>CUPS_PRINTER_BIND </dt> <dd class="description">Can bind output</dd> <dt>CUPS_PRINTER_BW </dt> @@ -2472,7 +2715,8 @@ locale ID.</p> <dt>CUPS_PRINTER_COLOR </dt> <dd class="description">Can do color printing</dd> <dt>CUPS_PRINTER_COMMANDS <span class="info"> CUPS 1.2/Mac OS X 10.5 </span></dt> -<dd class="description">Printer supports maintenance commands </dd> +<dd class="description">Printer supports maintenance commands +</dd> <dt>CUPS_PRINTER_COPIES </dt> <dd class="description">Can do copies</dd> <dt>CUPS_PRINTER_COVER </dt> @@ -2480,15 +2724,12 @@ locale ID.</p> <dt>CUPS_PRINTER_DEFAULT </dt> <dd class="description">Default printer on network</dd> <dt>CUPS_PRINTER_DELETE <span class="info"> CUPS 1.2/Mac OS X 10.5 </span></dt> -<dd class="description">Delete printer </dd> -<dt>CUPS_PRINTER_DISCOVERED <span class="info"> CUPS 1.3/Mac OS X 10.5 </span></dt> -<dd class="description">Printer was automatically discovered and added </dd> +<dd class="description">Delete printer +</dd> <dt>CUPS_PRINTER_DUPLEX </dt> <dd class="description">Can do duplexing</dd> <dt>CUPS_PRINTER_FAX </dt> <dd class="description">Fax queue</dd> -<dt>CUPS_PRINTER_IMPLICIT </dt> -<dd class="description">Implicit class</dd> <dt>CUPS_PRINTER_LARGE </dt> <dd class="description">Can do D/E/A1/A0</dd> <dt>CUPS_PRINTER_LOCAL </dt> @@ -2496,9 +2737,11 @@ locale ID.</p> <dt>CUPS_PRINTER_MEDIUM </dt> <dd class="description">Can do Tabloid/B/C/A3/A2</dd> <dt>CUPS_PRINTER_MFP <span class="info"> CUPS 1.4/Mac OS X 10.6 </span></dt> -<dd class="description">Printer with scanning capabilities </dd> +<dd class="description">Printer with scanning capabilities +</dd> <dt>CUPS_PRINTER_NOT_SHARED <span class="info"> CUPS 1.2/Mac OS X 10.5 </span></dt> -<dd class="description">Printer is not shared </dd> +<dd class="description">Printer is not shared +</dd> <dt>CUPS_PRINTER_PUNCH </dt> <dd class="description">Can punch output</dd> <dt>CUPS_PRINTER_REJECTING </dt> @@ -2506,7 +2749,8 @@ locale ID.</p> <dt>CUPS_PRINTER_REMOTE </dt> <dd class="description">Remote printer or class</dd> <dt>CUPS_PRINTER_SCANNER <span class="info"> CUPS 1.4/Mac OS X 10.6 </span></dt> -<dd class="description">Scanner-only device </dd> +<dd class="description">Scanner-only device +</dd> <dt>CUPS_PRINTER_SMALL </dt> <dd class="description">Can do Letter/Legal/A4</dd> <dt>CUPS_PRINTER_SORT </dt> diff --git a/doc/help/api-httpipp.html b/doc/help/api-httpipp.html index b0f94ecba..b04021e9c 100644 --- a/doc/help/api-httpipp.html +++ b/doc/help/api-httpipp.html @@ -468,6 +468,8 @@ request-uri.">httpMD5Final</a></li> <li><a href="#httpRead" title="Read data from a HTTP connection.">httpRead</a></li> <li><a href="#httpRead2" title="Read data from a HTTP connection.">httpRead2</a></li> <li><a href="#httpReconnect" title="Reconnect to a HTTP server.">httpReconnect</a></li> + <li><a href="#httpReconnect2" title="Reconnect to a HTTP server with timeout and optional +cancel.">httpReconnect2</a></li> <li><a href="#httpSeparate" title="Separate a Universal Resource Identifier into its components.">httpSeparate</a></li> <li><a href="#httpSeparate2" title="Separate a Universal Resource Identifier into its @@ -516,18 +518,21 @@ in seconds.">ippDateToTime</a></li> <li><a href="#ippEnumValue" title="Return the value associated with a given enum string.">ippEnumValue</a></li> <li><a href="#ippErrorString" title="Return a name for the given status code.">ippErrorString</a></li> <li><a href="#ippErrorValue" title="Return a status code for the given name.">ippErrorValue</a></li> - <li><a href="#ippFindAttribute" title="Find a named attribute in a request...">ippFindAttribute</a></li> - <li><a href="#ippFindNextAttribute" title="Find the next named attribute in a request...">ippFindNextAttribute</a></li> + <li><a href="#ippFindAttribute" title="Find a named attribute in a request.">ippFindAttribute</a></li> + <li><a href="#ippFindNextAttribute" title="Find the next named attribute in a request.">ippFindNextAttribute</a></li> <li><a href="#ippFirstAttribute" title="Return the first attribute in the message.">ippFirstAttribute</a></li> <li><a href="#ippGetBoolean" title="Get a boolean value for an attribute.">ippGetBoolean</a></li> <li><a href="#ippGetCollection" title="Get a collection value for an attribute.">ippGetCollection</a></li> <li><a href="#ippGetCount" title="Get the number of values in an attribute.">ippGetCount</a></li> + <li><a href="#ippGetDate" title="Get a date value for an attribute.">ippGetDate</a></li> <li><a href="#ippGetGroupTag" title="Get the group associated with an attribute.">ippGetGroupTag</a></li> <li><a href="#ippGetInteger" title="Get the integer/enum value for an attribute.">ippGetInteger</a></li> <li><a href="#ippGetName" title="Get the attribute name.">ippGetName</a></li> <li><a href="#ippGetOperation" title="Get the operation ID in an IPP message.">ippGetOperation</a></li> + <li><a href="#ippGetRange" title="Get a rangeOfInteger value from an attribute.">ippGetRange</a></li> <li><a href="#ippGetRequestId" title="Get the request ID from an IPP message.">ippGetRequestId</a></li> <li><a href="#ippGetResolution" title="Get a resolution value for an attribute.">ippGetResolution</a></li> + <li><a href="#ippGetState" title="Get the IPP message state.">ippGetState</a></li> <li><a href="#ippGetStatusCode" title="Get the status code from an IPP response or event message.">ippGetStatusCode</a></li> <li><a href="#ippGetString" title="Return the value...">ippGetString</a></li> <li><a href="#ippGetValueTag" title="Get the value tag for an attribute.">ippGetValueTag</a></li> @@ -544,6 +549,7 @@ in seconds.">ippDateToTime</a></li> <li><a href="#ippReadIO" title="Read data for an IPP message.">ippReadIO</a></li> <li><a href="#ippSetBoolean" title="Set a boolean value in an attribute.">ippSetBoolean</a></li> <li><a href="#ippSetCollection" title="Set a collection value in an attribute.">ippSetCollection</a></li> + <li><a href="#ippSetDate" title="Set a date value in an attribute.">ippSetDate</a></li> <li><a href="#ippSetGroupTag" title="Set the group tag of an attribute.">ippSetGroupTag</a></li> <li><a href="#ippSetInteger" title="Set an integer or enum value in an attribute.">ippSetInteger</a></li> <li><a href="#ippSetName" title="Set the name of an attribute.">ippSetName</a></li> @@ -552,6 +558,7 @@ in seconds.">ippDateToTime</a></li> <li><a href="#ippSetRange" title="Set a rangeOfInteger value in an attribute.">ippSetRange</a></li> <li><a href="#ippSetRequestId" title="Set the request ID in an IPP message.">ippSetRequestId</a></li> <li><a href="#ippSetResolution" title="Set a resolution value in an attribute.">ippSetResolution</a></li> + <li><a href="#ippSetState" title="Set the current state of the IPP message.">ippSetState</a></li> <li><a href="#ippSetStatusCode" title="Set the status code in an IPP response or event message.">ippSetStatusCode</a></li> <li><a href="#ippSetString" title="Set a string value in an attribute.">ippSetString</a></li> <li><a href="#ippSetValueTag" title="Set the value tag of an attribute.">ippSetValueTag</a></li> @@ -2350,6 +2357,26 @@ int httpReconnect (<br> </dl> <h4 class="returnvalue">Return Value</h4> <p class="description">0 on success, non-zero on failure</p> +<h3 class="function"><a name="httpReconnect2">httpReconnect2</a></h3> +<p class="description">Reconnect to a HTTP server with timeout and optional +cancel.</p> +<p class="code"> +int httpReconnect2 (<br> + <a href="#http_t">http_t</a> *http,<br> + int msec,<br> + int *cancel<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>http</dt> +<dd class="description">Connection to server</dd> +<dt>msec</dt> +<dd class="description">Timeout in milliseconds</dd> +<dt>cancel</dt> +<dd class="description">Pointer to "cancel" variable</dd> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">0 on success, non-zero on failure</p> <h3 class="function"><span class="info"> DEPRECATED </span><a name="httpSeparate">httpSeparate</a></h3> <p class="description">Separate a Universal Resource Identifier into its components.</p> @@ -3415,7 +3442,7 @@ void ippDeleteAttribute (<br> <p class="code"> int ippDeleteValues (<br> <a href="#ipp_t">ipp_t</a> *ipp,<br> - <a href="#ipp_attribute_t">ipp_attribute_t</a> *attr,<br> + <a href="#ipp_attribute_t">ipp_attribute_t</a> **attr,<br> int element,<br> int count<br> );</p> @@ -3433,8 +3460,10 @@ int ippDeleteValues (<br> <h4 class="returnvalue">Return Value</h4> <p class="description">1 on success, 0 on failure</p> <h4 class="discussion">Discussion</h4> -<p class="discussion">The <code>element</code> parameter specifies the first value to delete, starting at 0. It -must be less than the number of values returned by <a href="#ippGetCount"><code>ippGetCount</code></a>.<br> +<p class="discussion">The <code>element</code> parameter specifies the first value to delete, starting at +0. It must be less than the number of values returned by <a href="#ippGetCount"><code>ippGetCount</code></a>.<br> +<br> +The <code>attr</code> parameter may be modified as a result of setting the value.<br> <br> Deleting all values in an attribute deletes the attribute. @@ -3498,7 +3527,7 @@ ipp_status_t ippErrorValue (<br> <h4 class="returnvalue">Return Value</h4> <p class="description">IPP status code</p> <h3 class="function"><a name="ippFindAttribute">ippFindAttribute</a></h3> -<p class="description">Find a named attribute in a request...</p> +<p class="description">Find a named attribute in a request.</p> <p class="code"> <a href="#ipp_attribute_t">ipp_attribute_t</a> *ippFindAttribute (<br> <a href="#ipp_t">ipp_t</a> *ipp,<br> @@ -3517,7 +3546,7 @@ ipp_status_t ippErrorValue (<br> <h4 class="returnvalue">Return Value</h4> <p class="description">Matching attribute</p> <h3 class="function"><a name="ippFindNextAttribute">ippFindNextAttribute</a></h3> -<p class="description">Find the next named attribute in a request...</p> +<p class="description">Find the next named attribute in a request.</p> <p class="code"> <a href="#ipp_attribute_t">ipp_attribute_t</a> *ippFindNextAttribute (<br> <a href="#ipp_t">ipp_t</a> *ipp,<br> @@ -3603,6 +3632,27 @@ int ippGetCount (<br> </dl> <h4 class="returnvalue">Return Value</h4> <p class="description">Number of values or -1 on error</p> +<h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippGetDate">ippGetDate</a></h3> +<p class="description">Get a date value for an attribute.</p> +<p class="code"> +const <a href="#ipp_uchar_t">ipp_uchar_t</a> *ippGetDate (<br> + <a href="#ipp_attribute_t">ipp_attribute_t</a> *attr,<br> + int element<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>attr</dt> +<dd class="description">IPP attribute</dd> +<dt>element</dt> +<dd class="description">Value number (0-based)</dd> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">Date value or <code>NULL</code></p> +<h4 class="discussion">Discussion</h4> +<p class="discussion">The <code>element</code> parameter specifies which value to get from 0 to +<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a> - 1. + +</p> <h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippGetGroupTag">ippGetGroupTag</a></h3> <p class="description">Get the group associated with an attribute.</p> <p class="code"> @@ -3663,6 +3713,30 @@ ipp_op_t ippGetOperation (<br> </dl> <h4 class="returnvalue">Return Value</h4> <p class="description">Operation ID or -1 on error</p> +<h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippGetRange">ippGetRange</a></h3> +<p class="description">Get a rangeOfInteger value from an attribute.</p> +<p class="code"> +int ippGetRange (<br> + <a href="#ipp_attribute_t">ipp_attribute_t</a> *attr,<br> + int element,<br> + int *uppervalue<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>attr</dt> +<dd class="description">IPP attribute</dd> +<dt>element</dt> +<dd class="description">Value number (0-based)</dd> +<dt>uppervalue</dt> +<dd class="description">Upper value of range</dd> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">Lower value of range or -1</p> +<h4 class="discussion">Discussion</h4> +<p class="discussion">The <code>element</code> parameter specifies which value to get from 0 to +<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a> - 1. + +</p> <h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippGetRequestId">ippGetRequestId</a></h3> <p class="description">Get the request ID from an IPP message.</p> <p class="code"> @@ -3703,6 +3777,19 @@ int ippGetResolution (<br> <a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a> - 1. </p> +<h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippGetState">ippGetState</a></h3> +<p class="description">Get the IPP message state.</p> +<p class="code"> +<a href="#ipp_state_t">ipp_state_t</a> ippGetState (<br> + <a href="#ipp_t">ipp_t</a> *ipp<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>ipp</dt> +<dd class="description">IPP message</dd> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">IPP message state value</p> <h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippGetStatusCode">ippGetStatusCode</a></h3> <p class="description">Get the status code from an IPP response or event message.</p> <p class="code"> @@ -3972,6 +4059,38 @@ The <code>element</code> parameter specifies which value to set from 0 to <a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a>. </p> +<h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippSetDate">ippSetDate</a></h3> +<p class="description">Set a date value in an attribute.</p> +<p class="code"> +int ippSetDate (<br> + <a href="#ipp_t">ipp_t</a> *ipp,<br> + <a href="#ipp_attribute_t">ipp_attribute_t</a> **attr,<br> + int element,<br> + const <a href="#ipp_uchar_t">ipp_uchar_t</a> *datevalue<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>ipp</dt> +<dd class="description">IPP message</dd> +<dt>attr</dt> +<dd class="description">IPP attribute</dd> +<dt>element</dt> +<dd class="description">Value number (0-based)</dd> +<dt>datevalue</dt> +<dd class="description">Date value</dd> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">1 on success, 0 on failure</p> +<h4 class="discussion">Discussion</h4> +<p class="discussion">The <code>ipp</code> parameter refers to the IPP message containing the attribute that was +previously created using the <a href="#ippNew"><code>ippNew</code></a> or <a href="#ippNewRequest"><code>ippNewRequest</code></a> functions.<br> +<br> +The <code>attr</code> parameter may be modified as a result of setting the value.<br> +<br> +The <code>element</code> parameter specifies which value to set from 0 to +<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a>. + +</p> <h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippSetGroupTag">ippSetGroupTag</a></h3> <p class="description">Set the group tag of an attribute.</p> <p class="code"> @@ -4190,6 +4309,22 @@ The <code>element</code> parameter specifies which value to set from 0 to <a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a>. </p> +<h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippSetState">ippSetState</a></h3> +<p class="description">Set the current state of the IPP message.</p> +<p class="code"> +int ippSetState (<br> + <a href="#ipp_t">ipp_t</a> *ipp,<br> + <a href="#ipp_state_t">ipp_state_t</a> state<br> +);</p> +<h4 class="parameters">Parameters</h4> +<dl> +<dt>ipp</dt> +<dd class="description">IPP message</dd> +<dt>state</dt> +<dd class="description">IPP state value</dd> +</dl> +<h4 class="returnvalue">Return Value</h4> +<p class="description">1 on success, 0 on failure</p> <h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippSetStatusCode">ippSetStatusCode</a></h3> <p class="description">Set the status code in an IPP response or event message.</p> <p class="code"> @@ -5093,6 +5228,8 @@ are server-oriented...</p> <dd class="description">Hold a job for printing</dd> <dt>IPP_IDENTIFY_PRINTER </dt> <dd class="description">Identify-Printer (proposed IPP JPS3)</dd> +<dt>IPP_OP_CUPS_INVALID </dt> +<dd class="description">Invalid operation name for <a href="#ippOpValue"><code>ippOpValue</code></a></dd> <dt>IPP_PAUSE_PRINTER </dt> <dd class="description">Stop a printer</dd> <dt>IPP_PRINT_JOB </dt> @@ -5261,10 +5398,16 @@ are server-oriented...</p> <dd class="description">client-error-request-value-too-long</dd> <dt>IPP_SERVICE_UNAVAILABLE </dt> <dd class="description">server-error-service-unavailable</dd> +<dt>IPP_STATUS_CUPS_INVALID </dt> +<dd class="description">Invalid status name for <a href="#ippErrorValue"><code>ippErrorValue</code></a></dd> <dt>IPP_TEMPORARY_ERROR </dt> <dd class="description">server-error-temporary-error</dd> <dt>IPP_TIMEOUT </dt> <dd class="description">client-error-timeout</dd> +<dt>IPP_TOO_MANY_DOCUMENTS </dt> +<dd class="description">server-error-too-many-documents</dd> +<dt>IPP_TOO_MANY_JOBS </dt> +<dd class="description">server-error-too-many-jobs</dd> <dt>IPP_TOO_MANY_SUBSCRIPTIONS </dt> <dd class="description">client-error-too-many-subscriptions</dd> <dt>IPP_UPGRADE_REQUIRED </dt> @@ -5286,6 +5429,8 @@ are server-oriented...</p> <dd class="description">Boolean value</dd> <dt>IPP_TAG_CHARSET </dt> <dd class="description">Character set value</dd> +<dt>IPP_TAG_CUPS_INVALID </dt> +<dd class="description">Invalid tag name for <a href="#ippTagValue"><code>ippTagValue</code></a></dd> <dt>IPP_TAG_DATE </dt> <dd class="description">Date/time value</dd> <dt>IPP_TAG_DEFAULT </dt> diff --git a/doc/help/options.html b/doc/help/options.html index 0cfa74135..546f2ec1a 100644 --- a/doc/help/options.html +++ b/doc/help/options.html @@ -95,8 +95,8 @@ printing.</P> printer options using the <CODE>-o</CODE> option:</P> <PRE CLASS="command"> -lp -o landscape -o scaling=75 -o media=A4 filename.jpg -lpr -o landscape -o scaling=75 -o media=A4 filename.jpg +lp -o landscape -o fit-to-page -o media=A4 filename.jpg +lpr -o landscape -o fit-to-page -o media=A4 filename.jpg </PRE> <P>The available printer options vary depending on the printer. @@ -662,117 +662,5 @@ lpr -o nowrap filename </PRE> -<H2 CLASS="title"><SPAN CLASS="info">Not Supported on Mac OS X</SPAN><A NAME="IMAGEOPTIONS">Image Options</A></H2> - -<P>CUPS supports several options that are only used when printing -image files. These options have absolutely no effect on PostScript, PDF, -HP-GL/2, or text files.</P> - -<H3><A NAME="position">Positioning Images</A></H3> - -<P>The <CODE>-o position=name</CODE> option specifies the position of the -image on the page: - -<UL> - - <LI><CODE>center</CODE> - Center the image on the page (default) - - <LI><CODE>top</CODE> - Print the image centered at the top of the page - - <LI><CODE>left</CODE> - Print the image centered on the left of page - - <LI><CODE>right</CODE> - Print the image centered on the right of the page - - <LI><CODE>top-left</CODE> - Print the image at the top left corner of - the page - - <LI><CODE>top-right</CODE> - Print the image at the top right corner of - the page - - <LI><CODE>bottom</CODE> - Print the image centered at the bottom of - the page - - <LI><CODE>bottom-left</CODE> - Print the image at the bottom left - corner of the page - - <LI><CODE>bottom-right</CODE> - Print the image at the bottom right - corner of the page - -</UL> - -<H3><A NAME="scaling">Scaling Images</A></H3> - -<P>The <CODE>-o scaling=percent</CODE>, <CODE>-o -ppi=value</CODE>, and <CODE>-o natural-scaling=percent</CODE> -options change the size of a printed image: - -<PRE CLASS="command"> -lp -o scaling=<EM>percent</EM> filename -lp -o ppi=<EM>value</EM> filename -lpr -o natural-scaling=<EM>percent</EM> filename -</PRE> - -<P>The <CODE>scaling=percent</CODE> value is a number from 1 to 800 -specifying the size in relation to the page (<EM>not</EM> the image.) A -scaling of 100 percent will fill the page as completely as the image -aspect ratio allows. A scaling of 200 percent will print on up to 4 -pages. - -<P>The <CODE>ppi=value</CODE> value is a number from 1 to 1200 specifying the -resolution of the image in pixels per inch. An image that is 3000x2400 -pixels will print 10x8 inches at 300 pixels per inch, for example. If -the specified resolution makes the image larger than the page, multiple -pages will be printed to satisfy the request. - -<P>The <CODE>natural-scaling=percent</CODE> value is a number -from 1 to 800 specifying the size in relation to the natural -image size. A scaling of 100 percent will print the image at its -natural size, while a scaling of 50 percent will print the image -at half its natural size. If the specified scaling makes the -image larger than the page, multiple pages will be printed to -satisfy the request. - - -<H2 CLASS="title"><A NAME="HPGL2OPTIONS">HP-GL/2 Options</A></H2> - -<P>CUPS supports several options that are only used when printing -HP-GL/2 files. These options have absolutely no effect on PostScript, PDF, -image, or text files.</P> - -<H3><A NAME="blackplot">Printing in Black</A></H3> - -<P>The <CODE>-o blackplot</CODE> option specifies that all pens should -plot in black:</P> - -<PRE CLASS="command"> -lp -o blackplot filename -lpr -o blackplot filename -</PRE> - -<P>The default is to use the colors defined in the plot file or the -standard pen colors defined in the HP-GL/2 reference manual from -Hewlett Packard. - -<H3><A NAME="penwidth">Setting the Default Pen Width</A></H3> - -<P>The <CODE>-o penwidth=value</CODE> option specifies the default pen -width for HP-GL/2 files:</P> - -<PRE CLASS="command"> -lp -o penwidth=<EM>value</EM> filename -lpr -o penwidth=<EM>value</EM> filename -</PRE> - -<P>The pen width <CODE>value</CODE> specifies the pen width in micrometers. -The default value of 1000 produces lines that are 1 millimeter in width. -Specifying a pen width of 0 produces lines that are exactly 1 pixel wide.</P> - -<BLOCKQUOTE><B>Note:</B> - -<P>This option is ignored when the pen widths are set in the plot -file. - -</BLOCKQUOTE> - </BODY> </HTML> diff --git a/doc/help/policies.html b/doc/help/policies.html index 14a5b4b87..18f4c80e9 100644 --- a/doc/help/policies.html +++ b/doc/help/policies.html @@ -36,7 +36,7 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th 4 Require user @OWNER @SYSTEM 5 Order deny,allow 6 </Limit> - 7 + 7 8 # All administration operations require an administrator to authenticate... 9 <Limit CUPS-Add-Printer CUPS-Delete-Printer CUPS-Add-Class @@ -45,7 +45,7 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th 11 Require user @SYSTEM 12 Order deny,allow 13 </Limit> -14 +14 15 # All printer operations require a printer operator to authenticate... 16 <Limit Pause-Printer Resume-Printer @@ -59,14 +59,14 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th 18 Require user <em>varies by OS</em> 19 Order deny,allow 20 </Limit> -21 +21 22 # Only the owner or an administrator can cancel or authenticate a job... 23 <Limit Cancel-Job CUPS-Authenticate-Job> 24 Require user @OWNER @SYSTEM 25 Order deny,allow 26 </Limit> -27 +27 28 <Limit All> 29 Order deny,allow 30 </Limit> @@ -106,7 +106,7 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th 11 Require user @SYSTEM 12 Order deny,allow 13 </Limit> -14 +14 15 # All printer operations require a printer operator to authenticate... 16 <Limit Pause-Printer Resume-Printer @@ -380,12 +380,12 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th <TD>Prints a job after others.</TD> </TR> <TR> - <TD NOWRAP><TT>CUPS-Get-Default</TT></TD> + <TD NOWRAP><TT>CUPS-Get-Default</TT> *</TD> <TD>Yes</TD> <TD>Gets the server/network default printer or class.</TD> </TR> <TR> - <TD NOWRAP><TT>CUPS-Get-Printers</TT></TD> + <TD NOWRAP><TT>CUPS-Get-Printers</TT> *</TD> <TD>Yes</TD> <TD>Gets a list of printers and/or classes.</TD> </TR> @@ -395,12 +395,12 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th <TD>Adds or modifies a printer.</TD> </TR> <TR> - <TD NOWRAP><TT>CUPS-Delete-Printer</TT></TD> + <TD NOWRAP><TT>CUPS-Delete-Printer</TT> *</TD> <TD>Yes</TD> <TD>Removes a printer.</TD> </TR> <TR> - <TD NOWRAP><TT>CUPS-Get-Classes</TT></TD> + <TD NOWRAP><TT>CUPS-Get-Classes</TT> *</TD> <TD>Yes</TD> <TD>Gets a list of classes.</TD> </TR> @@ -410,7 +410,7 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th <TD>Adds or modifies a class.</TD> </TR> <TR> - <TD NOWRAP><TT>CUPS-Delete-Class</TT></TD> + <TD NOWRAP><TT>CUPS-Delete-Class</TT> *</TD> <TD>Yes</TD> <TD>Removes a class.</TD> </TR> @@ -427,17 +427,17 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th attribute to false.</TD> </TR> <TR> - <TD NOWRAP><TT>CUPS-Set-Default</TT></TD> + <TD NOWRAP><TT>CUPS-Set-Default</TT> *</TD> <TD>Yes</TD> <TD>Sets the server/network default printer or class.</TD> </TR> <TR> - <TD NOWRAP><TT>CUPS-Get-Devices</TT></TD> + <TD NOWRAP><TT>CUPS-Get-Devices</TT> *</TD> <TD>Yes</TD> <TD>Gets a list of printer devices.</TD> </TR> <TR> - <TD NOWRAP><TT>CUPS-Get-PPDs</TT></TD> + <TD NOWRAP><TT>CUPS-Get-PPDs</TT> *</TD> <TD>Yes</TD> <TD>Gets a list of printer drivers or manufacturers.</TD> </TR> @@ -459,6 +459,7 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th </TBODY> </TABLE></DIV> +<P>* = These operations only apply to the default policy.</P> <H2 CLASS="title"><A NAME="CREATING">Creating Your Own Policies</A></H2> @@ -556,7 +557,7 @@ Allow from @LOCAL</PRE></TD> 5 Order allow,deny 6 Allow from 10.0.2.0/24 7 </Limit> - 8 + 8 9 # All administration operations require a lab technician or an administrator to authenticate... 10 <Limit Pause-Printer Resume-Printer diff --git a/doc/help/ppd-compiler.html b/doc/help/ppd-compiler.html index 67fdfbc0e..b946ff652 100644 --- a/doc/help/ppd-compiler.html +++ b/doc/help/ppd-compiler.html @@ -345,7 +345,7 @@ div.contents ul.subcontents li { PPD compiler documentation for CUPS. - Copyright 2007-2010 by Apple Inc. + Copyright 2007-2012 by Apple Inc. Copyright 1997-2007 by Easy Software Products. These coded instructions, statements, and computer programs are the @@ -361,6 +361,12 @@ div.contents ul.subcontents li { (PPD) file compiler. The PPD compiler generates PPD files from simple text files that describe the features and capabilities of one or more printers.</P> +<BLOCKQUOTE><B>Note:</B> + +<P>The PPD compiler and related tools are deprecated and will be removed in a future release of CUPS.</P> + +</BLOCKQUOTE> + <div class='summary'><table summary='General Information'> <tbody> <tr> diff --git a/doc/help/ref-client-conf.html b/doc/help/ref-client-conf.html index 5b4e7e772..a69b568d3 100644 --- a/doc/help/ref-client-conf.html +++ b/doc/help/ref-client-conf.html @@ -71,5 +71,20 @@ ServerName foo.bar.com:8631 present, only the last one is used. This directive is not supported on Mac OS X 10.7 or later.</P> </BLOCKQUOTE> + +<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.6</SPAN><A NAME="User">User</A></H2> + +<H3>Examples</H3> + +<PRE CLASS="command"> +User joe +User bob +</PRE> + +<H3>Description</H3> + +<P>The <CODE>User</CODE> directive sets the user name to use. The default is the username associated with the current login.</P> + + </BODY> </HTML> diff --git a/doc/help/ref-cupsd-conf.html.in b/doc/help/ref-cupsd-conf.html.in index d14d0d7c0..38f00d2a3 100644 --- a/doc/help/ref-cupsd-conf.html.in +++ b/doc/help/ref-cupsd-conf.html.in @@ -1675,6 +1675,21 @@ copies to 100.</P> </BLOCKQUOTE> +<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.6</SPAN><A NAME="MaxHoldTime">MaxHoldTime</A></H2> + +<H3>Examples</H3> + +<PRE CLASS="command"> +MaxHoldTime 10800 +MaxHoldTime 0 +</PRE> + +<H3>Description</H3> + +<P>The <CODE>MaxHoldTime</CODE> directive controls the maximum number of seconds allowed for a job to remain in the "indefinite" hold state. The job is canceled automatically if it remains held indefinitely longer than the specified number of seconds.</P> + +<p>The default setting is 0 which disables this functionality.</P> + <H2 CLASS="title"><A NAME="MaxJobs">MaxJobs</A></H2> diff --git a/doc/help/spec-ipp.html b/doc/help/spec-ipp.html index 01d4086df..2b6c7a3d0 100644 --- a/doc/help/spec-ipp.html +++ b/doc/help/spec-ipp.html @@ -2277,23 +2277,23 @@ defined: </ul> -<h4><a name="page-bottom">page-bottom (integer(0:MAX))</a></h4> +<h4><a name="page-bottom">page-bottom (integer(0:MAX))</a><span class="info">Deprecated</span></h4> <p>The page-bottom attribute specifies the bottom margin in points (72 points equals 1 inch). The default value is the device physical margin. -<h4><a name="page-label">page-label (text(MAX))</a><span class='info'>CUPS 1.1.7</span></h4> +<h4><a name="page-label">page-label (text(MAX))</a><span class='info'>Deprecated</span></h4> <p>The page-label attribute provides a text value to place in the header and footer on each page. If a classification level is set on the server, then this classification is printed before the page label. -<h4><a name="page-left">page-left (integer(0:MAX))</a></h4> +<h4><a name="page-left">page-left (integer(0:MAX))</a><span class="info">Deprecated</span></h4> <p>The page-left attribute specifies the left margin in points (72 points equals 1 inch). The default value is the device physical margin. -<h4><a name="page-right">page-right (integer(0:MAX))</a></h4> +<h4><a name="page-right">page-right (integer(0:MAX))</a><span class="info">Deprecated</span></h4> <p>The page-right attribute specifies the right margin in points (72 points equals 1 inch). The default value is the device physical margin. @@ -2304,18 +2304,18 @@ equals 1 inch). The default value is the device physical margin. supported keywords are "all", "even", and "odd". The default value is "all". -<h4><a name="page-top">page-top (integer(0:MAX))</a></h4> +<h4><a name="page-top">page-top (integer(0:MAX))</a><span class="info">Deprecated</span></h4> <p>The page-top attribute specifies the top margin in points (72 points equals 1 inch). The default value is the device physical margin. -<h4><a name="prettyprint">prettyprint (boolean)</a></h4> +<h4><a name="prettyprint">prettyprint (boolean)</a><span class="info">Deprecated</span></h4> <p>The prettyprint attribute specifies whether text files should be printed with a shaded header and keyword highlighting (prettyprint=true) or without additional formatting (prettyprint=false). The default value is false. -<h4><a name="wrap">wrap (boolean)</a></h4> +<h4><a name="wrap">wrap (boolean)</a><span class="info">Deprecated</span></h4> <p>The wrap attribute specifies whether long lines should be wrapped (wrap=true) or not (wrap=false) when printing text files. The default diff --git a/doc/help/spec-ppd.html b/doc/help/spec-ppd.html index 21a980118..4521543bc 100644 --- a/doc/help/spec-ppd.html +++ b/doc/help/spec-ppd.html @@ -413,6 +413,7 @@ div.contents ul.subcontents li { <li><a href="#cupsManualCopies">cupsManualCopies</a></li> <li><a href="#cupsMarkerName">cupsMarkerName</a></li> <li><a href="#cupsMarkerNotice">cupsMarkerNotice</a></li> + <li><a href="#cupsMaxCopies">cupsMaxCopies</a></li> <li><a href="#cupsModelNumber">cupsModelNumber</a></li> <li><a href="#cupsPJLCharset">cupsPJLCharset</a></li> <li><a href="#cupsPJLDisplay">cupsPJLDisplay</a></li> @@ -1746,6 +1747,19 @@ are approximate".</p> *cupsMarkerNotice: "Supply levels are approximate." </pre> +<h3><span class='info'>CUPS 1.6</span><a name='cupsMaxCopies'>cupsMaxCopies</a></h3> + +<p class='summary'>*cupsMaxCopies: integer</p> + +<p>This integer keyword notifies the filters that the destination printer supports up to N copies in hardware. The default value is <code>9999</code>.</p> + +<p>Example:</p> + +<pre class='command'> +<em>*% Tell the RIP filters we can do up to 99 copies</em> +*cupsMaxCopies: 99 +</pre> + <h3><a name='cupsModelNumber'>cupsModelNumber</a></h3> <p class='summary'>*cupsModelNumber: number</p> @@ -2203,6 +2217,15 @@ the device.</p> <h2 class='title'><a name='HISTORY'>Change History</a></h2> +<h3>Changes in CUPS 1.6</h3> + +<ul> + + <li>Added <a href="#cupsMaxCopies"><tt>cupsMaxCopies</tt></a> keyword.</li> + +</ul> + + <h3>Changes in CUPS 1.5</h3> <ul> diff --git a/filter/ppd-compiler.header b/filter/ppd-compiler.header index 4af7865f8..2caf3aecd 100644 --- a/filter/ppd-compiler.header +++ b/filter/ppd-compiler.header @@ -3,7 +3,7 @@ PPD compiler documentation for CUPS. - Copyright 2007-2010 by Apple Inc. + Copyright 2007-2012 by Apple Inc. Copyright 1997-2007 by Easy Software Products. These coded instructions, statements, and computer programs are the @@ -19,6 +19,12 @@ (PPD) file compiler. The PPD compiler generates PPD files from simple text files that describe the features and capabilities of one or more printers.</P> +<BLOCKQUOTE><B>Note:</B> + +<P>The PPD compiler and related tools are deprecated and will be removed in a future release of CUPS.</P> + +</BLOCKQUOTE> + <div class='summary'><table summary='General Information'> <tbody> <tr> diff --git a/filter/pstops.c b/filter/pstops.c index 16628627a..1688d9287 100644 --- a/filter/pstops.c +++ b/filter/pstops.c @@ -128,7 +128,7 @@ typedef struct /**** Document information ****/ *ap_page_size; /* AP_FIRSTPAGE_PageSize value */ int collate, /* Collate copies? */ emit_jcl, /* Emit JCL commands? */ - fitplot; /* Fit pages to media */ + fit_to_page; /* Fit pages to media */ const char *input_slot, /* InputSlot value */ *manual_feed, /* ManualFeed value */ *media_color, /* MediaColor value */ @@ -978,7 +978,7 @@ copy_dsc(cups_file_t *fp, /* I - File to read from */ puts("%%Trailer"); printf("%%%%Pages: %d\n", cupsArrayCount(doc->pages)); - if (doc->number_up > 1 || doc->fitplot) + if (doc->number_up > 1 || doc->fit_to_page) printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom, PageRight, PageTop); else @@ -1382,7 +1382,7 @@ copy_page(cups_file_t *fp, /* I - File to read from */ memcpy(bounding_box, doc->bounding_box, sizeof(bounding_box)); } - else if (doc->number_up == 1 && !doc->fitplot && Orientation) + else if (doc->number_up == 1 && !doc->fit_to_page && Orientation) { int temp_bbox[4]; /* Temporary bounding box */ @@ -1480,7 +1480,7 @@ copy_page(cups_file_t *fp, /* I - File to read from */ * %%IncludeFeature: *MainKeyword OptionKeyword */ - if (doc->number_up == 1 &&!doc->fitplot) + if (doc->number_up == 1 &&!doc->fit_to_page) pageinfo->num_options = include_feature(ppd, line, pageinfo->num_options, &(pageinfo->options)); @@ -1557,14 +1557,14 @@ copy_page(cups_file_t *fp, /* I - File to read from */ { feature = 1; - if (doc->number_up > 1 || doc->fitplot) + if (doc->number_up > 1 || doc->fit_to_page) continue; } else if (!strncmp(line, "%%EndFeature", 12)) { feature = 0; - if (doc->number_up > 1 || doc->fitplot) + if (doc->number_up > 1 || doc->fit_to_page) continue; } else if (!strncmp(line, "%%IncludeFeature:", 17)) @@ -1580,7 +1580,7 @@ copy_page(cups_file_t *fp, /* I - File to read from */ if (line[0] != '%' && !feature) break; - if (!feature || (doc->number_up == 1 && !doc->fitplot)) + if (!feature || (doc->number_up == 1 && !doc->fit_to_page)) doc_write(doc, line, linelen); } @@ -1803,7 +1803,7 @@ copy_setup(cups_file_t *fp, /* I - File to read from */ * %%IncludeFeature: *MainKeyword OptionKeyword */ - if (doc->number_up == 1 && !doc->fitplot) + if (doc->number_up == 1 && !doc->fit_to_page) num_options = include_feature(ppd, line, num_options, &options); } else if (strncmp(line, "%%BeginSetup", 12)) @@ -1868,7 +1868,7 @@ copy_trailer(cups_file_t *fp, /* I - File to read from */ fprintf(stderr, "DEBUG: Wrote %d pages...\n", number); printf("%%%%Pages: %d\n", number); - if (doc->number_up > 1 || doc->fitplot) + if (doc->number_up > 1 || doc->fit_to_page) printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom, PageRight, PageTop); else @@ -2330,6 +2330,7 @@ set_pstops_options( ppd_option_t *option; /* PPD option */ ppd_choice_t *choice; /* PPD choice */ const char *content_type; /* Original content type */ + int max_copies; /* Maximum number of copies supported */ /* @@ -2421,7 +2422,7 @@ set_pstops_options( doc->emit_jcl = 1; /* - * fitplot/fit-to-page/ipp-attribute-fidelity + * fit-to-page/ipp-attribute-fidelity * * (Only for original PostScript content) */ @@ -2431,16 +2432,13 @@ set_pstops_options( if (!_cups_strcasecmp(content_type, "application/postscript")) { - if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && + if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && !_cups_strcasecmp(val, "true")) - doc->fitplot = 1; - else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && - !_cups_strcasecmp(val, "true")) - doc->fitplot = 1; + doc->fit_to_page = 1; else if ((val = cupsGetOption("ipp-attribute-fidelity", num_options, options)) != NULL && !_cups_strcasecmp(val, "true")) - doc->fitplot = 1; + doc->fit_to_page = 1; } /* @@ -2592,7 +2590,16 @@ set_pstops_options( * Now figure out if we have to force collated copies, etc. */ - if (ppd && ppd->manual_copies && Duplex && doc->copies > 1) + if ((attr = ppdFindAttr(ppd, "cupsMaxCopies", NULL)) != NULL) + max_copies = atoi(attr->value); + else if (ppd && ppd->manual_copies) + max_copies = 1; + else + max_copies = 9999; + + if (doc->copies > max_copies) + doc->collate = 1; + else if (ppd && ppd->manual_copies && Duplex && doc->copies > 1) { /* * Force collated copies when printing a duplexed document to @@ -2616,7 +2623,8 @@ set_pstops_options( doc->slow_collate = 1; - if ((choice = ppdFindMarkedChoice(ppd, "Collate")) != NULL && + if (doc->copies <= max_copies && + (choice = ppdFindMarkedChoice(ppd, "Collate")) != NULL && !_cups_strcasecmp(choice->choice, "True")) { /* @@ -2773,7 +2781,7 @@ start_nup(pstops_doc_t *doc, /* I - Document information */ pagew = PageRight - PageLeft; pagel = PageTop - PageBottom; - if (doc->fitplot) + if (doc->fit_to_page) { bboxx = bounding_box[0]; bboxy = bounding_box[1]; @@ -2820,18 +2828,18 @@ start_nup(pstops_doc_t *doc, /* I - Document information */ doc_printf(doc, "%.1f 0.0 translate -1 1 scale\n", PageWidth); /* - * Offset and scale as necessary for fitplot/fit-to-page/number-up... + * Offset and scale as necessary for fit_to_page/fit-to-page/number-up... */ if (Duplex && doc->number_up > 1 && ((number / doc->number_up) & 1)) doc_printf(doc, "%.1f %.1f translate\n", PageWidth - PageRight, PageBottom); - else if (doc->number_up > 1 || doc->fitplot) + else if (doc->number_up > 1 || doc->fit_to_page) doc_printf(doc, "%.1f %.1f translate\n", PageLeft, PageBottom); switch (doc->number_up) { default : - if (doc->fitplot) + if (doc->fit_to_page) { w = pagew; l = w * bboxl / bboxw; @@ -3157,7 +3165,7 @@ start_nup(pstops_doc_t *doc, /* I - Document information */ doc_puts(doc, "grestore\n"); } - if (doc->fitplot) + if (doc->fit_to_page) { /* * Offset the page by its bounding box... @@ -3167,7 +3175,7 @@ start_nup(pstops_doc_t *doc, /* I - Document information */ -bounding_box[1]); } - if (doc->fitplot || doc->number_up > 1) + if (doc->fit_to_page || doc->number_up > 1) { /* * Clip the page to the page's bounding box... diff --git a/filter/spec-ppd.shtml b/filter/spec-ppd.shtml index 670e89913..6daa361fe 100644 --- a/filter/spec-ppd.shtml +++ b/filter/spec-ppd.shtml @@ -1307,6 +1307,19 @@ are approximate".</p> *cupsMarkerNotice: "Supply levels are approximate." </pre> +<h3><span class='info'>CUPS 1.6</span><a name='cupsMaxCopies'>cupsMaxCopies</a></h3> + +<p class='summary'>*cupsMaxCopies: integer</p> + +<p>This integer keyword notifies the filters that the destination printer supports up to N copies in hardware. The default value is <code>9999</code>.</p> + +<p>Example:</p> + +<pre class='command'> +<em>*% Tell the RIP filters we can do up to 99 copies</em> +*cupsMaxCopies: 99 +</pre> + <h3><a name='cupsModelNumber'>cupsModelNumber</a></h3> <p class='summary'>*cupsModelNumber: number</p> @@ -1764,6 +1777,15 @@ the device.</p> <h2 class='title'><a name='HISTORY'>Change History</a></h2> +<h3>Changes in CUPS 1.6</h3> + +<ul> + + <li>Added <a href="#cupsMaxCopies"><tt>cupsMaxCopies</tt></a> keyword.</li> + +</ul> + + <h3>Changes in CUPS 1.5</h3> <ul> diff --git a/man/client.conf.man.in b/man/client.conf.man.in index ca659ff54..e7df54e2a 100644 --- a/man/client.conf.man.in +++ b/man/client.conf.man.in @@ -3,7 +3,7 @@ .\" .\" client.conf man page for CUPS. .\" -.\" Copyright 2007-2011 by Apple Inc. +.\" Copyright 2007-2012 by Apple Inc. .\" Copyright 2006 by Easy Software Products. .\" .\" These coded instructions, statements, and computer programs are the @@ -12,7 +12,7 @@ .\" which should have been included with this file. If this file is .\" file is missing or damaged, see the license at "http://www.cups.org/". .\" -.TH client.conf 5 "CUPS" "2 September 2011" "Apple Inc." +.TH client.conf 5 "CUPS" "15 February 2012" "Apple Inc." .SH NAME client.conf \- client configuration file for cups .SH DESCRIPTION @@ -46,10 +46,14 @@ ServerName /domain/socket .br Specifies the address and optionally the port to use when connecting to the server. \fBNote: Not supported on Mac OS X 10.7 or later.\fR +.TP 5 +User name +.br +Specifies the default user name to use for requests. .SH SEE ALSO http://localhost:631/help .SH COPYRIGHT -Copyright 2007-2011 by Apple Inc. +Copyright 2007-2012 by Apple Inc. .\" .\" End of "$Id: client.conf.man.in 6649 2007-07-11 21:46:42Z mike $". .\" diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in index d1d27cca4..b5d790f8b 100644 --- a/man/cupsd.conf.man.in +++ b/man/cupsd.conf.man.in @@ -12,7 +12,7 @@ .\" which should have been included with this file. If this file is .\" file is missing or damaged, see the license at "http://www.cups.org/". .\" -.TH cupsd.conf 5 "CUPS" "6 January 2012" "Apple Inc." +.TH cupsd.conf 5 "CUPS" "15 February 2012" "Apple Inc." .SH NAME cupsd.conf \- server configuration file for cups .SH DESCRIPTION @@ -386,6 +386,11 @@ MaxCopies number .br Specifies the maximum number of copies that a user can print of each job. .TP 5 +MaxHoldTime seconds +.br +Specifies the maximum time a job may remain in the "indefinite" hold state +before it is canceled. Set to 0 to disable cancellation of held jobs. +.TP 5 MaxJobs number .br Specifies the maximum number of simultaneous jobs to support. @@ -634,7 +639,7 @@ Specifies whether the web interface is enabled. .br http://localhost:631/help .SH COPYRIGHT -Copyright 2007-2011 by Apple Inc. +Copyright 2007-2012 by Apple Inc. .\" .\" End of "$Id: cupsd.conf.man.in 7935 2008-09-11 01:54:11Z mike $". .\" diff --git a/man/ppdc.man b/man/ppdc.man index bfed12f1f..8f30bfb56 100644 --- a/man/ppdc.man +++ b/man/ppdc.man @@ -3,7 +3,7 @@ .\" .\" ppdc man page for CUPS. .\" -.\" Copyright 2007-2011 by Apple Inc. +.\" Copyright 2007-2012 by Apple Inc. .\" Copyright 1997-2007 by Easy Software Products. .\" .\" These coded instructions, statements, and computer programs are the @@ -12,7 +12,7 @@ .\" which should have been included with this file. If this file is .\" file is missing or damaged, see the license at "http://www.cups.org/". .\" -.TH ppdc 1 "CUPS" "10 October 2008" "Apple Inc." +.TH ppdc 1 "CUPS" "15 February 2012" "Apple Inc." .SH NAME ppdc \- cups ppd compiler .SH SYNOPSIS @@ -31,7 +31,8 @@ ppdc \- cups ppd compiler .I source-file .SH DESCRIPTION \fIppdc\fR compiles PPDC source files into one or more PPD -files. +files. \fBThis program is deprecated and will be removed in a future release of +CUPS.\fR .PP The \fI-D\fR option sets the named variable for use in the source file. It is equivalent to using the #define directive @@ -74,7 +75,7 @@ ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1), ppdcfile(5) .br http://localhost:631/help .SH COPYRIGHT -Copyright 2007-2011 by Apple Inc. +Copyright 2007-2012 by Apple Inc. .\" .\" End of "$Id: ppdc.man 7600 2008-05-20 21:06:23Z mike $". .\" diff --git a/scheduler/Makefile b/scheduler/Makefile index e92e6048f..72c7f6488 100644 --- a/scheduler/Makefile +++ b/scheduler/Makefile @@ -17,6 +17,7 @@ include ../Makedefs CUPSDOBJS = \ auth.o \ + avahi.o \ banners.o \ cert.o \ classes.o \ @@ -39,7 +40,8 @@ CUPSDOBJS = \ server.o \ statbuf.o \ subscriptions.o \ - sysman.o + sysman.o \ + timeout.o LIBOBJS = \ filter.o \ mime.o \ diff --git a/scheduler/auth.c b/scheduler/auth.c index 044a3c3c6..732fc324e 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -3,7 +3,7 @@ * * Authorization routines for the CUPS scheduler. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * This file contains Kerberos support code, copyright 2006 by @@ -130,8 +130,8 @@ static void to64(char *s, unsigned long v, int n); #if HAVE_LIBPAM typedef struct cupsd_authdata_s /**** Authentication data ****/ { - char username[33], /* Username string */ - password[33]; /* Password string */ + char username[HTTP_MAX_VALUE], /* Username string */ + password[HTTP_MAX_VALUE]; /* Password string */ } cupsd_authdata_t; #endif /* HAVE_LIBPAM */ @@ -322,8 +322,10 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ int type; /* Authentication type */ const char *authorization; /* Pointer into Authorization string */ char *ptr, /* Pointer into string */ - username[256], /* Username string */ - password[33]; /* Password string */ + username[HTTP_MAX_VALUE], + /* Username string */ + password[HTTP_MAX_VALUE]; + /* Password string */ cupsd_cert_t *localuser; /* Certificate username */ char nonce[HTTP_MAX_VALUE], /* Nonce value from client */ md5[33], /* MD5 password */ diff --git a/scheduler/avahi.c b/scheduler/avahi.c new file mode 100644 index 000000000..5761317bf --- /dev/null +++ b/scheduler/avahi.c @@ -0,0 +1,441 @@ +/* + * "$Id$" + * + * Avahi poll implementation for the CUPS scheduler. + * + * Copyright (C) 2010, 2011 Red Hat, Inc. + * Authors: + * Tim Waugh <twaugh@redhat.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Contents: + * + * watch_read_cb - Read callback for file descriptor + * watch_write_cb - Write callback for file descriptor + * watched_fd_add_select() - Call cupsdAddSelect() as needed + * watch_new() - Create a new file descriptor watch + * watch_free() - Free a file descriptor watch + * watch_update() - Update watched events for a file descriptor + * watch_get_events() - Get events that happened for a file descriptor + * timeout_cb() - Run a timed Avahi callback + * timeout_new() - Set a wakeup time + * timeout_update() - Update the expiration time for a timeout + * timeout_free() - Free a timeout + * compare_watched_fds() - Compare watched file descriptors for array sorting + * avahi_cups_poll_new() - Create a new Avahi main loop object for CUPS + * avahi_cups_poll_free() - Free an Avahi main loop object for CUPS + * avahi_cups_poll_get() - Get the abstract poll API structure + */ + +#include <config.h> + +#ifdef HAVE_AVAHI /* Applies to entire file... */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" + +#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO) +# include <malloc.h> +#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */ + +#ifdef HAVE_AVAHI +# include <avahi-common/timeval.h> +#endif /* HAVE_AVAHI */ + + +typedef struct +{ + AvahiCupsPoll *cups_poll; + + int fd; + AvahiWatchEvent occurred; + cups_array_t *watches; +} cupsd_watched_fd_t; + +struct AvahiWatch +{ + cupsd_watched_fd_t *watched_fd; + + AvahiWatchEvent events; + AvahiWatchCallback callback; + void *userdata; +}; + +struct AvahiTimeout +{ + AvahiCupsPoll *cups_poll; + AvahiTimeoutCallback callback; + void *userdata; + cupsd_timeout_t *cupsd_timeout; +}; + +/* + * Local functions... + */ + +static AvahiWatch * watch_new(const AvahiPoll *api, + int fd, + AvahiWatchEvent events, + AvahiWatchCallback callback, + void *userdata); +static void watch_free(AvahiWatch *watch); +static void watch_update(AvahiWatch *watch, + AvahiWatchEvent events); +static AvahiWatchEvent watch_get_events(AvahiWatch *watch); + + +/* + * 'watch_read_cb' - Read callback for file descriptor + */ + +static void +watch_read_cb (void *userdata) +{ + AvahiWatch *watch; + cupsd_watched_fd_t *watched_fd = userdata; + watched_fd->occurred |= AVAHI_WATCH_IN; + for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches); + watch; + watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches)) + { + if (watch->events & watched_fd->occurred) + { + (watch->callback) (watch, watched_fd->fd, + AVAHI_WATCH_IN, watch->userdata); + watched_fd->occurred &= ~AVAHI_WATCH_IN; + break; + } + } +} + + +/* + * 'watch_write_cb' - Write callback for file descriptor + */ + +static void +watch_write_cb (void *userdata) +{ + AvahiWatch *watch; + cupsd_watched_fd_t *watched_fd = userdata; + watched_fd->occurred |= AVAHI_WATCH_OUT; + for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches); + watch; + watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches)) + { + if (watch->events & watched_fd->occurred) + { + (watch->callback) (watch, watched_fd->fd, + AVAHI_WATCH_OUT, watch->userdata); + watched_fd->occurred &= ~AVAHI_WATCH_OUT; + break; + } + } +} + + +/* + * 'watched_fd_add_select' - Call cupsdAddSelect() as needed + */ + +static int /* O - Watches? */ +watched_fd_add_select (cupsd_watched_fd_t *watched_fd) +{ + AvahiWatch *watch; + cupsd_selfunc_t read_cb = NULL, write_cb = NULL; + int any_watches = 0; + + for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches); + watch; + watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches)) + { + any_watches = 1; + if (watch->events & (AVAHI_WATCH_IN | + AVAHI_WATCH_ERR | + AVAHI_WATCH_HUP)) + { + read_cb = (cupsd_selfunc_t)watch_read_cb; + if (write_cb != NULL) + break; + } + + if (watch->events & AVAHI_WATCH_OUT) + { + write_cb = (cupsd_selfunc_t)watch_write_cb; + if (read_cb != NULL) + break; + } + } + + if (read_cb || write_cb) + cupsdAddSelect (watched_fd->fd, read_cb, write_cb, watched_fd); + else + cupsdRemoveSelect (watched_fd->fd); + + return (any_watches); +} + +/* + * 'watch_new' - Create a new file descriptor watch + */ + +static AvahiWatch * +watch_new (const AvahiPoll *api, + int fd, + AvahiWatchEvent events, + AvahiWatchCallback callback, + void *userdata) +{ + cupsd_watched_fd_t key, *watched_fd; + AvahiCupsPoll *cups_poll = api->userdata; + AvahiWatch *watch = malloc(sizeof(AvahiWatch)); + if (watch == NULL) + return (NULL); + + watch->events = events; + watch->callback = callback; + watch->userdata = userdata; + + key.fd = fd; + watched_fd = cupsArrayFind (cups_poll->watched_fds, &key); + if (watched_fd == NULL) + { + watched_fd = malloc(sizeof(cupsd_watched_fd_t)); + if (watched_fd == NULL) + { + free (watch); + return (NULL); + } + + watched_fd->fd = fd; + watched_fd->occurred = 0; + watched_fd->cups_poll = cups_poll; + watched_fd->watches = cupsArrayNew (NULL, NULL); + cupsArrayAdd (cups_poll->watched_fds, watched_fd); + } + + watch->watched_fd = watched_fd; + cupsArrayAdd(watched_fd->watches, watch); + watched_fd_add_select (watched_fd); + return (watch); +} + + +/* + * 'watch_free' - Free a file descriptor watch + */ + +static void +watch_free (AvahiWatch *watch) +{ + cupsd_watched_fd_t *watched_fd = watch->watched_fd; + AvahiCupsPoll *cups_poll = watched_fd->cups_poll; + + cupsArrayRemove (watched_fd->watches, watch); + free (watch); + + if (!watched_fd_add_select (watched_fd)) + { + /* No more watches */ + cupsArrayRemove (cups_poll->watched_fds, watched_fd); + free (watched_fd); + } +} + + +/* + * 'watch_update' - Update watched events for a file descriptor + */ + +static void +watch_update (AvahiWatch *watch, + AvahiWatchEvent events) +{ + watch->events = events; + watched_fd_add_select (watch->watched_fd); +} + + +/* + * 'watch_get_events' - Get events that happened for a file descriptor + */ + +static AvahiWatchEvent +watch_get_events (AvahiWatch *watch) +{ + return (watch->watched_fd->occurred); +} + + +/* + * 'timeout_cb()' - Run a timed Avahi callback + */ + +static void +timeout_cb (cupsd_timeout_t *cupsd_timeout, void *userdata) +{ + AvahiTimeout *timeout = userdata; + (timeout->callback) (timeout, timeout->userdata); +} + + +/* + * 'timeout_new' - Set a wakeup time + */ + +static AvahiTimeout * +timeout_new (const AvahiPoll *api, + const struct timeval *tv, + AvahiTimeoutCallback callback, + void *userdata) +{ + AvahiTimeout *timeout; + AvahiCupsPoll *cups_poll = api->userdata; + + timeout = malloc(sizeof(AvahiTimeout)); + if (timeout == NULL) + return (NULL); + + timeout->cups_poll = cups_poll; + timeout->callback = callback; + timeout->userdata = userdata; + timeout->cupsd_timeout = cupsdAddTimeout (tv, + (cupsd_timeoutfunc_t)timeout_cb, + timeout); + cupsArrayAdd (cups_poll->timeouts, timeout); + return (timeout); +} + + +/* + * 'timeout_update' - Update the expiration time for a timeout + */ + +static void +timeout_update (AvahiTimeout *timeout, + const struct timeval *tv) +{ + cupsdUpdateTimeout (timeout->cupsd_timeout, tv); +} + + +/* + * ' timeout_free' - Free a timeout + */ + +static void +timeout_free (AvahiTimeout *timeout) +{ + cupsArrayRemove (timeout->cups_poll->timeouts, timeout); + cupsdRemoveTimeout (timeout->cupsd_timeout); + free (timeout); +} + + +/* + * 'compare_watched_fds' - Compare watched file descriptors for array sorting + */ +static int +compare_watched_fds(cupsd_watched_fd_t *p0, + cupsd_watched_fd_t *p1) +{ + /* + * Compare by fd (no two elements have the same fd) + */ + + if (p0->fd == p1->fd) + return 0; + + return (p0->fd < p1->fd ? -1 : 1); +} + + +/* + * 'avahi_cups_poll_new' - Create a new Avahi main loop object for CUPS + */ + +AvahiCupsPoll * +avahi_cups_poll_new (void) +{ + AvahiCupsPoll *cups_poll = malloc(sizeof(AvahiCupsPoll)); + if (cups_poll == NULL) + return (NULL); + + cups_poll->watched_fds = cupsArrayNew ((cups_array_func_t)compare_watched_fds, + NULL); + cups_poll->timeouts = cupsArrayNew (NULL, NULL); + + cups_poll->api.userdata = cups_poll; + cups_poll->api.watch_new = watch_new; + cups_poll->api.watch_free = watch_free; + cups_poll->api.watch_update = watch_update; + cups_poll->api.watch_get_events = watch_get_events; + + cups_poll->api.timeout_new = timeout_new; + cups_poll->api.timeout_update = timeout_update; + cups_poll->api.timeout_free = timeout_free; + + return (cups_poll); +} + + +/* + * 'avahi_cups_poll_free' - Free an Avahi main loop object for CUPS + */ +void +avahi_cups_poll_free (AvahiCupsPoll *cups_poll) +{ + cupsd_watched_fd_t *watched_fd; + + for (watched_fd = (cupsd_watched_fd_t*)cupsArrayFirst(cups_poll->watched_fds); + watched_fd; + watched_fd = (cupsd_watched_fd_t*)cupsArrayNext(cups_poll->watched_fds)) + cupsArrayClear (watched_fd->watches); + + cupsArrayClear (cups_poll->watched_fds); + cupsArrayClear (cups_poll->timeouts); +} + + +/* + * 'avahi_cups_poll_get' - Get the abstract poll API structure + */ + +const AvahiPoll * +avahi_cups_poll_get (AvahiCupsPoll *cups_poll) +{ + return (&cups_poll->api); +} + + +#endif /* HAVE_AVAHI ... from top of file */ + +/* + * End of "$Id$". + */ diff --git a/scheduler/avahi.h b/scheduler/avahi.h new file mode 100644 index 000000000..d92049dc2 --- /dev/null +++ b/scheduler/avahi.h @@ -0,0 +1,69 @@ +/* + * "$Id$" + * + * Avahi poll implementation for the CUPS scheduler. + * + * Copyright (C) 2010, 2011 Red Hat, Inc. + * Authors: + * Tim Waugh <twaugh@redhat.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <config.h> + +#ifdef HAVE_AVAHI +# include <avahi-client/client.h> +# include <avahi-client/publish.h> +#endif /* HAVE_AVAHI */ + +#ifdef HAVE_AUTHORIZATION_H +# include <Security/Authorization.h> +#endif /* HAVE_AUTHORIZATION_H */ + + +#ifdef HAVE_AVAHI +typedef struct +{ + AvahiPoll api; + cups_array_t *watched_fds; + cups_array_t *timeouts; +} AvahiCupsPoll; +#endif /* HAVE_AVAHI */ + +/* + * Prototypes... + */ + +#ifdef HAVE_AVAHI +extern AvahiCupsPoll * avahi_cups_poll_new(void); +extern void avahi_cups_poll_free(AvahiCupsPoll *cups_poll); +extern const AvahiPoll *avahi_cups_poll_get(AvahiCupsPoll *cups_poll); +#endif /* HAVE_AVAHI */ + + +/* + * End of "$Id$". + */ diff --git a/scheduler/client.h b/scheduler/client.h index ded57bd75..ff1bfc0c9 100644 --- a/scheduler/client.h +++ b/scheduler/client.h @@ -32,8 +32,10 @@ struct cupsd_client_s http_state_t operation; /* Request operation */ off_t bytes; /* Bytes transferred for this request */ int type; /* AuthType for username */ - char username[256], /* Username from Authorization: line */ - password[33], /* Password from Authorization: line */ + char username[HTTP_MAX_VALUE], + /* Username from Authorization: line */ + password[HTTP_MAX_VALUE], + /* Password from Authorization: line */ uri[HTTP_MAX_URI], /* Localized URL/URI for GET/PUT */ *filename, /* Filename of output file */ diff --git a/scheduler/conf.c b/scheduler/conf.c index 7279f4ff5..de9d80c0e 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -3,7 +3,7 @@ * * Configuration routines for the CUPS scheduler. * - * 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 @@ -132,6 +132,7 @@ static const cupsd_var_t variables[] = { "MaxClientsPerHost", &MaxClientsPerHost, CUPSD_VARTYPE_INTEGER }, { "MaxCopies", &MaxCopies, CUPSD_VARTYPE_INTEGER }, { "MaxEvents", &MaxEvents, CUPSD_VARTYPE_INTEGER }, + { "MaxHoldTime", &MaxHoldTime, CUPSD_VARTYPE_INTEGER }, { "MaxJobs", &MaxJobs, CUPSD_VARTYPE_INTEGER }, { "MaxJobsPerPrinter", &MaxJobsPerPrinter, CUPSD_VARTYPE_INTEGER }, { "MaxJobsPerUser", &MaxJobsPerUser, CUPSD_VARTYPE_INTEGER }, @@ -743,6 +744,7 @@ cupsdReadConfiguration(void) JobHistory = DEFAULT_HISTORY; JobFiles = DEFAULT_FILES; JobAutoPurge = 0; + MaxHoldTime = 0; MaxJobs = 500; MaxActiveJobs = 0; MaxJobsPerUser = 0; diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx index dd44af3c6..95f6b3a31 100644 --- a/scheduler/cups-driverd.cxx +++ b/scheduler/cups-driverd.cxx @@ -7,7 +7,7 @@ * created from driver information files, and dynamically generated PPD files * using driver helper programs. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -2299,17 +2299,19 @@ load_ppds(const char *d, /* I - Actual directory */ ppd->record.model_number = model_number; ppd->record.type = type; + strlcpy(ppd->record.filename, name, sizeof(ppd->record.filename)); strlcpy(ppd->record.name, name, sizeof(ppd->record.name)); - strlcpy(ppd->record.make, manufacturer, sizeof(ppd->record.make)); - strlcpy(ppd->record.make_and_model, make_model, - sizeof(ppd->record.make_and_model)); strlcpy(ppd->record.languages[0], lang_version, sizeof(ppd->record.languages[0])); strlcpy(ppd->record.products[0], (char *)cupsArrayFirst(products), sizeof(ppd->record.products[0])); strlcpy(ppd->record.psversions[0], (char *)cupsArrayFirst(psversions), sizeof(ppd->record.psversions[0])); + strlcpy(ppd->record.make, manufacturer, sizeof(ppd->record.make)); + strlcpy(ppd->record.make_and_model, make_model, + sizeof(ppd->record.make_and_model)); strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id)); + strlcpy(ppd->record.scheme, "file", sizeof(ppd->record.scheme)); } /* diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h index 630285f3e..8d7117bb2 100644 --- a/scheduler/cupsd.h +++ b/scheduler/cupsd.h @@ -140,6 +140,15 @@ extern const char *cups_hstrerror(int); typedef void (*cupsd_selfunc_t)(void *data); +#ifdef HAVE_AVAHI +/* + * Timeout callback function type... + */ + +typedef struct _cupsd_timeout_s cupsd_timeout_t; +typedef void (*cupsd_timeoutfunc_t)(cupsd_timeout_t *timeout, void *data); +#endif /* HAVE_AVAHI */ + /* * Globals... @@ -173,6 +182,12 @@ VAR int Launchd VALUE(0); /* Running from launchd */ #endif /* HAVE_LAUNCH_H */ +#ifdef HAVE_AVAHI +VAR cups_array_t *Timeouts VALUE(NULL); + /* Timed callbacks for main loop */ +#endif /* HAVE_AVAHI */ + + /* * Prototypes... @@ -236,6 +251,19 @@ extern void cupsdStopSelect(void); extern void cupsdStartServer(void); extern void cupsdStopServer(void); +#ifdef HAVE_AVAHI +extern cupsd_timeout_t *cupsdAddTimeout(const struct timeval *tv, + cupsd_timeoutfunc_t cb, + void *data); +extern cupsd_timeout_t *cupsdNextTimeout(long *delay); +extern void cupsdRemoveTimeout(cupsd_timeout_t *timeout); +extern void cupsdRunTimeout(cupsd_timeout_t *timeout); +extern void cupsdUpdateTimeout(cupsd_timeout_t *timeout, + const struct timeval *tv); +#endif /* HAVE_AVAHI */ + +extern int cupsdRemoveFile(const char *filename); + /* * End of "$Id: cupsd.h 7928 2008-09-10 22:14:22Z mike $". diff --git a/scheduler/ipp.c b/scheduler/ipp.c index e5a464737..ce0ccc9f0 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -112,9 +112,7 @@ #ifdef __APPLE__ # include <ApplicationServices/ApplicationServices.h> -# ifdef HAVE_COLORSYNCREGISTERDEVICE extern CFUUIDRef ColorSyncCreateUUIDFromUInt32(unsigned id); -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ # include <CoreFoundation/CoreFoundation.h> # ifdef HAVE_MEMBERSHIP_H # include <membership.h> @@ -147,11 +145,7 @@ static void add_printer_state_reasons(cupsd_client_t *con, static void add_queued_job_count(cupsd_client_t *con, cupsd_printer_t *p); #ifdef __APPLE__ static void apple_init_profile(ppd_file_t *ppd, cups_array_t *languages, -# ifdef HAVE_COLORSYNCREGISTERDEVICE CFMutableDictionaryRef profile, -# else - CMDeviceProfileInfo *profile, -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ unsigned id, const char *name, const char *text, const char *iccfile); static void apple_register_profiles(cupsd_printer_t *p); @@ -2897,19 +2891,13 @@ static void apple_init_profile( ppd_file_t *ppd, /* I - PPD file */ cups_array_t *languages, /* I - Languages in the PPD file */ -# ifdef HAVE_COLORSYNCREGISTERDEVICE CFMutableDictionaryRef profile, /* I - Profile dictionary */ -# else - CMDeviceProfileInfo *profile, /* I - Profile record */ -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ unsigned id, /* I - Profile ID */ const char *name, /* I - Profile name */ const char *text, /* I - Profile UI text */ const char *iccfile) /* I - ICC filename */ { -# ifdef HAVE_COLORSYNCREGISTERDEVICE CFURLRef url; /* URL for profile filename */ -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ CFMutableDictionaryRef dict; /* Dictionary for name */ char *language; /* Current language */ ppd_attr_t *attr; /* Profile attribute */ @@ -2988,7 +2976,6 @@ apple_init_profile( * Fill in the profile data... */ -# ifdef HAVE_COLORSYNCREGISTERDEVICE if (iccfile) { url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, @@ -3004,17 +2991,6 @@ apple_init_profile( CFDictionarySetValue(profile, kColorSyncDeviceModeDescriptions, dict); CFRelease(dict); - -# else - profile->dataVersion = cmDeviceProfileInfoVersion1; - profile->profileID = id; - profile->profileLoc.locType = iccfile ? cmPathBasedProfile : cmNoProfileBase; - profile->profileName = dict; - - if (iccfile) - strlcpy(profile->profileLoc.u.pathLoc.path, iccfile, - sizeof(profile->profileLoc.u.pathLoc.path)); -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ } @@ -3054,34 +3030,18 @@ apple_register_profiles( CFMutableDictionaryRef device_name; /* Printer device name dictionary */ CFStringRef printer_name; /* Printer name string */ cups_array_t *languages; /* Languages array */ -# ifdef HAVE_COLORSYNCREGISTERDEVICE CFMutableDictionaryRef profiles, /* Dictionary of profiles */ profile; /* Current profile info dictionary */ CFStringRef dict_key; /* Key in factory profile dictionary */ -# else - CMDeviceScope scope = /* Scope of the registration */ - { - kCFPreferencesAnyUser, - kCFPreferencesCurrentHost - }; - CMDeviceProfileArrayPtr profiles; /* Profiles */ - CMDeviceProfileInfo *profile; /* Current profile */ -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ /* * Make sure ColorSync is available... */ -# ifdef HAVE_COLORSYNCREGISTERDEVICE if (ColorSyncRegisterDevice == NULL) return; -# else - if (CMRegisterColorDevice == NULL) - return; -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ - /* * Try opening the PPD file for this printer... */ @@ -3116,13 +3076,13 @@ apple_register_profiles( cupsdLogMessage(CUPSD_LOG_ERROR, "%s: ICC Profile \"%s\" does not exist.", p->name, iccfile); + cupsdSetPrinterReasons(p, "+cups-missing-filter-warning"); continue; } num_profiles ++; } -# ifdef HAVE_COLORSYNCREGISTERDEVICE /* * Create a dictionary for the factory profiles... */ @@ -3137,7 +3097,6 @@ apple_register_profiles( ppdClose(ppd); return; } -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ /* * If we have profiles, add them... @@ -3207,25 +3166,6 @@ apple_register_profiles( q3_choice = NULL; } -# ifndef HAVE_COLORSYNCREGISTERDEVICE - /* - * Build the array of profiles... - * - * Note: This calloc actually requests slightly more memory than needed. - */ - - if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to allocate memory for factory profiles."); - ppdClose(ppd); - return; - } - - profiles->profileCount = num_profiles; - profile = profiles->profiles; -# endif /* !HAVE_COLORSYNCREGISTERDEVICE */ - /* * Loop through the profiles listed in the PPD... */ @@ -3267,7 +3207,6 @@ apple_register_profiles( else profile_id = atoi(attr->spec); -# ifdef HAVE_COLORSYNCREGISTERDEVICE profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -3293,13 +3232,6 @@ apple_register_profiles( CFRelease(profile); -# else - apple_init_profile(ppd, languages, profile, profile_id, attr->spec, - attr->text[0] ? attr->text : attr->spec, iccfile); - - profile ++; -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ - /* * See if this is the default profile... */ @@ -3368,23 +3300,6 @@ apple_register_profiles( num_profiles = cm_option->num_choices; -# ifndef HAVE_COLORSYNCREGISTERDEVICE - /* - * Create an array for the factory profiles... - */ - - if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to allocate memory for factory profiles."); - ppdClose(ppd); - return; - } - - profiles->profileCount = num_profiles; - profile = profiles->profiles; -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ - for (i = cm_option->num_choices, cm_choice = cm_option->choices; i > 0; i --, cm_choice ++) @@ -3404,7 +3319,6 @@ apple_register_profiles( snprintf(selector, sizeof(selector), "%s..", profile_name); profile_id = _ppdHashName(selector); -# ifdef HAVE_COLORSYNCREGISTERDEVICE profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -3430,12 +3344,6 @@ apple_register_profiles( CFRelease(profile); -# else - apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice, - cm_choice->text, NULL); - profile ++; -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ - if (cm_choice->marked) default_profile_id = profile_id; } @@ -3450,7 +3358,6 @@ apple_register_profiles( num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2; -# ifdef HAVE_COLORSYNCREGISTERDEVICE /* * Add the grayscale profile first. We always have a grayscale profile. */ @@ -3538,61 +3445,6 @@ apple_register_profiles( } CFRelease(profile); - -# else - /* - * Create an array for the factory profiles... - */ - - if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to allocate memory for factory profiles."); - ppdClose(ppd); - return; - } - - profiles->profileCount = num_profiles; - - /* - * Add the grayscale profile first. We always have a grayscale profile. - */ - - profile_id = _ppdHashName("Gray.."); - apple_init_profile(ppd, NULL, profiles->profiles, profile_id, "Gray", - "Gray", NULL); - - /* - * Then add the RGB/CMYK/DeviceN color profile... - */ - - switch (ppd->colorspace) - { - default : - case PPD_CS_RGB : - case PPD_CS_CMY : - profile_id = _ppdHashName("RGB.."); - apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id, - "RGB", "RGB", NULL); - break; - case PPD_CS_RGBK : - case PPD_CS_CMYK : - profile_id = _ppdHashName("CMYK.."); - apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id, - "CMYK", "CMYK", NULL); - break; - - case PPD_CS_GRAY : - if (attr) - break; - - case PPD_CS_N : - profile_id = _ppdHashName("DeviceN.."); - apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id, - "DeviceN", "DeviceN", NULL); - break; - } -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ } if (num_profiles > 0) @@ -3604,7 +3456,6 @@ apple_register_profiles( if (!default_profile_id) default_profile_id = profile_id; /* Last profile */ -# ifdef HAVE_COLORSYNCREGISTERDEVICE dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"), default_profile_id); if (dict_key) @@ -3613,7 +3464,6 @@ apple_register_profiles( dict_key); CFRelease(dict_key); } -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ /* * Get the device ID hash and pathelogical name dictionary. @@ -3631,13 +3481,10 @@ apple_register_profiles( if (device_name && printer_name) { - CFDictionarySetValue(device_name, CFSTR("en_US"), printer_name); - /* * Register the device with ColorSync... */ -# ifdef HAVE_COLORSYNCREGISTERDEVICE CFTypeRef deviceDictKeys[] = { /* Device keys */ kColorSyncDeviceDescriptions, @@ -3655,6 +3502,8 @@ apple_register_profiles( CFDictionaryRef deviceDict; /* Device dictionary */ CFUUIDRef deviceUUID; /* Device UUID */ + CFDictionarySetValue(device_name, CFSTR("en_US"), printer_name); + deviceDict = CFDictionaryCreate(kCFAllocatorDefault, (const void **)deviceDictKeys, (const void **)deviceDictVals, @@ -3674,19 +3523,6 @@ apple_register_profiles( if (deviceDict) CFRelease(deviceDict); - -# else - error = CMRegisterColorDevice(cmPrinterDeviceClass, device_id, - device_name, &scope); - - /* - * Register the profiles... - */ - - if (error == noErr) - error = CMSetDeviceFactoryProfiles(cmPrinterDeviceClass, device_id, - default_profile_id, profiles); -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ } else error = 1000; @@ -3711,21 +3547,8 @@ apple_register_profiles( * Free any memory we used... */ -# ifdef HAVE_COLORSYNCREGISTERDEVICE CFRelease(profiles); -# else - if (num_profiles > 0) - { - for (profile = profiles->profiles; - num_profiles > 0; - profile ++, num_profiles --) - CFRelease(profile->profileName); - - free(profiles); - } -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ - ppdClose(ppd); } @@ -3743,7 +3566,6 @@ apple_unregister_profiles( * Make sure ColorSync is available... */ -# ifdef HAVE_COLORSYNCREGISTERDEVICE if (ColorSyncUnregisterDevice != NULL) { /* @@ -3761,11 +3583,6 @@ apple_unregister_profiles( CFRelease(deviceUUID); } } - -# else - if (CMUnregisterColorDevice != NULL) - CMUnregisterColorDevice(cmPrinterDeviceClass, _ppdHashName(p->name)); -# endif /* HAVE_COLORSYNCREGISTERDEVICE */ } #endif /* __APPLE__ */ @@ -5159,7 +4976,7 @@ copy_banner(cupsd_client_t *con, /* I - Client connection */ cupsFilePrintf(out, "%dx%d%s", attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); break; case IPP_TAG_URI : @@ -9713,6 +9530,7 @@ release_job(cupsd_client_t *con, /* I - Client connection */ cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job, "Job job-hold-until value changed by user."); + ippSetString(job->attrs, &job->reasons, 0, "none"); } /* @@ -11453,7 +11271,7 @@ set_printer_defaults( sprintf(value, "%dx%d%s", attr->values[0].resolution.xres, attr->values[0].resolution.yres, attr->values[0].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); printer->num_options = cupsAddOption(name, value, printer->num_options, &(printer->options)); diff --git a/scheduler/job.c b/scheduler/job.c index 49a408219..a9c07aa07 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -2239,12 +2239,16 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */ job->dirty = 1; cupsdMarkDirty(CUPSD_DIRTY_JOBS); } + + ippSetString(job->attrs, &job->reasons, 0, "job-hold-until-specified"); } /* * Update the hold time... */ + job->cancel_time = 0; + if (!strcmp(when, "indefinite") || !strcmp(when, "auth-info-required")) { /* @@ -2252,6 +2256,9 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */ */ job->hold_until = 0; + + if (MaxHoldTime > 0) + job->cancel_time = time(NULL) + MaxHoldTime; } else if (!strcmp(when, "day-time")) { @@ -3657,7 +3664,7 @@ get_options(cupsd_job_t *job, /* I - Job */ "%dx%d%s", attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); break; case IPP_TAG_STRING : @@ -4262,6 +4269,10 @@ start_job(cupsd_job_t *job, /* I - Job ID */ if (!cupsdLoadJob(job)) return; + if (!job->printer_message) + job->printer_message = ippFindAttribute(job->attrs, + "job-printer-state-message", + IPP_TAG_TEXT); if (job->printer_message) cupsdSetString(&(job->printer_message->values[0].string.text), ""); diff --git a/scheduler/job.h b/scheduler/job.h index 50f17cc9d..b34f91e16 100644 --- a/scheduler/job.h +++ b/scheduler/job.h @@ -99,6 +99,8 @@ VAR int MaxJobs VALUE(0), /* Max number of jobs */ MaxActiveJobs VALUE(0), /* Max number of active jobs */ + MaxHoldTime VALUE(0), + /* Max time for indefinite hold */ MaxJobsPerUser VALUE(0), /* Max jobs per user */ MaxJobsPerPrinter VALUE(0), diff --git a/scheduler/main.c b/scheduler/main.c index aa5a3b34c..e0de67e4b 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -3,7 +3,7 @@ * * Main loop for the CUPS scheduler. * - * 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 @@ -145,6 +145,10 @@ main(int argc, /* I - Number of command-line args */ int launchd_idle_exit; /* Idle exit on select timeout? */ #endif /* HAVE_LAUNCHD */ +#ifdef HAVE_AVAHI + cupsd_timeout_t *tmo; /* Next scheduled timed callback */ + long tmo_delay; /* Time before it must be called */ +#endif /* HAVE_AVAHI */ #ifdef HAVE_GETEUID @@ -858,6 +862,16 @@ main(int argc, /* I - Number of command-line args */ } #endif /* __APPLE__ */ +#ifdef HAVE_AVAHI + /* + * If a timed callback is due, run it. + */ + + tmo = cupsdNextTimeout(&tmo_delay); + if (tmo && tmo_delay == 0) + cupsdRunTimeout(tmo); +#endif /* HAVE_AVAHI */ + #ifndef __APPLE__ /* * Update the network interfaces once a minute... @@ -1753,6 +1767,10 @@ select_timeout(int fds) /* I - Number of descriptors returned */ cupsd_job_t *job; /* Job information */ cupsd_subscription_t *sub; /* Subscription information */ const char *why; /* Debugging aid */ +#ifdef HAVE_AVAHI + cupsd_timeout_t *tmo; /* Timed callback */ + long tmo_delay; /* Seconds before calling it */ +#endif /* HAVE_AVAHI */ /* @@ -1795,6 +1813,19 @@ select_timeout(int fds) /* I - Number of descriptors returned */ } #endif /* __APPLE__ */ +#ifdef HAVE_AVAHI + /* + * See if there are any scheduled timed callbacks to run. + */ + + if ((tmo = cupsdNextTimeout(&tmo_delay)) != NULL && + (now + tmo_delay) < timeout) + { + timeout = tmo_delay; + why = "run a timed callback"; + } +#endif /* HAVE_AVAHI */ + /* * Check whether we are accepting new connections... */ diff --git a/scheduler/printers.c b/scheduler/printers.c index 37c16511d..293b64d31 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -1947,7 +1947,7 @@ cupsdSetPrinterAttr( ptr ++; else if (*ptr == '\'' || *ptr == '\"') quote = *ptr; - else if (*ptr == '.') + else if (*ptr == ',') count ++; } @@ -2052,7 +2052,7 @@ cupsdSetPrinterAttr( else _cups_strcpy(ptr, ptr + 1); } - else if (*ptr == '.') + else if (*ptr == ',') { *ptr++ = '\0'; break; diff --git a/scheduler/testsub.c b/scheduler/testsub.c index 36e161507..88294a357 100644 --- a/scheduler/testsub.c +++ b/scheduler/testsub.c @@ -3,7 +3,7 @@ * * Scheduler notification tester for CUPS. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 2006-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -453,7 +453,7 @@ print_attributes(ipp_t *ipp, /* I - IPP request */ case IPP_TAG_RESOLUTION : for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) printf(" %dx%d%s", val->resolution.xres, val->resolution.yres, - val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc"); + val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm"); putchar('\n'); break; diff --git a/scheduler/timeout.c b/scheduler/timeout.c new file mode 100644 index 000000000..2c3b376c2 --- /dev/null +++ b/scheduler/timeout.c @@ -0,0 +1,249 @@ +/* + * "$Id$" + * + * Timeout functions for the CUPS Scheduler. + * + * Copyright 2012 by Apple Inc. + * + * 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" + * which should have been included with this file. If this file is + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Copyright (C) 2010, 2011 Red Hat, Inc. + * Authors: + * Tim Waugh <twaugh@redhat.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Contents: + * + * cupsdAddTimeout() - Add a timed callback. + * cupsdNextTimeout() - Find the next enabled timed callback. + * cupsdRemoveTimeout() - Discard a timed callback. + * cupsdRunTimeout() - Run a timed callback. + * cupsdUpdateTimeout() - Adjust the time of a timed callback or disable it. + * compare_addrs() - Compare pointers for array sorting. + * compare_timeouts() - Compare timed callbacks for array sorting. + */ + +#include "cupsd.h" +#ifdef HAVE_AVAHI /* Applies to entire file... */ + +/* + * Include necessary headers... + */ + +# include <avahi-common/timeval.h> + + +/* + * Local types... + */ + +struct _cupsd_timeout_s /* Timeout data */ +{ + struct timeval when; /* When to fire timeout */ + int enabled; /* Is the timeout enabled? */ + cupsd_timeoutfunc_t callback; /* Timeout callback */ + void *data; /* User data for callback */ +}; + + +/* + * Local functions... + */ + +static int compare_addrs(void *p0, void *p1); +static int compare_timeouts(cupsd_timeout_t *p0, cupsd_timeout_t *p1); + + +/* + * 'cupsdAddTimeout()' - Add a timed callback. + */ + +cupsd_timeout_t * /* O - Timeout handle */ +cupsdAddTimeout( + const struct timeval *tv, /* I - Absolute time */ + cupsd_timeoutfunc_t cb, /* I - Callback function */ + void *data) /* I - User data */ +{ + cupsd_timeout_t *timeout; /* I - New timeout */ + + + if ((timeout = calloc(1, sizeof(cupsd_timeout_t))) != NULL) + { + timeout->enabled = (tv != NULL); + if (tv) + timeout->when = *tv; + + timeout->callback = cb; + timeout->data = data; + + if (!Timeouts) + Timeouts = cupsArrayNew((cups_array_func_t)compare_timeouts, NULL); + + cupsArrayAdd(Timeouts, timeout); + } + + return (timeout); +} + + +/* + * 'cupsdNextTimeout()' - Find the next enabled timed callback. + */ + +cupsd_timeout_t * /* O - Next enabled timeout or NULL */ +cupsdNextTimeout(long *delay) /* O - Seconds before scheduled */ +{ + cupsd_timeout_t *first = cupsArrayFirst(Timeouts); + /* First timeout */ + struct timeval curtime; /* Current time */ + + + if (first && !first->enabled) + first = NULL; + + if (first && delay) + { + gettimeofday(&curtime, NULL); + if (avahi_timeval_compare(&curtime, &first->when) > 0) + *delay = 0; + else + { + *delay = 1 + first->when.tv_sec - curtime.tv_sec; + if (first->when.tv_usec < curtime.tv_usec) + (*delay) --; + } + } + + return (first); +} + + +/* + * 'cupsdRemoveTimeout()' - Discard a timed callback. + */ + +void +cupsdRemoveTimeout( + cupsd_timeout_t *timeout) /* I - Timeout */ +{ + cupsArrayRemove(Timeouts, timeout); + free(timeout); +} + + +/* + * 'cupsdRunTimeout()' - Run a timed callback. + */ + +void +cupsdRunTimeout( + cupsd_timeout_t *timeout) /* I - Timeout */ +{ + if (timeout) + { + timeout->enabled = 0; + if (timeout->callback) + (*timeout->callback)(timeout, timeout->data); + } +} + + +/* + * 'cupsdUpdateTimeout()' - Adjust the time of a timed callback or disable it. + */ + +void +cupsdUpdateTimeout( + cupsd_timeout_t *timeout, /* I - Timeout */ + const struct timeval *tv) /* I - Absolute time or NULL */ +{ + cupsArrayRemove(Timeouts, timeout); + timeout->enabled = (tv != NULL); + + if (tv) + timeout->when = *tv; + + cupsArrayAdd(Timeouts, timeout); +} + + +/* + * 'compare_addrs()' - Compare pointers for array sorting. + */ + +static int /* O - Result of comparison */ +compare_addrs(void *p0, /* I - First pointer */ + void *p1) /* I - Second pointer */ +{ + if (p0 == p1) + return (0); + else if (p0 < p1) + return (-1); + else + return (1); +} + + +/* + * 'compare_timeouts()' - Compare timed callbacks for array sorting. + */ + +static int /* O - Result of comparison */ +compare_timeouts(cupsd_timeout_t *p0, /* I - First timeout */ + cupsd_timeout_t *p1) /* I - Second timeout */ +{ + int addrsdiff = compare_addrs (p0, p1); + /* Address difference */ + int tvdiff; /* Time difference */ + + + if (addrsdiff == 0) + return (0); + + if (!p0->enabled || !p1->enabled) + { + if (!p0->enabled && !p1->enabled) + return (addrsdiff); + + return (p0->enabled ? -1 : 1); + } + + tvdiff = avahi_timeval_compare(&p0->when, &p1->when); + if (tvdiff != 0) + return (tvdiff); + + return (addrsdiff); +} +#endif /* HAVE_AVAHI */ + + +/* + * End of "$Id$". + */ diff --git a/test/get-completed-jobs.test b/test/get-completed-jobs.test index 9d8ebb40c..eca227935 100644 --- a/test/get-completed-jobs.test +++ b/test/get-completed-jobs.test @@ -3,7 +3,7 @@ # # Get list of completed jobs. # -# Copyright 2007-2010 by Apple Inc. +# Copyright 2007-2012 by Apple Inc. # Copyright 2001-2006 by Easy Software Products. All rights reserved. # # These coded instructions, statements, and computer programs are the @@ -32,7 +32,7 @@ ATTR uri printer-uri $uri ATTR keyword which-jobs completed ATTR keyword requested-attributes - job-id,job-state,job-name,job-originating-user-name,job-media-sheets-completed + job-id,job-state,job-state-reasons,job-name,job-originating-user-name,job-media-sheets-completed # What statuses are OK? STATUS successful-ok diff --git a/test/get-jobs.test b/test/get-jobs.test index 4da5f6a7a..13b9959c2 100644 --- a/test/get-jobs.test +++ b/test/get-jobs.test @@ -3,7 +3,7 @@ # # Get list of not-completed jobs. # -# Copyright 2007-2010 by Apple Inc. +# Copyright 2007-2012 by Apple Inc. # Copyright 2001-2006 by Easy Software Products. All rights reserved. # # These coded instructions, statements, and computer programs are the @@ -31,7 +31,7 @@ ATTR language attributes-natural-language en ATTR uri printer-uri $uri ATTR keyword requested-attributes - job-id,job-state,job-name,job-originating-user-name,job-media-sheets,job-media-sheets-completed,job-impressions,job-impressions-completed + job-id,job-state,job-state-reasons,job-name,job-originating-user-name,job-media-sheets,job-media-sheets-completed,job-impressions,job-impressions-completed # What statuses are OK? STATUS successful-ok diff --git a/test/ipptool.c b/test/ipptool.c index 66358e65f..d1cdea442 100644 --- a/test/ipptool.c +++ b/test/ipptool.c @@ -1608,7 +1608,9 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ } if (ptr <= token || xres <= 0 || yres <= 0 || !ptr || - (_cups_strcasecmp(ptr, "dpi") && _cups_strcasecmp(ptr, "dpc") && + (_cups_strcasecmp(ptr, "dpi") && + _cups_strcasecmp(ptr, "dpc") && + _cups_strcasecmp(ptr, "dpcm") && _cups_strcasecmp(ptr, "other"))) { print_fatal_error("Bad resolution value \"%s\" on line %d.", @@ -1620,7 +1622,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ if (!_cups_strcasecmp(ptr, "dpi")) attrptr = ippAddResolution(request, group, attr, IPP_RES_PER_INCH, xres, yres); - else if (!_cups_strcasecmp(ptr, "dpc")) + else if (!_cups_strcasecmp(ptr, "dpc") || + !_cups_strcasecmp(ptr, "dpcm")) attrptr = ippAddResolution(request, group, attr, IPP_RES_PER_CM, xres, yres); else @@ -2501,7 +2504,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ { int out_of_order = 0; /* Are attribute groups out-of-order? */ cupsArrayClear(a); - + switch (attrptr->group_tag) { @@ -2639,7 +2642,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ add_stringf(errors, "EXPECTED: %s OF-TYPE %s (got %s)", expect->name, expect->of_type, ippTagString(found->value_tag)); - + if (expect->in_group && found->group_tag != expect->in_group) add_stringf(errors, "EXPECTED: %s IN-GROUP %s (got %s).", expect->name, ippTagString(expect->in_group), @@ -3273,7 +3276,9 @@ get_collection(_cups_vars_t *vars, /* I - Variables */ char units[6]; /* Units */ if (sscanf(token, "%dx%d%5s", &xres, &yres, units) != 3 || - (_cups_strcasecmp(units, "dpi") && _cups_strcasecmp(units, "dpc") && + (_cups_strcasecmp(units, "dpi") && + _cups_strcasecmp(units, "dpc") && + _cups_strcasecmp(units, "dpcm") && _cups_strcasecmp(units, "other"))) { print_fatal_error("Bad resolution value \"%s\" on line %d.", @@ -3284,7 +3289,8 @@ get_collection(_cups_vars_t *vars, /* I - Variables */ if (!_cups_strcasecmp(units, "dpi")) ippAddResolution(col, IPP_TAG_ZERO, attr, xres, yres, IPP_RES_PER_INCH); - else if (!_cups_strcasecmp(units, "dpc")) + else if (!_cups_strcasecmp(units, "dpc") || + !_cups_strcasecmp(units, "dpcm")) ippAddResolution(col, IPP_TAG_ZERO, attr, xres, yres, IPP_RES_PER_CM); else @@ -3679,12 +3685,12 @@ print_attr(ipp_attribute_t *attr, /* I - Attribute to print */ attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); else printf("%dx%d%s ", attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); break; case IPP_TAG_DATE : @@ -3831,7 +3837,7 @@ print_col(ipp_t *col) /* I - Collection attribute to print */ printf("%dx%d%s ", attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? - "dpi" : "dpc"); + "dpi" : "dpcm"); break; case IPP_TAG_STRING : @@ -4554,7 +4560,7 @@ validate_attr(cups_array_t *errors, /* I - Errors array */ attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpc" : "unknown"); + IPP_RES_PER_CM ? "dpcm" : "unknown"); } if (attr->values[i].resolution.yres <= 0) @@ -4570,7 +4576,7 @@ validate_attr(cups_array_t *errors, /* I - Errors array */ attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpc" : "unknown"); + IPP_RES_PER_CM ? "dpcm" : "unknown"); } if (attr->values[i].resolution.units != IPP_RES_PER_INCH && @@ -4586,7 +4592,7 @@ validate_attr(cups_array_t *errors, /* I - Errors array */ attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpc" : "unknown"); + IPP_RES_PER_CM ? "dpcm" : "unknown"); } } break; |