From ed6e7faf3e76edf2b4dbcf38fdbfbfe5c387550a Mon Sep 17 00:00:00 2001 From: msweet Date: Sat, 6 Dec 2008 00:24:23 +0000 Subject: [PATCH] Merge changes from CUPS 1.4svn-r8162. git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@1079 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES-1.3.txt | 4 + CHANGES.txt | 15 +++- Makefile | 2 +- backend/lpd.c | 2 - backend/usb-darwin.c | 1 + backend/usb-unix.c | 18 +++++ cgi-bin/admin.c | 5 +- cups/cups.h | 2 + cups/encode.c | 3 + cups/getdevices.c | 16 +++- cups/ipp-support.c | 6 +- doc/help/options.html | 8 +- doc/help/spec-ipp.html | 56 +++++++++++-- filter/hpgl-main.c | 8 +- filter/imagetops.c | 8 +- filter/imagetoraster.c | 8 +- filter/pstops.c | 8 +- man/lpinfo.man | 22 +++++- scheduler/auth.c | 23 ++---- scheduler/cups-deviced.c | 65 ++++----------- scheduler/cups-driverd.cxx | 126 ++++++++++++++++------------- scheduler/ipp.c | 50 +++++++++--- scheduler/job.c | 157 +++++++++++++++++++++--------------- scheduler/log.c | 2 +- scheduler/main.c | 6 +- scheduler/printers.c | 23 +++++- scheduler/process.c | 15 +++- scheduler/util.c | 60 ++++++++++++-- scheduler/util.h | 1 + systemv/lpinfo.c | 158 +++++++++++++++++++++---------------- 30 files changed, 562 insertions(+), 316 deletions(-) diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt index 60223859c..36a48d95e 100644 --- a/CHANGES-1.3.txt +++ b/CHANGES-1.3.txt @@ -4,6 +4,10 @@ CHANGES-1.3.txt CHANGES IN CUPS V1.3.10 - Documentation fixes (STR #2994, STR #2995, STR #3008) + - The "-o job-hold-until=week-end" option did not work properly + (STR #3025) + - The Solaris USB printer device does not support select or poll + (STR #3028) - The scheduler would crash if you exceeded the MaxSubscriptions limit. - The lp "-H immediate" option did not specify that the job diff --git a/CHANGES.txt b/CHANGES.txt index e4cbfc604..290f90a89 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,9 +1,22 @@ -CHANGES.txt - 2008-11-19 +CHANGES.txt - 2008-12-05 ------------------------ CHANGES IN CUPS V1.4b2 - Documentation updates (STR #2983, STR #2998) + - Added support for marker-low-levels and marker-high-levels + attributes. + - The scheduler could hang writing a long log line. + - The cupsGetDevices() function now has an "include_schemes" + parameter. + - The lpinfo command now supports --include-schemes and + --exclude-schemes options. + - The CUPS-Get-PPDs operation now supports the include-schemes + and exclude-schemes attributes. + - The CUPS-Get-Devices operation now supports the include-schemes + attribute. + - The print filters now support a replacement for the fitplot + option called "fit-to-page". - The LPD backend no longer tries to collect page accounting information since the LPD protocol does not allow us to prevent race conditions. diff --git a/Makefile b/Makefile index 44beff0a3..fb892d04c 100644 --- a/Makefile +++ b/Makefile @@ -144,7 +144,7 @@ depend: .PHONY: clang clang: $(RM) -r clang - scan-build -k -o `pwd`/clang $(MAKE) $(MFLAGS) \ + scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) \ CC=ccc-analyzer CXX=ccc-analyzer clean all diff --git a/backend/lpd.c b/backend/lpd.c index c0aaa6532..159effe60 100644 --- a/backend/lpd.c +++ b/backend/lpd.c @@ -894,8 +894,6 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ snmp_fd = -1; } } - else - start_count = 0; /* * Check for side-channel requests... diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c index f25fbe017..23b7baecd 100644 --- a/backend/usb-darwin.c +++ b/backend/usb-darwin.c @@ -755,6 +755,7 @@ print_device(const char *uri, /* I - Device URI */ * Force the read thread to exit... */ + g.wait_eof = 0; pthread_kill(read_thread_id, SIGTERM); } } diff --git a/backend/usb-unix.c b/backend/usb-unix.c index e21142ff1..b1e75b820 100644 --- a/backend/usb-unix.c +++ b/backend/usb-unix.c @@ -80,6 +80,14 @@ print_device(const char *uri, /* I - Device URI */ use_bc = 0; +#elif defined(__sun) + /* + * CUPS STR #3028: Solaris' usbprn driver apparently does not support + * select() or poll(), so we can't support backchannel... + */ + + use_bc = 0; + #else /* * Disable backchannel data when printing to Brother, Canon, or @@ -173,7 +181,17 @@ print_device(const char *uri, /* I - Device URI */ lseek(print_fd, 0, SEEK_SET); } +#ifdef __sun + /* + * CUPS STR #3028: Solaris' usbprn driver apparently does not support + * select() or poll(), so we can't support the sidechannel either... + */ + + tbytes = backendRunLoop(print_fd, device_fd, -1, NULL, use_bc, NULL); + +#else tbytes = backendRunLoop(print_fd, device_fd, -1, NULL, use_bc, side_cb); +#endif /* __sun */ if (print_fd != 0 && tbytes >= 0) _cupsLangPrintf(stderr, diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c index bfaf7d374..1601ef7c8 100644 --- a/cgi-bin/admin.c +++ b/cgi-bin/admin.c @@ -918,8 +918,9 @@ do_am_printer(http_t *http, /* I - HTTP connection */ last_device_time = 0; current_device = 0; - if (cupsGetDevices(http, 30, NULL, (cups_device_cb_t)choose_device_cb, - (void *)title) == IPP_OK) + if (cupsGetDevices(http, 30, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE, + (cups_device_cb_t)choose_device_cb, + (void *)title) == IPP_OK) fputs("DEBUG: Got device list!\n", stderr); else { diff --git a/cups/cups.h b/cups/cups.h index f15786292..03ca44054 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -74,6 +74,7 @@ extern "C" { # define CUPS_FORMAT_RAW "application/vnd.cups-raw" # define CUPS_FORMAT_TEXT "text/plain" # define CUPS_HTTP_DEFAULT (http_t *)0 +# define CUPS_INCLUDE_ALL (const char *)0 # define CUPS_JOBID_ALL -1 # define CUPS_JOBID_CURRENT 0 # define CUPS_LENGTH_VARIABLE (ssize_t)0 @@ -282,6 +283,7 @@ extern ipp_status_t cupsFinishDocument(http_t *http, const char *name) _CUPS_API_1_4; extern ipp_status_t cupsGetDevices(http_t *http, int timeout, const char *exclude_schemes, + const char *include_schemes, cups_device_cb_t callback, void *user_data) _CUPS_API_1_4; extern cups_dest_t *cupsGetNamedDest(http_t *http, const char *name, diff --git a/cups/encode.c b/cups/encode.c index f3abe6dff..3b737aebd 100644 --- a/cups/encode.c +++ b/cups/encode.c @@ -59,12 +59,15 @@ static const _ipp_option_t ipp_options[] = { 1, "exclude-schemes", IPP_TAG_NAME, IPP_TAG_OPERATION }, { 1, "finishings", IPP_TAG_ENUM, IPP_TAG_JOB }, { 1, "finishings-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, + { 0, "fit-to-page", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { 0, "fit-to-page-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, { 0, "fitplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, { 0, "fitplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, { 0, "gamma", IPP_TAG_INTEGER, IPP_TAG_JOB }, { 0, "gamma-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { 0, "hue", IPP_TAG_INTEGER, IPP_TAG_JOB }, { 0, "hue-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 1, "include-schemes", IPP_TAG_NAME, IPP_TAG_OPERATION }, { 0, "job-impressions", IPP_TAG_INTEGER, IPP_TAG_JOB }, { 0, "job-k-limit", IPP_TAG_INTEGER, IPP_TAG_JOB }, { 0, "job-page-limit", IPP_TAG_INTEGER, IPP_TAG_JOB }, diff --git a/cups/getdevices.c b/cups/getdevices.c index c6f7ddac3..4f5f8d000 100644 --- a/cups/getdevices.c +++ b/cups/getdevices.c @@ -31,8 +31,9 @@ * * This function sends a CUPS-Get-Devices request and streams the discovered * devices to the specified callback function. The "timeout" parameter controls - * how long the request lasts, while the "exclude_schemes" parameter provides - * a comma-delimited list of backends to omit from the request. + * how long the request lasts, while the "include_schemes" and "exclude_schemes" + * parameters provide comma-delimited lists of backends to include or omit from + * the request respectively. * * @since CUPS 1.4@ */ @@ -41,6 +42,7 @@ ipp_status_t /* O - Request status - @code IPP_OK@ on success. */ cupsGetDevices( http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ int timeout, /* I - Timeout in seconds or @code CUPS_TIMEOUT_DEFAULT@ */ + const char *include_schemes, /* I - Comma-separated URI schemes to include or @code CUPS_INCLUDE_ALL@ */ const char *exclude_schemes, /* I - Comma-separated URI schemes to exclude or @code CUPS_EXCLUDE_NONE@ */ cups_device_cb_t callback, /* I - Callback function */ void *user_data) /* I - User data pointer */ @@ -55,7 +57,7 @@ cupsGetDevices( *device_make_and_model, /* device-make-and-model value */ *device_uri; /* device-uri value */ int blocking; /* Current blocking-IO mode */ - cups_option_t option; /* exclude-schemes option */ + cups_option_t option; /* in/exclude-schemes option */ http_status_t status; /* HTTP status of request */ ipp_state_t state; /* IPP response state */ @@ -83,6 +85,14 @@ cupsGetDevices( ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "timeout", timeout); + if (include_schemes) + { + option.name = "include-schemes"; + option.value = (char *)include_schemes; + + cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); + } + if (exclude_schemes) { option.name = "exclude-schemes"; diff --git a/cups/ipp-support.c b/cups/ipp-support.c index 6ab14b16e..ca1111b85 100644 --- a/cups/ipp-support.c +++ b/cups/ipp-support.c @@ -4,7 +4,7 @@ * Internet Printing Protocol support functions for the Common UNIX * Printing System (CUPS). * - * Copyright 2007 by Apple Inc. + * Copyright 2007-2008 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -23,6 +23,8 @@ * ippOpValue() - Return an operation id for the given name. * ippPort() - Return the default IPP port number. * ippSetPort() - Set the default port number. + * ippTagString() - Return the tag name corresponding to a tag value. + * ippTagValue() - Return the tag value corresponding to a tag name. */ /* @@ -465,6 +467,8 @@ ippSetPort(int p) /* I - Port number to use */ const char * /* O - Tag name */ ippTagString(ipp_tag_t tag) /* I - Tag value */ { + tag &= IPP_TAG_MASK; + if (tag < (ipp_tag_t)(sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0]))) return (ipp_tag_names[tag]); else diff --git a/doc/help/options.html b/doc/help/options.html index 24fb3e68e..f32e1b9dd 100644 --- a/doc/help/options.html +++ b/doc/help/options.html @@ -500,14 +500,14 @@ layout of the pages on each output page:

  • -o number-up-layout=tbrl; Top to bottom, right to left
  • -

    Scaling to Fit

    +

    Scaling to Fit

    -

    The -o fitplot option specifies that the document +

    The -o fit-to-page option specifies that the document should be scaled to fit on the page:

    -lp -o fitplot filename
    -lpr -o fitplot filename
    +lp -o fit-to-page filename
    +lpr -o fit-to-page filename
     

    The default is to use the size specified in the file.

    diff --git a/doc/help/spec-ipp.html b/doc/help/spec-ipp.html index 442a752ef..70db03765 100644 --- a/doc/help/spec-ipp.html +++ b/doc/help/spec-ipp.html @@ -1576,7 +1576,15 @@ CUPS-Get-Devices request:
    The client OPTIONALLY supplies a set of scheme names that the requestor does not want to discover. If the client omits this attribute, - the server responds with devices of all schemes. + the server responds with devices of all schemes specified by + the "include-schemes" attribute. + +
    "include-schemes" (1setOf name) :CUPS 1.4 + +
    The client OPTIONALLY supplies a set of scheme names that the + requestor wants to discover. If the client omits this attribute, + the server responds with devices of all schemes except those specified + by the "exclude-schemes" attribute.
    "limit" (integer (1:MAX)): @@ -1647,6 +1655,20 @@ CUPS-Get-PPDs request: attributes as described in section 3.1.4.1 of the IPP Model and Semantics document. +
    "exclude-schemes" (1setOf name) :CUPS 1.4 + +
    The client OPTIONALLY supplies a set of scheme names that the + requestor does not want to list. If the client omits this attribute, + the server responds with PPDs of all schemes specified by the + "include-schemes" attribute. + +
    "include-schemes" (1setOf name) :CUPS 1.4 + +
    The client OPTIONALLY supplies a set of scheme names that the + requestor wants to list. If the client omits this attribute, the server + responds with PPDs of all schemes except those specified by the + "exclude-schemes" attribute. +
    "limit" (integer (1:MAX)):
    The client OPTIONALLY supplies this attribute limiting the number of PPDs that are returned. @@ -2146,7 +2168,13 @@ supported. The default value is 10.

    The document-count attribute specifies the number of documents that are present in the job. -

    fitplot (boolean)

    +

    fit-to-page (boolean)CUPS 1.4

    + +

    The fit-to-page attribute specifies whether to scale documents to fit on the +selected media (fit-to-page=true) or use the physical size specified in the +document (fit-to-page=false). The default value is false. + +

    fitplot (boolean)Deprecated

    The fitplot attribute specifies whether to scale HP-GL/2 plot files to fit on the selected media (fitplot=true) or use the physical scale specified @@ -2510,38 +2538,50 @@ the system.

    The job-sheets-supported attribute specifies the available banner files. There will always be at least one banner file available called "none". -

    marker-change-time (integer)

    +

    marker-change-time (integer)CUPS 1.3

    The marker-change-time attribute specifies the printer-up-time value when the last change to the marker-colors, marker-levels, marker-message, marker-names, or marker-types attributes was made.

    -

    marker-colors (1setof name(MAX))

    +

    marker-colors (1setof name(MAX))CUPS 1.3

    The marker-colors attribute specifies the color(s) for each supply in the printer. It is only available when the driver provides supply levels. The color is either "none" or one or more hex-encoded sRGB colors of the form "#RRGGBB".

    -

    marker-levels (1setof integer(-1:100))

    +

    marker-high-levels (1setof integer(0:100))CUPS 1.4

    + +

    The marker-high-levels attribute specifies the supply levels that indicate +a near-full condition. A value of 100 should be used for supplies that are +consumed/emptied, e.g. ink cartridges.

    + +

    marker-levels (1setof integer(-1:100))CUPS 1.3

    The marker-levels attribute specifies the current supply levels for the printer. It is only available when the driver provides supply levels. A value of -1 indicates the level is unknown, while values from 0 to 100 indicate the corresponding percentage.

    -

    marker-message (text(MAX))

    +

    marker-low-levels (1setof integer(0:100))CUPS 1.4

    + +

    The marker-low-levels attribute specifies the supply levels that indicate +a near-empty condition. A value of 0 should be used for supplies that are +filled, e.g. waste ink tanks.

    + +

    marker-message (text(MAX))CUPS 1.4

    The marker-message attribute provides a human-readable status message for the current supply levels, e.g. "12 pages of ink remaining." It is only available when the driver provides supply levels.

    -

    marker-names (1setof name(MAX))

    +

    marker-names (1setof name(MAX))CUPS 1.3

    The marker-names attribute specifies the name(s) for each supply in the printer. It is only available when the driver provides supply levels.

    -

    marker-types (1setof type3 keyword)

    +

    marker-types (1setof type3 keyword)CUPS 1.3

    The marker-types attribute specifies the type(s) of each supply in the printer. It is only available when the driver provides supply levels. The diff --git a/filter/hpgl-main.c b/filter/hpgl-main.c index 7660f8ed0..953d44702 100644 --- a/filter/hpgl-main.c +++ b/filter/hpgl-main.c @@ -3,7 +3,7 @@ * * HP-GL/2 filter main entry for the Common UNIX Printing System (CUPS). * - * Copyright 2007 by Apple Inc. + * Copyright 2007-2008 by Apple Inc. * Copyright 1993-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -191,8 +191,10 @@ main(int argc, /* I - Number of command-line arguments */ shading = 0; if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && - strcasecmp(val, "no") && strcasecmp(val, "off") && - strcasecmp(val, "false")) + !strcasecmp(val, "true")) + FitPlot = 1; + else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && + !strcasecmp(val, "true")) FitPlot = 1; if ((val = cupsGetOption("penwidth", num_options, options)) != NULL) diff --git a/filter/imagetops.c b/filter/imagetops.c index 95e647ddc..93a41bfaa 100644 --- a/filter/imagetops.c +++ b/filter/imagetops.c @@ -3,7 +3,7 @@ * * Image file to PostScript filter for the Common UNIX Printing System (CUPS). * - * Copyright 2007 by Apple Inc. + * Copyright 2007-2008 by Apple Inc. * Copyright 1993-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -212,7 +212,11 @@ main(int argc, /* I - Number of command-line arguments */ if ((val = cupsGetOption("scaling", num_options, options)) != NULL) zoom = atoi(val) * 0.01; - else if (cupsGetOption("fitplot", num_options, options)) + else if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && + !strcasecmp(val, "true")) + zoom = 1.0; + else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && + !strcasecmp(val, "true")) zoom = 1.0; if ((val = cupsGetOption("ppi", num_options, options)) != NULL) diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c index ba21bdb1c..c57275b7a 100644 --- a/filter/imagetoraster.c +++ b/filter/imagetoraster.c @@ -3,7 +3,7 @@ * * Image file to raster filter for the Common UNIX Printing System (CUPS). * - * Copyright 2007 by Apple Inc. + * Copyright 2007-2008 by Apple Inc. * Copyright 1993-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -373,7 +373,11 @@ main(int argc, /* I - Number of command-line arguments */ if ((val = cupsGetOption("scaling", num_options, options)) != NULL) zoom = atoi(val) * 0.01; - else if (cupsGetOption("fitplot", num_options, options)) + else if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && + !strcasecmp(val, "true")) + zoom = 1.0; + else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && + !strcasecmp(val, "true")) zoom = 1.0; if ((val = cupsGetOption("ppi", num_options, options)) != NULL) diff --git a/filter/pstops.c b/filter/pstops.c index 0e8ac48d0..91f1edd9a 100644 --- a/filter/pstops.c +++ b/filter/pstops.c @@ -2449,12 +2449,14 @@ set_pstops_options( doc->emit_jcl = 1; /* - * fitplot + * fitplot/fit-to-page */ if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && - (!strcasecmp(val, "true") || !strcasecmp(val, "on") || - !strcasecmp(val, "yes"))) + !strcasecmp(val, "true")) + doc->fitplot = 1; + else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && + !strcasecmp(val, "true")) doc->fitplot = 1; /* diff --git a/man/lpinfo.man b/man/lpinfo.man index a16df1b7f..b4f572cbd 100644 --- a/man/lpinfo.man +++ b/man/lpinfo.man @@ -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 lpinfo 8 "Common UNIX Printing System" "8 October 2008" "Apple Inc." +.TH lpinfo 8 "Common UNIX Printing System" "5 December 2008" "Apple Inc." .SH NAME lpinfo \- show available devices or drivers .SH SYNOPSIS @@ -23,6 +23,10 @@ lpinfo \- show available devices or drivers .I server[:port] ] [ -l ] [ --device-id .I device-id-string +] [ --exclude-schemes +.I scheme-list +] [ --include-schemes +.I scheme-list ] [ --language .I locale ] [ --make-and-model @@ -36,7 +40,11 @@ lpinfo \- show available devices or drivers .I username ] [ -h .I server[:port] -] [ -l ] [ --timeout +] [ -l ] [ --exclude-schemes +.I scheme-list +] [ --include-schemes +.I scheme-list +] [ --timeout .I seconds ] -v .SH DESCRIPTION @@ -68,6 +76,16 @@ Shows a "long" listing of devices or drivers. Specifies the IEEE-1284 device ID to match when listing drivers with the \fI-m\fR option. .TP 5 +--exclude-schemes scheme-list +.br +Specifies a comma-separated list of device or PPD schemes that should be +excluded from the results. Static PPD files use the "file" scheme. +.TP 5 +--include-schemes scheme-list +.br +Specifies a comma-separated list of device or PPD schemes that should be +included in the results. Static PPD files use the "file" scheme. +.TP 5 --language locale .br Specifies the language to match when listing drivers with the \fI-m\fR option. diff --git a/scheduler/auth.c b/scheduler/auth.c index 0654af4b7..b3b93d34f 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -454,28 +454,19 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ return; } + strlcpy(username, "_AUTHREF_", sizeof(username)); + if ((status = AuthorizationCopyInfo(con->authref, kAuthorizationEnvironmentUsername, - &authinfo)) != 0) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "AuthorizationCopyInfo returned %d (%s)", - (int)status, cssmErrorString(status)); - return; - } - - if (authinfo->count == 0 || !authinfo->items[0].value || - authinfo->items[0].valueLength < 2) + &authinfo)) == 0) { + if (authinfo->count == 1 && authinfo->items[0].value && + authinfo->items[0].valueLength >= 2) + strlcpy(username, authinfo->items[0].value, sizeof(username)); + AuthorizationFreeItemSet(authinfo); - cupsdLogMessage(CUPSD_LOG_ERROR, - "AuthorizationCopyInfo returned empty rights!"); - return; } - strlcpy(username, authinfo->items[0].value, sizeof(username)); - AuthorizationFreeItemSet(authinfo); - cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: Authorized as \"%s\" using AuthRef", username); diff --git a/scheduler/cups-deviced.c b/scheduler/cups-deviced.c index d35940c07..912109f1b 100644 --- a/scheduler/cups-deviced.c +++ b/scheduler/cups-deviced.c @@ -17,7 +17,6 @@ * main() - Scan for devices and return an IPP response. * add_device() - Add a new device to the list. * compare_devices() - Compare device names to eliminate duplicates. - * create_strings_array() - Create a CUPS array of strings. * get_current_time() - Get the current time as a double value in seconds. * get_device() - Get a device from a backend. * process_children() - Process all dead children... @@ -108,7 +107,6 @@ static int add_device(const char *device_class, const char *device_location); static int compare_devices(cupsd_device_t *p0, cupsd_device_t *p1); -static cups_array_t *create_strings_array(const char *s); static double get_current_time(void); static int get_device(cupsd_backend_t *backend); static void process_children(void); @@ -140,7 +138,8 @@ main(int argc, /* I - Number of command-line args */ int num_options; /* Number of options */ cups_option_t *options; /* Options */ cups_array_t *requested, /* requested-attributes values */ - *exclude; /* exclude-schemes values */ + *exclude, /* exclude-schemes values */ + *include; /* include-schemes values */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ @@ -192,10 +191,12 @@ main(int argc, /* I - Number of command-line args */ } num_options = cupsParseOptions(argv[5], 0, &options); - requested = create_strings_array(cupsGetOption("requested-attributes", - num_options, options)); - exclude = create_strings_array(cupsGetOption("exclude-schemes", - num_options, options)); + requested = cupsdCreateStringsArray(cupsGetOption("requested-attributes", + num_options, options)); + exclude = cupsdCreateStringsArray(cupsGetOption("exclude-schemes", + num_options, options)); + include = cupsdCreateStringsArray(cupsGetOption("include-schemes", + num_options, options)); if (!requested || cupsArrayFind(requested, "all") != NULL) { @@ -267,7 +268,12 @@ main(int argc, /* I - Number of command-line args */ (dent->fileinfo.st_mode & (S_IRUSR | S_IXUSR)) != (S_IRUSR | S_IXUSR)) continue; - if (cupsArrayFind(exclude, dent->filename)) + /* + * Skip excluded or not included backends... + */ + + if (cupsArrayFind(exclude, dent->filename) || + (include && !cupsArrayFind(include, dent->filename))) continue; /* @@ -447,49 +453,6 @@ compare_devices(cupsd_device_t *d0, /* I - First device */ } -/* - * 'create_strings_array()' - Create a CUPS array of strings. - */ - -static cups_array_t * /* O - CUPS array */ -create_strings_array(const char *s) /* I - Comma-delimited strings */ -{ - cups_array_t *a; /* CUPS array */ - const char *start, /* Start of string */ - *end; /* End of string */ - char *ptr; /* New string */ - - - if (!s) - return (NULL); - - if ((a = cupsArrayNew((cups_array_func_t)strcmp, NULL)) != NULL) - { - for (start = end = s; *end; start = end + 1) - { - /* - * Find the end of the current delimited string... - */ - - if ((end = strchr(start, ',')) == NULL) - end = start + strlen(start); - - /* - * Duplicate the string and add it to the array... - */ - - if ((ptr = calloc(1, end - start + 1)) == NULL) - break; - - memcpy(ptr, start, end - start); - cupsArrayAdd(a, ptr); - } - } - - return (a); -} - - /* * 'get_current_time()' - Get the current time as a double value in seconds. */ diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx index a7fc29c08..f902d309f 100644 --- a/scheduler/cups-driverd.cxx +++ b/scheduler/cups-driverd.cxx @@ -53,7 +53,7 @@ * Constants... */ -#define PPD_SYNC 0x50504435 /* Sync word for ppds.dat (PPD5) */ +#define PPD_SYNC 0x50504436 /* Sync word for ppds.dat (PPD6) */ #define PPD_MAX_LANG 32 /* Maximum languages */ #define PPD_MAX_PROD 8 /* Maximum products */ #define PPD_MAX_VERS 8 /* Maximum versions */ @@ -95,7 +95,8 @@ typedef struct /**** PPD record ****/ /* PSVersion strings */ make[128], /* Manufacturer */ make_and_model[128], /* NickName/ModelName */ - device_id[256]; /* IEEE 1284 Device ID */ + device_id[256], /* IEEE 1284 Device ID */ + scheme[128]; /* PPD scheme */ } ppd_rec_t; typedef struct /**** In-memory record ****/ @@ -124,7 +125,8 @@ static ppd_info_t *add_ppd(const char *filename, const char *name, const char *make_and_model, const char *device_id, const char *product, const char *psversion, time_t mtime, - size_t size, int model_number, int type); + size_t size, int model_number, int type, + const char *scheme); static int cat_drv(const char *name, int request_id); static int cat_ppd(const char *name, int request_id); static int cat_static(const char *name, int request_id); @@ -136,7 +138,8 @@ static int compare_ppds(const ppd_info_t *p0, const ppd_info_t *p1); static void free_array(cups_array_t *a); static int list_ppds(int request_id, int limit, const char *opt); -static int load_drivers(void); +static int load_drivers(cups_array_t *include, + cups_array_t *exclude); static int load_drv(const char *filename, const char *name, cups_file_t *fp, time_t mtime, off_t size); static int load_ppds(const char *d, const char *p, int descend); @@ -192,7 +195,8 @@ add_ppd(const char *filename, /* I - PPD filename */ time_t mtime, /* I - Modification time */ size_t size, /* I - File size */ int model_number, /* I - Model number */ - int type) /* I - Driver type */ + int type, /* I - Driver type */ + const char *scheme) /* I - PPD scheme */ { ppd_info_t *ppd; /* PPD */ char *recommended; /* Foomatic driver string */ @@ -231,6 +235,7 @@ add_ppd(const char *filename, /* I - PPD filename */ strlcpy(ppd->record.make_and_model, make_and_model, sizeof(ppd->record.make_and_model)); strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id)); + strlcpy(ppd->record.scheme, scheme, sizeof(ppd->record.scheme)); /* * Strip confusing (and often wrong) "recommended" suffix added by @@ -745,8 +750,10 @@ list_ppds(int request_id, /* I - Request ID */ const char *cups_datadir; /* CUPS_DATADIR environment variable */ int num_options; /* Number of options */ cups_option_t *options; /* Options */ - const char *requested, /* requested-attributes option */ - *device_id, /* ppd-device-id option */ + cups_array_t *requested, /* requested-attributes values */ + *include, /* PPD schemes to include */ + *exclude; /* PPD schemes to exclude */ + const char *device_id, /* ppd-device-id option */ *language, /* ppd-natural-language option */ *make, /* ppd-make option */ *make_and_model, /* ppd-make-and-model option */ @@ -932,21 +939,28 @@ list_ppds(int request_id, /* I - Request ID */ * Scan for dynamic PPD files... */ - load_drivers(); + num_options = cupsParseOptions(opt, 0, &options); + exclude = cupsdCreateStringsArray(cupsGetOption("exclude-schemes", + num_options, options)); + include = cupsdCreateStringsArray(cupsGetOption("exclude-schemes", + num_options, options)); + + load_drivers(include, exclude); /* * Add the raw driver... */ add_ppd("", "raw", "en", "Raw", "Raw Queue", "", "", "", 0, 0, 0, - PPD_TYPE_UNKNOWN); + PPD_TYPE_UNKNOWN, "raw"); /* * Send IPP attributes... */ - num_options = cupsParseOptions(opt, 0, &options); - requested = cupsGetOption("requested-attributes", num_options, options); + requested = cupsdCreateStringsArray( + cupsGetOption("requested-attributes", num_options, + options)); device_id = cupsGetOption("ppd-device-id", num_options, options); language = cupsGetOption("ppd-natural-language", num_options, options); make = cupsGetOption("ppd-make", num_options, options); @@ -989,34 +1003,11 @@ list_ppds(int request_id, /* I - Request ID */ else type = 0; - if (requested) - fprintf(stderr, "DEBUG: [cups-driverd] requested-attributes=\"%s\"\n", - requested); - if (device_id) - fprintf(stderr, "DEBUG: [cups-driverd] ppd-device-id=\"%s\"\n", - device_id); - if (language) - fprintf(stderr, "DEBUG: [cups-driverd] ppd-natural-language=\"%s\"\n", - language); - if (make) - fprintf(stderr, "DEBUG: [cups-driverd] ppd-make=\"%s\"\n", - make); - if (make_and_model) - fprintf(stderr, "DEBUG: [cups-driverd] ppd-make-and-model=\"%s\"\n", - make_and_model); - if (model_number_str) - fprintf(stderr, "DEBUG: [cups-driverd] ppd-model-number=\"%s\"\n", - model_number_str); - if (product) - fprintf(stderr, "DEBUG: [cups-driverd] ppd-product=\"%s\"\n", - product); - if (psversion) - fprintf(stderr, "DEBUG: [cups-driverd] ppd-psversion=\"%s\"\n", - psversion); - if (type_str) - fprintf(stderr, "DEBUG: [cups-driverd] ppd-type=\"%s\"\n", type_str); + for (i = 0; i < num_options; i ++) + fprintf(stderr, "DEBUG: [cups-driverd] %s=\"%s\"\n", options[i].name, + options[i].value); - if (!requested || strstr(requested, "all")) + if (!requested || cupsArrayFind(requested, (void *)"all") != NULL) { send_name = 1; send_make = 1; @@ -1030,17 +1021,24 @@ list_ppds(int request_id, /* I - Request ID */ } else { - send_name = strstr(requested, "ppd-name") != NULL; - send_make = strstr(requested, "ppd-make,") != NULL || - strstr(requested, ",ppd-make") != NULL || - !strcmp(requested, "ppd-make"); - send_make_and_model = strstr(requested, "ppd-make-and-model") != NULL; - send_model_number = strstr(requested, "ppd-model-number") != NULL; - send_natural_language = strstr(requested, "ppd-natural-language") != NULL; - send_device_id = strstr(requested, "ppd-device-id") != NULL; - send_product = strstr(requested, "ppd-product") != NULL; - send_psversion = strstr(requested, "ppd-psversion") != NULL; - send_type = strstr(requested, "ppd-type") != NULL; + send_name = cupsArrayFind(requested, + (void *)"ppd-name") != NULL; + send_make = cupsArrayFind(requested, + (void *)"ppd-make") != NULL; + send_make_and_model = cupsArrayFind(requested, + (void *)"ppd-make-and-model") != NULL; + send_model_number = cupsArrayFind(requested, + (void *)"ppd-model-number") != NULL; + send_natural_language = cupsArrayFind(requested, + (void *)"ppd-natural-language") != NULL; + send_device_id = cupsArrayFind(requested, + (void *)"ppd-device-id") != NULL; + send_product = cupsArrayFind(requested, + (void *)"ppd-product") != NULL; + send_psversion = cupsArrayFind(requested, + (void *)"ppd-psversion") != NULL; + send_type = cupsArrayFind(requested, + (void *)"ppd-type") != NULL; } puts("Content-Type: application/ipp\n"); @@ -1053,7 +1051,7 @@ list_ppds(int request_id, /* I - Request ID */ count = limit; if (device_id || language || make || make_and_model || model_number_str || - product) + product || include || exclude) { matches = cupsArrayNew((cups_array_func_t)compare_matches, NULL); @@ -1084,6 +1082,10 @@ list_ppds(int request_id, /* I - Request ID */ ppd->record.type >= PPD_TYPE_DRV) continue; + if (cupsArrayFind(exclude, ppd->record.scheme) || + (include && !cupsArrayFind(include, ppd->record.scheme))) + continue; + ppd->matches = 0; if (device_id_re && @@ -1259,7 +1261,8 @@ list_ppds(int request_id, /* I - Request ID */ * the remaining PPDs with this make... */ - if (requested && !strcmp(requested, "ppd-make")) + if (cupsArrayFind(requested, (void *)"ppd-make") && + cupsArrayCount(requested) == 1) { const char *this_make; /* This ppd-make */ @@ -1716,7 +1719,7 @@ load_ppds(const char *d, /* I - Actual directory */ device_id, (char *)cupsArrayFirst(products), (char *)cupsArrayFirst(psversions), dent->fileinfo.st_mtime, dent->fileinfo.st_size, - model_number, type); + model_number, type, "file"); if (!ppd) { @@ -1837,7 +1840,7 @@ load_drv(const char *filename, /* I - Actual filename */ */ add_ppd(filename, filename, "", "", "", "", "", "", mtime, size, 0, - PPD_TYPE_DRV); + PPD_TYPE_DRV, "drv"); /* * Then the drivers in the file... @@ -1898,7 +1901,7 @@ load_drv(const char *filename, /* I - Actual filename */ device_id ? device_id->value->value : "", product->value->value, ps_version ? ps_version->value->value : "(3010) 0", - mtime, size, d->model_number, type); + mtime, size, d->model_number, type, "drv"); } if (!product_found) @@ -1906,7 +1909,7 @@ load_drv(const char *filename, /* I - Actual filename */ device_id ? device_id->value->value : "", d->model_name->value, ps_version ? ps_version->value->value : "(3010) 0", - mtime, size, d->model_number, type); + mtime, size, d->model_number, type, "drv"); } src->release(); @@ -1920,7 +1923,8 @@ load_drv(const char *filename, /* I - Actual filename */ */ static int /* O - 1 on success, 0 on failure */ -load_drivers(void) +load_drivers(cups_array_t *include, /* I - Drivers to include */ + cups_array_t *exclude) /* I - Drivers to exclude */ { int i; /* Looping var */ char *start, /* Start of value */ @@ -1979,6 +1983,14 @@ load_drivers(void) if (!(dent->fileinfo.st_mode & 0111) || !S_ISREG(dent->fileinfo.st_mode)) continue; + /* + * Include/exclude specific drivers... + */ + + if (cupsArrayFind(exclude, dent->filename) || + (include && !cupsArrayFind(include, dent->filename))) + continue; + /* * Run the driver with no arguments and collect the output... */ @@ -2044,7 +2056,7 @@ load_drivers(void) } ppd = add_ppd("", name, languages, make, make_and_model, device_id, - product, psversion, 0, 0, 0, type); + product, psversion, 0, 0, 0, type, dent->filename); if (!ppd) { diff --git a/scheduler/ipp.c b/scheduler/ipp.c index c7e98ed71..86db35441 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -6433,13 +6433,16 @@ get_devices(cupsd_client_t *con) /* I - Client connection */ ipp_attribute_t *limit, /* limit attribute */ *timeout, /* timeout attribute */ *requested, /* requested-attributes attribute */ - *exclude; /* exclude-schemes attribute */ + *exclude, /* exclude-schemes attribute */ + *include; /* include-schemes attribute */ char command[1024], /* cups-deviced command */ - options[1024], /* Options to pass to command */ + options[2048], /* Options to pass to command */ requested_str[256], /* String for requested attributes */ - exclude_str[512]; - /* String for excluded attributes */ + exclude_str[512], + /* String for excluded schemes */ + include_str[512]; + /* String for included schemes */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_devices(%p[%d])", con, con->http.fd); @@ -6463,6 +6466,7 @@ get_devices(cupsd_client_t *con) /* I - Client connection */ requested = ippFindAttribute(con->request, "requested-attributes", IPP_TAG_KEYWORD); exclude = ippFindAttribute(con->request, "exclude-schemes", IPP_TAG_NAME); + include = ippFindAttribute(con->request, "include-schemes", IPP_TAG_NAME); if (requested) url_encode_attr(requested, requested_str, sizeof(requested_str)); @@ -6474,15 +6478,21 @@ get_devices(cupsd_client_t *con) /* I - Client connection */ else exclude_str[0] = '\0'; + if (include) + url_encode_attr(include, include_str, sizeof(include_str)); + else + include_str[0] = '\0'; + snprintf(command, sizeof(command), "%s/daemon/cups-deviced", ServerBin); snprintf(options, sizeof(options), - "%d+%d+%d+%d+%s%s%s", + "%d+%d+%d+%d+%s%s%s%s%s", con->request->request.op.request_id, limit ? limit->values[0].integer : 0, timeout ? timeout->values[0].integer : 10, (int)User, requested_str, - exclude_str[0] ? "%20" : "", exclude_str); + exclude_str[0] ? "%20" : "", exclude_str, + include_str[0] ? "%20" : "", include_str); if (cupsdSendCommand(con, command, options, 1)) { @@ -7270,9 +7280,11 @@ get_ppds(cupsd_client_t *con) /* I - Client connection */ *product, /* ppd-product attribute */ *psversion, /* ppd-psverion attribute */ *type, /* ppd-type attribute */ - *requested; /* requested-attributes attribute */ + *requested, /* requested-attributes attribute */ + *exclude, /* exclude-schemes attribute */ + *include; /* include-schemes attribute */ char command[1024], /* cups-driverd command */ - options[1024], /* Options to pass to command */ + options[4096], /* Options to pass to command */ device_str[256],/* Escaped ppd-device-id string */ language_str[256], /* Escaped ppd-natural-language */ @@ -7285,8 +7297,12 @@ get_ppds(cupsd_client_t *con) /* I - Client connection */ psversion_str[256], /* Escaped ppd-psversion string */ type_str[256], /* Escaped ppd-type string */ - requested_str[256]; + requested_str[256], /* String for requested attributes */ + exclude_str[512], + /* String for excluded schemes */ + include_str[512]; + /* String for included schemes */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->http.fd); @@ -7366,9 +7382,19 @@ get_ppds(cupsd_client_t *con) /* I - Client connection */ else type_str[0] = '\0'; + if (exclude) + url_encode_attr(exclude, exclude_str, sizeof(exclude_str)); + else + exclude_str[0] = '\0'; + + if (include) + url_encode_attr(include, include_str, sizeof(include_str)); + else + include_str[0] = '\0'; + snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin); snprintf(options, sizeof(options), - "list+%d+%d+%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + "list+%d+%d+%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", con->request->request.op.request_id, limit ? limit->values[0].integer : 0, requested_str, @@ -7379,7 +7405,9 @@ get_ppds(cupsd_client_t *con) /* I - Client connection */ model_number ? "%20" : "", model_number_str, product ? "%20" : "", product_str, psversion ? "%20" : "", psversion_str, - type ? "%20" : "", type_str); + type ? "%20" : "", type_str, + exclude_str[0] ? "%20" : "", exclude_str, + include_str[0] ? "%20" : "", include_str); if (cupsdSendCommand(con, command, options, 0)) { diff --git a/scheduler/job.c b/scheduler/job.c index abdc338e8..64fbfd6eb 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -18,15 +18,17 @@ * cupsdCancelJob() - Cancel the specified print job. * cupsdCancelJobs() - Cancel all jobs for the given * destination/user... - * cupsdCheckJobs() - Check the pending jobs and start any if - * the destination is available. + * cupsdCheckJobs() - Check the pending jobs and start any if the + * destination is available. * cupsdCleanJobs() - Clean out old jobs. * cupsdDeleteJob() - Free all memory used by a job. * cupsdFinishJob() - Finish a job. * cupsdFreeAllJobs() - Free all jobs from memory. * cupsdFindJob() - Find the specified job. - * cupsdGetPrinterJobCount() - Get the number of pending, processing, - * cupsdGetUserJobCount() - Get the number of pending, processing, + * cupsdGetPrinterJobCount() - Get the number of pending, processing, or held + * jobs in a printer or class. + * cupsdGetUserJobCount() - Get the number of pending, processing, or held + * jobs for a user. * cupsdHoldJob() - Hold the specified job. * cupsdLoadAllJobs() - Load all jobs from disk. * cupsdLoadJob() - Load a single job... @@ -37,26 +39,26 @@ * cupsdSaveAllJobs() - Save a summary of all jobs to disk. * cupsdSaveJob() - Save a job to disk. * cupsdSetJobHoldUntil() - Set the hold time for a job... - * cupsdSetJobPriority() - Set the priority of a job, moving it - * up/down in the list as needed. + * cupsdSetJobPriority() - Set the priority of a job, moving it up/down + * in the list as needed. * cupsdStopAllJobs() - Stop all print jobs. * cupsdStopJob() - Stop a print job. * cupsdUnloadCompletedJobs() - Flush completed job history from memory. * compare_active_jobs() - Compare the job IDs and priorities of two * jobs. * compare_jobs() - Compare the job IDs of two jobs. - * ipp_length() - Compute the size of the buffer needed to - * hold the textual IPP attributes. + * ipp_length() - Compute the size of the buffer needed to hold + * the textual IPP attributes. * load_job_cache() - Load jobs from the job.cache file. - * load_next_job_id() - Load the NextJobId value from the - * job.cache file. + * load_next_job_id() - Load the NextJobId value from the job.cache + * file. * load_request_root() - Load jobs from the RequestRoot directory. * set_time() - Set one of the "time-at-xyz" attributes... * set_hold_until() - Set the hold time and update job-hold-until * attribute... * start_job() - Start a print job. * unload_job() - Unload a job from memory. - * update_job() - Read a status update from a jobs filters. + * update_job() - Read a status update from a job's filters. * update_job_attrs() - Update the job-printer-* attributes. */ @@ -447,9 +449,9 @@ cupsdCheckJobs(void) * cancel the job... */ - cupsdLogJob(job, CUPSD_LOG_WARN, - "Printer/class %s has gone away; canceling job!", - job->dest); + cupsdLogMessage(CUPSD_LOG_WARN, + "[Job %d] Printer/class %s has gone away; canceling " + "job!", job->id, job->dest); cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, "Job canceled because the destination printer/class has " @@ -1070,7 +1072,8 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ if ((job->attrs = ippNew()) == NULL) { - cupsdLogJob(job, CUPSD_LOG_ERROR, "Ran out of memory for job attributes!"); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Ran out of memory for job attributes!", job->id); return; } @@ -1078,14 +1081,14 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ * Load job attributes... */ - cupsdLogJob(job, CUPSD_LOG_DEBUG, "Loading attributes..."); + cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Loading attributes...", job->id); snprintf(jobfile, sizeof(jobfile), "%s/c%05d", RequestRoot, job->id); if ((fp = cupsFileOpen(jobfile, "r")) == NULL) { - cupsdLogJob(job, CUPSD_LOG_ERROR, - "Unable to open job control file \"%s\" - %s!", - jobfile, strerror(errno)); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to open job control file \"%s\" - %s!", + job->id, jobfile, strerror(errno)); ippDelete(job->attrs); job->attrs = NULL; return; @@ -1093,9 +1096,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, job->attrs) != IPP_DATA) { - cupsdLogJob(job, CUPSD_LOG_ERROR, - "Unable to read job control file \"%s\"!", - jobfile); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to read job control file \"%s\"!", job->id, + jobfile); cupsFileClose(fp); ippDelete(job->attrs); job->attrs = NULL; @@ -1112,8 +1115,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ if ((job->state = ippFindAttribute(job->attrs, "job-state", IPP_TAG_ENUM)) == NULL) { - cupsdLogJob(job, CUPSD_LOG_ERROR, - "Missing or bad job-state attribute in control file!"); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Missing or bad job-state attribute in control " + "file!", job->id); ippDelete(job->attrs); job->attrs = NULL; unlink(jobfile); @@ -1127,8 +1131,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ if ((attr = ippFindAttribute(job->attrs, "job-printer-uri", IPP_TAG_URI)) == NULL) { - cupsdLogJob(job, CUPSD_LOG_ERROR, - "No job-printer-uri attribute in control file!"); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] No job-printer-uri attribute in control file!", + job->id); ippDelete(job->attrs); job->attrs = NULL; unlink(jobfile); @@ -1138,9 +1143,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ if ((dest = cupsdValidateDest(attr->values[0].string.text, &(job->dtype), &destptr)) == NULL) { - cupsdLogJob(job, CUPSD_LOG_ERROR, - "Unable to queue job for destination \"%s\"!", - attr->values[0].string.text); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to queue job for destination \"%s\"!", + job->id, attr->values[0].string.text); ippDelete(job->attrs); job->attrs = NULL; unlink(jobfile); @@ -1151,8 +1156,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ } else if ((destptr = cupsdFindDest(job->dest)) == NULL) { - cupsdLogJob(job, CUPSD_LOG_ERROR, - "Unable to queue job for destination \"%s\"!", job->dest); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to queue job for destination \"%s\"!", + job->id, job->dest); ippDelete(job->attrs); job->attrs = NULL; unlink(jobfile); @@ -1168,8 +1174,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ if ((attr = ippFindAttribute(job->attrs, "job-priority", IPP_TAG_INTEGER)) == NULL) { - cupsdLogJob(job, CUPSD_LOG_ERROR, - "Missing or bad job-priority attribute in control file!"); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Missing or bad job-priority attribute in " + "control file!", job->id); ippDelete(job->attrs); job->attrs = NULL; unlink(jobfile); @@ -1184,9 +1191,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ if ((attr = ippFindAttribute(job->attrs, "job-originating-user-name", IPP_TAG_NAME)) == NULL) { - cupsdLogJob(job, CUPSD_LOG_ERROR, - "Missing or bad job-originating-user-name attribute in " - "control file!"); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Missing or bad job-originating-user-name " + "attribute in control file!", job->id); ippDelete(job->attrs); job->attrs = NULL; unlink(jobfile); @@ -1234,8 +1241,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ if (access(jobfile, 0)) break; - cupsdLogJob(job, CUPSD_LOG_DEBUG, - "Auto-typing document file \"%s\"...", jobfile); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "[Job %d] Auto-typing document file \"%s\"...", job->id, + jobfile); if (fileid > job->num_files) { @@ -1255,8 +1263,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ if (!compressions || !filetypes) { - cupsdLogJob(job, CUPSD_LOG_ERROR, - "Ran out of memory for job file types!"); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Ran out of memory for job file types!", + job->id); return; } @@ -1313,6 +1322,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ cupsFileClose(fp); } } + job->access_time = time(NULL); } @@ -1525,9 +1535,9 @@ cupsdSaveJob(cupsd_job_t *job) /* I - Job */ if ((fp = cupsFileOpen(filename, "w")) == NULL) { - cupsdLogJob(job, CUPSD_LOG_ERROR, - "Unable to create job control file \"%s\" - %s.", - filename, strerror(errno)); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to create job control file \"%s\" - %s.", + job->id, filename, strerror(errno)); return; } @@ -1538,7 +1548,8 @@ cupsdSaveJob(cupsd_job_t *job) /* I - Job */ if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL, job->attrs) != IPP_DATA) - cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to write job control file!"); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to write job control file!", job->id); cupsFileClose(fp); @@ -1647,7 +1658,7 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */ curtime = time(NULL); curdate = localtime(&curtime); - if (curdate->tm_wday || curdate->tm_wday == 6) + if (curdate->tm_wday == 0 || curdate->tm_wday == 6) job->hold_until = curtime; else job->hold_until = curtime + @@ -1758,7 +1769,8 @@ cupsdStopJob(cupsd_job_t *job, /* I - Job */ int i; /* Looping var */ - cupsdLogJob(job, CUPSD_LOG_DEBUG2, "cupsdStopJob: force = %d", force); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "[Job %d] cupsdStopJob: force = %d", + job->id, force); if (job->state_value != IPP_JOB_PROCESSING) return; @@ -1791,18 +1803,18 @@ cupsdStopJob(cupsd_job_t *job, /* I - Job */ cupsdDestroyProfile(job->profile); job->profile = NULL; - cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Closing print pipes [ %d %d ]...", - job->print_pipes[0], job->print_pipes[1]); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "[Job %d] Closing print pipes [ %d %d ]...", + job->id, job->print_pipes[0], job->print_pipes[1]); cupsdClosePipe(job->print_pipes); - cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Closing back pipes [ %d %d ]...", - job->back_pipes[0], job->back_pipes[1]); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "[Job %d] Closing back pipes [ %d %d ]...", + job->id, job->back_pipes[0], job->back_pipes[1]); cupsdClosePipe(job->back_pipes); - cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Closing side pipes [ %d %d ]...", - job->side_pipes[0], job->side_pipes[1]); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "[Job %d] Closing side pipes [ %d %d ]...", + job->id, job->side_pipes[0], job->side_pipes[1]); cupsdClosePipe(job->side_pipes); @@ -1814,8 +1826,9 @@ cupsdStopJob(cupsd_job_t *job, /* I - Job */ cupsdRemoveSelect(job->status_buffer->fd); - cupsdLogJob(job, CUPSD_LOG_DEBUG2, "Closing status pipes [ %d %d ]...", - job->status_pipes[0], job->status_pipes[1]); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "[Job %d] Closing status pipes [ %d %d ]...", + job->id, job->status_pipes[0], job->status_pipes[1]); cupsdClosePipe(job->status_pipes); cupsdStatBufDelete(job->status_buffer); @@ -2107,7 +2120,8 @@ load_job_cache(const char *filename) /* I - job.cache filename */ job->status_pipes[0] = -1; job->status_pipes[1] = -1; - cupsdLogJob(job, CUPSD_LOG_DEBUG, "Loading from cache..."); + cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Loading from cache...", + job->id); } else if (!job) { @@ -2175,7 +2189,8 @@ load_job_cache(const char *filename) /* I - job.cache filename */ job->id); if (access(jobfile, 0)) { - cupsdLogJob(job, CUPSD_LOG_INFO, "Data files have gone away!"); + cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Data files have gone away!", + job->id); job->num_files = 0; continue; } @@ -2185,9 +2200,9 @@ load_job_cache(const char *filename) /* I - job.cache filename */ if (!job->filetypes || !job->compressions) { - cupsdLogJob(job, CUPSD_LOG_EMERG, - "Unable to allocate memory for %d files!", - job->num_files); + cupsdLogMessage(CUPSD_LOG_EMERG, + "[Job %d] Unable to allocate memory for %d files!", + job->id, job->num_files); break; } } @@ -2225,9 +2240,9 @@ load_job_cache(const char *filename) /* I - job.cache filename */ * If the original MIME type is unknown, auto-type it! */ - cupsdLogJob(job, CUPSD_LOG_ERROR, - "Unknown MIME type %s/%s for file %d!", - super, type, number + 1); + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unknown MIME type %s/%s for file %d!", + job->id, super, type, number + 1); snprintf(jobfile, sizeof(jobfile), "%s/d%05d-%03d", RequestRoot, job->id, number + 1); @@ -3588,7 +3603,7 @@ unload_job(cupsd_job_t *job) /* I - Job */ if (!job->attrs) return; - cupsdLogJob(job, CUPSD_LOG_DEBUG, "Unloading..."); + cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Unloading...", job->id); ippDelete(job->attrs); @@ -3772,6 +3787,22 @@ update_job(cupsd_job_t *job) /* I - Job to check */ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); } + if ((attr = cupsGetOption("marker-low-levels", num_attrs, attrs)) != NULL) + { + cupsdSetPrinterAttr(job->printer, "marker-low-levels", (char *)attr); + job->printer->marker_time = time(NULL); + event |= CUPSD_EVENT_PRINTER_STATE; + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + + if ((attr = cupsGetOption("marker-high-levels", num_attrs, attrs)) != NULL) + { + cupsdSetPrinterAttr(job->printer, "marker-high-levels", (char *)attr); + job->printer->marker_time = time(NULL); + event |= CUPSD_EVENT_PRINTER_STATE; + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + if ((attr = cupsGetOption("marker-message", num_attrs, attrs)) != NULL) { cupsdSetPrinterAttr(job->printer, "marker-message", (char *)attr); diff --git a/scheduler/log.c b/scheduler/log.c index 19cb0cc86..47eb67b12 100644 --- a/scheduler/log.c +++ b/scheduler/log.c @@ -928,7 +928,7 @@ format_log_line(const char *message, /* I - Printf-style format string */ * Resize the buffer as needed... */ - if (len >= log_linesize) + if (len >= log_linesize && log_linesize < 65536) { char *temp; /* Temporary string pointer */ diff --git a/scheduler/main.c b/scheduler/main.c index 6f9902441..afbf149e2 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -1175,8 +1175,7 @@ main(int argc, /* I - Number of command-line args */ krb5_free_context(KerberosContext); #endif /* HAVE_GSSAPI */ -#ifdef __APPLE__ -#ifdef HAVE_DLFCN_H +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) /* * Unload Print Service quota enforcement library (X Server only) */ @@ -1187,8 +1186,7 @@ main(int argc, /* I - Number of command-line args */ dlclose(PSQLibRef); PSQLibRef = NULL; } -#endif /* HAVE_DLFCN_H */ -#endif /* __APPLE__ */ +#endif /* __APPLE__ && HAVE_DLFCN_H */ #ifdef __sgi /* diff --git a/scheduler/printers.c b/scheduler/printers.c index 5a2af4a2d..db3f5773f 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -1630,6 +1630,26 @@ cupsdSaveAllPrinters(void) cupsFilePuts(fp, "\n"); } + if ((marker = ippFindAttribute(printer->attrs, "marker-low-levels", + IPP_TAG_INTEGER)) != NULL) + { + cupsFilePrintf(fp, "Attribute %s %d", marker->name, + marker->values[0].integer); + for (i = 1; i < marker->num_values; i ++) + cupsFilePrintf(fp, ",%d", marker->values[i].integer); + cupsFilePuts(fp, "\n"); + } + + if ((marker = ippFindAttribute(printer->attrs, "marker-high-levels", + IPP_TAG_INTEGER)) != NULL) + { + cupsFilePrintf(fp, "Attribute %s %d", marker->name, + marker->values[0].integer); + for (i = 1; i < marker->num_values; i ++) + cupsFilePrintf(fp, ",%d", marker->values[i].integer); + cupsFilePuts(fp, "\n"); + } + if ((marker = ippFindAttribute(printer->attrs, "marker-message", IPP_TAG_TEXT)) != NULL) { @@ -1960,7 +1980,8 @@ cupsdSetPrinterAttr( * Then add or update the attribute as needed... */ - if (!strcmp(name, "marker-levels")) + if (!strcmp(name, "marker-levels") || !strcmp(name, "marker-low-levels") || + !strcmp(name, "marker-high-levels")) { /* * Integer values... diff --git a/scheduler/process.c b/scheduler/process.c index b0481296c..15ce14d5d 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -3,7 +3,7 @@ * * Process management routines for the Common UNIX Printing System (CUPS). * - * Copyright 2007 by Apple Inc. + * Copyright 2007-2008 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -106,9 +106,18 @@ cupsdCreateProfile(int job_id) /* I - Job ID or 0 for none */ "#\"^/Library\" #\"^/System\" #\"^/Users\"))\n", root); cupsFilePrintf(fp, "(allow file-write* file-read-data file-read-metadata\n" - " (regex #\"^%s$\" #\"^%s/\" #\"^%s$\" #\"^%s/\" " - "#\"^/Library/Caches/\"))\n", + " (regex #\"^%s$\" #\"^%s/\" #\"^%s$\" #\"^%s/\"" + " #\"^/Library/Application Support/\"" + " #\"^/Library/Caches/\"" + " #\"^/Library/Preferences/\"" + " #\"^/Library/Printers/\"" + "))\n", temp, temp, cache, cache); + cupsFilePuts(fp, + "(deny file-write*\n" + " (regex #\"^/Library/Printers/PPDs/\"" + " #\"^/Library/Printers/PPD Plugins/\"" + "))\n"); if (job_id) cupsFilePrintf(fp, "(allow file-read-data file-read-metadata\n" diff --git a/scheduler/util.c b/scheduler/util.c index c876c9a04..3e1f898f3 100644 --- a/scheduler/util.c +++ b/scheduler/util.c @@ -14,14 +14,15 @@ * * Contents: * - * cupsdCompareNames() - Compare two names. - * cupsdExec() - Run a program with the correct environment. - * cupsdPipeCommand() - Read output from a command. - * cupsdSendIPPGroup() - Send a group tag. - * cupsdSendIPPHeader() - Send the IPP response header. - * cupsdSendIPPInteger() - Send an integer attribute. - * cupsdSendIPPString() - Send a string attribute. - * cupsdSendIPPTrailer() - Send the end-of-message tag. + * cupsdCompareNames() - Compare two names. + * cupsdCreateStringsArray() - Create a CUPS array of strings. + * cupsdExec() - Run a program with the correct environment. + * cupsdPipeCommand() - Read output from a command. + * cupsdSendIPPGroup() - Send a group tag. + * cupsdSendIPPHeader() - Send the IPP response header. + * cupsdSendIPPInteger() - Send an integer attribute. + * cupsdSendIPPString() - Send a string attribute. + * cupsdSendIPPTrailer() - Send the end-of-message tag. */ /* @@ -152,6 +153,49 @@ cupsdCompareNames(const char *s, /* I - First string */ } +/* + * 'cupsdCreateStringsArray()' - Create a CUPS array of strings. + */ + +cups_array_t * /* O - CUPS array */ +cupsdCreateStringsArray(const char *s) /* I - Comma-delimited strings */ +{ + cups_array_t *a; /* CUPS array */ + const char *start, /* Start of string */ + *end; /* End of string */ + char *ptr; /* New string */ + + + if (!s) + return (NULL); + + if ((a = cupsArrayNew((cups_array_func_t)strcmp, NULL)) != NULL) + { + for (start = end = s; *end; start = end + 1) + { + /* + * Find the end of the current delimited string... + */ + + if ((end = strchr(start, ',')) == NULL) + end = start + strlen(start); + + /* + * Duplicate the string and add it to the array... + */ + + if ((ptr = calloc(1, end - start + 1)) == NULL) + break; + + memcpy(ptr, start, end - start); + cupsArrayAdd(a, ptr); + } + } + + return (a); +} + + /* * 'cupsdExec()' - Run a program with the correct environment. * diff --git a/scheduler/util.h b/scheduler/util.h index ae7ba7bb2..31e729730 100644 --- a/scheduler/util.h +++ b/scheduler/util.h @@ -50,6 +50,7 @@ typedef int (*cupsd_compare_func_t)(const void *, const void *); */ extern int cupsdCompareNames(const char *s, const char *t); +extern cups_array_t *cupsdCreateStringsArray(const char *s); extern int cupsdExec(const char *command, char **argv); extern cups_file_t *cupsdPipeCommand(int *pid, const char *command, char **argv, int user); diff --git a/systemv/lpinfo.c b/systemv/lpinfo.c index 72e8fbab8..7b144148b 100644 --- a/systemv/lpinfo.c +++ b/systemv/lpinfo.c @@ -42,10 +42,14 @@ static void device_cb(const char *device_clas, const char *device_id, const char *device_make_and_model, const char *device_uri, const char *device_location, void *user_data); -static int show_devices(http_t *http, int long_status, int timeout); -static int show_models(http_t *http, int long_status, +static int show_devices(int long_status, int timeout, + const char *include_schemes, + const char *exclude_schemes); +static int show_models(int long_status, const char *device_id, const char *language, - const char *make_model, const char *product); + const char *make_model, const char *product, + const char *include_schemes, + const char *exclude_schemes); /* @@ -57,24 +61,26 @@ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ - http_t *http; /* Connection to server */ int long_status; /* Long listing? */ const char *device_id, /* 1284 device ID */ *language, /* Language */ *make_model, /* Make and model */ - *product; /* Product */ + *product, /* Product */ + *include_schemes, /* Schemes to include */ + *exclude_schemes; /* Schemes to exclude */ int timeout; /* Device timeout */ _cupsSetLocale(argv); - http = NULL; - long_status = 0; - device_id = NULL; - language = NULL; - make_model = NULL; - product = NULL; - timeout = CUPS_TIMEOUT_DEFAULT; + long_status = 0; + device_id = NULL; + language = NULL; + make_model = NULL; + product = NULL; + include_schemes = CUPS_INCLUDE_ALL; + exclude_schemes = CUPS_EXCLUDE_NONE; + timeout = CUPS_TIMEOUT_DEFAULT; for (i = 1; i < argc; i ++) if (argv[i][0] == '-') @@ -83,9 +89,6 @@ main(int argc, /* I - Number of command-line arguments */ case 'E' : /* Encrypt */ #ifdef HAVE_SSL cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); - - if (http) - httpEncryption(http, HTTP_ENCRYPT_REQUIRED); #else _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support compiled in!\n"), @@ -94,12 +97,6 @@ main(int argc, /* I - Number of command-line arguments */ break; case 'h' : /* Connect to host */ - if (http) - { - httpClose(http); - http = NULL; - } - if (argv[i][2] != '\0') cupsSetServer(argv[i] + 2); else @@ -122,41 +119,14 @@ main(int argc, /* I - Number of command-line arguments */ break; case 'm' : /* Show models */ - if (!http) - { - http = httpConnectEncrypt(cupsServer(), ippPort(), - cupsEncryption()); - - if (http == NULL) - { - _cupsLangPrintf(stderr, - _("lpinfo: Unable to connect to server: %s\n"), - strerror(errno)); - return (1); - } - } - - if (show_models(http, long_status, device_id, language, make_model, - product)) + if (show_models(long_status, device_id, language, make_model, + product, include_schemes, exclude_schemes)) return (1); break; case 'v' : /* Show available devices */ - if (!http) - { - http = httpConnectEncrypt(cupsServer(), ippPort(), - cupsEncryption()); - - if (http == NULL) - { - _cupsLangPrintf(stderr, - _("lpinfo: Unable to connect to server: %s\n"), - strerror(errno)); - return (1); - } - } - - if (show_devices(http, long_status, timeout)) + if (show_devices(long_status, timeout, include_schemes, + exclude_schemes)) return (1); break; @@ -179,6 +149,42 @@ main(int argc, /* I - Number of command-line arguments */ { device_id = argv[i] + 12; } + else if (!strcmp(argv[i], "--exclude-schemes")) + { + i ++; + + if (i < argc) + exclude_schemes = argv[i]; + else + { + _cupsLangPuts(stderr, + _("lpinfo: Expected scheme list after " + "--exclude-schemes!\n")); + return (1); + } + } + else if (!strncmp(argv[i], "--exclude-schemes=", 18) && argv[i][18]) + { + exclude_schemes = argv[i] + 18; + } + else if (!strcmp(argv[i], "--include-schemes")) + { + i ++; + + if (i < argc) + include_schemes = argv[i]; + else + { + _cupsLangPuts(stderr, + _("lpinfo: Expected scheme list after " + "--include-schemes!\n")); + return (1); + } + } + else if (!strncmp(argv[i], "--include-schemes=", 18) && argv[i][18]) + { + include_schemes = argv[i] + 18; + } else if (!strcmp(argv[i], "--language")) { i ++; @@ -315,12 +321,14 @@ device_cb( */ static int /* O - 0 on success, 1 on failure */ -show_devices(http_t *http, /* I - HTTP connection to server */ - int long_status, /* I - Long status report? */ - int timeout) /* I - Timeout */ +show_devices( + int long_status, /* I - Long status report? */ + int timeout, /* I - Timeout */ + const char *include_schemes, /* I - List of schemes to include */ + const char *exclude_schemes) /* I - List of schemes to exclude */ { - if (cupsGetDevices(http, timeout, CUPS_EXCLUDE_NONE, device_cb, - &long_status) != IPP_OK) + if (cupsGetDevices(CUPS_HTTP_DEFAULT, timeout, include_schemes, + exclude_schemes, device_cb, &long_status) != IPP_OK) { _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString()); return (1); @@ -335,12 +343,14 @@ show_devices(http_t *http, /* I - HTTP connection to server */ */ static int /* O - 0 on success, 1 on failure */ -show_models(http_t *http, /* I - HTTP connection to server */ - int long_status, /* I - Long status report? */ - const char *device_id, /* I - 1284 device ID */ - const char *language, /* I - Language */ - const char *make_model, /* I - Make and model */ - const char *product) /* I - Product */ +show_models( + int long_status, /* I - Long status report? */ + const char *device_id, /* I - 1284 device ID */ + const char *language, /* I - Language */ + const char *make_model, /* I - Make and model */ + const char *product, /* I - Product */ + const char *include_schemes, /* I - List of schemes to include */ + const char *exclude_schemes) /* I - List of schemes to exclude */ { ipp_t *request, /* IPP Request */ *response; /* IPP Response */ @@ -349,11 +359,9 @@ show_models(http_t *http, /* I - HTTP connection to server */ *ppd_language, /* Pointer to ppd-natural-language */ *ppd_make_model, /* Pointer to ppd-make-and-model */ *ppd_name; /* Pointer to ppd-name */ + cups_option_t option; /* in/exclude-schemes option */ - if (http == NULL) - return (1); - /* * Build a CUPS_GET_PPDS request... */ @@ -373,11 +381,27 @@ show_models(http_t *http, /* I - HTTP connection to server */ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-product", NULL, product); + if (include_schemes) + { + option.name = "include-schemes"; + option.value = (char *)include_schemes; + + cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); + } + + if (exclude_schemes) + { + option.name = "exclude-schemes"; + option.value = (char *)exclude_schemes; + + cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); + } + /* * Do the request and get back a response... */ - if ((response = cupsDoRequest(http, request, "/")) != NULL) + if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL) { /* * Loop through the device list and display them... -- 2.39.2