From ed6e7faf3e76edf2b4dbcf38fdbfbfe5c387550a Mon Sep 17 00:00:00 2001
From: msweet
-o number-up-layout=tbrl
; Top to bottom, right to leftThe -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 document-count attribute specifies the number of documents that are present in the job. -
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. + +
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". -
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.
-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".
-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.
+ +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.
-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.
+ +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.
-The marker-names attribute specifies the name(s) for each supply in the printer. It is only available when the driver provides supply levels.
-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