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