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
-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.
.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
snmp_fd = -1;
}
}
- else
- start_count = 0;
/*
* Check for side-channel requests...
* Force the read thread to exit...
*/
+ g.wait_eof = 0;
pthread_kill(read_thread_id, SIGTERM);
}
}
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
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,
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
{
# 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
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,
{ 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 },
*
* 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@
*/
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 */
*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 */
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";
* 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
* 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.
*/
/*
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
<LI><CODE>-o number-up-layout=tbrl</CODE>; Top to bottom, right to left</LI>
</UL>
-<H3><A NAME="FITPLOT">Scaling to Fit</A></H3>
+<H3><A NAME="FIT_TO_PAGE">Scaling to Fit</A></H3>
-<P>The <CODE>-o fitplot</CODE> option specifies that the document
+<P>The <CODE>-o fit-to-page</CODE> option specifies that the document
should be scaled to fit on the page:</P>
<PRE CLASS="command">
-lp -o fitplot filename
-lpr -o fitplot filename
+lp -o fit-to-page filename
+lpr -o fit-to-page filename
</PRE>
<P>The default is to use the size specified in the file.</P>
<dd>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.
+
+ <dt>"include-schemes" (1setOf name) :<span class='info'>CUPS 1.4</span>
+
+ <dd>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.
<dt>"limit" (integer (1:MAX)):
attributes as described in section 3.1.4.1 of the IPP Model and
Semantics document.
+ <dt>"exclude-schemes" (1setOf name) :<span class='info'>CUPS 1.4</span>
+
+ <dd>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.
+
+ <dt>"include-schemes" (1setOf name) :<span class='info'>CUPS 1.4</span>
+
+ <dd>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.
+
<dt>"limit" (integer (1:MAX)):
<dd>The client OPTIONALLY supplies this attribute limiting the number of PPDs that are returned.
<p>The document-count attribute specifies the number of documents that
are present in the job.
-<h4><a name="fitplot">fitplot (boolean)</a></h4>
+<h4><a name="fit-to-page">fit-to-page (boolean)</a><span class="info">CUPS 1.4</span></h4>
+
+<p>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.
+
+<h4><a name="fitplot">fitplot (boolean)</a><span class="info">Deprecated</span></h4>
<p>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
<p>The job-sheets-supported attribute specifies the available banner files.
There will always be at least one banner file available called "none".
-<h4><a name="marker-change-time">marker-change-time (integer)</a></h4>
+<h4><a name="marker-change-time">marker-change-time (integer)</a><span class='info'>CUPS 1.3</span></h4>
<p>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.</p>
-<h4><a name="marker-colors">marker-colors (1setof name(MAX))</a></h4>
+<h4><a name="marker-colors">marker-colors (1setof name(MAX))</a><span class='info'>CUPS 1.3</span></h4>
<p>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".</p>
-<h4><a name="marker-levels">marker-levels (1setof integer(-1:100))</a></h4>
+<h4><a name="marker-high-levels">marker-high-levels (1setof integer(0:100))</a><span class='info'>CUPS 1.4</span></h4>
+
+<p>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.</p>
+
+<h4><a name="marker-levels">marker-levels (1setof integer(-1:100))</a><span class='info'>CUPS 1.3</span></h4>
<p>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.</p>
-<h4><a name="marker-message">marker-message (text(MAX))</a></h4>
+<h4><a name="marker-low-levels">marker-low-levels (1setof integer(0:100))</a><span class='info'>CUPS 1.4</span></h4>
+
+<p>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.</p>
+
+<h4><a name="marker-message">marker-message (text(MAX))</a><span class='info'>CUPS 1.4</span></h4>
<p>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.</p>
-<h4><a name="marker-names">marker-names (1setof name(MAX))</a></h4>
+<h4><a name="marker-names">marker-names (1setof name(MAX))</a><span class='info'>CUPS 1.3</span></h4>
<p>The marker-names attribute specifies the name(s) for each supply in the
printer. It is only available when the driver provides supply levels.</p>
-<h4><a name="marker-types">marker-types (1setof type3 keyword)</a></h4>
+<h4><a name="marker-types">marker-types (1setof type3 keyword)</a><span class='info'>CUPS 1.3</span></h4>
<p>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
*
* 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
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)
*
* 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
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)
*
* 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
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)
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;
/*
.\" 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
.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
.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
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.
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);
* 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...
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);
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 */
}
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)
{
(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;
/*
}
-/*
- * '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.
*/
* 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 */
/* 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 ****/
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);
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);
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 */
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
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 */
* 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);
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;
}
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");
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);
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 &&
* 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 */
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)
{
*/
add_ppd(filename, filename, "", "", "", "", "", "", mtime, size, 0,
- PPD_TYPE_DRV);
+ PPD_TYPE_DRV, "drv");
/*
* Then the drivers in the file...
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)
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();
*/
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 */
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...
*/
}
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)
{
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);
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));
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))
{
*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 */
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);
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,
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))
{
* 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...
* 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.
*/
* 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 "
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;
}
* 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;
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;
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);
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);
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);
}
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);
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);
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);
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)
{
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;
}
cupsFileClose(fp);
}
}
+
job->access_time = time(NULL);
}
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;
}
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);
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 +
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;
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);
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);
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)
{
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;
}
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;
}
}
* 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);
if (!job->attrs)
return;
- cupsdLogJob(job, CUPSD_LOG_DEBUG, "Unloading...");
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Unloading...", job->id);
ippDelete(job->attrs);
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);
* Resize the buffer as needed...
*/
- if (len >= log_linesize)
+ if (len >= log_linesize && log_linesize < 65536)
{
char *temp; /* Temporary string pointer */
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)
*/
dlclose(PSQLibRef);
PSQLibRef = NULL;
}
-#endif /* HAVE_DLFCN_H */
-#endif /* __APPLE__ */
+#endif /* __APPLE__ && HAVE_DLFCN_H */
#ifdef __sgi
/*
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)
{
* 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...
*
* 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
"#\"^/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"
*
* 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.
*/
/*
}
+/*
+ * '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.
*
*/
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);
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);
/*
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] == '-')
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"),
break;
case 'h' : /* Connect to host */
- if (http)
- {
- httpClose(http);
- http = NULL;
- }
-
if (argv[i][2] != '\0')
cupsSetServer(argv[i] + 2);
else
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;
{
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 ++;
*/
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);
*/
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 */
*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...
*/
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...