From b94498cfba64422f0f21181b0c51cc0bed7c7d92 Mon Sep 17 00:00:00 2001 From: jlovell Date: Fri, 4 May 2007 21:17:48 +0000 Subject: [PATCH] Load cups into easysw/current. git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@321 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES-1.2.txt | 44 + CHANGES.txt | 36 +- Makefile | 16 +- backend/ipp.c | 18 +- backend/runloop.c | 19 +- backend/snmp.c | 524 ++----- backend/usb-darwin.c | 26 +- backend/usb-unix.c | 13 +- config-scripts/cups-compiler.m4 | 8 +- configure.in | 8 +- cups/array.c | 74 +- cups/array.h | 11 +- cups/auth.c | 16 +- cups/cups.h | 8 +- cups/globals.c | 9 +- cups/globals.h | 13 +- cups/http-private.h | 11 +- cups/http.c | 15 +- cups/ipp-support.c | 16 +- cups/ipp.h | 10 +- cups/language.c | 47 +- cups/localize.c | 30 +- cups/mark.c | 287 ++-- cups/ppd.c | 83 +- cups/ppd.h | 9 +- cups/request.c | 149 +- cups/util.c | 81 +- doc/help/options.html | 29 +- ...cupsd-conf.html => ref-cupsd-conf.html.in} | 86 +- doc/help/ref-snmp-conf.html | 26 + doc/help/spec-ipp.html | 91 +- doc/help/spec-ppd.html | 33 +- man/cupstestppd.man | 49 +- packaging/cups.list.in | 8 +- pdftops/PSOutputDev.cxx | 12 +- scheduler/client.c | 59 +- scheduler/client.h | 6 +- scheduler/conf.c | 301 ++-- scheduler/conf.h | 10 +- scheduler/cups-driverd.c | 718 +++++++-- scheduler/dirsvc.c | 6 +- scheduler/ipp.c | 313 +++- scheduler/job.c | 7 +- scheduler/log.c | 25 +- scheduler/main.c | 421 +----- scheduler/printers.c | 21 +- systemv/cupstestppd.c | 1327 ++++++++++------- templates/printers.tmpl | 2 +- test/get-ppd-printer.test | 20 + test/get-ppd.test | 20 + test/get-ppds-language.test | 21 + test/get-ppds-make-and-model.test | 21 + test/get-ppds-make.test | 21 + test/get-ppds-product.test | 21 + test/get-ppds-psversion.test | 21 + test/ipptest.c | 41 +- 56 files changed, 3282 insertions(+), 2035 deletions(-) rename doc/help/{ref-cupsd-conf.html => ref-cupsd-conf.html.in} (98%) create mode 100644 test/get-ppd-printer.test create mode 100644 test/get-ppd.test create mode 100644 test/get-ppds-language.test create mode 100644 test/get-ppds-make-and-model.test create mode 100644 test/get-ppds-make.test create mode 100644 test/get-ppds-product.test create mode 100644 test/get-ppds-psversion.test diff --git a/CHANGES-1.2.txt b/CHANGES-1.2.txt index a6b1ba0d0..ce6be902b 100644 --- a/CHANGES-1.2.txt +++ b/CHANGES-1.2.txt @@ -3,6 +3,50 @@ CHANGES-1.2.txt CHANGES IN CUPS V1.2.11 + - "make distclean" didn't remove all generated files + (STR #2366) + - Fixed a bug in the advertisement of classes (STR + #2373) + - The IPP backend now stays running until the job is + actually printed by the remote server; previously + it would stop monitoring the job if it was held or + temporarily stopped (STR #2352) + - PDF files were not always printed using the correct + orientation (STR #2348) + - The scheduler could crash if you specified a bad file: + URI for a printer (STR #2351) + - The Renew-Subscription operation now returns the + notify-lease-duration value that was used (STR #2346) + - The IPP backend sent job options to IPP printers, + however some printers tried to override the options + embedded in the PS/PCL stream with those job options + (STR #2349) + - ppdLocalize() now also tries a country-specific + localization for when localizing to a generic locale + name. + - The cupstestppd program now allows for partial + localizations to reduce the size of universal PPD + files. + - Chinese PPD files were incorrectly tagged with the + "cn" locale (should have been "zh") + - The backends now manage the printer-state-reasons + attribute more accurately (STR #2345) + - Java, PHP, Perl, and Python scripts did not work + properly (STR #2342) + - The scheduler would take forever to start if the + maximum number of file descriptors was set to + "unlimited" (STR #2329) + - The page-ranges option was incorrectly applied to the + banner pages (STR #2336) + - Fixed some GCC compile warnings (STR #2340) + - The DBUS notification code was broken for older + versions of DBUS (STR #2327) + - The IPv6 code did not compile on HP-UX 11.23 (STR + #2331) + - PPD constraints did not work properly with custom + options. + - Regular PPD options with the name "CustomFoo" did + not work. - The USB backend did not work on NetBSD (STR #2324) - The printer-state-reasons attribute was incorrectly cleared after a job completed (STR #2323) diff --git a/CHANGES.txt b/CHANGES.txt index 45602a84d..3985acf68 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,9 +1,41 @@ -CHANGES.txt - 2007-04-04 +CHANGES.txt - 2007-05-03 ------------------------ CHANGES IN CUPS V1.3 - - Documentation updates (STR #1775, STR #2130, STR #2131) + - Documentation updates (STR #1775, STR #2130, STR #2131, + STR #2263, STR #2356) + - Added new -R and -W options to the cupstestppd program + for greater control over the testing of PPDs. + - Added a new cupsGetServerPPD() function for getting + an available PPD from the server (STR #2334) + - Added a new cupsDoIORequest() function for reading + and writing files via IPP requests (STR #2334) + - Added a new CUPS_GET_PPD operation for getting an + available PPD file on the server (STR #2334) + - CUPS_GET_PPDS now reports multiple ppd-product values + if the corresponding PPD contains multiple products + (STR #2334) + - CUPS_GET_PPDS now reports the PSVersion attributes + from a PPD file in the ppd-psversion attribute + (STR #2334) + - Added a new printer attribute called "cups-version" + which reports the version of CUPS that is running + (STR #2240) + - backendRunLoop() now aborts immediately on SIGTERM + if no data has been written yet (STR #2103) + - Due to poor IPP support from the vendors, the SNMP + backend no longer tries IPP connections; instead, + it now uses a lookup file with fallback to port 9100 + (socket://address) and 515 (lpd://address) printing + (STR #2035, STR #2354) + - The scheduler now recreates the CUPS log directory as + needed (STR #2353) + - cupsLangDefault() now maps new-style Apple locale names + to the traditional ll_CC form (STR #2357) + - Add new cupsArrayNew2() API to support hashed lookups + of array elements (STR #2358) + - ppdConflicts() optimizations (STR #2358) - The cupstestppd program now tests for existing filters, icons, profiles, and dialog extensions (STR #2326) - The web interface no longer lists new printers on the diff --git a/Makefile b/Makefile index c24ccdb2d..1cb72a932 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 6332 2007-03-12 16:08:51Z mike $" +# "$Id: Makefile 6500 2007-04-30 21:47:48Z mike $" # # Top-level Makefile for the Common UNIX Printing System (CUPS). # @@ -64,8 +64,10 @@ clean: distclean: clean $(RM) Makedefs config.h config.log config.status $(RM) cups-config conf/cupsd.conf conf/pam.std - $(RM) doc/help/standard.html doc/index.html + $(RM) doc/help/ref-cupsd-conf.html doc/help/standard.html + $(RM) doc/index.html $(RM) init/cups.sh init/cups-lpd + $(RM) man/client.conf.man $(RM) man/cups-deviced.man man/cups-driverd.man $(RM) man/cups-lpd.man man/cupsaddsmb.man man/cupsd.man $(RM) man/cupsd.conf.man man/lpoptions.man @@ -88,6 +90,14 @@ depend: done +# +# Generate a ctags file... +# + +ctags: + ctags -R . + + # # Install object and target files... # @@ -270,5 +280,5 @@ dist: all # -# End of "$Id: Makefile 6332 2007-03-12 16:08:51Z mike $". +# End of "$Id: Makefile 6500 2007-04-30 21:47:48Z mike $". # diff --git a/backend/ipp.c b/backend/ipp.c index fba56dbfe..2ff1fb823 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -1,5 +1,5 @@ /* - * "$Id: ipp.c 6434 2007-04-02 22:07:10Z mike $" + * "$Id: ipp.c 6482 2007-04-30 17:05:59Z mike $" * * IPP backend for the Common UNIX Printing System (CUPS). * @@ -101,6 +101,7 @@ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ + int send_options; /* Send job options? */ int num_options; /* Number of printer options */ cups_option_t *options; /* Printer options */ char method[255], /* Method in URI */ @@ -432,6 +433,8 @@ main(int argc, /* I - Number of command-line args */ filename = tmpfilename; files = &filename; num_files = 1; + + send_options = 0; } else { @@ -442,6 +445,8 @@ main(int argc, /* I - Number of command-line args */ num_files = argc - 6; files = argv + 6; + send_options = strncasecmp(content_type, "application/vnd.cups-", 21) != 0; + #ifdef HAVE_LIBZ if (compression) compress_files(num_files, files); @@ -928,6 +933,7 @@ main(int argc, /* I - Number of command-line args */ content_type = "application/postscript"; copies = 1; copies_remaining = 1; + send_options = 0; } } #endif /* __APPLE__ */ @@ -943,7 +949,7 @@ main(int argc, /* I - Number of command-line args */ num_options, &options); } - if (copies_sup && version > 0) + if (copies_sup && version > 0 && send_options) { /* * Only send options if the destination printer supports the copies @@ -1153,8 +1159,7 @@ main(int argc, /* I - Number of command-line args */ * Stop polling if the job is finished or pending-held... */ - if (job_state->values[0].integer > IPP_JOB_PROCESSING || - job_state->values[0].integer == IPP_JOB_HELD) + if (job_state->values[0].integer > IPP_JOB_STOPPED) { if ((job_sheets = ippFindAttribute(response, "job-media-sheets-completed", @@ -1350,7 +1355,8 @@ compress_files(int num_files, /* I - Number of files */ if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) { fprintf(stderr, - _("ERROR: Unable to create temporary compressed print file: %s\n"), + _("ERROR: Unable to create temporary compressed print file: " + "%s\n"), strerror(errno)); exit(CUPS_BACKEND_FAILED); } @@ -1761,5 +1767,5 @@ sigterm_handler(int sig) /* I - Signal */ /* - * End of "$Id: ipp.c 6434 2007-04-02 22:07:10Z mike $". + * End of "$Id: ipp.c 6482 2007-04-30 17:05:59Z mike $". */ diff --git a/backend/runloop.c b/backend/runloop.c index dc2890a89..fd0bb8f04 100644 --- a/backend/runloop.c +++ b/backend/runloop.c @@ -1,5 +1,5 @@ /* - * "$Id: runloop.c 6403 2007-03-27 16:00:56Z mike $" + * "$Id: runloop.c 6498 2007-04-30 21:40:33Z mike $" * * Common run loop API for the Common UNIX Printing System (CUPS). * @@ -104,7 +104,8 @@ backendRunLoop( * Now loop until we are out of data from print_fd... */ - for (print_bytes = 0, print_ptr = print_buffer, offline = 0, paperout = 0, total_bytes = 0;;) + for (print_bytes = 0, print_ptr = print_buffer, offline = -1, + paperout = -1, total_bytes = 0;;) { /* * Use select() to determine whether we have data to copy around... @@ -130,12 +131,18 @@ backendRunLoop( * Pause printing to clear any pending errors... */ - if (errno == ENXIO && !offline) + if (errno == ENXIO && offline != 1) { fputs("STATE: +offline-error\n", stderr); fputs(_("INFO: Printer is currently off-line.\n"), stderr); offline = 1; } + else if (errno == EINTR && total_bytes == 0) + { + fputs("DEBUG: Received an interrupt before any bytes were " + "written, aborting!\n", stderr); + return (0); + } sleep(1); continue; @@ -215,7 +222,7 @@ backendRunLoop( if (errno == ENOSPC) { - if (!paperout) + if (paperout != 1) { fputs("STATE: +media-empty-error\n", stderr); fputs(_("ERROR: Out of paper!\n"), stderr); @@ -224,7 +231,7 @@ backendRunLoop( } else if (errno == ENXIO) { - if (!offline) + if (offline != 1) { fputs("STATE: +offline-error\n", stderr); fputs(_("INFO: Printer is currently off-line.\n"), stderr); @@ -271,5 +278,5 @@ backendRunLoop( /* - * End of "$Id: runloop.c 6403 2007-03-27 16:00:56Z mike $". + * End of "$Id: runloop.c 6498 2007-04-30 21:40:33Z mike $". */ diff --git a/backend/snmp.c b/backend/snmp.c index 0298ee9db..bcacf14c1 100644 --- a/backend/snmp.c +++ b/backend/snmp.c @@ -1,5 +1,5 @@ /* - * "$Id: snmp.c 6403 2007-03-27 16:00:56Z mike $" + * "$Id: snmp.c 6495 2007-04-30 21:23:04Z mike $" * * SNMP discovery backend for the Common UNIX Printing System (CUPS). * @@ -28,6 +28,7 @@ * main() - Discover printers via SNMP. * add_array() - Add a string to an array. * add_cache() - Add a cached device... + * add_device_uri() - Add a device URI to the cache. * alarm_handler() - Handle alarm signals... * asn1_decode_snmp() - Decode a SNMP packet. * asn1_debug() - Decode an ASN1-encoded message. @@ -52,7 +53,6 @@ * packed integer value. * compare_cache() - Compare two cache entries. * debug_printf() - Display some debugging information. - * do_request() - Do a non-blocking IPP request. * fix_make_model() - Fix common problems in the make-and-model * string. * free_array() - Free an array of strings. @@ -82,13 +82,15 @@ #include "backend-private.h" #include #include +#include /* * This backend implements SNMP printer discovery. It uses a broadcast- - * based approach to get SNMP response packets from potential printers - * and then interrogates each responder by trying to connect on port - * 631, 9100, and 515. + * based approach to get SNMP response packets from potential printers, + * tries a mDNS lookup (Mac OS X only at present), a URI lookup based on + * the device description string, and finally a probe of port 9100 + * (AppSocket) and 515 (LPD). * * The current focus is on printers with internal network cards, although * the code also works with many external print servers as well. Future @@ -104,8 +106,10 @@ * Address @IF(name) * Community name * DebugLevel N + * DeviceURI "regex pattern" uri * HostNameLookups on * HostNameLookups off + * MaxRunTime N * * The default is to use: * @@ -113,6 +117,7 @@ * Community public * DebugLevel 0 * HostNameLookups off + * MaxRunTime 10 * * This backend is known to work with the following network printers and * print servers: @@ -162,6 +167,12 @@ * Types... */ +typedef struct device_uri_s /**** DeviceURI values ****/ +{ + regex_t re; /* Regular expression to match */ + cups_array_t *uris; /* URIs */ +} device_uri_t; + typedef struct snmp_cache_s /**** SNMP scan cache ****/ { http_addr_t address; /* Address of device */ @@ -209,6 +220,7 @@ static char *add_array(cups_array_t *a, const char *s); static void add_cache(http_addr_t *addr, const char *addrname, const char *uri, const char *id, const char *make_and_model); +static device_uri_t *add_device_uri(char *value); static void alarm_handler(int sig); static int asn1_decode_snmp(unsigned char *buffer, size_t len, snmp_packet_t *packet); @@ -246,8 +258,6 @@ static int asn1_size_oid(const int *oid); static int asn1_size_packed(int integer); static int compare_cache(snmp_cache_t *a, snmp_cache_t *b); static void debug_printf(const char *format, ...); -static ipp_t *do_request(http_t *http, ipp_t *request, - const char *resource); static void fix_make_model(char *make_model, const char *old_make_model, int make_model_size); @@ -281,12 +291,13 @@ static cups_array_t *Addresses = NULL; static cups_array_t *Communities = NULL; static cups_array_t *Devices = NULL; static int DebugLevel = 0; -static int DeviceTypeOID[] = { 1, 3, 6, 1, 2, 1, 25, 3, - 2, 1, 2, 1, 0 }; static int DeviceDescOID[] = { 1, 3, 6, 1, 2, 1, 25, 3, 2, 1, 3, 1, 0 }; -static unsigned DeviceTypeRequest; static unsigned DeviceDescRequest; +static int DeviceTypeOID[] = { 1, 3, 6, 1, 2, 1, 25, 3, + 2, 1, 2, 1, 0 }; +static unsigned DeviceTypeRequest; +static cups_array_t *DeviceURIs = NULL; static int HostNameLookups = 0; static int MaxRunTime = 10; static struct timeval StartTime; @@ -433,6 +444,96 @@ add_cache(http_addr_t *addr, /* I - Device IP address */ } +/* + * 'add_device_uri()' - Add a device URI to the cache. + * + * The value string is modified (chopped up) as needed. + */ + +static device_uri_t * /* O - Device URI */ +add_device_uri(char *value) /* I - Value from snmp.conf */ +{ + device_uri_t *device_uri; /* Device URI */ + char *start; /* Start of value */ + + + /* + * Allocate memory as needed... + */ + + if (!DeviceURIs) + DeviceURIs = cupsArrayNew(NULL, NULL); + + if (!DeviceURIs) + return (NULL); + + if ((device_uri = calloc(1, sizeof(device_uri_t))) == NULL) + return (NULL); + + if ((device_uri->uris = cupsArrayNew(NULL, NULL)) == NULL) + { + free(device_uri); + return (NULL); + } + + /* + * Scan the value string for the regular expression and URI(s)... + */ + + value ++; /* Skip leading " */ + + for (start = value; *value && *value != '\"'; value ++) + if (*value == '\\' && value[1]) + _cups_strcpy(value, value + 1); + + if (!*value) + { + fputs("ERROR: Missing end quote for DeviceURI!\n", stderr); + + cupsArrayDelete(device_uri->uris); + free(device_uri); + + return (NULL); + } + + *value++ = '\0'; + + if (regcomp(&(device_uri->re), start, REG_EXTENDED | REG_ICASE)) + { + fputs("ERROR: Bad regular expression for DeviceURI!\n", stderr); + + cupsArrayDelete(device_uri->uris); + free(device_uri); + + return (NULL); + } + + while (*value) + { + while (isspace(*value & 255)) + value ++; + + if (!*value) + break; + + for (start = value; *value && !isspace(*value & 255); value ++); + + if (*value) + *value++ = '\0'; + + cupsArrayAdd(device_uri->uris, strdup(start)); + } + + /* + * Add the device URI to the list and return it... + */ + + cupsArrayAdd(DeviceURIs, device_uri); + + return (device_uri); +} + + /* * 'alarm_handler()' - Handle alarm signals... */ @@ -1259,173 +1360,6 @@ debug_printf(const char *format, /* I - Printf-style format string */ } -/* - * 'do_request()' - Do a non-blocking IPP request. - */ - -static ipp_t * /* O - Response data or NULL */ -do_request(http_t *http, /* I - HTTP connection to server */ - ipp_t *request, /* I - IPP request */ - const char *resource) /* I - HTTP resource for POST */ -{ - ipp_t *response; /* IPP response data */ - http_status_t status; /* Status of HTTP request */ - ipp_state_t state; /* State of IPP processing */ - - - /* - * Setup the HTTP variables needed... - */ - - httpClearFields(http); - httpSetLength(http, ippLength(request)); - httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp"); - - /* - * Do the POST request... - */ - - debug_printf("DEBUG: %.3f POST %s...\n", run_time(), resource); - - if (httpPost(http, resource)) - { - if (httpReconnect(http)) - { - _cupsSetError(IPP_DEVICE_ERROR, "Unable to reconnect"); - return (NULL); - } - else if (httpPost(http, resource)) - { - _cupsSetError(IPP_GONE, "Unable to POST"); - return (NULL); - } - } - - /* - * Send the IPP data... - */ - - request->state = IPP_IDLE; - status = HTTP_CONTINUE; - - while ((state = ippWrite(http, request)) != IPP_DATA) - if (state == IPP_ERROR) - { - status = HTTP_ERROR; - break; - } - else if (httpCheck(http)) - { - if ((status = httpUpdate(http)) != HTTP_CONTINUE) - break; - } - - /* - * Get the server's return status... - */ - - debug_printf("DEBUG: %.3f Getting response...\n", run_time()); - - while (status == HTTP_CONTINUE) - if (httpWait(http, 1000)) - status = httpUpdate(http); - else - { - status = HTTP_ERROR; - http->error = ETIMEDOUT; - } - - if (status != HTTP_OK) - { - /* - * Flush any error message... - */ - - httpFlush(http); - response = NULL; - } - else - { - /* - * Read the response... - */ - - response = ippNew(); - - while ((state = ippRead(http, response)) != IPP_DATA) - if (state == IPP_ERROR) - { - /* - * Delete the response... - */ - - ippDelete(response); - response = NULL; - - _cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno)); - break; - } - } - - /* - * Delete the original request and return the response... - */ - - ippDelete(request); - - if (response) - { - ipp_attribute_t *attr; /* status-message attribute */ - - - attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT); - - _cupsSetError(response->request.status.status_code, - attr ? attr->values[0].string.text : - ippErrorString(response->request.status.status_code)); - } - else if (status != HTTP_OK) - { - switch (status) - { - case HTTP_NOT_FOUND : - _cupsSetError(IPP_NOT_FOUND, httpStatus(status)); - break; - - case HTTP_UNAUTHORIZED : - _cupsSetError(IPP_NOT_AUTHORIZED, httpStatus(status)); - break; - - case HTTP_FORBIDDEN : - _cupsSetError(IPP_FORBIDDEN, httpStatus(status)); - break; - - case HTTP_BAD_REQUEST : - _cupsSetError(IPP_BAD_REQUEST, httpStatus(status)); - break; - - case HTTP_REQUEST_TOO_LARGE : - _cupsSetError(IPP_REQUEST_VALUE, httpStatus(status)); - break; - - case HTTP_NOT_IMPLEMENTED : - _cupsSetError(IPP_OPERATION_NOT_SUPPORTED, httpStatus(status)); - break; - - case HTTP_NOT_SUPPORTED : - _cupsSetError(IPP_VERSION_NOT_SUPPORTED, httpStatus(status)); - break; - - default : - _cupsSetError(IPP_SERVICE_UNAVAILABLE, httpStatus(status)); - break; - } - } - - return (response); -} - - /* * 'fix_make_model()' - Fix common problems in the make-and-model string. */ @@ -1718,216 +1652,67 @@ password_cb(const char *prompt) /* I - Prompt message */ static void probe_device(snmp_cache_t *device) /* I - Device */ { - int i, j; /* Looping vars */ - http_t *http; /* HTTP connection for IPP */ - char uri[1024]; /* Full device URI */ + char uri[1024], /* Full device URI */ + *uriptr, /* Pointer into URI */ + *format; /* Format string for device */ + device_uri_t *device_uri; /* Current DeviceURI match */ - /* - * Try connecting via IPP first... - */ - debug_printf("DEBUG: %.3f Probing %s...\n", run_time(), device->addrname); - if (device->make_and_model && - (!strncasecmp(device->make_and_model, "Epson", 5) || - !strncasecmp(device->make_and_model, "HP ", 3) || - !strncasecmp(device->make_and_model, "Hewlett", 7) || - !strncasecmp(device->make_and_model, "Kyocera", 7) || - !strncasecmp(device->make_and_model, "Lexmark", 7) || - !strncasecmp(device->make_and_model, "Tektronix", 9) || - !strncasecmp(device->make_and_model, "Xerox", 5))) - { - /* - * Epson, HP, Kyocera, Lexmark, Tektronix, and Xerox printers often lock - * up on IPP probes, so exclude them from the IPP connection test... - */ +#ifdef __APPLE__ + /* + * TODO: Try an mDNS query first, and then fallback on direct probes... + */ - http = NULL; - } - else + if (!try_connect(&(device->address), device->addrname, 5353)) { - /* - * Otherwise, try connecting for up to 1 second... - */ - - alarm(1); - http = httpConnect(device->addrname, 631); - alarm(0); + debug_printf("DEBUG: %s supports mDNS, not reporting!\n", device->addrname); + return; } +#endif /* __APPLE__ */ - if (http) - { - /* - * IPP is supported... - */ - - ipp_t *request, /* IPP request */ - *response; /* IPP response */ - ipp_attribute_t *model, /* printer-make-and-model attribute */ - *info, /* printer-info attribute */ - *supported; /* printer-uri-supported attribute */ - char make_model[256],/* Make and model string to use */ - temp[256]; /* Temporary make/model string */ - int num_uris; /* Number of good URIs */ - static const char * const resources[] = - { /* Common resource paths for IPP */ - "/ipp", - /*"/ipp/port2",*/ - /*"/ipp/port3",*/ - /*"/EPSON_IPP_Printer",*/ - "/LPT1", - "/LPT2", - "/COM1", - "/" - }; - - - /* - * Use non-blocking IO... - */ - - httpBlocking(http, 0); - - /* - * Loop through a list of common resources that covers 99% of the - * IPP-capable printers on the market today... - */ + /* + * Lookup the device in the match table... + */ - for (i = 0, num_uris = 0; - i < (int)(sizeof(resources) / sizeof(resources[0])); - i ++) + for (device_uri = (device_uri_t *)cupsArrayFirst(DeviceURIs); + device_uri; + device_uri = (device_uri_t *)cupsArrayNext(DeviceURIs)) + if (!regexec(&(device_uri->re), device->make_and_model, 0, NULL, 0)) { /* - * Stop early if we are out of time... - */ - - if (MaxRunTime > 0 && run_time() >= MaxRunTime) - break; - - /* - * Don't look past /ipp if we have found a working URI... + * Found a match, add the URIs... */ - if (num_uris > 0 && strncmp(resources[i], "/ipp", 4)) - break; - - httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, - device->addrname, 631, resources[i]); - - request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); - - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", - NULL, uri); - - response = do_request(http, request, resources[i]); - - debug_printf("DEBUG: %.3f %s %s (%s)\n", run_time(), uri, - ippErrorString(cupsLastError()), cupsLastErrorString()); - - if (response && response->request.status.status_code == IPP_OK) + for (format = (char *)cupsArrayFirst(device_uri->uris); + format; + format = (char *)cupsArrayNext(device_uri->uris)) { - model = ippFindAttribute(response, "printer-make-and-model", - IPP_TAG_TEXT); - info = ippFindAttribute(response, "printer-info", IPP_TAG_TEXT); - supported = ippFindAttribute(response, "printer-uri-supported", - IPP_TAG_URI); - - if (!supported) - { - fprintf(stderr, "ERROR: Missing printer-uri-supported from %s!\n", - device->addrname); - - httpClose(http); - return; - } - - debug_printf("DEBUG: printer-info=\"%s\"\n", - info ? info->values[0].string.text : "(null)"); - debug_printf("DEBUG: printer-make-and-model=\"%s\"\n", - model ? model->values[0].string.text : "(null)"); - - /* - * Don't advertise this port if the printer actually only supports - * a more generic version... - */ - - if (!strncmp(resources[i], "/ipp/", 5)) - { - for (j = 0; j < supported->num_values; j ++) - if (strstr(supported->values[j].string.text, "/ipp/")) - break; - - if (j >= supported->num_values) + for (uriptr = uri; *format && uriptr < (uri + sizeof(uri) - 1);) + if (*format == '%' && format[1] == 's') { - ippDelete(response); - break; - } - } - - /* - * Don't use the printer-info attribute if it does not contain the - * IEEE-1284 device ID data... - */ - - if (info && - (!strchr(info->values[0].string.text, ':') || - !strchr(info->values[0].string.text, ';'))) - info = NULL; - - /* - * Don't use the printer-make-and-model if it contains a generic - * string like "Ricoh IPP Printer"... - */ - - if (model && strstr(model->values[0].string.text, "IPP Printer")) - model = NULL; - - /* - * If we don't have a printer-make-and-model string from the printer - * but do have the 1284 device ID string, generate a make-and-model - * string from the device ID info... - */ - - if (model) - strlcpy(temp, model->values[0].string.text, sizeof(temp)); - else if (info) - backendGetMakeModel(info->values[0].string.text, temp, sizeof(temp)); - else - temp[0] = '\0'; - - fix_make_model(make_model, temp, sizeof(make_model)); + /* + * Insert hostname/address... + */ - /* - * Update the current device or add a new printer to the cache... - */ + strlcpy(uriptr, device->addrname, sizeof(uri) - (uriptr - uri)); + uriptr += strlen(uriptr); + format += 2; + } + else + *uriptr++ = *format++; - if (num_uris == 0) - update_cache(device, uri, - info ? info->values[0].string.text : NULL, - make_model[0] ? make_model : NULL); - else - add_cache(&(device->address), device->addrname, uri, - info ? info->values[0].string.text : NULL, - make_model[0] ? make_model : NULL); + *uriptr = '\0'; - num_uris ++; + update_cache(device, uri, NULL, NULL); } - ippDelete(response); - - if (num_uris > 0 && cupsLastError() != IPP_OK) - break; - } - - httpClose(http); - - if (num_uris > 0) return; - } + } /* - * OK, now try the standard ports... + * Then try the standard ports... */ if (!try_connect(&(device->address), device->addrname, 9100)) @@ -2011,6 +1796,15 @@ read_snmp_conf(const char *address) /* I - Single address to probe */ add_array(Communities, value); else if (!strcasecmp(line, "DebugLevel")) DebugLevel = atoi(value); + else if (!strcasecmp(line, "DeviceURI")) + { + if (*value != '\"') + fprintf(stderr, + "ERROR: Missing double quote for regular expression on " + "line %d of %s!\n", linenum, filename); + else + add_device_uri(value); + } else if (!strcasecmp(line, "HostNameLookups")) HostNameLookups = !strcasecmp(value, "on") || !strcasecmp(value, "yes") || @@ -2461,5 +2255,5 @@ update_cache(snmp_cache_t *device, /* I - Device */ /* - * End of "$Id: snmp.c 6403 2007-03-27 16:00:56Z mike $". + * End of "$Id: snmp.c 6495 2007-04-30 21:23:04Z mike $". */ diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c index d14076961..4cde9129c 100644 --- a/backend/usb-darwin.c +++ b/backend/usb-darwin.c @@ -1,5 +1,5 @@ /* - * "$Id: usb-darwin.c 6432 2007-04-02 21:50:28Z mike $" + * "$Id: usb-darwin.c 6491 2007-04-30 18:21:52Z mike $" * * Copyright © 2005-2007 Apple Inc. All rights reserved. * @@ -598,16 +598,6 @@ static Boolean list_device_callback(void *refcon, io_service_t obj) else strcpy(modelstr + 1, "Printer"); - /* - * Fix common HP 1284 bug... - */ - - if (!strcasecmp(makestr, "Hewlett-Packard")) - strcpy(makestr, "HP"); - - if (!strncasecmp(modelstr + 1, "hp ", 3)) - _cups_strcpy(modelstr + 1, modelstr + 4); - optionsstr[0] = '\0'; if (serial != NULL) { @@ -622,6 +612,16 @@ static Boolean list_device_callback(void *refcon, io_service_t obj) httpAssembleURI(HTTP_URI_CODING_ALL, uristr, sizeof(uristr), "usb", NULL, makestr, 0, modelstr); strncat(uristr, optionsstr, sizeof(uristr)); + /* + * Fix common HP 1284 bug... + */ + + if (!strcasecmp(makestr, "Hewlett-Packard")) + strcpy(makestr, "HP"); + + if (!strncasecmp(modelstr + 1, "hp ", 3)) + _cups_strcpy(modelstr + 1, modelstr + 4); + printf("direct %s \"%s %s\" \"%s %s USB\" \"%s\"\n", uristr, makestr, &modelstr[1], makestr, &modelstr[1], idstr); @@ -654,7 +654,7 @@ static Boolean find_device_callback(void *refcon, io_service_t obj) copy_deviceinfo(idString, &make, &model, &serial); if (CFStringCompare(make, userData->make, kCFCompareCaseInsensitive) == kCFCompareEqualTo) { if (CFStringCompare(model, userData->model, kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - if (userData->serial != NULL) { + if (userData->serial != NULL && CFStringGetLength(userData->serial) > 0 ) { if (serial != NULL && CFStringCompare(serial, userData->serial, kCFCompareCaseInsensitive) == kCFCompareEqualTo) { IOObjectRetain(obj); userData->printerObj = obj; @@ -1729,5 +1729,5 @@ static void usbGetDevState(printer_data_t *userData, cups_sc_status_t *status, c } /* - * End of "$Id: usb-darwin.c 6432 2007-04-02 21:50:28Z mike $". + * End of "$Id: usb-darwin.c 6491 2007-04-30 18:21:52Z mike $". */ diff --git a/backend/usb-unix.c b/backend/usb-unix.c index feddc046a..477fee2f6 100644 --- a/backend/usb-unix.c +++ b/backend/usb-unix.c @@ -1,5 +1,5 @@ /* - * "$Id: usb-unix.c 6437 2007-04-03 17:38:10Z mike $" + * "$Id: usb-unix.c 6510 2007-05-04 13:08:05Z mike $" * * USB port backend for the Common UNIX Printing System (CUPS). * @@ -80,10 +80,11 @@ print_device(const char *uri, /* I - Device URI */ do { -#ifdef __NetBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) /* - * NetBSD's ulpt driver currently does not support the - * back-channel... + * *BSD's ulpt driver currently does not support the + * back-channel, incorrectly returns data ready on a select(), + * and locks up on read()... */ use_bc = 0; @@ -100,7 +101,7 @@ print_device(const char *uri, /* I - Device URI */ strcasecmp(hostname, "Canon") && strcasecmp(hostname, "Konica Minolta") && strcasecmp(hostname, "Minolta"); -#endif /* __NetBSD__ */ +#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ */ if ((device_fd = open_device(uri, &use_bc)) == -1) { @@ -617,5 +618,5 @@ side_cb(int print_fd, /* I - Print file */ /* - * End of "$Id: usb-unix.c 6437 2007-04-03 17:38:10Z mike $". + * End of "$Id: usb-unix.c 6510 2007-05-04 13:08:05Z mike $". */ diff --git a/config-scripts/cups-compiler.m4 b/config-scripts/cups-compiler.m4 index 1af623a16..e2e0585e4 100644 --- a/config-scripts/cups-compiler.m4 +++ b/config-scripts/cups-compiler.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-compiler.m4 6264 2007-02-11 17:11:15Z mike $" +dnl "$Id: cups-compiler.m4 6447 2007-04-10 18:02:00Z mike $" dnl dnl Compiler stuff for the Common UNIX Printing System (CUPS). dnl @@ -435,6 +435,10 @@ case $uname in # HP-UX 11.00 (at least) needs this definition to get the # u_short type used by the IP headers... OPTIM="$OPTIM -D_INCLUDE_HPUX_SOURCE" + + # HP-UX 11.23 (at least) needs this definition to get the + # IPv6 header to work... + OPTIM="$OPTIM -D_HPUX_SOURCE" ;; OSF*) @@ -445,5 +449,5 @@ case $uname in esac dnl -dnl End of "$Id: cups-compiler.m4 6264 2007-02-11 17:11:15Z mike $". +dnl End of "$Id: cups-compiler.m4 6447 2007-04-10 18:02:00Z mike $". dnl diff --git a/configure.in b/configure.in index 2472ce6fc..0850d8d23 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl -dnl "$Id: configure.in 6291 2007-02-19 21:54:27Z mike $" +dnl "$Id: configure.in 6488 2007-04-30 17:45:57Z mike $" dnl dnl Configuration script for the Common UNIX Printing System (CUPS). dnl @@ -77,8 +77,8 @@ AC_SUBST(UNINSTALL_LANGUAGES) AC_OUTPUT(Makedefs packaging/cups.list init/cups.sh init/cups-lpd cups-config conf/cupsd.conf conf/pam.std doc/index.html - doc/help/standard.html man/client.conf.man - man/cups-deviced.man man/cups-driverd.man + doc/help/ref-cupsd-conf.html doc/help/standard.html + man/client.conf.man man/cups-deviced.man man/cups-driverd.man man/cups-lpd.man man/cupsaddsmb.man man/cupsd.man man/cupsd.conf.man man/lpoptions.man templates/edit-config.tmpl templates/header.tmpl @@ -87,5 +87,5 @@ AC_OUTPUT(Makedefs packaging/cups.list init/cups.sh init/cups-lpd cups-config chmod +x cups-config dnl -dnl End of "$Id: configure.in 6291 2007-02-19 21:54:27Z mike $". +dnl End of "$Id: configure.in 6488 2007-04-30 17:45:57Z mike $". dnl diff --git a/cups/array.c b/cups/array.c index b792c465c..50223a5ae 100644 --- a/cups/array.c +++ b/cups/array.c @@ -1,9 +1,9 @@ /* - * "$Id: array.c 6123 2006-11-21 15:36:04Z mike $" + * "$Id: array.c 6477 2007-04-25 19:55:45Z mike $" * * Sorted array routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -90,6 +90,9 @@ struct _cups_array_s /**** CUPS array structure ****/ void **elements; /* Array elements */ cups_array_func_t compare; /* Element comparison function */ void *data; /* User data passed to compare */ + cups_ahash_func_t hashfunc; /* Hash function */ + int hashsize, /* Size of hash */ + *hash; /* Hash array */ }; @@ -229,6 +232,9 @@ cupsArrayDelete(cups_array_t *a) /* I - Array */ if (a->alloc_elements) free(a->elements); + if (a->hashsize) + free(a->hash); + free(a); } @@ -306,7 +312,8 @@ cupsArrayFind(cups_array_t *a, /* I - Array */ void *e) /* I - Element */ { int current, /* Current element */ - diff; /* Difference */ + diff, /* Difference */ + hash; /* Hash index */ /* @@ -327,7 +334,30 @@ cupsArrayFind(cups_array_t *a, /* I - Array */ * Yes, look for a match... */ - current = cups_array_find(a, e, a->current, &diff); + if (a->hash) + { + hash = (*(a->hashfunc))(e, a->data); + + if (hash < 0 || hash >= a->hashsize) + { + current = a->current; + hash = -1; + } + else + { + current = a->hash[hash]; + + if (current < 0 || current >= a->num_elements) + current = a->current; + } + } + else + { + current = a->current; + hash = -1; + } + + current = cups_array_find(a, e, current, &diff); if (!diff) { /* @@ -348,6 +378,9 @@ cupsArrayFind(cups_array_t *a, /* I - Array */ a->current = current; + if (hash >= 0) + a->hash[hash] = current; + return (a->elements[current]); } else @@ -499,6 +532,22 @@ cupsArrayLast(cups_array_t *a) /* I - Array */ cups_array_t * /* O - Array */ cupsArrayNew(cups_array_func_t f, /* I - Comparison function */ void *d) /* I - User data */ +{ + return (cupsArrayNew2(f, d, 0, 0)); +} + + +/* + * 'cupsArrayNew2()' - Create a new array with hash. + * + * @since CUPS 1.3@ + */ + +cups_array_t * /* O - Array */ +cupsArrayNew2(cups_array_func_t f, /* I - Comparison function */ + void *d, /* I - User data */ + cups_ahash_func_t h, /* I - Hash function*/ + int hsize) /* I - Hash size */ { cups_array_t *a; /* Array */ @@ -518,6 +567,21 @@ cupsArrayNew(cups_array_func_t f, /* I - Comparison function */ a->num_saved = 0; a->unique = 1; + if (hsize > 0 && h) + { + a->hashfunc = h; + a->hashsize = hsize; + a->hash = malloc(hsize * sizeof(int)); + + if (!a->hash) + { + free(a); + return (NULL); + } + + memset(a->hash, -1, hsize * sizeof(int)); + } + return (a); } @@ -998,5 +1062,5 @@ cups_array_find(cups_array_t *a, /* I - Array */ /* - * End of "$Id: array.c 6123 2006-11-21 15:36:04Z mike $". + * End of "$Id: array.c 6477 2007-04-25 19:55:45Z mike $". */ diff --git a/cups/array.h b/cups/array.h index 6756a100a..47d28b930 100644 --- a/cups/array.h +++ b/cups/array.h @@ -1,9 +1,9 @@ /* - * "$Id: array.h 6123 2006-11-21 15:36:04Z mike $" + * "$Id: array.h 6477 2007-04-25 19:55:45Z mike $" * * Sorted array definitions for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -51,6 +51,9 @@ typedef struct _cups_array_s cups_array_t; /**** CUPS array type ****/ typedef int (*cups_array_func_t)(void *first, void *second, void *data); /**** Array comparison function ****/ +typedef int (*cups_ahash_func_t)(void *element, void *data); + /**** Array hash function ****/ + /* * Functions... @@ -70,6 +73,8 @@ extern void *cupsArrayIndex(cups_array_t *a, int n); extern int cupsArrayInsert(cups_array_t *a, void *e); extern void *cupsArrayLast(cups_array_t *a); extern cups_array_t *cupsArrayNew(cups_array_func_t f, void *d); +extern cups_array_t *cupsArrayNew2(cups_array_func_t f, void *d, + cups_ahash_func_t h, int hsize); extern void *cupsArrayNext(cups_array_t *a); extern void *cupsArrayPrev(cups_array_t *a); extern int cupsArrayRemove(cups_array_t *a, void *e); @@ -83,5 +88,5 @@ extern void *cupsArrayUserData(cups_array_t *a); #endif /* !_CUPS_ARRAY_H_ */ /* - * End of "$Id: array.h 6123 2006-11-21 15:36:04Z mike $". + * End of "$Id: array.h 6477 2007-04-25 19:55:45Z mike $". */ diff --git a/cups/auth.c b/cups/auth.c index 1ee0476f2..7a3f324c9 100644 --- a/cups/auth.c +++ b/cups/auth.c @@ -1,5 +1,5 @@ /* - * "$Id: auth.c 6397 2007-03-25 23:33:32Z mike $" + * "$Id: auth.c 6499 2007-04-30 21:44:43Z mike $" * * Authentication functions for the Common UNIX Printing System (CUPS). * @@ -468,17 +468,17 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ * Delete any previous authorization reference... */ - if (cg->auth_ref) + if (http->auth_ref) { - AuthorizationFree(cg->auth_ref, kAuthorizationFlagDefaults); - cg->auth_ref = NULL; + AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults); + http->auth_ref = NULL; } if (httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey", auth_key, sizeof(auth_key))) { status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, - kAuthorizationFlagDefaults, &cg->auth_ref); + kAuthorizationFlagDefaults, &http->auth_ref); if (status != errAuthorizationSuccess) { DEBUG_printf(("cups_local_auth: AuthorizationCreate() returned %d (%s)\n", @@ -499,11 +499,11 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights; - status = AuthorizationCopyRights(cg->auth_ref, &auth_rights, + status = AuthorizationCopyRights(http->auth_ref, &auth_rights, kAuthorizationEmptyEnvironment, auth_flags, NULL); if (status == errAuthorizationSuccess) - status = AuthorizationMakeExternalForm(cg->auth_ref, &auth_extrn); + status = AuthorizationMakeExternalForm(http->auth_ref, &auth_extrn); if (status == errAuthorizationSuccess) { @@ -583,5 +583,5 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ /* - * End of "$Id: auth.c 6397 2007-03-25 23:33:32Z mike $". + * End of "$Id: auth.c 6499 2007-04-30 21:44:43Z mike $". */ diff --git a/cups/cups.h b/cups/cups.h index 54103fffa..88b4d50de 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -1,5 +1,5 @@ /* - * "$Id: cups.h 6187 2007-01-10 16:20:42Z mike $" + * "$Id: cups.h 6506 2007-05-03 18:12:35Z mike $" * * API definitions for the Common UNIX Printing System (CUPS). * @@ -244,6 +244,10 @@ extern int cupsRemoveOption(const char *name, int num_options, extern cups_file_t *cupsTempFile2(char *filename, int len); /**** New in CUPS 1.3 ****/ +extern ipp_t *cupsDoIORequest(http_t *http, ipp_t *request, + const char *resource, int infile, + int outfile); +extern char *cupsGetServerPPD(http_t *http, const char *name); extern int cupsRemoveDest(const char *name, const char *instance, int num_dests, cups_dest_t **dests); @@ -260,5 +264,5 @@ extern void cupsSetDefaultDest(const char *name, #endif /* !_CUPS_CUPS_H_ */ /* - * End of "$Id: cups.h 6187 2007-01-10 16:20:42Z mike $". + * End of "$Id: cups.h 6506 2007-05-03 18:12:35Z mike $". */ diff --git a/cups/globals.c b/cups/globals.c index a0f323b16..4b09a427d 100644 --- a/cups/globals.c +++ b/cups/globals.c @@ -1,5 +1,5 @@ /* - * "$Id: globals.c 6253 2007-02-10 18:48:40Z mike $" + * "$Id: globals.c 6499 2007-04-30 21:44:43Z mike $" * * Global variable access routines for the Common UNIX Printing System (CUPS). * @@ -180,11 +180,6 @@ globals_destructor(void *value) /* I - Data to free */ cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings); -#ifdef HAVE_AUTHORIZATION_H - if (cg->auth_ref) - AuthorizationFree(cg->auth_ref, kAuthorizationFlagDefaults); -#endif /* HAVE_AUTHORIZATION_H */ - free(value); } @@ -231,5 +226,5 @@ _cupsGlobals(void) /* - * End of "$Id: globals.c 6253 2007-02-10 18:48:40Z mike $". + * End of "$Id: globals.c 6499 2007-04-30 21:44:43Z mike $". */ diff --git a/cups/globals.h b/cups/globals.h index 0db1dac2f..09fdbcad9 100644 --- a/cups/globals.h +++ b/cups/globals.h @@ -1,5 +1,5 @@ /* - * "$Id: globals.h 6253 2007-02-10 18:48:40Z mike $" + * "$Id: globals.h 6499 2007-04-30 21:44:43Z mike $" * * Global variable definitions for the Common UNIX Printing System (CUPS). * @@ -40,10 +40,6 @@ # include # endif /* HAVE_PTHREAD_H */ -# ifdef HAVE_AUTHORIZATION_H -# include -# endif /* HAVE_AUTHORIZATION_H */ - /* * C++ magic... @@ -130,11 +126,6 @@ typedef struct _cups_globals_s /**** CUPS global state data ****/ /* Default printer */ char ppd_filename[HTTP_MAX_URI]; /* PPD filename */ - -#ifdef HAVE_AUTHORIZATION_H - /* auth.c */ - AuthorizationRef auth_ref; /* Authorization ref */ -#endif /* HAVE_AUTHORIZATION_H */ } _cups_globals_t; @@ -157,5 +148,5 @@ extern void _cupsSetError(ipp_status_t status, const char *message); #endif /* !_CUPS_GLOBALS_H_ */ /* - * End of "$Id: globals.h 6253 2007-02-10 18:48:40Z mike $". + * End of "$Id: globals.h 6499 2007-04-30 21:44:43Z mike $". */ diff --git a/cups/http-private.h b/cups/http-private.h index 60dede364..fdf3d2da5 100644 --- a/cups/http-private.h +++ b/cups/http-private.h @@ -1,5 +1,5 @@ /* - * "$Id: http-private.h 6187 2007-01-10 16:20:42Z mike $" + * "$Id: http-private.h 6499 2007-04-30 21:44:43Z mike $" * * Private HTTP definitions for the Common UNIX Printing System (CUPS). * @@ -73,6 +73,10 @@ # endif /* !HAVE_GSS_C_NT_HOSTBASED_SERVICE */ # endif /* HAVE_GSSAPI */ +# ifdef HAVE_AUTHORIZATION_H +# include +# endif /* HAVE_AUTHORIZATION_H */ + # if defined(__sgi) || (defined(__APPLE__) && !defined(_SOCKLEN_T)) /* * IRIX and MacOS X 10.2.x do not define socklen_t, and in fact use an int instead of @@ -193,6 +197,9 @@ struct _http_s /**** HTTP connection structure. ****/ gss_ctx_id_t gssctx; /* Authentication context @since CUPS 1.3@ */ gss_name_t gssname; /* Authentication server name @since CUPS 1.3@ */ # endif /* HAVE_GSSAPI */ +# ifdef HAVE_AUTHORIZATION_H + AuthorizationRef auth_ref; /* Authorization ref */ +# endif /* HAVE_AUTHORIZATION_H */ }; @@ -265,5 +272,5 @@ extern void _cups_freeifaddrs(struct ifaddrs *addrs); #endif /* !_CUPS_HTTP_PRIVATE_H_ */ /* - * End of "$Id: http-private.h 6187 2007-01-10 16:20:42Z mike $". + * End of "$Id: http-private.h 6499 2007-04-30 21:44:43Z mike $". */ diff --git a/cups/http.c b/cups/http.c index 7a6f68408..251321d51 100644 --- a/cups/http.c +++ b/cups/http.c @@ -1,5 +1,5 @@ /* - * "$Id: http.c 6285 2007-02-16 01:10:55Z mike $" + * "$Id: http.c 6499 2007-04-30 21:44:43Z mike $" * * HTTP routines for the Common UNIX Printing System (CUPS). * @@ -335,6 +335,11 @@ httpClose(http_t *http) /* I - HTTP connection */ major_status = gss_release_name(&minor_status, &http->gssname); #endif /* HAVE_GSSAPI */ +#ifdef HAVE_AUTHORIZATION_H + if (http->auth_ref) + AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults); +#endif /* HAVE_AUTHORIZATION_H */ + httpClearFields(http); if (http->authstring && http->authstring != http->_authstring) @@ -2574,10 +2579,12 @@ http_send(http_t *http, /* I - HTTP connection */ httpClearFields(http); /* - * The Kerberos authentication string can only be used once... + * The Kerberos and AuthRef authentication strings can only be used once... */ - if (http->authstring && !strncmp(http->authstring, "Negotiate", 9)) + if (http->authstring && + (!strncmp(http->authstring, "Negotiate", 9) || + !strncmp(http->authstring, "AuthRef", 7))) { http->_authstring[0] = '\0'; @@ -3156,5 +3163,5 @@ http_write_ssl(http_t *http, /* I - HTTP connection */ /* - * End of "$Id: http.c 6285 2007-02-16 01:10:55Z mike $". + * End of "$Id: http.c 6499 2007-04-30 21:44:43Z mike $". */ diff --git a/cups/ipp-support.c b/cups/ipp-support.c index f868e3996..3ff58417f 100644 --- a/cups/ipp-support.c +++ b/cups/ipp-support.c @@ -1,10 +1,10 @@ /* - * "$Id: ipp-support.c 5903 2006-08-29 20:45:15Z mike $" + * "$Id: ipp-support.c 6503 2007-05-01 23:06:44Z mike $" * * Internet Printing Protocol support functions for the Common UNIX * Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -157,7 +157,8 @@ static char * const ipp_std_ops[] = "CUPS-Get-Devices", "CUPS-Get-PPDs", "CUPS-Move-Job", - "CUPS-Authenticate-Job" + "CUPS-Authenticate-Job", + "CUPS-Get-PPD" }; @@ -179,6 +180,8 @@ ippErrorString(ipp_status_t error) /* I - Error status */ return (ipp_status_oks[error]); else if (error == IPP_REDIRECTION_OTHER_SITE) return ("redirection-other-site"); + else if (error == CUPS_SEE_OTHER) + return ("cups-see-other"); else if (error >= IPP_BAD_REQUEST && error <= IPP_PRINT_SUPPORT_FILE_NOT_FOUND) return (ipp_status_400s[error - IPP_BAD_REQUEST]); else if (error >= IPP_INTERNAL_ERROR && error <= IPP_PRINTER_IS_DEACTIVATED) @@ -213,6 +216,9 @@ ippErrorValue(const char *name) /* I - Name */ if (!strcasecmp(name, "redirection-other-site")) return (IPP_REDIRECTION_OTHER_SITE); + if (!strcasecmp(name, "cups-see-other")) + return (CUPS_SEE_OTHER); + for (i = 0; i < (sizeof(ipp_status_400s) / sizeof(ipp_status_400s[0])); i ++) if (!strcasecmp(name, ipp_status_400s[i])) return ((ipp_status_t)(i + 0x400)); @@ -245,7 +251,7 @@ ippOpString(ipp_op_t op) /* I - Operation ID */ return (ipp_std_ops[op]); else if (op == IPP_PRIVATE) return ("windows-ext"); - else if (op >= CUPS_GET_DEFAULT && op <= CUPS_AUTHENTICATE_JOB) + else if (op >= CUPS_GET_DEFAULT && op <= CUPS_GET_PPD) return (ipp_cups_ops[op - CUPS_GET_DEFAULT]); /* @@ -364,5 +370,5 @@ ippSetPort(int p) /* I - Port number to use */ /* - * End of "$Id: ipp-support.c 5903 2006-08-29 20:45:15Z mike $". + * End of "$Id: ipp-support.c 6503 2007-05-01 23:06:44Z mike $". */ diff --git a/cups/ipp.h b/cups/ipp.h index d4ae704ea..a37448776 100644 --- a/cups/ipp.h +++ b/cups/ipp.h @@ -1,5 +1,5 @@ /* - * "$Id: ipp.h 5873 2006-08-24 14:37:24Z mike $" + * "$Id: ipp.h 6503 2007-05-01 23:06:44Z mike $" * * Internet Printing Protocol definitions for the Common UNIX Printing * System (CUPS). @@ -254,7 +254,8 @@ typedef enum ipp_op_e /**** IPP operations... ****/ CUPS_GET_DEVICES, /* Get a list of supported devices */ CUPS_GET_PPDS, /* Get a list of supported drivers */ CUPS_MOVE_JOB, /* Move a job to a different printer */ - CUPS_AUTHENTICATE_JOB /* Authenticate a job @since CUPS 1.2@ */ + CUPS_AUTHENTICATE_JOB, /* Authenticate a job @since CUPS 1.2@ */ + CUPS_GET_PPD /* Get a PPD file @since CUPS 1.3@ */ } ipp_op_t; /* Old names for the operations */ @@ -271,7 +272,8 @@ typedef enum ipp_status_e /**** IPP status codes... ****/ IPP_OK_TOO_MANY_EVENTS, /* successful-ok-too-many-events */ IPP_OK_BUT_CANCEL_SUBSCRIPTION, /* successful-ok-but-cancel-subscription */ IPP_OK_EVENTS_COMPLETE, /* successful-ok-events-complete */ - IPP_REDIRECTION_OTHER_SITE = 0x300, /* */ + IPP_REDIRECTION_OTHER_SITE = 0x200, /* */ + CUPS_SEE_OTHER = 0x280, /* cups-see-other */ IPP_BAD_REQUEST = 0x0400, /* client-error-bad-request */ IPP_FORBIDDEN, /* client-error-forbidden */ IPP_NOT_AUTHENTICATED, /* client-error-not-authenticated */ @@ -499,5 +501,5 @@ extern ipp_state_t ippWriteIO(void *dst, ipp_iocb_t cb, int blocking, #endif /* !_CUPS_IPP_H_ */ /* - * End of "$Id: ipp.h 5873 2006-08-24 14:37:24Z mike $". + * End of "$Id: ipp.h 6503 2007-05-01 23:06:44Z mike $". */ diff --git a/cups/language.c b/cups/language.c index 78e22e8ee..21c6ad782 100644 --- a/cups/language.c +++ b/cups/language.c @@ -1,5 +1,5 @@ /* - * "$Id: language.c 6407 2007-03-27 17:45:12Z mike $" + * "$Id: language.c 6489 2007-04-30 17:55:15Z mike $" * * I18N/language support for the Common UNIX Printing System (CUPS). * @@ -984,6 +984,21 @@ _cupsMessageLookup(cups_array_t *a, /* I - Message array */ */ # ifdef HAVE_CF_LOCALE_ID + +typedef struct +{ + const char * const name; /* Language name */ + const char * const locale; /* Locale name */ +} _apple_name_locale_t; + +static const _apple_name_locale_t apple_name_locale[] = +{ + { "en" , "en_US" }, + { "no" , "nb" }, + { "zh-Hans" , "zh_CN" }, + { "zh-Hant" , "zh_TW" } +}; + /* * 'appleLangDefault()' - Get the default locale string. */ @@ -991,6 +1006,7 @@ _cupsMessageLookup(cups_array_t *a, /* I - Message array */ static const char * /* O - Locale string */ appleLangDefault(void) { + int i; /* Looping var */ CFPropertyListRef localizationList; /* List of localization data */ CFStringRef languageName; /* Current name */ @@ -1033,9 +1049,30 @@ appleLangDefault(void) kCFStringEncodingASCII); CFRelease(localeName); - if (!strcmp(cg->language, "en")) - strlcpy(cg->language, "en_US.UTF-8", sizeof(cg->language)); - else if (strchr(cg->language, '.') == NULL) + /* + * Map new language identifiers to locales... + */ + + for (i = 0; + i < sizeof(apple_name_locale) / sizeof(apple_name_locale[0]); + i++) + { + if (!strcmp(cg->language, apple_name_locale[i].name)) + { + strlcpy(cg->language, apple_name_locale[i].locale, + sizeof(cg->language)); + break; + } + } + + /* + * Convert language subtag into region subtag... + */ + + if (cg->language[2] == '-') + cg->language[2] = '_'; + + if (strchr(cg->language, '.') == NULL) strlcat(cg->language, ".UTF-8", sizeof(cg->language)); } } @@ -1326,5 +1363,5 @@ cups_unquote(char *d, /* O - Unquoted string */ /* - * End of "$Id: language.c 6407 2007-03-27 17:45:12Z mike $". + * End of "$Id: language.c 6489 2007-04-30 17:55:15Z mike $". */ diff --git a/cups/localize.c b/cups/localize.c index ee88a790f..bf3a5303b 100644 --- a/cups/localize.c +++ b/cups/localize.c @@ -1,5 +1,5 @@ /* - * "$Id: localize.c 6388 2007-03-24 14:21:31Z mike $" + * "$Id: localize.c 6457 2007-04-17 18:40:55Z mike $" * * PPD custom option routines for the Common UNIX Printing System (CUPS). * @@ -96,6 +96,32 @@ ppdLocalize(ppd_file_t *ppd) /* I - PPD file */ strlcpy(ll_CC, lang->language, sizeof(ll_CC)); strlcpy(ll, lang->language, sizeof(ll)); + if (strlen(ll_CC) == 2) + { + /* + * Map "ll" to primary/origin country locales to have the best + * chance of finding a match... + */ + + if (!strcmp(ll_CC, "cs")) + strcpy(ll_CC, "cs_CZ"); + else if (!strcmp(ll_CC, "en")) + strcpy(ll_CC, "en_US"); + else if (!strcmp(ll_CC, "ja")) + strcpy(ll_CC, "ja_JP"); + else if (!strcmp(ll_CC, "sv")) + strcpy(ll_CC, "sv_SE"); + else if (!strcmp(ll_CC, "zh")) + strcpy(ll_CC, "zh_CN"); /* Simplified Chinese */ + else + { + ll_CC[2] = '_'; + ll_CC[3] = toupper(ll_CC[0] & 255); + ll_CC[4] = toupper(ll_CC[1] & 255); + ll_CC[5] = '\0'; + } + } + DEBUG_printf((" lang->language=\"%s\", ll=\"%s\", ll_CC=\"%s\"...\n", lang->language, ll, ll_CC)); @@ -239,5 +265,5 @@ ppd_text(ppd_file_t *ppd, /* I - PPD file */ /* - * End of "$Id: localize.c 6388 2007-03-24 14:21:31Z mike $". + * End of "$Id: localize.c 6457 2007-04-17 18:40:55Z mike $". */ diff --git a/cups/mark.c b/cups/mark.c index 20a94fd4a..6f68d6b00 100644 --- a/cups/mark.c +++ b/cups/mark.c @@ -1,5 +1,5 @@ /* - * "$Id: mark.c 6187 2007-01-10 16:20:42Z mike $" + * "$Id: mark.c 6477 2007-04-25 19:55:45Z mike $" * * Option marking routines for the Common UNIX Printing System (CUPS). * @@ -59,14 +59,15 @@ static void ppd_defaults(ppd_file_t *ppd, ppd_group_t *g); * 'ppdConflicts()' - Check to see if there are any conflicts. */ -int /* O - Number of conflicts found */ -ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */ +int /* O - Number of conflicts found */ +ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */ { - int i, j, /* Looping variables */ - conflicts; /* Number of conflicts */ - ppd_const_t *c; /* Current constraint */ - ppd_option_t *o1, *o2; /* Options */ - ppd_choice_t *c1, *c2; /* Choices */ + int i, /* Looping variable */ + conflicts; /* Number of conflicts */ + ppd_const_t *c; /* Current constraint */ + ppd_option_t *o1, *o2; /* Options */ + ppd_choice_t *c1, *c2; /* Choices */ + ppd_choice_t key; /* Search key */ if (!ppd) @@ -86,38 +87,45 @@ ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */ * that conflict... */ - for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++) + for (i = ppd->num_consts, c = ppd->consts, o1 = o2 = NULL, c1 = c2 = NULL; + i > 0; + i --, c ++) { /* * Grab pointers to the first option... */ - o1 = ppdFindOption(ppd, c->option1); + if (!o1 || strcmp(c->option1, o1->keyword)) + { + o1 = ppdFindOption(ppd, c->option1); + c1 = NULL; + } if (!o1) continue; - else if (c->choice1[0]) + else if (c->choice1[0] && (!c1 || strcmp(c->choice1, c1->choice))) { /* * This constraint maps to a specific choice. */ - c1 = ppdFindChoice(o1, c->choice1); + key.option = o1; + + if ((c1 = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL && + !c1->marked) + c1 = NULL; } - else + else if (!c1) { /* * This constraint applies to any choice for this option. */ - for (j = o1->num_choices, c1 = o1->choices; j > 0; j --, c1 ++) - if (c1->marked) - break; + key.option = o1; - if (!j || - !strcasecmp(c1->choice, "None") || - !strcasecmp(c1->choice, "Off") || - !strcasecmp(c1->choice, "False")) + if ((c1 = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL && + (!strcasecmp(c1->choice, "None") || !strcasecmp(c1->choice, "Off") || + !strcasecmp(c1->choice, "False"))) c1 = NULL; } @@ -125,32 +133,37 @@ ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */ * Grab pointers to the second option... */ - o2 = ppdFindOption(ppd, c->option2); + if (!o2 || strcmp(c->option2, o2->keyword)) + { + o2 = ppdFindOption(ppd, c->option2); + c2 = NULL; + } if (!o2) continue; - else if (c->choice2[0]) + else if (c->choice2[0] && (!c2 || strcmp(c->choice2, c2->choice))) { /* * This constraint maps to a specific choice. */ - c2 = ppdFindChoice(o2, c->choice2); + key.option = o2; + + if ((c2 = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL && + !c2->marked) + c2 = NULL; } - else + else if (!c2) { /* * This constraint applies to any choice for this option. */ - for (j = o2->num_choices, c2 = o2->choices; j > 0; j --, c2 ++) - if (c2->marked) - break; + key.option = o2; - if (!j || - !strcasecmp(c2->choice, "None") || - !strcasecmp(c2->choice, "Off") || - !strcasecmp(c2->choice, "False")) + if ((c2 = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL && + (!strcasecmp(c2->choice, "None") || !strcasecmp(c2->choice, "Off") || + !strcasecmp(c2->choice, "False"))) c2 = NULL; } @@ -185,8 +198,8 @@ ppd_choice_t * /* O - Choice pointer or NULL */ ppdFindChoice(ppd_option_t *o, /* I - Pointer to option */ const char *choice) /* I - Name of choice */ { - int i; /* Looping var */ - ppd_choice_t *c; /* Current choice */ + int i; /* Looping var */ + ppd_choice_t *c; /* Current choice */ if (o == NULL || choice == NULL) @@ -208,19 +221,13 @@ ppd_choice_t * /* O - Pointer to choice or NULL */ ppdFindMarkedChoice(ppd_file_t *ppd, /* I - PPD file */ const char *option) /* I - Keyword/option name */ { - int i; /* Looping var */ - ppd_option_t *o; /* Pointer to option */ - ppd_choice_t *c; /* Pointer to choice */ + ppd_choice_t key; /* Search key for choice */ - if ((o = ppdFindOption(ppd, option)) == NULL) + if ((key.option = ppdFindOption(ppd, option)) == NULL) return (NULL); - for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) - if (c->marked) - return (c); - - return (NULL); + return ((ppd_choice_t *)cupsArrayFind(ppd->marked, &key)); } @@ -279,25 +286,25 @@ ppdFindOption(ppd_file_t *ppd, /* I - PPD file data */ * 'ppdIsMarked()' - Check to see if an option is marked... */ -int /* O - Non-zero if option is marked */ -ppdIsMarked(ppd_file_t *ppd, /* I - PPD file data */ - const char *option, /* I - Option/Keyword name */ - const char *choice) /* I - Choice name */ +int /* O - Non-zero if option is marked */ +ppdIsMarked(ppd_file_t *ppd, /* I - PPD file data */ + const char *option, /* I - Option/Keyword name */ + const char *choice) /* I - Choice name */ { - ppd_option_t *o; /* Option pointer */ - ppd_choice_t *c; /* Choice pointer */ + ppd_choice_t key, /* Search key */ + *c; /* Choice pointer */ - if (ppd == NULL) + if (!ppd) return (0); - if ((o = ppdFindOption(ppd, option)) == NULL) + if ((key.option = ppdFindOption(ppd, option)) == NULL) return (0); - if ((c = ppdFindChoice(o, choice)) == NULL) + if ((c = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) == NULL) return (0); - return (c->marked); + return (!strcmp(c->choice, choice)); } @@ -306,15 +313,29 @@ ppdIsMarked(ppd_file_t *ppd, /* I - PPD file data */ */ void -ppdMarkDefaults(ppd_file_t *ppd)/* I - PPD file record */ +ppdMarkDefaults(ppd_file_t *ppd) /* I - PPD file record */ { - int i; /* Looping variables */ - ppd_group_t *g; /* Current group */ + int i; /* Looping variables */ + ppd_group_t *g; /* Current group */ + ppd_choice_t *c; /* Current choice */ - if (ppd == NULL) + if (!ppd) return; + /* + * Clean out the marked array... + */ + + for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked); + c; + c = (ppd_choice_t *)cupsArrayNext(ppd->marked)) + cupsArrayRemove(ppd->marked, c); + + /* + * Then repopulate it with the defaults... + */ + for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++) ppd_defaults(ppd, g); } @@ -336,7 +357,9 @@ ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */ { int i, j; /* Looping vars */ ppd_option_t *o; /* Option pointer */ - ppd_choice_t *c; /* Choice pointer */ + ppd_choice_t *c, /* Choice pointer */ + *oldc, /* Old choice pointer */ + key; /* Search key for choice */ struct lconv *loc; /* Locale data */ @@ -358,8 +381,14 @@ ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */ if (!strcasecmp(option, "AP_D_InputSlot")) { if ((o = ppdFindOption(ppd, "InputSlot")) != NULL) - for (i = 0; i < o->num_choices; i ++) - o->choices[i].marked = 0; + { + key.option = o; + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + } } /* @@ -542,73 +571,98 @@ ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */ * Option found; mark it and then handle unmarking any other options. */ - c->marked = 1; - if (o->ui != PPD_UI_PICKMANY) { /* * Unmark all other choices... */ - for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) - if (strcasecmp(c->choice, choice)) + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, c)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + + if (!strcasecmp(option, "PageSize") || !strcasecmp(option, "PageRegion")) + { + /* + * Mark current page size... + */ + + for (j = 0; j < ppd->num_sizes; j ++) + ppd->sizes[j].marked = !strcasecmp(ppd->sizes[j].name, + choice); + + /* + * Unmark the current PageSize or PageRegion setting, as + * appropriate... + */ + + if (!strcasecmp(option, "PageSize")) { - c->marked = 0; + if ((o = ppdFindOption(ppd, "PageRegion")) != NULL) + { + key.option = o; + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + } + } + else + { + if ((o = ppdFindOption(ppd, "PageSize")) != NULL) + { + key.option = o; + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + } + } + } + else if (!strcasecmp(option, "InputSlot")) + { + /* + * Unmark ManualFeed True and possibly mark ManualFeed False + * option... + */ - if (!strcasecmp(option, "PageSize") || - !strcasecmp(option, "PageRegion")) - { - /* - * Mark current page size... - */ - - for (j = 0; j < ppd->num_sizes; j ++) - ppd->sizes[j].marked = !strcasecmp(ppd->sizes[j].name, - choice); - - /* - * Unmark the current PageSize or PageRegion setting, as - * appropriate... - */ - - if (!strcasecmp(option, "PageSize")) - { - if ((o = ppdFindOption(ppd, "PageRegion")) != NULL) - for (j = 0; j < o->num_choices; j ++) - o->choices[j].marked = 0; - } - else - { - if ((o = ppdFindOption(ppd, "PageSize")) != NULL) - for (j = 0; j < o->num_choices; j ++) - o->choices[j].marked = 0; - } - } - else if (!strcasecmp(option, "InputSlot")) - { - /* - * Unmark ManualFeed True and possibly mark ManualFeed False - * option... - */ - - if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL) - for (j = 0; j < o->num_choices; j ++) - o->choices[j].marked = !strcasecmp(o->choices[j].choice, "False"); - } - else if (!strcasecmp(option, "ManualFeed") && - !strcasecmp(choice, "True")) - { - /* - * Unmark InputSlot option... - */ + if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL) + { + key.option = o; + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + } + } + else if (!strcasecmp(option, "ManualFeed") && + !strcasecmp(choice, "True")) + { + /* + * Unmark InputSlot option... + */ - if ((o = ppdFindOption(ppd, "InputSlot")) != NULL) - for (j = 0; j < o->num_choices; j ++) - o->choices[j].marked = 0; - } + if ((o = ppdFindOption(ppd, "InputSlot")) != NULL) + { + key.option = o; + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } } + } } + c->marked = 1; + + cupsArrayAdd(ppd->marked, c); + /* * Return the number of conflicts... */ @@ -666,9 +720,6 @@ ppd_defaults(ppd_file_t *ppd, /* I - PPD file */ ppd_group_t *sg; /* Current sub-group */ - if (g == NULL) - return; - for (i = g->num_options, o = g->options; i > 0; i --, o ++) if (strcasecmp(o->keyword, "PageRegion") != 0) ppdMarkOption(ppd, o->keyword, o->defchoice); @@ -679,5 +730,5 @@ ppd_defaults(ppd_file_t *ppd, /* I - PPD file */ /* - * End of "$Id: mark.c 6187 2007-01-10 16:20:42Z mike $". + * End of "$Id: mark.c 6477 2007-04-25 19:55:45Z mike $". */ diff --git a/cups/ppd.c b/cups/ppd.c index c25e57ce2..d68a1209c 100644 --- a/cups/ppd.c +++ b/cups/ppd.c @@ -1,5 +1,5 @@ /* - * "$Id: ppd.c 6445 2007-04-04 23:43:26Z mike $" + * "$Id: ppd.c 6479 2007-04-27 11:44:10Z mike $" * * PPD file routines for the Common UNIX Printing System (CUPS). * @@ -48,6 +48,8 @@ * ppd_add_choice() - Add a choice to an option. * ppd_add_size() - Add a page size. * ppd_compare_attrs() - Compare two attributes. + * ppd_compare_choices() - Compare two choices... + * ppd_compare_consts() - Compare two constraints. * ppd_compare_coptions() - Compare two custom options. * ppd_compare_cparams() - Compare two custom parameters. * ppd_compare_options() - Compare two options. @@ -58,6 +60,7 @@ * ppd_get_cparam() - Get a custom parameter record. * ppd_get_group() - Find or create the named group as needed. * ppd_get_option() - Find or create the named option as needed. + * ppd_hash_option() - Generate a hash of the option name... * ppd_read() - Read a line from a PPD file, skipping comment * lines as necessary. */ @@ -90,6 +93,8 @@ #define PPD_TEXT 4 /* Line contained human-readable text */ #define PPD_STRING 8 /* Line contained a string or code */ +#define PPD_HASHSIZE 512 /* Size of hash */ + /* * Local functions... @@ -101,6 +106,8 @@ static ppd_attr_t *ppd_add_attr(ppd_file_t *ppd, const char *name, static ppd_choice_t *ppd_add_choice(ppd_option_t *option, const char *name); static ppd_size_t *ppd_add_size(ppd_file_t *ppd, const char *name); static int ppd_compare_attrs(ppd_attr_t *a, ppd_attr_t *b); +static int ppd_compare_choices(ppd_choice_t *a, ppd_choice_t *b); +static int ppd_compare_consts(ppd_const_t *a, ppd_const_t *b); static int ppd_compare_coptions(ppd_coption_t *a, ppd_coption_t *b); static int ppd_compare_cparams(ppd_cparam_t *a, ppd_cparam_t *b); @@ -116,6 +123,7 @@ static ppd_group_t *ppd_get_group(ppd_file_t *ppd, const char *name, const char *text, _cups_globals_t *cg, cups_encoding_t encoding); static ppd_option_t *ppd_get_option(ppd_group_t *group, const char *name); +static int ppd_hash_option(ppd_option_t *option); static int ppd_read(cups_file_t *fp, char *keyword, char *option, char *text, char **string, int ignoreblank, _cups_globals_t *cg); @@ -184,6 +192,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ } cupsArrayDelete(ppd->options); + cupsArrayDelete(ppd->marked); /* * Free any page sizes... @@ -1892,7 +1901,9 @@ ppdOpen2(cups_file_t *fp) /* I - File to read from */ * each choice and custom option... */ - ppd->options = cupsArrayNew((cups_array_func_t)ppd_compare_options, NULL); + ppd->options = cupsArrayNew2((cups_array_func_t)ppd_compare_options, NULL, + (cups_ahash_func_t)ppd_hash_option, + PPD_HASHSIZE); for (i = ppd->num_groups, group = ppd->groups; i > 0; @@ -1915,6 +1926,20 @@ ppdOpen2(cups_file_t *fp) /* I - File to read from */ } } + /* + * Sort the constraints... + */ + + if (ppd->num_consts > 1) + qsort(ppd->consts, ppd->num_consts, sizeof(ppd_const_t), + (int (*)(const void *, const void *))ppd_compare_consts); + + /* + * Create an array to track the marked choices... + */ + + ppd->marked = cupsArrayNew((cups_array_func_t)ppd_compare_choices, NULL); + /* * Return the PPD file structure... */ @@ -2208,6 +2233,40 @@ ppd_compare_attrs(ppd_attr_t *a, /* I - First attribute */ } +/* + * 'ppd_compare_choices()' - Compare two choices... + */ + +static int /* O - Result of comparison */ +ppd_compare_choices(ppd_choice_t *a, /* I - First choice */ + ppd_choice_t *b) /* I - Second choice */ +{ + return (a->option - b->option); +} + + +/* + * 'ppd_compare_consts()' - Compare two constraints. + */ + +static int /* O - Result of comparison */ +ppd_compare_consts(ppd_const_t *a, /* I - First constraint */ + ppd_const_t *b) /* I - Second constraint */ +{ + int ret; /* Result of comparison */ + + + if ((ret = strcmp(a->option1, b->option1)) != 0) + return (ret); + else if ((ret = strcmp(a->choice1, b->choice1)) != 0) + return (ret); + else if ((ret = strcmp(a->option2, b->option2)) != 0) + return (ret); + else + return (strcmp(a->choice2, b->choice2)); +} + + /* * 'ppd_compare_coptions()' - Compare two custom options. */ @@ -2545,6 +2604,24 @@ ppd_get_option(ppd_group_t *group, /* I - Group */ } +/* + * 'ppd_hash_option()' - Generate a hash of the option name... + */ + +static int /* O - Hash index */ +ppd_hash_option(ppd_option_t *option) /* I - Option */ +{ + int hash = 0; /* Hash index */ + const char *k; /* Pointer into keyword */ + + + for (hash = option->keyword[0], k = option->keyword + 1; *k;) + hash = 33 * hash + *k++; + + return (hash & 511); +} + + /* * 'ppd_read()' - Read a line from a PPD file, skipping comment lines as * necessary. @@ -3102,5 +3179,5 @@ ppd_read(cups_file_t *fp, /* I - File to read from */ /* - * End of "$Id: ppd.c 6445 2007-04-04 23:43:26Z mike $". + * End of "$Id: ppd.c 6479 2007-04-27 11:44:10Z mike $". */ diff --git a/cups/ppd.h b/cups/ppd.h index d7688c3d5..b0ded47cc 100644 --- a/cups/ppd.h +++ b/cups/ppd.h @@ -1,10 +1,10 @@ /* - * "$Id: ppd.h 5238 2006-03-07 04:41:42Z mike $" + * "$Id: ppd.h 6477 2007-04-25 19:55:45Z mike $" * * PostScript Printer Description definitions for the Common UNIX Printing * System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -331,6 +331,9 @@ typedef struct ppd_file_s /**** PPD File ****/ cups_array_t *sorted_attrs; /* Attribute lookup array @since CUPS 1.2@ @private@ */ cups_array_t *options; /* Option lookup array @since CUPS 1.2@ @private@ */ cups_array_t *coptions; /* Custom options array @since CUPS 1.2@ @private@ */ + + /**** New in CUPS 1.3 ****/ + cups_array_t *marked; /* Marked choices @since CUPS 1.3@ @private@ */ } ppd_file_t; @@ -405,5 +408,5 @@ extern ppd_file_t *ppdOpen2(cups_file_t *fp); #endif /* !_CUPS_PPD_H_ */ /* - * End of "$Id: ppd.h 5238 2006-03-07 04:41:42Z mike $". + * End of "$Id: ppd.h 6477 2007-04-25 19:55:45Z mike $". */ diff --git a/cups/request.c b/cups/request.c index 95870a8fc..5e80fd645 100644 --- a/cups/request.c +++ b/cups/request.c @@ -1,5 +1,5 @@ /* - * "$Id: request.c 6416 2007-03-30 18:30:33Z mike $" + * "$Id: request.c 6506 2007-05-03 18:12:35Z mike $" * * IPP utilities for the Common UNIX Printing System (CUPS). * @@ -45,6 +45,9 @@ #else # include #endif /* WIN32 || __EMX__ */ +#ifndef O_BINARY +# define O_BINARY 0 +#endif /* O_BINARY */ /* @@ -60,20 +63,71 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ ipp_t *request, /* I - IPP request */ const char *resource, /* I - HTTP resource for POST */ const char *filename) /* I - File to send or NULL for none */ +{ + ipp_t *response; /* IPP response data */ + int infile; /* Input file */ + + + if (filename) + { + if ((infile = open(filename, O_RDONLY | O_BINARY)) < 0) + { + /* + * Can't get file information! + */ + + _cupsSetError(errno == ENOENT ? IPP_NOT_FOUND : IPP_NOT_AUTHORIZED, + strerror(errno)); + + ippDelete(request); + + return (NULL); + } + } + else + infile = -1; + + response = cupsDoIORequest(http, request, resource, infile, -1); + + if (infile >= 0) + close(infile); + + return (response); +} + + +/* + * 'cupsDoIORequest()' - Do an IPP request with file descriptors. + * + * This function sends the IPP request to the specified server, retrying + * and authenticating as necessary. The request is freed with ippDelete() + * after receiving a valid IPP response. + * + * If "infile" is a valid file descriptor, cupsDoIORequest() copies + * all of the data from the file after the IPP request message. + * + * If "outfile" is a valid file descriptor, cupsDoIORequest() copies + * all of the data after the IPP response message to the file. + * + * @since CUPS 1.3@ + */ + +ipp_t * /* O - Response data */ +cupsDoIORequest(http_t *http, /* I - HTTP connection to server */ + ipp_t *request, /* I - IPP request */ + const char *resource, /* I - HTTP resource for POST */ + int infile, /* I - File to read from or -1 for none */ + int outfile) /* I - File to write to or -1 for none */ { ipp_t *response; /* IPP response data */ size_t length; /* Content-Length value */ http_status_t status; /* Status of HTTP request */ int got_status; /* Did we get the status? */ ipp_state_t state; /* State of IPP processing */ - FILE *file; /* File to send */ struct stat fileinfo; /* File information */ int bytes; /* Number of bytes read/written */ char buffer[32768]; /* Output buffer */ http_status_t expect; /* Expect: header to use */ -#ifdef HAVE_AUTHORIZATION_H - _cups_globals_t *cg = _cupsGlobals(); /* Global data */ -#endif /* HAVE_AUTHORIZATION_H */ DEBUG_printf(("cupsDoFileRequest(%p, %p, \'%s\', \'%s\')\n", @@ -94,16 +148,16 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ * See if we have a file to send... */ - if (filename != NULL) + if (infile >= 0) { - if (stat(filename, &fileinfo)) + if (fstat(infile, &fileinfo)) { /* * Can't get file information! */ _cupsSetError(errno == ENOENT ? IPP_NOT_FOUND : IPP_NOT_AUTHORIZED, - strerror(errno)); + strerror(errno)); ippDelete(request); @@ -126,23 +180,7 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ return (NULL); } - - if ((file = fopen(filename, "rb")) == NULL) - { - /* - * Can't open file! - */ - - _cupsSetError(errno == ENOENT ? IPP_NOT_FOUND : IPP_NOT_AUTHORIZED, - strerror(errno)); - - ippDelete(request); - - return (NULL); - } } - else - file = NULL; #ifdef HAVE_SSL /* @@ -174,8 +212,15 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ */ length = ippLength(request); - if (filename) + if (infile >= 0) + { +#ifndef WIN32 + if (!S_ISREG(fileinfo.st_mode)) + length = 0; /* Chunk when piping */ + else +#endif /* !WIN32 */ length += fileinfo.st_size; + } httpClearFields(http); httpSetLength(http, length); @@ -235,7 +280,7 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ else if (httpCheck(http)) status = httpUpdate(http); - if (status == HTTP_CONTINUE && state == IPP_DATA && filename) + if (status == HTTP_CONTINUE && state == IPP_DATA && infile >= 0) { DEBUG_puts("cupsDoFileRequest: file write..."); @@ -243,9 +288,12 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ * Send the file... */ - rewind(file); +#ifndef WIN32 + if (S_ISREG(fileinfo.st_mode)) +#endif /* WIN32 */ + lseek(infile, 0, SEEK_SET); - while ((bytes = (int)fread(buffer, 1, sizeof(buffer), file)) > 0) + while ((bytes = (int)read(infile, buffer, sizeof(buffer))) > 0) { if (httpCheck(http)) { @@ -377,21 +425,26 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ break; } - } - } - - /* - * Close the file if needed... - */ - - if (filename != NULL) - fclose(file); + else if (outfile >= 0) + { + /* + * Write trailing data to file... + */ - /* - * Flush any remaining data... - */ + while ((bytes = (int)httpRead2(http, buffer, sizeof(buffer))) > 0) + if (write(outfile, buffer, bytes) < bytes) + break; + } + else + { + /* + * Flush any remaining data... + */ - httpFlush(http); + httpFlush(http); + } + } + } /* * Delete the original request and return the response... @@ -450,18 +503,6 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ } } -#ifdef HAVE_AUTHORIZATION_H - /* - * Delete any authorization reference created for this request... - */ - - if (cg->auth_ref) - { - AuthorizationFree(cg->auth_ref, kAuthorizationFlagDefaults); - cg->auth_ref = NULL; - } -#endif /* HAVE_AUTHORIZATION_H */ - return (response); } @@ -510,5 +551,5 @@ _cupsSetError(ipp_status_t status, /* I - IPP status code */ /* - * End of "$Id: request.c 6416 2007-03-30 18:30:33Z mike $". + * End of "$Id: request.c 6506 2007-05-03 18:12:35Z mike $". */ diff --git a/cups/util.c b/cups/util.c index 0e321ce0c..9da9f1533 100644 --- a/cups/util.c +++ b/cups/util.c @@ -1,5 +1,5 @@ /* - * "$Id: util.c 6138 2006-12-06 18:52:39Z mike $" + * "$Id: util.c 6506 2007-05-03 18:12:35Z mike $" * * Printing utilities for the Common UNIX Printing System (CUPS). * @@ -40,6 +40,7 @@ * cupsGetPPD2() - Get the PPD file for a printer on the specified * server. * cupsGetPrinters() - Get a list of printers from the default server. + * cupsGetServerPPD() - Get an available PPD file from the server. * cupsLastError() - Return the last IPP status code. * cupsLastErrorString() - Return the last IPP status-message. * cupsPrintFile() - Print a file to a printer or class on the default @@ -1069,6 +1070,82 @@ cupsGetPrinters(char ***printers) /* O - Printers */ } +/* + * 'cupsGetServerPPD()' - Get an available PPD file from the server. + * + * This function returns the named PPD file from the server. The + * list of available PPDs is provided by the IPP CUPS_GET_PPDS + * operation. + * + * You must remove (unlink) the PPD file when you are finished with + * it. The PPD filename is stored in a static location that will be + * overwritten on the next call to cupsGetPPD(), cupsGetPPD2(), or + * cupsGetServerPPD(). + * + * @since CUPS 1.3@ + */ + +char * /* O - Name of PPD file or NULL on error */ +cupsGetServerPPD(http_t *http, /* I - HTTP connection */ + const char *name) /* I - Name of PPD file ("ppd-name") */ +{ + int fd; /* PPD file descriptor */ + ipp_t *request; /* IPP request */ + _cups_globals_t *cg = _cupsGlobals(); + /* Pointer to library globals */ + + + /* + * Range check input... + */ + + if (!http || !name) + { + if (!http) + _cupsSetError(IPP_INTERNAL_ERROR, "No HTTP connection!"); + else + _cupsSetError(IPP_INTERNAL_ERROR, "No PPD name!"); + + return (NULL); + } + + /* + * Get a temp file... + */ + + if ((fd = cupsTempFd(cg->ppd_filename, sizeof(cg->ppd_filename))) < 0) + { + /* + * Can't open file; close the server connection and return NULL... + */ + + _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno)); + + return (NULL); + } + + /* + * Get the PPD file... + */ + + request = ippNewRequest(CUPS_GET_PPD); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name", NULL, + name); + + ippDelete(cupsDoIORequest(http, request, "/", -1, fd)); + + close(fd); + + if (cupsLastError() != IPP_OK) + { + unlink(cg->ppd_filename); + return (NULL); + } + else + return (cg->ppd_filename); +} + + /* * 'cupsLastError()' - Return the last IPP status code. */ @@ -1660,5 +1737,5 @@ cups_get_printer_uri( /* - * End of "$Id: util.c 6138 2006-12-06 18:52:39Z mike $". + * End of "$Id: util.c 6506 2007-05-03 18:12:35Z mike $". */ diff --git a/doc/help/options.html b/doc/help/options.html index 20a17d3a8..d42b384dd 100644 --- a/doc/help/options.html +++ b/doc/help/options.html @@ -1,7 +1,7 @@ - Printing and Options + Command-Line Printing and Options @@ -171,6 +171,33 @@ lpstat +

Moving a Print Job

+ +

The lpmove(8) command moves a print +job to a new printer or class:

+ +
+lpmove job-id destination
+
+ +

The job-id is the number that was reported to you by +the lp or lpstat commands. Destination is the +name of a printer or class that you want to actually print the job. + +

Note: + +

The lpmove command is located in the system command +directory (typically /usr/sbin or /usr/local/sbin), +and so may not be in your command path. Specify the full path to the +command if you get a "command not found" error, for example: + +

+/usr/sbin/lpmove foo-123 bar
+
+ +
+ +

Standard Printing Options

The following options apply when printing all types of diff --git a/doc/help/ref-cupsd-conf.html b/doc/help/ref-cupsd-conf.html.in similarity index 98% rename from doc/help/ref-cupsd-conf.html rename to doc/help/ref-cupsd-conf.html.in index 997b479a3..e15c6c1d4 100644 --- a/doc/help/ref-cupsd-conf.html +++ b/doc/help/ref-cupsd-conf.html.in @@ -67,7 +67,7 @@ server activity.

information to the system log instead of a plain file.

The default access log file is -/var/log/cups/access_log.

+@CUPS_LOGDIR@/access_log.

Allow

@@ -521,8 +521,7 @@ BrowseLocalProtocols cups dns-sd

The BrowseLocalProtocols directive specifies the protocols to use when advertising local shared printers on the network. Multiple protocols can be specified by separating them -with spaces. The default is cups, which is a -broadcast-based protocol.

+with spaces. The default is @CUPS_BROWSE_REMOTE_PROTOCOLS@.

BrowseOrder

@@ -616,7 +615,10 @@ BrowseProtocols cups dns-sd protocols to use when showing and advertising shared printers on the local network. Multiple protocols can be specified by separating them with spaces. The default protocol is -cups, which is a broadcast-based protocol.

+@CUPS_BROWSE_LOCAL_PROTOCOLS@ for +BrowseLocalProtocols and +@CUPS_BROWSE_REMOTE_PROTOCOLS@ for +BrowseRemoteProtocols.

Note: @@ -698,8 +700,7 @@ BrowseRemoteProtocols cups dns-sd

The BrowseRemoteProtocols directive specifies the protocols to use when finding remote shared printers on the network. Multiple protocols can be specified by separating them -with spaces. The default is cups, which is a -broadcast-based protocol.

+with spaces. The default is @CUPS_BROWSE_REMOTE_PROTOCOLS@.

BrowseShortNames

@@ -720,7 +721,7 @@ Short names are just the remote printer name, without the server same name, the printers will have long names ("printer@server1", "printer@server2".)

-

The default value for this option is Yes.

+

The default value for this option is @CUPS_BROWSE_SHORT_NAMES@.

BrowseTimeout

@@ -759,7 +760,7 @@ Browsing Off

The Browsing directive controls whether or not network printer browsing is enabled. The default setting is -On.

+@CUPS_BROWSING@.

This directive does not enable sharing of local printers by itself; you must also use the The ConfigFilePerm directive specifies the permissions to use when writing configuration files. The default -is 0640.

+is @CUPS_CONFIG_FILE_PERM@.

DataDir

@@ -956,7 +957,7 @@ DefaultShared no

The DefaultShared directive specifies whether printers are shared (published) by default. The default is -yes.

+@CUPS_DEFAULT_SHARED@.

Deny

@@ -1020,13 +1021,13 @@ DocumentRoot /foo/bar/doc/cups of web content for the HTTP server in CUPS. If an absolute path is not specified then it is assumed to be relative to the ServerRoot directory. The -default directory is /usr/share/doc/cups.

+default directory is @CUPS_DOCROOT@.

Documents are first looked up in a sub-directory for the primary language requested by the client (e.g. -/usr/share/doc/cups/fr/...) and then directly under +@CUPS_DOCROOT@/fr/...) and then directly under the DocumentRoot directory (e.g. -/usr/share/doc/cups/...), so it is possible to +@CUPS_DOCROOT@/...), so it is possible to localize the web content by providing subdirectories for each language needed.

@@ -1069,7 +1070,7 @@ ErrorLog syslog log file. If the filename is not absolute then it is assumed to be relative to the ServerRoot directory. The -default error log file is /var/log/cups/error_log.

+default error log file is @CUPS_LOGDIR@/error_log.

The server name can be included in the filename by using %s in the name.

@@ -1283,25 +1284,6 @@ performance problems with hostname lookups. Set this option to required.

-

ImplicitClasses

- -

Examples

- -
-ImplicitClasses On
-ImplicitClasses Off
-
- -

Description

- -

The ImplicitClasses directive controls whether -implicit classes are created based upon the available network -printers and classes. The default setting is On but -is automatically turned Off if Browsing is turned -Off.

- -

CUPS 1.1.10ImplicitAnyClasses

Examples

@@ -1322,6 +1304,25 @@ setting is Off.

must be enabled for this directive to have any effect.

+

ImplicitClasses

+ +

Examples

+ +
+ImplicitClasses On
+ImplicitClasses Off
+
+ +

Description

+ +

The ImplicitClasses directive controls whether +implicit classes are created based upon the available network +printers and classes. The default setting is +@CUPS_IMPLICIT_CLASSES@ but is automatically turned +Off if Browsing is turned +Off.

+ +

CUPS 1.1.9Include

Examples

@@ -1819,7 +1820,7 @@ LogFilePerm 0600

The LogFilePerm directive specifies the permissions to use when writing configuration files. The default -is 0644.

+is @CUPS_LOG_FILE_PERM@.

LogLevel

@@ -1934,7 +1935,7 @@ MaxCopies 65535

The MaxCopies directive controls the maximum number of copies that a user can print of a job. The default is -100 copies.

+@CUPS_MAX_COPIES@ copies.

Note: @@ -2107,7 +2108,7 @@ PageLog syslog log file. If the filename is not absolute then it is assumed to be relative to the ServerRoot directory. The -default page log file is /var/log/cups/page_log.

+default page log file is @CUPS_LOGDIR@/page_log.

The server name can be included in the filename by using %s in the name.

@@ -2349,7 +2350,7 @@ RequestRoot /foo/bar/spool/cups incoming IPP requests and HTML forms. If an absolute path is not provided then it is assumed to be relative to the ServerRoot directory. The -default request directory is /var/spool/cups.

+default request directory is @CUPS_REQUESTS@.

CUPS 1.1.7Require

@@ -2700,10 +2701,7 @@ SystemGroup root lpadmin

The SystemGroup directive specifies the system administration group for System authentication. Multiple groups can be listed, separated with spaces. The default -is system-dependent and generally consists of all of the -following groups, if present: lpadmin, -root, sys, and/or -system.

+group list is @CUPS_SYSTEM_GROUPS@.

TempDir

@@ -2719,7 +2717,7 @@ TempDir /foo/bar/tmp

The TempDir directive specifies an absolute path for the directory to use for temporary files. The default -directory is /var/spool/cups/tmp.

+directory is @CUPS_REQUESTS@/tmp.

Temporary directories must be world-writable and should have the "sticky" permission bit enabled so that other users cannot @@ -2768,7 +2766,7 @@ advertising a default printer, the client's default printer is set to the first discovered printer, or to the implicit class for the same printer available from multiple servers.

-

The default is yes.

+

The default is @CUPS_USE_NETWORK_DEFAULT@.

User

@@ -2784,7 +2782,7 @@ User guest

The User directive specifies the UNIX user that filter and CGI programs run as. The default user is -lp.

+@CUPS_USER@.

Note: diff --git a/doc/help/ref-snmp-conf.html b/doc/help/ref-snmp-conf.html index e3047f24b..71e18d6d6 100644 --- a/doc/help/ref-snmp-conf.html +++ b/doc/help/ref-snmp-conf.html @@ -80,6 +80,32 @@ messages. Level 3 adds a hex dump of the network data.

The default setting is 0.

+

DeviceURI

+ +

Examples

+ +
+DeviceURI "HP.*JetDirect.*" socket://%s:9100 socket://%s:9101 socket://%s:9102
+DeviceURI "HP.*" socket://%s
+DeviceURI "Acme.*Laser.*" lpd://%s/print
+DeviceURI "Xerox.*"
+
+ +

Description

+ +

The DeviceURI directive specifies a regular expression +(enclosed in double quotes) that is matched against the SNMP device +description OID returned by a printer. If the description matches the +regular expression, each device URI that follows the regular expression +is listed by the backend, with any occurrences of %s +replaced by the device's hostname or IP address. If no URIs are listed, +the device is ignored.

+ +

The DeviceURI directives are processed serially in +the order specified in the snmp.conf file until a match +is found.

+ +

HostNameLookups

Examples

diff --git a/doc/help/spec-ipp.html b/doc/help/spec-ipp.html index 9816e6743..be45bdd94 100644 --- a/doc/help/spec-ipp.html +++ b/doc/help/spec-ipp.html @@ -38,7 +38,7 @@ Output-bin Attribute Extension", and "IPP/1.1: finishings 'fold',' trim', and 'bale' attribute values extension" specifications.

-

CUPS also provides 13 new operations and many new attributes +

CUPS also provides 15 new operations and many new attributes to support multiple IPP printers and printer classes on a single host.

@@ -321,6 +321,12 @@ summary='Supported Operations'> 0x400E Authenticate a job for printing. + + CUPS-Get-PPD + 1.3 + 0x400F + Get a PPD file. + @@ -1685,6 +1691,77 @@ CUPS-Authenticate-Job Response: CUPS 1.3CUPS-Get-PPD Operation + +

The CUPS-Get-PPD operation (0x400F) gets a PPD file from the +server. The PPD file can be specified using a ppd-name +returned by CUPS-Get-PPDs +or using the printer-uri for a queue.

+ +

If the PPD file is found, successful-ok is returned with +the PPD file following the response data.

+ +

If the PPD file cannot be served by the local server because +the printer-uri attribute points to an external printer, +a cups-see-other status is returned with the correct +URI to use.

+ +

If the PPD file does not exist, client-error-not-found is +returned.

+ +

CUPS-Get-PPD Request

+ +

The following group of attributes is supplied as part of the +CUPS-Get-PPD request: + +

Group 1: Operation Attributes + +

+ +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +
"printer-uri" (uri) +
OR +
"ppd-name" (name(255)): + +
The client MUST supply a printer URI or PPD name. + +
+ +

CUPS-Get-PPD Response

+ +

The following group of attributes is sent as part of the +CUPS-Get-PPD Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The printer that provides the actual PPD file when + the status code is cups-see-other (0x280) + +
+ +

If the status code is successful-ok, the PPD file follows +the end of the IPP response.

+ +

Attributes

CUPS provides many extension attributes to support multiple @@ -1843,7 +1920,7 @@ for billing purposes.

The job-hold-until attribute specifies a hold time. In addition to the standard IPP/1.1 keyword names, CUPS supports name values of the form "HH:MM" and "HH:MM:SS" that specify a hold time. The hold time is in -Greenwich Mean Time (GMT) and not in the local time zone. If the +Universal Coordinated Time (UTC) and not in the local time zone. If the specified time is less than the current time, the job is held until the next day. @@ -2064,15 +2141,19 @@ ShortNickName attributes are used instead. relative to the model directory. The forward slash (/) is used to delineate directories. -

ppd-natural-language (naturalLanguage)

+

ppd-natural-language (1setOf naturalLanguage)

The ppd-natural-language attribute specifies the language encoding of the PPD file (the LanguageVersion attribute in the PPD file). If the language is unknown or undefined then "en" (English) is assumed. -

ppd-product (text(127))

+

ppd-product (1setOf text(127))

+ +

The ppd-product attribute specifies the Product attribute values in the PPD file. + +

ppd-psversion (1setOf text(127))CUPS 1.3

-

The ppd-product attribute specifies the Product attribute value in the PPD file. +

The ppd-product attribute specifies the PSVersion attribute values in the PPD file.

Printer Attributes

diff --git a/doc/help/spec-ppd.html b/doc/help/spec-ppd.html index 16c054544..cf02272bc 100644 --- a/doc/help/spec-ppd.html +++ b/doc/help/spec-ppd.html @@ -8,7 +8,7 @@