summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2010-07-08 20:45:48 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2010-07-08 20:45:48 +0000
commitc7017eccd21da514f345a5c7a41156b1adf7cb35 (patch)
tree155dfe5c7696ab6789d31cc7bfc5eb0874eecb11
parentcc75483441ba4241a6b0079e028d7699d99a6b0f (diff)
downloadcups-c7017eccd21da514f345a5c7a41156b1adf7cb35.tar.gz
Merge changes from CUPS 1.5svn-r9198.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@2309 a1ca3aef-8c08-0410-bb20-df032aa958be
-rw-r--r--CHANGES-1.4.txt33
-rw-r--r--CHANGES.txt5
-rw-r--r--backend/ipp.c51
-rw-r--r--backend/lpd.c58
-rw-r--r--backend/pap.c20
-rw-r--r--backend/runloop.c2
-rw-r--r--backend/serial.c7
-rw-r--r--backend/socket.c37
-rw-r--r--backend/usb-darwin.c123
-rw-r--r--backend/usb.c4
-rw-r--r--cgi-bin/admin.c6
-rw-r--r--cgi-bin/ipp-var.c8
-rw-r--r--cgi-bin/var.c5
-rw-r--r--conf/cupsd.conf.in6
-rw-r--r--config-scripts/cups-common.m48
-rw-r--r--config-scripts/cups-sharedlibs.m415
-rw-r--r--config-scripts/cups-ssl.m443
-rw-r--r--config.h.in15
-rw-r--r--configure.in3
-rwxr-xr-xcups-config.in10
-rw-r--r--cups/dest.c3
-rw-r--r--cups/file.c110
-rw-r--r--cups/globals.c2
-rw-r--r--cups/http-support.c3
-rw-r--r--cups/http.c2
-rw-r--r--cups/http.h2
-rw-r--r--cups/ipp.h4
-rw-r--r--cups/language.c8
-rw-r--r--cups/mark.c160
-rw-r--r--cups/ppd-private.h59
-rw-r--r--cups/ppd.h2
-rw-r--r--cups/pwg-file.c72
-rw-r--r--cups/pwg-ppd.c200
-rw-r--r--cups/pwg-private.h39
-rw-r--r--cups/raster.h58
-rw-r--r--cups/testfile.c14
-rw-r--r--cups/thread-private.h86
-rw-r--r--cups/thread.c144
-rw-r--r--cups/versioning.h2
-rw-r--r--doc/Makefile1
-rw-r--r--doc/help/spec-ppd.html88
-rw-r--r--driver/rastertoescpx.c12
-rw-r--r--driver/rastertopclx.c12
-rw-r--r--filter/imagetoraster.c57
-rw-r--r--filter/pdftops.c16
-rw-r--r--filter/pstops.c48
-rw-r--r--filter/raster.c26
-rw-r--r--filter/rastertoepson.c19
-rw-r--r--filter/rastertohp.c15
-rw-r--r--filter/rastertolabel.c20
-rw-r--r--filter/texttops.c18
-rw-r--r--man/Makefile1
-rw-r--r--man/drv.man.in40
-rw-r--r--notifier/mailto.c6
-rw-r--r--packaging/cups.list.in2
-rw-r--r--ppdc/ppdc-source.cxx16
-rw-r--r--scheduler/auth.c71
-rw-r--r--scheduler/client.c252
-rw-r--r--scheduler/conf.c38
-rw-r--r--scheduler/cups.xml.in8
-rw-r--r--scheduler/ipp.c84
-rw-r--r--scheduler/job.c184
-rw-r--r--scheduler/main.c11
-rw-r--r--scheduler/printers.c4
-rw-r--r--scheduler/select.c12
-rw-r--r--templates/admin.tmpl2
-rw-r--r--test/ipp-1.1.test2
-rw-r--r--test/print-job-hold.test27
-rwxr-xr-xtest/run-stp-tests.sh2
-rw-r--r--tools/makeipptoolpkg2
-rw-r--r--vcnet/libcups2.vcproj16
71 files changed, 1820 insertions, 721 deletions
diff --git a/CHANGES-1.4.txt b/CHANGES-1.4.txt
index b58c52908..5dac60fbc 100644
--- a/CHANGES-1.4.txt
+++ b/CHANGES-1.4.txt
@@ -3,15 +3,46 @@ CHANGES-1.4.txt
CHANGES IN CUPS V1.4.5
+ - Documentation fixes (STR #3542)
+ - Fixed the Solaris SMF configuration file for cups-lpd (STR #3611)
+ - The scheduler did not set the notify-subscribed-event attribute when
+ delivering printer-added or printer-modified events (STR #3608)
+ - The mailto notifier could get into an infinite loop (STR #3609)
+ - Date/time information was not shown in banner pages.
+ - Relational operators were broken in #if/#elif/#else/#endif expressions
+ for the PPD compiler.
+ - Moving a job via the web interface failed without asking for
+ authentication (STR #3559)
+ - The scheduler now clears the printer-state-reasons when the driver is
+ changed (STR #3570)
+ - The web interface did not allow a user to change the driver
+ (STR #3537, STR #3601)
+ - The scheduler was not setting the PATH_INFO environment variable when
+ needed (STR #3600)
+ - The scheduler incorrectly set the CUPSD_AUTH_TYPE environment
+ variable instead of AUTH_TYPE (STR #3599)
+ - Fixed a buffer overrun in the PPD compiler (STR #3594)
+ - Fixed some additional IPP job template attribute mapping issues in the
+ scheduler.
CHANGES IN CUPS V1.4.4
- Documentation updates (STR #3453, STR #3527, STR #3528, STR #3529)
+ - Security: The fix for CVE-2009-3553 was incomplete (STR #3490)
+ - Security: The texttops filter did not check the results of allocations
+ (STR #3516)
+ - Security: The web admin interface could disclose the contents of
+ memory (STR #3577)
+ - Security: CUPS could overwrite files as root in directories owned or
+ writable by non-root users (STR #3510)
+ - The cups-config utility did not return the correct linker options on
+ AIX (STR #3587)
- Fixed some IPP conformance issues with the scheduler's
ippget-event-life, operations-supported, output-bin, and sides
attributes (STR #3554)
- - The GNU TLS and OpenSSL interfaces have been made thread-safe
+ - The OpenSSL interfaces have been made thread-safe and the GNU TLS
+ interface is explicitly forbidden when threading is enabled
(STR #3461)
- Fixed an IPP conformance issue with the scheduler's Send-Document
implementation (STR #3514)
diff --git a/CHANGES.txt b/CHANGES.txt
index 8c072e6ed..067dc958e 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,8 +1,11 @@
-CHANGES.txt - 2010-05-10
+CHANGES.txt - 2010-06-16
------------------------
CHANGES IN CUPS V1.5b1
+ - Added several new color spaces to the CUPS raster format (STR #3419)
+ - The Validate-Job operation now uses the same policy as Print-Job by
+ default.
- CUPS now uses iconv to implement all of its character encoding
support (STR #3097)
- The scheduler now implements the Cancel-Jobs, Cancel-My-Jobs, and
diff --git a/backend/ipp.c b/backend/ipp.c
index 3ec92d227..0a41ab367 100644
--- a/backend/ipp.c
+++ b/backend/ipp.c
@@ -472,6 +472,8 @@ main(int argc, /* I - Number of command-line args */
if ((http = httpConnectEncrypt(hostname, port, cupsEncryption())) == NULL)
{
+ int error = errno; /* Connection error */
+
if (job_canceled)
break;
@@ -497,19 +499,40 @@ main(int argc, /* I - Number of command-line args */
return (CUPS_BACKEND_FAILED);
}
+ fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(errno));
+
if (errno == ECONNREFUSED || errno == EHOSTDOWN ||
errno == EHOSTUNREACH)
{
if (contimeout && (time(NULL) - start_time) > contimeout)
{
- _cupsLangPuts(stderr, _("ERROR: Printer not responding\n"));
+ _cupsLangPuts(stderr, _("ERROR: The printer is not responding.\n"));
return (CUPS_BACKEND_FAILED);
}
- _cupsLangPrintf(stderr,
- _("WARNING: Network host \'%s\' is busy; "
- "will retry in %d seconds...\n"),
- hostname, delay);
+ switch (error)
+ {
+ case EHOSTDOWN :
+ _cupsLangPrintf(stderr,
+ _("WARNING: Network printer \'%s\' may not exist "
+ "or is unavailable at this time.\n"),
+ hostname);
+ break;
+
+ case EHOSTUNREACH :
+ _cupsLangPrintf(stderr,
+ _("WARNING: Network printer \'%s\' is "
+ "unreachable at this time.\n"),
+ hostname);
+ break;
+
+ case ECONNREFUSED :
+ default :
+ _cupsLangPrintf(stderr,
+ _("WARNING: Network printer \'%s\' is busy.\n"),
+ hostname);
+ break;
+ }
sleep(delay);
@@ -518,16 +541,15 @@ main(int argc, /* I - Number of command-line args */
}
else if (h_errno)
{
- _cupsLangPrintf(stderr, _("ERROR: Unable to locate printer \'%s\'\n"),
+ _cupsLangPrintf(stderr,
+ _("ERROR: Unable to locate network printer \'%s\'.\n"),
hostname);
return (CUPS_BACKEND_STOP);
}
else
{
- fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(errno));
- _cupsLangPuts(stderr,
- _("ERROR: Unable to connect to printer; will retry in 30 "
- "seconds...\n"));
+ _cupsLangPrintf(stderr, _("ERROR: Network printer \'%s\' is not "
+ "responding.\n"), hostname);
sleep(30);
}
@@ -616,8 +638,11 @@ main(int argc, /* I - Number of command-line args */
if (http->version < HTTP_1_1)
{
+ fprintf(stderr, "DEBUG: Printer responded with HTTP version %d.%d.\n",
+ http->version / 100, http->version % 100);
+
_cupsLangPuts(stderr,
- _("ERROR: Unable to print - printer does not conform to "
+ _("ERROR: Unable to print: the printer does not conform to "
"the IPP standard.\n"));
exit(CUPS_BACKEND_STOP);
}
@@ -634,7 +659,7 @@ main(int argc, /* I - Number of command-line args */
{
if (contimeout && (time(NULL) - start_time) > contimeout)
{
- _cupsLangPuts(stderr, _("ERROR: Printer not responding\n"));
+ _cupsLangPuts(stderr, _("ERROR: The printer is not responding.\n"));
return (CUPS_BACKEND_FAILED);
}
@@ -675,7 +700,7 @@ main(int argc, /* I - Number of command-line args */
}
else if (ipp_status == IPP_NOT_FOUND)
{
- _cupsLangPuts(stderr, _("ERROR: Destination printer does not exist\n"));
+ _cupsLangPuts(stderr, _("ERROR: The printer URI is incorrect or no longer exists.\n"));
if (supported)
ippDelete(supported);
diff --git a/backend/lpd.c b/backend/lpd.c
index 2b03c1667..4210ff0c4 100644
--- a/backend/lpd.c
+++ b/backend/lpd.c
@@ -3,7 +3,7 @@
*
* Line Printer Daemon backend for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007-2009 by Apple Inc.
+ * Copyright 2007-2010 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -34,6 +34,7 @@
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <stdio.h>
#ifdef WIN32
# include <winsock.h>
@@ -441,7 +442,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0)
{
- _cupsLangPrintError(_("ERROR: Unable to create temporary file"));
+ perror("DEBUG: Unable to create temporary file");
return (CUPS_BACKEND_FAILED);
}
@@ -587,7 +588,7 @@ lpd_command(int fd, /* I - Socket connection to LPD host */
if (lpd_write(fd, buf, bytes) < bytes)
{
- _cupsLangPrintError(_("ERROR: Unable to send LPD command"));
+ perror("DEBUG: Unable to send LPD command");
return (-1);
}
@@ -754,7 +755,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
if ((fd = socket(addr->addr.addr.sa_family, SOCK_STREAM, 0)) < 0)
{
- _cupsLangPrintError(_("ERROR: Unable to create socket"));
+ perror("DEBUG: Unable to create socket");
sleep(1);
continue;
@@ -771,7 +772,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
if ((fd = rresvport_af(&lport, addr->addr.addr.sa_family)) < 0)
{
- _cupsLangPrintError(_("ERROR: Unable to reserve port"));
+ perror("DEBUG: Unable to reserve port");
sleep(1);
continue;
@@ -824,18 +825,40 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
return (CUPS_BACKEND_FAILED);
}
+ fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(error));
+
if (error == ECONNREFUSED || error == EHOSTDOWN ||
error == EHOSTUNREACH)
{
if (contimeout && (time(NULL) - start_time) > contimeout)
{
- _cupsLangPuts(stderr, _("ERROR: Printer not responding\n"));
+ _cupsLangPuts(stderr, _("ERROR: The printer is not responding.\n"));
return (CUPS_BACKEND_FAILED);
}
- _cupsLangPrintf(stderr,
- _("WARNING: Network host \'%s\' is busy; will retry in "
- "%d seconds...\n"), hostname, delay);
+ switch (error)
+ {
+ case EHOSTDOWN :
+ _cupsLangPrintf(stderr,
+ _("WARNING: Network printer \'%s\' may not exist "
+ "or is unavailable at this time.\n"),
+ hostname);
+ break;
+
+ case EHOSTUNREACH :
+ _cupsLangPrintf(stderr,
+ _("WARNING: Network printer \'%s\' is "
+ "unreachable at this time.\n"),
+ hostname);
+ break;
+
+ case ECONNREFUSED :
+ default :
+ _cupsLangPrintf(stderr,
+ _("WARNING: Network printer \'%s\' is busy.\n"),
+ hostname);
+ break;
+ }
sleep(delay);
@@ -852,10 +875,8 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
}
else
{
- fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(errno));
- _cupsLangPuts(stderr,
- _("ERROR: Unable to connect to printer; will retry in 30 "
- "seconds...\n"));
+ _cupsLangPrintf(stderr, _("ERROR: Network printer \'%s\' is not "
+ "responding.\n"), hostname);
sleep(30);
}
}
@@ -905,7 +926,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
httpAddrFreeList(addrlist);
close(fd);
- _cupsLangPrintError(_("ERROR: unable to stat print file"));
+ perror("DEBUG: unable to stat print file");
return (CUPS_BACKEND_FAILED);
}
@@ -998,7 +1019,8 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
if (lpd_write(fd, control, strlen(control) + 1) < (strlen(control) + 1))
{
status = errno;
- _cupsLangPrintError(_("ERROR: Unable to write control file"));
+ perror("DEBUG: Unable to write control file");
+
}
else
{
@@ -1068,7 +1090,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
if (lpd_write(fd, buffer, nbytes) < nbytes)
{
- _cupsLangPrintError(_("ERROR: Unable to send print file to printer"));
+ perror("DEBUG: Unable to send print file to printer");
break;
}
else
@@ -1082,7 +1104,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
status = errno;
else if (lpd_write(fd, "", 1) < 1)
{
- _cupsLangPrintError(_("ERROR: Unable to send trailing nul to printer"));
+ perror("DEBUG: Unable to send trailing nul to printer");
status = errno;
}
else
@@ -1145,7 +1167,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
if (lpd_write(fd, control, strlen(control) + 1) < (strlen(control) + 1))
{
status = errno;
- _cupsLangPrintError(_("ERROR: Unable to write control file"));
+ perror("DEBUG: Unable to write control file");
}
else
{
diff --git a/backend/pap.c b/backend/pap.c
index 3c8d8571d..b57698fd2 100644
--- a/backend/pap.c
+++ b/backend/pap.c
@@ -299,7 +299,7 @@ static int listDevices(void)
if (zip_getmyzone(ZIP_DEF_INTERFACE, &at_zone))
{
- _cupsLangPrintError(_("ERROR: Unable to get default AppleTalk zone"));
+ perror("DEBUG: Unable to get default AppleTalk zone.");
return -2;
}
@@ -319,7 +319,7 @@ static int listDevices(void)
if ((numberFound = nbp_lookup(&entity, buf, MAX_PRINTERS, &retry)) < 0)
{
- _cupsLangPrintError(_("ERROR: Unable to lookup AppleTalk printers"));
+ perror("DEBUG: Unable to lookup AppleTalk printers.");
return numberFound;
}
@@ -448,7 +448,7 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in
/* try to find our printer */
if ((err = nbp_make_entity(&entity, name, type, zone)) != noErr)
{
- _cupsLangPrintError(_("ERROR: Unable to make AppleTalk address"));
+ perror("DEBUG: Unable to make AppleTalk address.");
goto Exit;
}
@@ -568,7 +568,7 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in
/* Start the tickle packets and set a timeout alarm */
if ((err = papSendRequest(gSockfd, &gSessionAddr, gConnID, AT_PAP_TYPE_TICKLE, 0, false, false)) < 0)
{
- _cupsLangPrintError(_("ERROR: Unable to send PAP tickle request"));
+ perror("DEBUG: Unable to send PAP tickle request.");
goto Exit;
}
signal(SIGALRM, signalHandler);
@@ -577,7 +577,7 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in
/* Prime the pump with an initial send-data packet */
if ((err = papSendRequest(gSockfd, &gSessionAddr, gConnID, AT_PAP_TYPE_SEND_DATA, 0xFF, true, true)) < 0)
{
- _cupsLangPrintError(_("ERROR: Unable to send initial PAP send data request"));
+ perror("DEBUG: Unable to send initial PAP send data request.");
goto Exit;
}
@@ -626,7 +626,7 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in
/* Wait here for something interesting to happen */
if ((err = select(maxfdp1, &readSet, 0, 0, timeoutPtr)) < 0)
{
- _cupsLangPrintError(_("ERROR: select() failed"));
+ perror("DEBUG: select() failed.");
break;
}
@@ -634,7 +634,7 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in
{
/* Time to send a status request */
if ((err = papSendRequest(gSockfd, &tuple.enu_addr, 0, AT_PAP_TYPE_SEND_STATUS, 0x01, false, false)) < 0)
- _cupsLangPrintError(_("WARNING: Unable to send PAP status request"));
+ _cupsLangPrintError(_("WARNING: Unable to send PAP status request"));
if (gStatusInterval)
nextStatusTime = time(NULL) + gStatusInterval;
@@ -685,7 +685,7 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in
{
if ((rc = atp_look(gSockfd)) < 0)
{
- _cupsLangPrintError(_("ERROR: Unable to look for PAP response"));
+ perror("DEBUG: Unable to look for PAP response.");
break;
}
@@ -698,7 +698,7 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in
if ((err = atp_getresp(gSockfd, &tid, &resp)) < 0)
{
- _cupsLangPrintError(_("ERROR: Unable to get PAP response"));
+ perror("DEBUG: Unable to get PAP response.");
break;
}
userdata = resp.userdata[0];
@@ -709,7 +709,7 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in
reqlen = sizeof(atpReqBuf);
if ((err = atp_getreq(gSockfd, &src, atpReqBuf, &reqlen, &userdata, &xo, &tid, &bitmap, 0)) < 0)
{
- _cupsLangPrintError(_("ERROR: Unable to get PAP request"));
+ perror("DEBUG: Unable to get PAP response.");
break;
}
}
diff --git a/backend/runloop.c b/backend/runloop.c
index 3c914ecf4..13f9c23da 100644
--- a/backend/runloop.c
+++ b/backend/runloop.c
@@ -355,7 +355,7 @@ backendRunLoop(
if (paperout != 1 && update_state)
{
fputs("STATE: +media-empty-warning\n", stderr);
- _cupsLangPuts(stderr, _("ERROR: Out of paper\n"));
+ _cupsLangPuts(stderr, _("DEBUG: Out of paper\n"));
paperout = 1;
}
}
diff --git a/backend/serial.c b/backend/serial.c
index a77b76cba..4eb3700ff 100644
--- a/backend/serial.c
+++ b/backend/serial.c
@@ -3,7 +3,7 @@
*
* Serial port backend for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007-2009 by Apple Inc.
+ * Copyright 2007-2010 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -26,6 +26,7 @@
*/
#include "backend-private.h"
+#include <stdio.h>
#ifdef __hpux
# include <sys/modem.h>
@@ -614,7 +615,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
if (errno != EAGAIN || errno != EINTR)
{
- _cupsLangPrintError(_("ERROR: Unable to read print data"));
+ perror("DEBUG: Unable to read print data");
tcsetattr(device_fd, TCSADRAIN, &origopts);
@@ -690,7 +691,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
if (errno != EAGAIN && errno != EINTR && errno != ENOTTY)
{
- _cupsLangPrintError(_("ERROR: Unable to write print data"));
+ perror("DEBUG: Unable to write print data");
tcsetattr(device_fd, TCSADRAIN, &origopts);
diff --git a/backend/socket.c b/backend/socket.c
index 53f8dc0b5..84e5fe5f6 100644
--- a/backend/socket.c
+++ b/backend/socket.c
@@ -302,18 +302,40 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
return (CUPS_BACKEND_FAILED);
}
+ fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(error));
+
if (error == ECONNREFUSED || error == EHOSTDOWN ||
error == EHOSTUNREACH)
{
if (contimeout && (time(NULL) - start_time) > contimeout)
{
- _cupsLangPuts(stderr, _("ERROR: Printer not responding\n"));
+ _cupsLangPuts(stderr, _("ERROR: The printer is not responding.\n"));
return (CUPS_BACKEND_FAILED);
}
- _cupsLangPrintf(stderr,
- _("WARNING: Network host \'%s\' is busy; will retry in "
- "%d seconds...\n"), hostname, delay);
+ switch (error)
+ {
+ case EHOSTDOWN :
+ _cupsLangPrintf(stderr,
+ _("WARNING: Network printer \'%s\' may not exist "
+ "or is unavailable at this time.\n"),
+ hostname);
+ break;
+
+ case EHOSTUNREACH :
+ _cupsLangPrintf(stderr,
+ _("WARNING: Network printer \'%s\' is "
+ "unreachable at this time.\n"),
+ hostname);
+ break;
+
+ case ECONNREFUSED :
+ default :
+ _cupsLangPrintf(stderr,
+ _("WARNING: Network printer \'%s\' is busy.\n"),
+ hostname);
+ break;
+ }
sleep(delay);
@@ -322,11 +344,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
}
else
{
- _cupsLangPrintf(stderr, "DEBUG: Connection error: %s\n",
- strerror(errno));
- _cupsLangPuts(stderr,
- _("ERROR: Unable to connect to printer; will retry in 30 "
- "seconds...\n"));
+ _cupsLangPrintf(stderr, _("ERROR: Network printer \'%s\' is not "
+ "responding.\n"), hostname);
sleep(30);
}
}
diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c
index 43fd770da..f94059984 100644
--- a/backend/usb-darwin.c
+++ b/backend/usb-darwin.c
@@ -112,12 +112,6 @@ extern char **environ;
#define DEBUG_WRITES 0
-/*
- * WAIT_EOF_DELAY is number of seconds we'll wait for responses from
- * the printer after we've finished sending all the data
- */
-#define WAIT_EOF_DELAY 7
-#define WAIT_SIDE_DELAY 3
#define DEFAULT_TIMEOUT 5000L
#define USB_INTERFACE_KIND CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID190)
@@ -247,11 +241,6 @@ typedef struct globals_s
Boolean wait_eof;
int drain_output; /* Drain all pending output */
int bidi_flag; /* 0=unidirectional, 1=bidirectional */
-
- pthread_mutex_t sidechannel_thread_mutex;
- pthread_cond_t sidechannel_thread_cond;
- int sidechannel_thread_stop;
- int sidechannel_thread_done;
} globals_t;
@@ -344,7 +333,6 @@ print_device(const char *uri, /* I - Device URI */
UInt32 bytes; /* Bytes written */
struct timeval *timeout, /* Timeout pointer */
stimeout; /* Timeout for select() */
- struct timespec cond_timeout; /* pthread condition timeout */
/*
@@ -373,7 +361,8 @@ print_device(const char *uri, /* I - Device URI */
if (!g.make || !g.model)
{
- _cupsLangPuts(stderr, _("ERROR: Fatal USB error\n"));
+ fprintf(stderr, "DEBUG: Fatal USB error.\n");
+ _cupsLangPuts(stderr, _("ERROR: There was an unrecoverable USB error.\n"));
if (!g.make)
fputs("DEBUG: USB make string is NULL\n", stderr);
@@ -431,7 +420,7 @@ print_device(const char *uri, /* I - Device URI */
strlcpy(print_buffer, "USB class driver", sizeof(print_buffer));
fputs("STATE: +apple-missing-usbclassdriver-error\n", stderr);
- _cupsLangPuts(stderr, _("ERROR: Fatal USB error\n"));
+ _cupsLangPuts(stderr, _("ERROR: There was an unrecoverable USB error.\n"));
fprintf(stderr, "DEBUG: Could not load %s\n", print_buffer);
if (driverBundlePath)
@@ -488,15 +477,10 @@ print_device(const char *uri, /* I - Device URI */
if (have_sidechannel)
{
- g.sidechannel_thread_stop = 0;
- g.sidechannel_thread_done = 0;
-
- pthread_cond_init(&g.sidechannel_thread_cond, NULL);
- pthread_mutex_init(&g.sidechannel_thread_mutex, NULL);
-
if (pthread_create(&sidechannel_thread_id, NULL, sidechannel_thread, NULL))
{
- _cupsLangPuts(stderr, _("ERROR: Fatal USB error\n"));
+ fprintf(stderr, "DEBUG: Fatal USB error.\n");
+ _cupsLangPuts(stderr, _("ERROR: There was an unrecoverable USB error.\n"));
fputs("DEBUG: Couldn't create side-channel thread\n", stderr);
registry_close();
return (CUPS_BACKEND_STOP);
@@ -515,7 +499,8 @@ print_device(const char *uri, /* I - Device URI */
if (pthread_create(&read_thread_id, NULL, read_thread, NULL))
{
- _cupsLangPuts(stderr, _("ERROR: Fatal USB error\n"));
+ fprintf(stderr, "DEBUG: Fatal USB error.\n");
+ _cupsLangPuts(stderr, _("ERROR: There was an unrecoverable USB error.\n"));
fputs("DEBUG: Couldn't create read thread\n", stderr);
registry_close();
return (CUPS_BACKEND_STOP);
@@ -601,7 +586,7 @@ print_device(const char *uri, /* I - Device URI */
}
else if (errno != EAGAIN && errno != EINTR)
{
- _cupsLangPuts(stderr, _("ERROR: Unable to read print data\n"));
+ _cupsLangPuts(stderr, _("ERROR: Unable to read print data.\n"));
perror("DEBUG: select");
registry_close();
return (CUPS_BACKEND_FAILED);
@@ -644,7 +629,7 @@ print_device(const char *uri, /* I - Device URI */
if (errno != EAGAIN && errno != EINTR)
{
- _cupsLangPuts(stderr, _("ERROR: Unable to read print data\n"));
+ _cupsLangPuts(stderr, _("ERROR: Unable to read print data.\n"));
perror("DEBUG: read");
registry_close();
return (CUPS_BACKEND_FAILED);
@@ -720,8 +705,7 @@ print_device(const char *uri, /* I - Device URI */
/*
* Write error - bail if we don't see an error we can retry...
*/
-
- _cupsLangPuts(stderr, _("ERROR: Unable to send print data\n"));
+ _cupsLangPuts(stderr, _("ERROR: Unable to send print data to printer.\n"));
fprintf(stderr, "DEBUG: USB class driver WritePipe returned %x\n",
iostatus);
@@ -751,86 +735,6 @@ print_device(const char *uri, /* I - Device URI */
fprintf(stderr, "DEBUG: Sent %lld bytes...\n", (off_t)total_bytes);
/*
- * Wait for the side channel thread to exit...
- */
-
- if (have_sidechannel)
- {
- close(CUPS_SC_FD);
- pthread_mutex_lock(&g.readwrite_lock_mutex);
- g.readwrite_lock = 0;
- pthread_cond_signal(&g.readwrite_lock_cond);
- pthread_mutex_unlock(&g.readwrite_lock_mutex);
-
- g.sidechannel_thread_stop = 1;
- pthread_mutex_lock(&g.sidechannel_thread_mutex);
- if (!g.sidechannel_thread_done)
- {
- /*
- * Wait for the side-channel thread to exit...
- */
-
- cond_timeout.tv_sec = time(NULL) + WAIT_SIDE_DELAY;
- cond_timeout.tv_nsec = 0;
- if (pthread_cond_timedwait(&g.sidechannel_thread_cond,
- &g.sidechannel_thread_mutex,
- &cond_timeout) != 0)
- {
- /*
- * Force the side-channel thread to exit...
- */
-
- pthread_kill(sidechannel_thread_id, SIGTERM);
- }
- }
- pthread_mutex_unlock(&g.sidechannel_thread_mutex);
-
- pthread_join(sidechannel_thread_id, NULL);
-
- pthread_cond_destroy(&g.sidechannel_thread_cond);
- pthread_mutex_destroy(&g.sidechannel_thread_mutex);
- }
-
- pthread_cond_destroy(&g.readwrite_lock_cond);
- pthread_mutex_destroy(&g.readwrite_lock_mutex);
-
- /*
- * Signal the read thread to stop...
- */
-
- g.read_thread_stop = 1;
-
- /*
- * Give the read thread WAIT_EOF_DELAY seconds to complete all the data. If
- * we are not signaled in that time then force the thread to exit.
- */
-
- pthread_mutex_lock(&g.read_thread_mutex);
-
- if (!g.read_thread_done)
- {
- cond_timeout.tv_sec = time(NULL) + WAIT_EOF_DELAY;
- cond_timeout.tv_nsec = 0;
-
- if (pthread_cond_timedwait(&g.read_thread_cond, &g.read_thread_mutex,
- &cond_timeout) != 0)
- {
- /*
- * Force the read thread to exit...
- */
-
- g.wait_eof = 0;
- pthread_kill(read_thread_id, SIGTERM);
- }
- }
- pthread_mutex_unlock(&g.read_thread_mutex);
-
- pthread_join(read_thread_id, NULL); /* wait for the read thread to return */
-
- pthread_cond_destroy(&g.read_thread_cond);
- pthread_mutex_destroy(&g.read_thread_mutex);
-
- /*
* Close the connection and input file and general clean up...
*/
@@ -1038,12 +942,7 @@ sidechannel_thread(void *reference)
break;
}
}
- while (!g.sidechannel_thread_stop);
-
- pthread_mutex_lock(&g.sidechannel_thread_mutex);
- g.sidechannel_thread_done = 1;
- pthread_cond_signal(&g.sidechannel_thread_cond);
- pthread_mutex_unlock(&g.sidechannel_thread_mutex);
+ while (1);
return NULL;
}
diff --git a/backend/usb.c b/backend/usb.c
index b33f731b9..74cd6e580 100644
--- a/backend/usb.c
+++ b/backend/usb.c
@@ -197,8 +197,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
resource, sizeof(resource)) < HTTP_URI_OK)
{
_cupsLangPuts(stderr,
- _("ERROR: No device URI found in argv[0] or in DEVICE_URI "
- "environment variable\n"));
+ _("ERROR: No device URI found in argv[0] or in DEVICE_URI "
+ "environment variable\n"));
return (1);
}
diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c
index d8527cdb8..b890c8b99 100644
--- a/cgi-bin/admin.c
+++ b/cgi-bin/admin.c
@@ -951,8 +951,6 @@ do_am_printer(http_t *http, /* I - HTTP connection */
if (!cgiGetVariable("CURRENT_MAKE"))
cgiSetVariable("CURRENT_MAKE", make);
- cgiSetVariable("PPD_MAKE", make);
-
if (!cgiGetVariable("CURRENT_MAKE_AND_MODEL"))
cgiSetVariable("CURRENT_MAKE_AND_MODEL", uriptr);
@@ -1218,8 +1216,8 @@ do_am_printer(http_t *http, /* I - HTTP connection */
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, "ipp://localhost/printers/");
- if ((var = cgiGetVariable("CURRENT_MAKE")) == NULL)
- var = cgiGetVariable("PPD_MAKE");
+ if ((var = cgiGetVariable("PPD_MAKE")) == NULL)
+ var = cgiGetVariable("CURRENT_MAKE");
if (var && !cgiGetVariable("SELECT_MAKE"))
{
const char *make_model; /* Make and model */
diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c
index 4c1eb3b95..fe9bc52db 100644
--- a/cgi-bin/ipp-var.c
+++ b/cgi-bin/ipp-var.c
@@ -285,10 +285,14 @@ cgiMoveJobs(http_t *http, /* I - Connection to server */
/*
- * See who is logged in...
+ * Make sure we have a username...
*/
- user = getenv("REMOTE_USER");
+ if ((user = getenv("REMOTE_USER")) == NULL)
+ {
+ puts("Status: 401\n");
+ exit(0);
+ }
/*
* See if the user has already selected a new destination...
diff --git a/cgi-bin/var.c b/cgi-bin/var.c
index 0ec9800cb..9a37b35e7 100644
--- a/cgi-bin/var.c
+++ b/cgi-bin/var.c
@@ -1111,6 +1111,9 @@ cgi_initialize_string(const char *data) /* I - Form data string */
* Read the hex code...
*/
+ if (!isxdigit(data[1] & 255) || !isxdigit(data[2] & 255))
+ return (0);
+
if (s < (value + sizeof(value) - 1))
{
data ++;
@@ -1232,7 +1235,7 @@ cgi_set_sid(void)
_cupsMD5Append(&md5, (unsigned char *)buffer, (int)strlen(buffer));
_cupsMD5Finish(&md5, sum);
- cgiSetCookie(CUPS_SID, httpMD5String(sum, sid), "/", server_name, 0, 0);
+ cgiSetCookie(CUPS_SID, httpMD5String(sum, sid), "/", NULL, 0, 0);
return (cupsGetOption(CUPS_SID, num_cookies, cookies));
}
diff --git a/conf/cupsd.conf.in b/conf/cupsd.conf.in
index e51c430c1..a7143b7dc 100644
--- a/conf/cupsd.conf.in
+++ b/conf/cupsd.conf.in
@@ -46,6 +46,10 @@ DefaultAuthType Basic
# Set the default printer/job policies...
<Policy default>
# Job-related operations must be done by the owner or an administrator...
+ <Limit Create-Job Print-Job Print-URI Validate-Job>
+ Order deny,allow
+ </Limit>
+
<Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
Require user @OWNER @SYSTEM
Order deny,allow
@@ -79,7 +83,7 @@ DefaultAuthType Basic
# Set the authenticated printer/job policies...
<Policy authenticated>
# Job-related operations must be done by the owner or an administrator...
- <Limit Create-Job Print-Job Print-URI>
+ <Limit Create-Job Print-Job Print-URI Validate-Job>
AuthType Default
Order deny,allow
</Limit>
diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4
index c73aa3b48..db0c6c0c9 100644
--- a/config-scripts/cups-common.m4
+++ b/config-scripts/cups-common.m4
@@ -183,6 +183,14 @@ AC_TRY_COMPILE([#include <time.h>],[struct tm t;
AC_DEFINE(HAVE_TM_GMTOFF),
AC_MSG_RESULT(no))
+dnl See if the stat structure has the st_gen member...
+AC_MSG_CHECKING(for st_gen member in stat structure)
+AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat t;
+ int o = t.st_gen;],
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_ST_GEN),
+ AC_MSG_RESULT(no))
+
dnl See if we have the removefile(3) function for securely removing files
AC_CHECK_FUNCS(removefile)
diff --git a/config-scripts/cups-sharedlibs.m4 b/config-scripts/cups-sharedlibs.m4
index 4363bfce2..2e255b763 100644
--- a/config-scripts/cups-sharedlibs.m4
+++ b/config-scripts/cups-sharedlibs.m4
@@ -165,16 +165,31 @@ AC_SUBST(LIBCUPSSTATIC)
if test x$enable_shared = xno; then
LINKCUPS="../cups/lib$cupsbase.a"
LINKCUPSIMAGE="../filter/libcupsimage.a"
+
+ EXTLINKCUPS="-lcups"
+ EXTLINKCUPSDRIVER="-lcupsdriver"
+ EXTLINKCUPSIMAGE="-lcupsimage"
else
if test $uname = AIX; then
LINKCUPS="-l${cupsbase}_s"
LINKCUPSIMAGE="-lcupsimage_s"
+
+ EXTLINKCUPS="-lcups_s"
+ EXTLINKCUPSDRIVER="-lcupsdriver_s"
+ EXTLINKCUPSIMAGE="-lcupsimage_s"
else
LINKCUPS="-l${cupsbase}"
LINKCUPSIMAGE="-lcupsimage"
+
+ EXTLINKCUPS="-lcups"
+ EXTLINKCUPSDRIVER="-lcupsdriver"
+ EXTLINKCUPSIMAGE="-lcupsimage"
fi
fi
+AC_SUBST(EXTLINKCUPS)
+AC_SUBST(EXTLINKCUPSDRIVER)
+AC_SUBST(EXTLINKCUPSIMAGE)
AC_SUBST(LINKCUPS)
AC_SUBST(LINKCUPSIMAGE)
diff --git a/config-scripts/cups-ssl.m4 b/config-scripts/cups-ssl.m4
index f8c869755..c605121c0 100644
--- a/config-scripts/cups-ssl.m4
+++ b/config-scripts/cups-ssl.m4
@@ -38,6 +38,8 @@ if test x$enable_ssl != xno; then
AC_DEFINE(HAVE_CDSASSL)
dnl Check for the various security headers...
+ AC_CHECK_HEADER(Security/SecItemPriv.h,
+ AC_DEFINE(HAVE_SECITEMPRIV_H))
AC_CHECK_HEADER(Security/SecPolicy.h,
AC_DEFINE(HAVE_SECPOLICY_H))
AC_CHECK_HEADER(Security/SecPolicyPriv.h,
@@ -54,6 +56,15 @@ if test x$enable_ssl != xno; then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
+ fi
+
+ dnl Check for SecPolicyCreateSSL...
+ AC_MSG_CHECKING(for SecPolicyCreateSSL)
+ if test $uversion -ge 100; then
+ AC_DEFINE(HAVE_SECPOLICYCREATESSL)
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
fi])
fi
fi
@@ -63,24 +74,32 @@ if test x$enable_ssl != xno; then
AC_PATH_PROG(LIBGNUTLSCONFIG,libgnutls-config)
AC_PATH_PROG(LIBGCRYPTCONFIG,libgcrypt-config)
if $PKGCONFIG --exists gnutls; then
- have_ssl=1
- SSLLIBS=`$PKGCONFIG --libs gnutls`
- SSLFLAGS=`$PKGCONFIG --cflags gnutls`
- AC_DEFINE(HAVE_SSL)
- AC_DEFINE(HAVE_GNUTLS)
- elif "x$LIBGNUTLSCONFIG" != x; then
- have_ssl=1
- SSLLIBS=`$LIBGNUTLSCONFIG --libs`
- SSLFLAGS=`$LIBGNUTLSCONFIG --cflags`
- AC_DEFINE(HAVE_SSL)
- AC_DEFINE(HAVE_GNUTLS)
+ if test "x$have_pthread" = xyes; then
+ AC_MSG_WARN([The current version of GNU TLS cannot be made thread-safe.])
+ else
+ have_ssl=1
+ SSLLIBS=`$PKGCONFIG --libs gnutls`
+ SSLFLAGS=`$PKGCONFIG --cflags gnutls`
+ AC_DEFINE(HAVE_SSL)
+ AC_DEFINE(HAVE_GNUTLS)
+ fi
+ elif test "x$LIBGNUTLSCONFIG" != x; then
+ if test "x$have_pthread" = xyes; then
+ AC_MSG_WARN([The current version of GNU TLS cannot be made thread-safe.])
+ else
+ have_ssl=1
+ SSLLIBS=`$LIBGNUTLSCONFIG --libs`
+ SSLFLAGS=`$LIBGNUTLSCONFIG --cflags`
+ AC_DEFINE(HAVE_SSL)
+ AC_DEFINE(HAVE_GNUTLS)
+ fi
fi
if test $have_ssl = 1; then
if $PKGCONFIG --exists gcrypt; then
SSLLIBS="$SSLLIBS `$PKGCONFIG --libs gcrypt`"
SSLFLAGS="$SSLFLAGS `$PKGCONFIG --cflags gcrypt`"
- elif "x$LIBGCRYPTCONFIG" != x; then
+ elif test "x$LIBGCRYPTCONFIG" != x; then
SSLLIBS="$SSLLIBS `$LIBGCRYPTCONFIG --libs`"
SSLFLAGS="$SSLFLAGS `$LIBGCRYPTCONFIG --cflags`"
fi
diff --git a/config.h.in b/config.h.in
index 5c986e3cf..af0813dc6 100644
--- a/config.h.in
+++ b/config.h.in
@@ -289,6 +289,7 @@
*/
#undef HAVE_AUTHORIZATION_H
+#undef HAVE_SECITEMPRIV_H
#undef HAVE_SECPOLICY_H
#undef HAVE_SECPOLICYPRIV_H
#undef HAVE_SECBASEPRIV_H
@@ -303,6 +304,13 @@
/*
+ * Do we have the SecPolicyCreateSSL function?
+ */
+
+#undef HAVE_SECPOLICYCREATESSL
+
+
+/*
* Do we have the SLP library?
*/
@@ -343,6 +351,13 @@
/*
+ * Does the "stat" structure contain the "st_gen" member?
+ */
+
+#undef HAVE_ST_GEN
+
+
+/*
* Does the "tm" structure contain the "tm_gmtoff" member?
*/
diff --git a/configure.in b/configure.in
index 34198e412..11b3e49cc 100644
--- a/configure.in
+++ b/configure.in
@@ -31,9 +31,9 @@ sinclude(config-scripts/cups-poll.m4)
sinclude(config-scripts/cups-slp.m4)
sinclude(config-scripts/cups-gssapi.m4)
sinclude(config-scripts/cups-ldap.m4)
+sinclude(config-scripts/cups-threads.m4)
sinclude(config-scripts/cups-ssl.m4)
sinclude(config-scripts/cups-pam.m4)
-sinclude(config-scripts/cups-threads.m4)
sinclude(config-scripts/cups-largefile.m4)
sinclude(config-scripts/cups-dnssd.m4)
sinclude(config-scripts/cups-launchd.m4)
@@ -80,7 +80,6 @@ AC_OUTPUT(Makedefs
man/cupsaddsmb.man
man/cupsd.conf.man
man/cupsd.man
- man/drv.man
man/lpoptions.man
scheduler/cups-lpd.xinetd
scheduler/cups.sh
diff --git a/cups-config.in b/cups-config.in
index 8a3db3375..f59abe0bb 100755
--- a/cups-config.in
+++ b/cups-config.in
@@ -4,7 +4,7 @@
#
# CUPS configuration utility.
#
-# Copyright 2007-2008 by Apple Inc.
+# Copyright 2007-2010 by Apple Inc.
# Copyright 2001-2006 by Easy Software Products, all rights reserved.
#
# These coded instructions, statements, and computer programs are the
@@ -15,7 +15,7 @@
#
VERSION="@CUPS_VERSION@"
-APIVERSION="1.4"
+APIVERSION="1.5"
BUILD="@CUPS_BUILD@"
prefix=@prefix@
@@ -113,12 +113,12 @@ while test $# -gt 0; do
;;
--libs)
if test $static = no; then
- libs="-lcups $LIBS";
+ libs="@EXTLINKCUPS@ $LIBS";
if test $image = yes; then
- libs="-lcupsimage $libs"
+ libs="@EXTLINKCUPSIMAGE@ $libs"
fi
if test $driver = yes; then
- libs="-lcupsdriver $libs"
+ libs="@EXTLINKCUPSDRIVER@ $libs"
fi
else
libs="$libdir/libcups.a $LIBS";
diff --git a/cups/dest.c b/cups/dest.c
index 191ec7b84..98cba04d3 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -1211,7 +1211,8 @@ appleSetDefault(const char *name) /* I - Default printer/class name */
CFArrayRemoveValueAtIndex(newlocations, locindex);
}
else
- newlocations = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
+ newlocations = CFArrayCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeArrayCallBacks);
newlocation = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
diff --git a/cups/file.c b/cups/file.c
index 0259716db..68fb11892 100644
--- a/cups/file.c
+++ b/cups/file.c
@@ -59,6 +59,8 @@
*/
#include "file-private.h"
+#include <sys/stat.h>
+#include <sys/types.h>
/*
@@ -69,6 +71,7 @@
static ssize_t cups_compress(cups_file_t *fp, const char *buf, size_t bytes);
#endif /* HAVE_LIBZ */
static ssize_t cups_fill(cups_file_t *fp);
+static int cups_open(const char *filename, int mode);
static ssize_t cups_read(cups_file_t *fp, char *buf, size_t bytes);
static ssize_t cups_write(cups_file_t *fp, const char *buf, size_t bytes);
@@ -827,7 +830,8 @@ cupsFileOpen(const char *filename, /* I - Name of file */
switch (*mode)
{
case 'a' : /* Append file */
- fd = open(filename, O_RDWR | O_CREAT | O_APPEND | O_LARGEFILE | O_BINARY, 0666);
+ fd = cups_open(filename,
+ O_RDWR | O_CREAT | O_APPEND | O_LARGEFILE | O_BINARY);
break;
case 'r' : /* Read file */
@@ -835,7 +839,21 @@ cupsFileOpen(const char *filename, /* I - Name of file */
break;
case 'w' : /* Write file */
- fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT | O_LARGEFILE | O_BINARY, 0666);
+ fd = cups_open(filename, O_WRONLY | O_LARGEFILE | O_BINARY);
+ if (fd < 0 && errno == ENOENT)
+ {
+ fd = cups_open(filename,
+ O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE | O_BINARY);
+ if (fd < 0 && errno == EEXIST)
+ fd = cups_open(filename, O_WRONLY | O_LARGEFILE | O_BINARY);
+ }
+
+ if (fd >= 0)
+#ifdef WIN32
+ _chsize(fd, 0);
+#else
+ ftruncate(fd, 0);
+#endif /* WIN32 */
break;
case 's' : /* Read/write socket */
@@ -2209,6 +2227,94 @@ cups_fill(cups_file_t *fp) /* I - CUPS file */
/*
+ * 'cups_open()' - Safely open a file for writing.
+ *
+ * We don't allow appending to directories or files that are hard-linked or
+ * symlinked.
+ */
+
+static int /* O - File descriptor or -1 otherwise */
+cups_open(const char *filename, /* I - Filename */
+ int mode) /* I - Open mode */
+{
+ int fd; /* File descriptor */
+ struct stat fileinfo; /* File information */
+#ifndef WIN32
+ struct stat linkinfo; /* Link information */
+#endif /* !WIN32 */
+
+
+ /*
+ * Open the file...
+ */
+
+ if ((fd = open(filename, mode, 0666)) < 0)
+ return (-1);
+
+ /*
+ * Then verify that the file descriptor doesn't point to a directory or hard-
+ * linked file.
+ */
+
+ if (fstat(fd, &fileinfo))
+ {
+ close(fd);
+ return (-1);
+ }
+
+ if (fileinfo.st_nlink != 1)
+ {
+ close(fd);
+ errno = EPERM;
+ return (-1);
+ }
+
+#ifdef WIN32
+ if (fileinfo.st_mode & _S_IFDIR)
+#else
+ if (S_ISDIR(fileinfo.st_mode))
+#endif /* WIN32 */
+ {
+ close(fd);
+ errno = EISDIR;
+ return (-1);
+ }
+
+#ifndef WIN32
+ /*
+ * Then use lstat to determine whether the filename is a symlink...
+ */
+
+ if (lstat(filename, &linkinfo))
+ {
+ close(fd);
+ return (-1);
+ }
+
+ if (S_ISLNK(linkinfo.st_mode) ||
+ fileinfo.st_dev != linkinfo.st_dev ||
+ fileinfo.st_ino != linkinfo.st_ino ||
+#ifdef HAVE_ST_GEN
+ fileinfo.st_gen != linkinfo.st_gen ||
+#endif /* HAVE_ST_GEN */
+ fileinfo.st_nlink != linkinfo.st_nlink ||
+ fileinfo.st_mode != linkinfo.st_mode)
+ {
+ /*
+ * Yes, don't allow!
+ */
+
+ close(fd);
+ errno = EPERM;
+ return (-1);
+ }
+#endif /* !WIN32 */
+
+ return (fd);
+}
+
+
+/*
* 'cups_read()' - Read from a file descriptor.
*/
diff --git a/cups/globals.c b/cups/globals.c
index 04afcab2c..3d678d427 100644
--- a/cups/globals.c
+++ b/cups/globals.c
@@ -320,7 +320,9 @@ cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */
cupsFileClose(cg->stdio_files[1]);
cupsFileClose(cg->stdio_files[2]);
+# ifndef CUPS_LITE
cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings);
+# endif /* !CUPS_LITE */
free(cg);
}
diff --git a/cups/http-support.c b/cups/http-support.c
index f1e4893d3..5c1dce5d8 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -1353,6 +1353,9 @@ _httpResolveURI(
if (strstr(hostname, "._tcp"))
{
#ifdef HAVE_DNSSD
+# ifdef WIN32
+# pragma comment(lib, "dnssd.lib")
+# endif /* WIN32 */
DNSServiceRef ref, /* DNS-SD master service reference */
domainref, /* DNS-SD service reference for domain */
localref; /* DNS-SD service reference for .local */
diff --git a/cups/http.c b/cups/http.c
index a83fc20cc..6df51abc6 100644
--- a/cups/http.c
+++ b/cups/http.c
@@ -1240,7 +1240,7 @@ httpInitialize(void)
}
#ifdef WIN32
- WSAStartup(MAKEWORD(1,1), &winsockdata);
+ WSAStartup(MAKEWORD(2,2), &winsockdata);
#elif !defined(SO_NOSIGPIPE)
/*
diff --git a/cups/http.h b/cups/http.h
index 08067c456..85a2c8b43 100644
--- a/cups/http.h
+++ b/cups/http.h
@@ -250,7 +250,7 @@ typedef enum http_status_e /**** HTTP status codes ****/
HTTP_GATEWAY_TIMEOUT, /* Gateway connection timed out */
HTTP_NOT_SUPPORTED, /* HTTP version not supported */
- HTTP_AUTHORIZATION_CANCELED = 1000 /* User cancelled authorization */
+ HTTP_AUTHORIZATION_CANCELED = 1000 /* User canceled authorization */
} http_status_t;
diff --git a/cups/ipp.h b/cups/ipp.h
index 12126e260..4f3dd5eec 100644
--- a/cups/ipp.h
+++ b/cups/ipp.h
@@ -414,8 +414,8 @@ struct ipp_s /**** IPP Request/Response/Notification ****/
/**** New in CUPS 1.2 ****/
ipp_attribute_t *prev; /* Previous attribute (for read) @since CUPS 1.2/Mac OS X 10.5@ */
-/**** New in CUPS 1.5 ****/
- int use; /* Use count */
+/**** New in CUPS 1.4.4 ****/
+ int use; /* Use count @since CUPS 1.4.4/Mac OS X 10.6.?@ */
};
diff --git a/cups/language.c b/cups/language.c
index 8ce4bc7d1..38f8e5ae0 100644
--- a/cups/language.c
+++ b/cups/language.c
@@ -262,9 +262,17 @@ _cupsEncodingName(
{
if (encoding < 0 ||
encoding >= (sizeof(lang_encodings) / sizeof(const char *)))
+ {
+ DEBUG_printf(("1_cupsEncodingName(encoding=%d) = out of range (\"%s\")",
+ encoding, lang_encodings[0]));
return (lang_encodings[0]);
+ }
else
+ {
+ DEBUG_printf(("1_cupsEncodingName(encoding=%d) = \"%s\"",
+ encoding, lang_encodings[encoding]));
return (lang_encodings[encoding]);
+ }
}
diff --git a/cups/mark.c b/cups/mark.c
index e75544b72..648e8f28b 100644
--- a/cups/mark.c
+++ b/cups/mark.c
@@ -72,7 +72,7 @@ cupsMarkOptions(
int num_options, /* I - Number of options */
cups_option_t *options) /* I - Options */
{
- int i, j, k; /* Looping vars */
+ int i, j; /* Looping vars */
char *ptr, /* Pointer into string */
s[255]; /* Temporary string */
const char *val, /* Pointer into value */
@@ -80,33 +80,7 @@ cupsMarkOptions(
*page_size, /* PageSize option */
*ppd_keyword; /* PPD keyword */
cups_option_t *optptr; /* Current option */
- ppd_option_t *option; /* PPD option */
ppd_attr_t *attr; /* PPD attribute */
- static const char * const duplex_options[] =
- { /* Duplex option names */
- "Duplex", /* Adobe */
- "EFDuplex", /* EFI */
- "EFDuplexing", /* EFI */
- "KD03Duplex", /* Kodak */
- "JCLDuplex" /* Samsung */
- };
- static const char * const duplex_one[] =
- { /* one-sided names */
- "None",
- "False"
- };
- static const char * const duplex_two_long[] =
- { /* two-sided-long-edge names */
- "DuplexNoTumble", /* Adobe */
- "LongEdge", /* EFI */
- "Top" /* EFI */
- };
- static const char * const duplex_two_short[] =
- { /* two-sided-long-edge names */
- "DuplexTumble", /* Adobe */
- "ShortEdge", /* EFI */
- "Bottom" /* EFI */
- };
/*
@@ -185,98 +159,11 @@ cupsMarkOptions(
*/
for (i = num_options, optptr = options; i > 0; i --, optptr ++)
- if (!strcasecmp(optptr->name, "media"))
+ if (!strcasecmp(optptr->name, "media") ||
+ !strcasecmp(optptr->name, "output-bin") ||
+ !strcasecmp(optptr->name, "output-mode") ||
+ !strcasecmp(optptr->name, "sides"))
continue;
- else if (!strcasecmp(optptr->name, "sides"))
- {
- for (j = 0;
- j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0]));
- j ++)
- if (cupsGetOption(duplex_options[j], num_options, options))
- break;
-
- if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
- {
- /*
- * Don't override the PPD option with the IPP attribute...
- */
-
- continue;
- }
-
- if (!strcasecmp(optptr->value, "one-sided"))
- {
- /*
- * Mark the appropriate duplex option for one-sided output...
- */
-
- for (j = 0;
- j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0]));
- j ++)
- if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
- break;
-
- if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
- {
- for (k = 0;
- k < (int)(sizeof(duplex_one) / sizeof(duplex_one[0]));
- k ++)
- if (ppdFindChoice(option, duplex_one[k]))
- {
- ppd_mark_option(ppd, duplex_options[j], duplex_one[k]);
- break;
- }
- }
- }
- else if (!strcasecmp(optptr->value, "two-sided-long-edge"))
- {
- /*
- * Mark the appropriate duplex option for two-sided-long-edge output...
- */
-
- for (j = 0;
- j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0]));
- j ++)
- if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
- break;
-
- if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
- {
- for (k = 0;
- k < (int)(sizeof(duplex_two_long) / sizeof(duplex_two_long[0]));
- k ++)
- if (ppdFindChoice(option, duplex_two_long[k]))
- {
- ppd_mark_option(ppd, duplex_options[j], duplex_two_long[k]);
- break;
- }
- }
- }
- else if (!strcasecmp(optptr->value, "two-sided-short-edge"))
- {
- /*
- * Mark the appropriate duplex option for two-sided-short-edge output...
- */
-
- for (j = 0;
- j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0]));
- j ++)
- if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
- break;
-
- if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
- {
- for (k = 0;
- k < (int)(sizeof(duplex_two_short) / sizeof(duplex_two_short[0]));
- k ++)
- if (ppdFindChoice(option, duplex_two_short[k]))
- {
- ppd_mark_option(ppd, duplex_options[j], duplex_two_short[k]);
- break;
- }
- }
- }
- }
else if (!strcasecmp(optptr->name, "resolution") ||
!strcasecmp(optptr->name, "printer-resolution"))
{
@@ -288,13 +175,6 @@ cupsMarkOptions(
ppd_mark_option(ppd, "CNRes_PGP", optptr->value);
/* Canon */
}
- else if (!strcasecmp(optptr->name, "output-bin"))
- {
- if (!cupsGetOption("OutputBin", num_options, options) &&
- (ppd_keyword = _pwgGetOutputBin((_pwg_t *)ppd->pwg,
- optptr->value)) != NULL)
- ppd_mark_option(ppd, "OutputBin", ppd_keyword);
- }
else if (!strcasecmp(optptr->name, "multiple-document-handling"))
{
if (!cupsGetOption("Collate", num_options, options) &&
@@ -668,6 +548,7 @@ ppdNextOption(ppd_file_t *ppd) /* I - PPD file */
* This function looks for strings of the form:
*
* *option choice ... *optionN choiceN
+ * property value ... propertyN valueN
*
* It stops when it finds a string that doesn't match this format.
*/
@@ -676,10 +557,11 @@ int /* O - Number of options */
_ppdParseOptions(
const char *s, /* I - String to parse */
int num_options, /* I - Number of options */
- cups_option_t **options) /* IO - Options */
+ cups_option_t **options, /* IO - Options */
+ _ppd_parse_t which) /* I - What to parse */
{
- char option[PPD_MAX_NAME], /* Current option */
- choice[PPD_MAX_NAME], /* Current choice */
+ char option[PPD_MAX_NAME + 1], /* Current option/property */
+ choice[PPD_MAX_NAME], /* Current choice/value */
*ptr; /* Pointer into option or choice */
@@ -687,8 +569,8 @@ _ppdParseOptions(
return (num_options);
/*
- * Read all of the "*Option Choice" pairs from the string, marking PPD
- * options as we go...
+ * Read all of the "*Option Choice" and "property value" pairs from the
+ * string, add them to an options array as we go...
*/
while (*s)
@@ -700,19 +582,15 @@ _ppdParseOptions(
while (isspace(*s & 255))
s ++;
- if (*s != '*')
- break;
-
/*
- * Get the option name...
+ * Get the option/property name...
*/
- s ++;
ptr = option;
while (*s && !isspace(*s & 255) && ptr < (option + sizeof(option) - 1))
*ptr++ = *s++;
- if (ptr == s)
+ if (ptr == s || !isspace(*s & 255))
break;
*ptr = '\0';
@@ -731,13 +609,19 @@ _ppdParseOptions(
while (*s && !isspace(*s & 255) && ptr < (choice + sizeof(choice) - 1))
*ptr++ = *s++;
+ if (!isspace(*s & 255) && *s)
+ break;
+
*ptr = '\0';
/*
* Add it to the options array...
*/
- num_options = cupsAddOption(option, choice, num_options, options);
+ if (option[0] == '*' && which != _PPD_PARSE_PROPERTIES)
+ num_options = cupsAddOption(option + 1, choice, num_options, options);
+ else if (option[0] != '*' && which != _PPD_PARSE_OPTIONS)
+ num_options = cupsAddOption(option, choice, num_options, options);
}
return (num_options);
@@ -806,7 +690,7 @@ ppd_mark_choices(ppd_file_t *ppd, /* I - PPD file */
return;
options = NULL;
- num_options = _ppdParseOptions(s, 0, &options);
+ num_options = _ppdParseOptions(s, 0, &options, 0);
for (i = num_options, option = options; i > 0; i --, option ++)
ppd_mark_option(ppd, option->name, option->value);
diff --git a/cups/ppd-private.h b/cups/ppd-private.h
index 2867fc83e..3b2d3aa1a 100644
--- a/cups/ppd-private.h
+++ b/cups/ppd-private.h
@@ -31,6 +31,7 @@
* Include necessary headers...
*/
+# include <cups/cups.h>
# include <cups/ppd.h>
# include "pwg-private.h"
@@ -45,9 +46,16 @@ extern "C" {
/*
- * Structures...
+ * Types and structures...
*/
+typedef enum _ppd_parse_e /**** Selector for _ppdParseOptions ****/
+{
+ _PPD_PARSE_OPTIONS, /* Parse only the options */
+ _PPD_PARSE_PROPERTIES, /* Parse only the properties */
+ _PPD_PARSE_ALL /* Parse everything */
+} _ppd_parse_t;
+
typedef struct _ppd_cups_uiconst_s /**** Constraint from cupsUIConstraints ****/
{
ppd_option_t *option; /* Constrained option */
@@ -63,6 +71,49 @@ typedef struct _ppd_cups_uiconsts_s /**** cupsUIConstraints ****/
_ppd_cups_uiconst_t *constraints; /* Constraints */
} _ppd_cups_uiconsts_t;
+typedef enum _pwg_output_mode_e /**** PWG output-mode indices ****/
+{
+ _PWG_OUTPUT_MODE_MONOCHROME = 0, /* output-mode=monochrome */
+ _PWG_OUTPUT_MODE_COLOR, /* output-mode=color */
+ _PWG_OUTPUT_MODE_MAX
+} _pwg_output_mode_t;
+
+typedef enum _pwg_print_quality_e /**** PWG print-quality indices ****/
+{
+ _PWG_PRINT_QUALITY_DRAFT = 0, /* print-quality=3 */
+ _PWG_PRINT_QUALITY_NORMAL, /* print-quality=4 */
+ _PWG_PRINT_QUALITY_HIGH, /* print-quality=5 */
+ _PWG_PRINT_QUALITY_MAX
+} _pwg_print_quality_t;
+
+typedef struct _pwg_s /**** PWG-PPD conversion data ****/
+{
+ int num_bins; /* Number of output bins */
+ _pwg_map_t *bins; /* Output bins */
+ int num_sizes; /* Number of media sizes */
+ _pwg_size_t *sizes; /* Media sizes */
+ int custom_max_width, /* Maximum custom width in 2540ths */
+ custom_max_length, /* Maximum custom length in 2540ths */
+ custom_min_width, /* Minimum custom width in 2540ths */
+ custom_min_length; /* Minimum custom length in 2540ths */
+ char *custom_max_keyword, /* Maximum custom size PWG keyword */
+ *custom_min_keyword, /* Minimum custom size PWG keyword */
+ custom_ppd_size[41]; /* Custom PPD size name */
+ _pwg_size_t custom_size; /* Custom size record */
+ int num_sources; /* Number of media sources */
+ _pwg_map_t *sources; /* Media sources */
+ int num_types; /* Number of media types */
+ _pwg_map_t *types; /* Media types */
+ int num_presets[_PWG_OUTPUT_MODE_MAX][_PWG_PRINT_QUALITY_MAX];
+ /* Number of output-mode/print-quality options */
+ cups_option_t *presets[_PWG_OUTPUT_MODE_MAX][_PWG_PRINT_QUALITY_MAX];
+ /* output-mode/print-quality options */
+ char *sides_option, /* PPD option for sides */
+ *sides_1sided, /* Choice for one-sided */
+ *sides_2sided_long, /* Choice for two-sided-long-edge */
+ *sides_2sided_short; /* Choice for two-sided-short-edge */
+} _pwg_t;
+
/*
* Prototypes...
@@ -78,8 +129,11 @@ extern char *_ppdNormalizeMakeAndModel(const char *make_and_model,
char *buffer,
size_t bufsize);
extern int _ppdParseOptions(const char *s, int num_options,
- cups_option_t **options);
+ cups_option_t **options,
+ _ppd_parse_t which);
+extern _pwg_t *_pwgCreateWithFile(const char *filename);
extern _pwg_t *_pwgCreateWithPPD(ppd_file_t *ppd);
+extern void _pwgDestroy(_pwg_t *pwg);
extern const char *_pwgGetBin(_pwg_t *pwg, const char *output_bin);
extern const char *_pwgGetInputSlot(_pwg_t *pwg, ipp_t *job,
const char *keyword);
@@ -98,6 +152,7 @@ extern const char *_pwgMediaTypeForType(const char *media_type,
char *name, size_t namesize);
extern const char *_pwgPageSizeForMedia(_pwg_media_t *media,
char *name, size_t namesize);
+extern int _pwgWriteFile(_pwg_t *pwg, const char *filename);
/*
diff --git a/cups/ppd.h b/cups/ppd.h
index a84bcadcc..42c08df33 100644
--- a/cups/ppd.h
+++ b/cups/ppd.h
@@ -336,7 +336,7 @@ typedef struct ppd_file_s /**** PPD File ****/
cups_array_t *cups_uiconstraints; /* cupsUIConstraints @since CUPS 1.4/Mac OS X 10.6@ @private@ */
/**** New in CUPS 1.5 ****/
- void *pwg; /* PWG to/from PPD mappings */
+ void *pwg; /* PWG to/from PPD mappings @since CUPS 1.5@ @private@ */
} ppd_file_t;
diff --git a/cups/pwg-file.c b/cups/pwg-file.c
index 8e4a4835e..6ebd4aaeb 100644
--- a/cups/pwg-file.c
+++ b/cups/pwg-file.c
@@ -46,11 +46,14 @@ _pwgCreateWithFile(const char *filename)/* I - File to read */
num_sizes, /* Number of sizes in file */
num_sources, /* Number of sources in file */
num_types; /* Number of types in file */
- char line[512], /* Current line */
+ char line[2048], /* Current line */
*value, /* Pointer to value in line */
+ *valueptr, /* Pointer into value */
pwg_keyword[128], /* PWG keyword */
ppd_keyword[PPD_MAX_NAME];
/* PPD keyword */
+ _pwg_output_mode_t output_mode; /* Output mode for preset */
+ _pwg_print_quality_t print_quality; /* Print quality for preset */
DEBUG_printf(("_pwgCreateWithFile(filename=\"%s\")", filename));
@@ -331,6 +334,38 @@ _pwgCreateWithFile(const char *filename)/* I - File to read */
pwg->num_types ++;
}
+ else if (!strcasecmp(line, "Preset"))
+ {
+ /*
+ * Preset output-mode print-quality name=value ...
+ */
+
+ output_mode = (_pwg_output_mode_t)strtol(value, &valueptr, 10);
+ print_quality = (_pwg_print_quality_t)strtol(valueptr, &valueptr, 10);
+
+ if (output_mode < _PWG_OUTPUT_MODE_MONOCHROME ||
+ output_mode >= _PWG_OUTPUT_MODE_MAX ||
+ print_quality < _PWG_PRINT_QUALITY_DRAFT ||
+ print_quality >= _PWG_PRINT_QUALITY_MAX ||
+ valueptr == value || !*valueptr)
+ {
+ DEBUG_printf(("_pwgCreateWithFile: Bad Preset on line %d.", linenum));
+ _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
+ goto create_error;
+ }
+
+ pwg->num_presets[output_mode][print_quality] =
+ cupsParseOptions(valueptr, 0,
+ pwg->presets[output_mode] + print_quality);
+ }
+ else if (!strcasecmp(line, "SidesOption"))
+ pwg->sides_option = _cupsStrAlloc(value);
+ else if (!strcasecmp(line, "Sides1Sided"))
+ pwg->sides_1sided = _cupsStrAlloc(value);
+ else if (!strcasecmp(line, "Sides2SidedLong"))
+ pwg->sides_2sided_long = _cupsStrAlloc(value);
+ else if (!strcasecmp(line, "Sides2SidedShort"))
+ pwg->sides_2sided_short = _cupsStrAlloc(value);
else
{
DEBUG_printf(("_pwgCreateWithFile: Unknown %s on line %d.", line,
@@ -466,10 +501,11 @@ int /* O - 1 on success, 0 on failure */
_pwgWriteFile(_pwg_t *pwg, /* I - PWG mapping data */
const char *filename) /* I - File to write */
{
- int i; /* Looping var */
+ int i, j, k; /* Looping vars */
cups_file_t *fp; /* Output file */
_pwg_size_t *size; /* Current size */
_pwg_map_t *map; /* Current map */
+ cups_option_t *option; /* Current option */
/*
@@ -548,6 +584,38 @@ _pwgWriteFile(_pwg_t *pwg, /* I - PWG mapping data */
}
/*
+ * Presets...
+ */
+
+ for (i = _PWG_OUTPUT_MODE_MONOCHROME; i < _PWG_OUTPUT_MODE_MAX; i ++)
+ for (j = _PWG_PRINT_QUALITY_DRAFT; i < _PWG_PRINT_QUALITY_MAX; i ++)
+ if (pwg->num_presets[i][j])
+ {
+ cupsFilePrintf(fp, "Preset %d %d", i, j);
+ for (k = pwg->num_presets[i][j], option = pwg->presets[i][j];
+ k > 0;
+ k --, option ++)
+ cupsFilePrintf(fp, " %s=%s", option->name, option->value);
+ cupsFilePutChar(fp, '\n');
+ }
+
+ /*
+ * Duplex/sides...
+ */
+
+ if (pwg->sides_option)
+ cupsFilePrintf(fp, "SidesOption %s\n", pwg->sides_option);
+
+ if (pwg->sides_1sided)
+ cupsFilePrintf(fp, "Sides1Sided %s\n", pwg->sides_1sided);
+
+ if (pwg->sides_2sided_long)
+ cupsFilePrintf(fp, "Sides2SidedLong %s\n", pwg->sides_2sided_long);
+
+ if (pwg->sides_2sided_short)
+ cupsFilePrintf(fp, "Sides2SidedShort %s\n", pwg->sides_2sided_short);
+
+ /*
* Close and return...
*/
diff --git a/cups/pwg-ppd.c b/cups/pwg-ppd.c
index 714304483..86c7715ec 100644
--- a/cups/pwg-ppd.c
+++ b/cups/pwg-ppd.c
@@ -62,20 +62,29 @@ static void pwg_unppdize_name(const char *ppd, char *name, size_t namesize);
_pwg_t * /* O - PWG mapping data */
_pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
{
- int i, j; /* Looping vars */
- _pwg_t *pwg; /* PWG mapping data */
- ppd_option_t *input_slot, /* InputSlot option */
- *media_type, /* MediaType option */
- *output_bin; /* OutputBin option */
- ppd_choice_t *choice; /* Current InputSlot/MediaType */
- _pwg_map_t *map; /* Current source/type map */
- ppd_size_t *ppd_size; /* Current PPD size */
- _pwg_size_t *pwg_size; /* Current PWG size */
- char pwg_keyword[3 + PPD_MAX_NAME + 1 + 12 + 1 + 12 + 3],
+ int i, j; /* Looping vars */
+ _pwg_t *pwg; /* PWG mapping data */
+ ppd_option_t *input_slot, /* InputSlot option */
+ *media_type, /* MediaType option */
+ *output_bin, /* OutputBin option */
+ *color_model, /* ColorModel option */
+ *duplex; /* Duplex option */
+ ppd_choice_t *choice; /* Current InputSlot/MediaType */
+ _pwg_map_t *map; /* Current source/type map */
+ ppd_attr_t *ppd_attr; /* Current PPD preset attribute */
+ int num_options; /* Number of preset options and props */
+ cups_option_t *options; /* Preset options and properties */
+ ppd_size_t *ppd_size; /* Current PPD size */
+ _pwg_size_t *pwg_size; /* Current PWG size */
+ char pwg_keyword[3 + PPD_MAX_NAME + 1 + 12 + 1 + 12 + 3],
/* PWG keyword string */
- ppd_name[PPD_MAX_NAME]; /* Normalized PPD name */
- const char *pwg_name; /* Standard PWG media name */
- _pwg_media_t *pwg_media; /* PWG media data */
+ ppd_name[PPD_MAX_NAME];
+ /* Normalized PPD name */
+ const char *pwg_name; /* Standard PWG media name */
+ _pwg_media_t *pwg_media; /* PWG media data */
+ _pwg_output_mode_t pwg_output_mode;/* output-mode index */
+ _pwg_print_quality_t pwg_print_quality;
+ /* print-quality index */
DEBUG_printf(("_pwgCreateWithPPD(ppd=%p)", ppd));
@@ -361,6 +370,171 @@ _pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
}
}
+ if ((ppd_attr = ppdFindAttr(ppd, "APPrinterPreset", NULL)) != NULL)
+ {
+ /*
+ * Copy and convert APPrinterPreset (output-mode + print-quality) data...
+ */
+
+ const char *quality, /* com.apple.print.preset.quality value */
+ *output_mode, /* com.apple.print.preset.output-mode value */
+ *color_model_val; /* ColorModel choice */
+
+
+ do
+ {
+ num_options = _ppdParseOptions(ppd_attr->value, 0, &options,
+ _PPD_PARSE_ALL);
+
+ if ((quality = cupsGetOption("com.apple.print.preset.quality",
+ num_options, options)) != NULL)
+ {
+ /*
+ * Get the print-quality for this preset...
+ */
+
+ if (!strcmp(quality, "low"))
+ pwg_print_quality = _PWG_PRINT_QUALITY_DRAFT;
+ else if (!strcmp(quality, "high"))
+ pwg_print_quality = _PWG_PRINT_QUALITY_HIGH;
+ else
+ pwg_print_quality = _PWG_PRINT_QUALITY_NORMAL;
+
+ /*
+ * Get the output mode for this preset...
+ */
+
+ output_mode = cupsGetOption("com.apple.print.preset.output-mode",
+ num_options, options);
+ color_model_val = cupsGetOption("ColorModel", num_options, options);
+
+ if (output_mode)
+ {
+ if (!strcmp(output_mode, "monochrome"))
+ pwg_output_mode = _PWG_OUTPUT_MODE_MONOCHROME;
+ else
+ pwg_output_mode = _PWG_OUTPUT_MODE_COLOR;
+ }
+ else if (color_model_val)
+ {
+ if (!strcasecmp(color_model_val, "Gray"))
+ pwg_output_mode = _PWG_OUTPUT_MODE_MONOCHROME;
+ else
+ pwg_output_mode = _PWG_OUTPUT_MODE_COLOR;
+ }
+ else
+ pwg_output_mode = _PWG_OUTPUT_MODE_COLOR;
+
+ /*
+ * Save the options for this combination as needed...
+ */
+
+ if (!pwg->num_presets[pwg_output_mode][pwg_print_quality])
+ pwg->num_presets[pwg_output_mode][pwg_print_quality] =
+ _ppdParseOptions(ppd_attr->value, 0,
+ pwg->presets[pwg_output_mode] +
+ pwg_print_quality, _PPD_PARSE_OPTIONS);
+ }
+
+ cupsFreeOptions(num_options, options);
+ }
+ while ((ppd_attr = ppdFindNextAttr(ppd, "APPrinterPreset", NULL)) != NULL);
+ }
+
+ if (!pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_DRAFT] &&
+ !pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_NORMAL] &&
+ !pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_HIGH] &&
+ (color_model = ppdFindOption(ppd, "ColorModel")) != NULL &&
+ ppdFindChoice(color_model, "Gray"))
+ {
+ /*
+ * Copy and convert ColorModel (output-mode) data...
+ */
+
+ cups_option_t *coption, /* Color option */
+ *moption; /* Monochrome option */
+
+ for (pwg_print_quality = _PWG_PRINT_QUALITY_DRAFT;
+ pwg_print_quality < _PWG_PRINT_QUALITY_MAX;
+ pwg_print_quality ++)
+ {
+ if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][pwg_print_quality])
+ {
+ /*
+ * Copy the color options...
+ */
+
+ num_options = pwg->num_presets[_PWG_OUTPUT_MODE_COLOR]
+ [pwg_print_quality];
+ options = calloc(sizeof(cups_option_t), num_options);
+
+ if (options)
+ {
+ for (i = num_options, moption = options,
+ coption = pwg->presets[_PWG_OUTPUT_MODE_COLOR]
+ [pwg_print_quality];
+ i > 0;
+ i --, moption ++, coption ++)
+ {
+ moption->name = _cupsStrRetain(coption->name);
+ moption->value = _cupsStrRetain(coption->value);
+ }
+
+ pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+ num_options;
+ pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+ options;
+ }
+ }
+ else if (pwg_print_quality != _PWG_PRINT_QUALITY_NORMAL)
+ continue;
+
+ /*
+ * Add ColorModel=Gray to the preset...
+ */
+
+ pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+ cupsAddOption("ColorModel", "Gray",
+ pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME]
+ [pwg_print_quality],
+ pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME] +
+ pwg_print_quality);
+ }
+ }
+
+ /*
+ * Copy and convert Duplex (sides) data...
+ */
+
+ if ((duplex = ppdFindOption(ppd, "Duplex")) == NULL)
+ if ((duplex = ppdFindOption(ppd, "JCLDuplex")) == NULL)
+ if ((duplex = ppdFindOption(ppd, "EFDuplex")) == NULL)
+ if ((duplex = ppdFindOption(ppd, "EFDuplexing")) == NULL)
+ duplex = ppdFindOption(ppd, "KD03Duplex");
+
+ if (duplex)
+ {
+ pwg->sides_option = _cupsStrAlloc(duplex->keyword);
+
+ for (i = duplex->num_choices, choice = duplex->choices;
+ i > 0;
+ i --, choice ++)
+ {
+ if ((!strcasecmp(choice->choice, "None") ||
+ !strcasecmp(choice->choice, "False")) && !pwg->sides_1sided)
+ pwg->sides_1sided = _cupsStrAlloc(choice->choice);
+ else if ((!strcasecmp(choice->choice, "DuplexNoTumble") ||
+ !strcasecmp(choice->choice, "LongEdge") ||
+ !strcasecmp(choice->choice, "Top")) && !pwg->sides_2sided_long)
+ pwg->sides_2sided_long = _cupsStrAlloc(choice->choice);
+ else if ((!strcasecmp(choice->choice, "DuplexTumble") ||
+ !strcasecmp(choice->choice, "ShortEdge") ||
+ !strcasecmp(choice->choice, "Bottom")) &&
+ !pwg->sides_2sided_short)
+ pwg->sides_2sided_short = _cupsStrAlloc(choice->choice);
+ }
+ }
+
return (pwg);
/*
diff --git a/cups/pwg-private.h b/cups/pwg-private.h
index 623fc5801..33a0790af 100644
--- a/cups/pwg-private.h
+++ b/cups/pwg-private.h
@@ -48,9 +48,11 @@ extern "C" {
* Types and structures...
*/
-# ifndef _CUPS_PPD_H_
-typedef struct ppd_file_s ppd_file_t;
-# endif /* _CUPS_PPD_H_ */
+typedef struct _pwg_map_s /**** Map element - PPD to/from PWG */
+{
+ char *pwg, /* PWG media keyword */
+ *ppd; /* PPD option keyword */
+} _pwg_map_t;
typedef struct _pwg_media_s /**** Common media size data ****/
{
@@ -61,12 +63,6 @@ typedef struct _pwg_media_s /**** Common media size data ****/
length; /* Length in 2540ths */
} _pwg_media_t;
-typedef struct _pwg_map_s /**** Map element - PPD to/from PWG */
-{
- char *pwg, /* PWG media keyword */
- *ppd; /* PPD option keyword */
-} _pwg_map_t;
-
typedef struct _pwg_size_s /**** Size element - PPD to/from PWG */
{
_pwg_map_t map; /* Map element */
@@ -78,43 +74,20 @@ typedef struct _pwg_size_s /**** Size element - PPD to/from PWG */
top; /* Top margin in 2540ths */
} _pwg_size_t;
-typedef struct _pwg_s /**** PWG-PPD conversion data ****/
-{
- int num_bins; /* Number of output bins */
- _pwg_map_t *bins; /* Output bins */
- int num_sizes; /* Number of media sizes */
- _pwg_size_t *sizes; /* Media sizes */
- int custom_max_width, /* Maximum custom width in 2540ths */
- custom_max_length, /* Maximum custom length in 2540ths */
- custom_min_width, /* Minimum custom width in 2540ths */
- custom_min_length; /* Minimum custom length in 2540ths */
- char *custom_max_keyword, /* Maximum custom size PWG keyword */
- *custom_min_keyword, /* Minimum custom size PWG keyword */
- custom_ppd_size[41]; /* Custom PPD size name */
- _pwg_size_t custom_size; /* Custom size record */
- int num_sources; /* Number of media sources */
- _pwg_map_t *sources; /* Media sources */
- int num_types; /* Number of media types */
- _pwg_map_t *types; /* Media types */
-} _pwg_t;
-
/*
* Functions...
*/
-extern _pwg_t *_pwgCreateWithFile(const char *filename);
-extern void _pwgDestroy(_pwg_t *pwg);
extern void _pwgGenerateSize(char *keyword, size_t keysize,
const char *prefix,
- const char *ppdname,
+ const char *name,
int width, int length);
extern int _pwgInitSize(_pwg_size_t *size, ipp_t *job,
int *margins_set);
extern _pwg_media_t *_pwgMediaForLegacy(const char *legacy);
extern _pwg_media_t *_pwgMediaForPWG(const char *pwg);
extern _pwg_media_t *_pwgMediaForSize(int width, int length);
-extern int _pwgWriteFile(_pwg_t *pwg, const char *filename);
# ifdef __cplusplus
diff --git a/cups/raster.h b/cups/raster.h
index 4848dacc2..dbb7e30b8 100644
--- a/cups/raster.h
+++ b/cups/raster.h
@@ -1,9 +1,9 @@
/*
* "$Id$"
*
- * Raster file definitions for the Common UNIX Printing System (CUPS).
+ * Raster file definitions for CUPS.
*
- * Copyright 2007-2008 by Apple Inc.
+ * Copyright 2007-2010 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* This file is part of the CUPS Imaging library.
@@ -86,26 +86,28 @@ typedef enum cups_bool_e /**** Boolean type ****/
typedef enum cups_cspace_e /**** cupsColorSpace attribute values ****/
{
- CUPS_CSPACE_W = 0, /* Luminance */
- CUPS_CSPACE_RGB = 1, /* Red, green, blue */
- CUPS_CSPACE_RGBA = 2, /* Red, green, blue, alpha */
- CUPS_CSPACE_K = 3, /* Black */
- CUPS_CSPACE_CMY = 4, /* Cyan, magenta, yellow */
- CUPS_CSPACE_YMC = 5, /* Yellow, magenta, cyan */
- CUPS_CSPACE_CMYK = 6, /* Cyan, magenta, yellow, black */
- CUPS_CSPACE_YMCK = 7, /* Yellow, magenta, cyan, black */
- CUPS_CSPACE_KCMY = 8, /* Black, cyan, magenta, yellow */
- CUPS_CSPACE_KCMYcm = 9, /* Black, cyan, magenta, yellow, *
- * light-cyan, light-magenta */
- CUPS_CSPACE_GMCK = 10, /* Gold, magenta, yellow, black */
- CUPS_CSPACE_GMCS = 11, /* Gold, magenta, yellow, silver */
- CUPS_CSPACE_WHITE = 12, /* White ink (as black) */
- CUPS_CSPACE_GOLD = 13, /* Gold foil */
- CUPS_CSPACE_SILVER = 14, /* Silver foil */
+ CUPS_CSPACE_W = 0, /* Luminance (DeviceGray, gamma 2.2 by default) */
+ CUPS_CSPACE_RGB = 1, /* Red, green, blue (DeviceRGB, sRGB by default) */
+ CUPS_CSPACE_RGBA = 2, /* Red, green, blue, alpha (DeviceRGB, sRGB by default) */
+ CUPS_CSPACE_K = 3, /* Black (DeviceK) */
+ CUPS_CSPACE_CMY = 4, /* Cyan, magenta, yellow (DeviceCMY) */
+ CUPS_CSPACE_YMC = 5, /* Yellow, magenta, cyan @deprecated@ */
+ CUPS_CSPACE_CMYK = 6, /* Cyan, magenta, yellow, black (DeviceCMYK) */
+ CUPS_CSPACE_YMCK = 7, /* Yellow, magenta, cyan, black @deprecated@ */
+ CUPS_CSPACE_KCMY = 8, /* Black, cyan, magenta, yellow @deprecated@ */
+ CUPS_CSPACE_KCMYcm = 9, /* Black, cyan, magenta, yellow, light-cyan, light-magenta @deprecated@ */
+ CUPS_CSPACE_GMCK = 10, /* Gold, magenta, yellow, black @deprecated@ */
+ CUPS_CSPACE_GMCS = 11, /* Gold, magenta, yellow, silver @deprecated@ */
+ CUPS_CSPACE_WHITE = 12, /* White ink (as black) @deprecated@ */
+ CUPS_CSPACE_GOLD = 13, /* Gold foil @deprecated@ */
+ CUPS_CSPACE_SILVER = 14, /* Silver foil @deprecated@ */
CUPS_CSPACE_CIEXYZ = 15, /* CIE XYZ @since CUPS 1.1.19/Mac OS X 10.3@ */
CUPS_CSPACE_CIELab = 16, /* CIE Lab @since CUPS 1.1.19/Mac OS X 10.3@ */
- CUPS_CSPACE_RGBW = 17, /* Red, green, blue, white @since CUPS 1.2/Mac OS X 10.5@ */
+ CUPS_CSPACE_RGBW = 17, /* Red, green, blue, white (DeviceRGB, sRGB by default) @since CUPS 1.2/Mac OS X 10.5@ */
+ CUPS_CSPACE_SW = 18, /* Luminance (gamma 2.2) @since CUPS 1.4.5@ */
+ CUPS_CSPACE_SRGB = 19, /* Red, green, blue (sRGB) @since CUPS 1.4.5@ */
+ CUPS_CSPACE_ADOBERGB = 20, /* Red, green, blue (Adobe RGB) @since CUPS 1.4.5@ */
CUPS_CSPACE_ICC1 = 32, /* ICC-based, 1 color @since CUPS 1.1.19/Mac OS X 10.3@ */
CUPS_CSPACE_ICC2 = 33, /* ICC-based, 2 colors @since CUPS 1.1.19/Mac OS X 10.3@ */
@@ -121,7 +123,23 @@ typedef enum cups_cspace_e /**** cupsColorSpace attribute values ****/
CUPS_CSPACE_ICCC = 43, /* ICC-based, 12 colors @since CUPS 1.1.19/Mac OS X 10.3@ */
CUPS_CSPACE_ICCD = 44, /* ICC-based, 13 colors @since CUPS 1.1.19/Mac OS X 10.3@ */
CUPS_CSPACE_ICCE = 45, /* ICC-based, 14 colors @since CUPS 1.1.19/Mac OS X 10.3@ */
- CUPS_CSPACE_ICCF = 46 /* ICC-based, 15 colors @since CUPS 1.1.19/Mac OS X 10.3@ */
+ CUPS_CSPACE_ICCF = 46, /* ICC-based, 15 colors @since CUPS 1.1.19/Mac OS X 10.3@ */
+
+ CUPS_CSPACE_DEVICE1 = 48, /* DeviceN, 1 color @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICE2 = 49, /* DeviceN, 2 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICE3 = 50, /* DeviceN, 3 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICE4 = 51, /* DeviceN, 4 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICE5 = 52, /* DeviceN, 5 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICE6 = 53, /* DeviceN, 6 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICE7 = 54, /* DeviceN, 7 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICE8 = 55, /* DeviceN, 8 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICE9 = 56, /* DeviceN, 9 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICEA = 57, /* DeviceN, 10 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICEB = 58, /* DeviceN, 11 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICEC = 59, /* DeviceN, 12 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICED = 60, /* DeviceN, 13 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICEE = 61, /* DeviceN, 14 colors @since CUPS 1.4.5@ */
+ CUPS_CSPACE_DEVICEF = 62 /* DeviceN, 15 colors @since CUPS 1.4.5@ */
} cups_cspace_t;
typedef enum cups_cut_e /**** CutMedia attribute values ****/
diff --git a/cups/testfile.c b/cups/testfile.c
index 1363dfacf..74da14b64 100644
--- a/cups/testfile.c
+++ b/cups/testfile.c
@@ -130,12 +130,12 @@ main(int argc, /* I - Number of command-line arguments */
#endif /* !WIN32 */
/*
- * Count lines in euc-jp.txt, rewind, then count again.
+ * Count lines in psglyphs, rewind, then count again.
*/
- fputs("\ncupsFileOpen(\"../data/euc-jp.txt\", \"r\"): ", stdout);
+ fputs("\ncupsFileOpen(\"../data/psglyphs\", \"r\"): ", stdout);
- if ((fp = cupsFileOpen("../data/euc-jp.txt", "r")) == NULL)
+ if ((fp = cupsFileOpen("../data/psglyphs", "r")) == NULL)
{
puts("FAIL");
status ++;
@@ -145,9 +145,9 @@ main(int argc, /* I - Number of command-line arguments */
puts("PASS");
fputs("cupsFileGets: ", stdout);
- if ((count = count_lines(fp)) != 15184)
+ if ((count = count_lines(fp)) != 1051)
{
- printf("FAIL (got %d lines, expected 15184)\n", count);
+ printf("FAIL (got %d lines, expected 1051)\n", count);
status ++;
}
else
@@ -165,9 +165,9 @@ main(int argc, /* I - Number of command-line arguments */
puts("PASS");
fputs("cupsFileGets: ", stdout);
- if ((count = count_lines(fp)) != 15184)
+ if ((count = count_lines(fp)) != 1051)
{
- printf("FAIL (got %d lines, expected 15184)\n", count);
+ printf("FAIL (got %d lines, expected 1051)\n", count);
status ++;
}
else
diff --git a/cups/thread-private.h b/cups/thread-private.h
new file mode 100644
index 000000000..859e6c1a8
--- /dev/null
+++ b/cups/thread-private.h
@@ -0,0 +1,86 @@
+/*
+ * "$Id$"
+ *
+ * Private threading definitions for CUPS.
+ *
+ * Copyright 2009-2010 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * 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/".
+ */
+
+#ifndef _CUPS_THREAD_PRIVATE_H_
+# define _CUPS_THREAD_PRIVATE_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include "config.h"
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+
+# ifdef HAVE_PTHREAD_H
+# include <pthread.h>
+typedef void *(*_cups_thread_func_t)(void *arg);
+typedef pthread_mutex_t _cups_mutex_t;
+typedef pthread_key_t _cups_threadkey_t;
+# define _CUPS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+# define _CUPS_THREADKEY_INITIALIZER -1
+# define _cupsThreadGetData(k) pthread_getspecific(k)
+# define _cupsThreadSetData(k,p) pthread_setspecific(k,p)
+
+# elif defined(WIN32)
+# include <winsock2.h>
+# include <windows.h>
+typedef void *(__stdcall *_cups_thread_func_t)(void *arg);
+typedef struct _cups_mutex_s
+{
+ int m_init; /* Flag for on-demand initialization */
+ CRITICAL_SECTION m_criticalSection;
+ /* Win32 Critical Section */
+} _cups_mutex_t;
+typedef DWORD _cups_threadkey_t;
+# define _CUPS_MUTEX_INITIALIZER { 0, 0 }
+# define _CUPS_THREADKEY_INITIALIZER 0
+# define _cupsThreadGetData(k) TlsGetValue(k)
+# define _cupsThreadSetData(k,p) TlsSetValue(k,p)
+
+# else
+typedef char _cups_mutex_t;
+typedef void *_cups_threadkey_t;
+# define _CUPS_MUTEX_INITIALIZER 0
+# define _CUPS_THREADKEY_INITIALIZER (void *)0
+# define _cupsThreadGetData(k) k
+# define _cupsThreadSetData(k,p) k=p
+# endif /* HAVE_PTHREAD_H */
+
+
+/*
+ * Functions...
+ */
+
+extern void _cupsMutexLock(_cups_mutex_t *mutex);
+extern void _cupsMutexUnlock(_cups_mutex_t *mutex);
+extern int _cupsThreadCreate(_cups_thread_func_t func, void *arg);
+
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+#endif /* !_CUPS_THREAD_PRIVATE_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/thread.c b/cups/thread.c
new file mode 100644
index 000000000..deb3a8ebc
--- /dev/null
+++ b/cups/thread.c
@@ -0,0 +1,144 @@
+/*
+ * "$Id$"
+ *
+ * Threading primitives for CUPS.
+ *
+ * Copyright 2009-2010 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * 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/".
+ *
+ * Contents:
+ *
+ * _cupsMutexLock() - Lock a mutex.
+ * _cupsMutexUnlock() - Unlock a mutex.
+ * _cupsThreadCreate() - Create a thread.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups-private.h"
+#include "thread-private.h"
+
+
+#if defined(HAVE_PTHREAD_H)
+/*
+ * '_cupsMutexLock()' - Lock a mutex.
+ */
+
+void
+_cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */
+{
+ pthread_mutex_lock(mutex);
+}
+
+
+/*
+ * '_cupsMutexUnlock()' - Unlock a mutex.
+ */
+
+void
+_cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */
+{
+ pthread_mutex_unlock(mutex);
+}
+
+
+/*
+ * '_cupsThreadCreate()' - Create a thread.
+ */
+
+int /* O - 0 on failure, 1 on success */
+_cupsThreadCreate(
+ _cups_thread_func_t func, /* I - Entry point */
+ void *arg) /* I - Entry point context */
+{
+ pthread_t thread;
+
+ return (pthread_create(&thread, NULL, (void *(*)(void *))func, arg) == 0);
+}
+
+
+#elif defined(WIN32)
+# include <process.h>
+
+
+/*
+ * '_cupsMutexLock()' - Lock a mutex.
+ */
+
+void
+_cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */
+{
+ if (!mutex->m_init)
+ {
+ _cupsGlobalLock();
+
+ if (!mutex->m_init)
+ {
+ InitializeCriticalSection(&mutex->m_criticalSection);
+ mutex->m_init = 1;
+ }
+
+ _cupsGlobalUnlock();
+ }
+
+ EnterCriticalSection(&mutex->m_criticalSection);
+}
+
+
+/*
+ * '_cupsMutexUnlock()' - Unlock a mutex.
+ */
+
+void
+_cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */
+{
+ LeaveCriticalSection(&mutex->m_criticalSection);
+}
+
+
+/*
+ * '_cupsThreadCreate()' - Create a thread.
+ */
+
+int /* O - 0 on failure, 1 on success */
+_cupsThreadCreate(
+ _cups_thread_func_t func, /* I - Entry point */
+ void *arg) /* I - Entry point context */
+{
+ return (_beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE) func, arg, 0, NULL)
+ != 0);
+}
+
+
+#else
+/*
+ * '_cupsMutexLock()' - Lock a mutex.
+ */
+
+void
+_cupsMutexLock(_cups_mutex_t *mutex) /* I - Mutex */
+{
+}
+
+
+/*
+ * '_cupsMutexUnlock()' - Unlock a mutex.
+ */
+
+void
+_cupsMutexUnlock(_cups_mutex_t *mutex) /* I - Mutex */
+{
+}
+#endif /* HAVE_PTHREAD_H */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/versioning.h b/cups/versioning.h
index 7d506f893..323fea5a8 100644
--- a/cups/versioning.h
+++ b/cups/versioning.h
@@ -49,6 +49,7 @@
# define _CUPS_API_1_2 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
# define _CUPS_API_1_3 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
# define _CUPS_API_1_4 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
+# define _CUPS_API_1_5
# else
# define _CUPS_API_1_1_19
# define _CUPS_API_1_1_20
@@ -56,6 +57,7 @@
# define _CUPS_API_1_2
# define _CUPS_API_1_3
# define _CUPS_API_1_4
+# define _CUPS_API_1_5
# endif /* __APPLE__ && !_CUPS_SOURCE */
/*
diff --git a/doc/Makefile b/doc/Makefile
index bab8f31e6..07350e3fc 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -69,7 +69,6 @@ HELPFILES = \
help/man-cupsenable.html \
help/man-cupstestdsc.html \
help/man-cupstestppd.html \
- help/man-drv.html \
help/man-filter.html \
help/man-ipptool.html \
help/man-ipptoolfile.html \
diff --git a/doc/help/spec-ppd.html b/doc/help/spec-ppd.html
index 2ac011e77..3c81a763c 100644
--- a/doc/help/spec-ppd.html
+++ b/doc/help/spec-ppd.html
@@ -10,9 +10,9 @@
<!--
"$Id: spec-ppd.html 7937 2008-09-11 16:16:41Z mike $"
- CUPS PPD extensions specification for the Common UNIX Printing System (CUPS).
+ CUPS PPD extensions specification for CUPS.
- Copyright 2007-2009 by Apple Inc.
+ Copyright 2007-2010 by Apple Inc.
Copyright 1997-2007 by Easy Software Products.
These coded instructions, statements, and computer programs are the
@@ -1566,6 +1566,31 @@ before the filter that accepts the given MIME type.</p>
*cupsPreFilter: "image/png 0 mypngprefilter"
</pre>
+
+<h3><span class='info'>CUPS 1.5</span><a name='cupsPrintQuality'>cupsPrintQuality</a></h3>
+
+<p class='summary'>*cupsPrintQuality keyword/text: "code"</p>
+
+<p>This UI keyword defines standard print qualities that directly map from the IPP "print-quality" job template attribute. Standard keyword values are "Draft", "Normal", and "High" which are mapped from the IPP "print-quality" values 3, 4, and 5 respectively. Each <code>cupsPrintQuality</code> option typically sets output mode and resolution parameters in the page device dictionary, eliminating the need for separate (and sometimes confusing) output mode and resolution options.</p>
+
+<blockquote><b>Note:</b>
+
+<p>Unlike all of the other keywords defined in this document, <code>cupsPrintQuality</code> is a UI keyword that MUST be enclosed inside the PPD <code>OpenUI</code> and <code>CloseUI</code> keywords.</p>
+
+</blockquote>
+
+<p>Examples:</p>
+
+<pre class='command'>
+*OpenUI *cupsPrintQuality/Print Quality: PickOne
+*OrderDependency: 10 AnySetup *cupsPrintQuality
+*DefaultcupsPrintQuality: Normal
+*cupsPrintQuality Draft/Draft: "code"
+*cupsPrintQuality Normal/Normal: "code"
+*cupsPrintQuality High/Photo: "code"
+*CloseUI: *cupsPrintQuality
+</pre>
+
<h3><span class='info'>CUPS 1.4/Mac OS X 10.6</span><a name='cupsSNMPSupplies'>cupsSNMPSupplies</a></h3>
<p class='summary'>*cupsSNMPSupplies: boolean</p>
@@ -1775,39 +1800,51 @@ Technical Note TN2144</a> for more information.</p>
in the print dialog of applications (such as iPhoto) that set the job
style hint to <tt>NSPrintPhotoJobStyleHint</tt>. Each preset maps to one or
more pairs of PPD options and choices as well as providing key/value data for
-the application. The following preset names are currently defined:</p>
+the application. The following standard preset names are currently defined:</p>
<ul>
- <li><code>Photo_with_Paper_Auto-Detect</code>; Photo printing
- with paper auto-detect</li>
+ <li><code>General_with_Paper_Auto-Detect</code>; Normal quality general printing with auto-detected media.</li>
+
+ <li><code>General_with_Paper_Auto-Detect_-_Draft</code>; Draft quality general printing with auto-detected media.</li>
+
+ <li><code>General_on_Plain_Paper</code>; Normal quality general printing on plain paper.</li>
+
+ <li><code>General_on_Plain_Paper_-_Draft</code>; Draft quality general printing on plain paper.</li>
- <li><code>Photo_with_Paper_Auto-Detect_-_Fine</code>; Photo printing
- with paper auto-detect - fine</li>
+ <li><code>Photo_with_Paper_Auto-Detect</code>; Normal quality photo printing with auto-detected media.</li>
- <li><code>Photo_on_Plain_Paper</code>; Photo printing on plain paper</li>
+ <li><code>Photo_with_Paper_Auto-Detect_-_Fine</code>; High quality photo printing with auto-detected media.</li>
- <li><code>Photo_on_Plain_Paper_-_Fine</code>; Photo printing on plain
- paper - fine</li>
+ <li><code>Photo_on_Plain_Paper</code>; Normal quality photo printing on plain paper.</li>
- <li><code>Photo_on_Photo_Paper</code>; Photo printing on photo paper</li>
+ <li><code>Photo_on_Plain_Paper_-_Fine</code>; High quality photo printing on plain paper.</li>
- <li><code>Photo_on_Photo_Paper_-_Fine</code>; Photo printing on photo
- paper - fine</li>
+ <li><code>Photo_on_Photo_Paper</code>; Normal quality photo printing on glossy photo paper.</li>
- <li><code>Photo_on_Matte_Paper</code>; Photo printing on matte paper</li>
+ <li><code>Photo_on_Photo_Paper_-_Fine</code>; High quality photo printing on glossy photo paper.</li>
- <li><code>Photo_on_Matte_Paper_-_Fine</code>; Photo printing on matte
- paper - fine</li>
+ <li><code>Photo_on_Matte_Paper</code>; Normal quality photo printing on matte paper.</li>
+
+ <li><code>Photo_on_Matte_Paper_-_Fine</code>; High quality photo printing on matte paper.</li>
</ul>
<p>The value string consists of pairs of keywords, either an option name and
choice (*MainKeyword OptionKeyword) or a preset identifier and value
-(com.apple.print.preset.foo value). Preset identifiers and their supported
-values are documented in "<a
-href='http://developer.apple.com/documentation/Printing/Conceptual/PresetDraft/presets_intro/chapter_1_section_2.html'
->Creating Printing Presets for iPhoto: Printing Presets File Format</a>".</p>
+(com.apple.print.preset.foo value). The following preset identifiers are currently used:</p>
+
+<ul>
+
+ <li><code>com.apple.print.preset.graphicsType</code>; specifies the type of printing used for this printing - "General" for general purpose printing and "Photo" for photo printing.</li>
+
+ <li><code>com.apple.print.preset.media-front-coating</code>; specifies the media type selected by this preset - "none" (plain paper), "glossy", "high-gloss", "semi-gloss", "satin", "matte", and "autodetect".</li>
+
+ <li><code>com.apple.print.preset.output-mode</code>; specifies the output mode for this preset - "color" (default for color printers) or "monochrome" (grayscale, default for B&amp;W printers).</li>
+
+ <li><code>com.apple.print.preset.quality</code>; specifies the overall print quality selected by this preset - "low" (draft), "mid" (normal), or "high".</li>
+
+</ul>
<p>Presets, like options, can also be localized in multiple languages.</p>
@@ -1871,6 +1908,17 @@ the device.</p>
<h2 class='title'><a name='HISTORY'>Change History</a></h2>
+<h3>Changes in CUPS 1.4.5</h3>
+
+<ul>
+
+ <li>Added <a href='#cupsPrintQuality'><tt>cupsPrintQuality</tt></a> UI keyword.</li>
+
+ <li>Added new properties and values for the <a href='#APPrinterPreset'><tt>APPrinterPreset</tt></a> keyword.</li>
+
+</ul>
+
+
<h3>Changes in CUPS 1.4</h3>
<ul>
diff --git a/driver/rastertoescpx.c b/driver/rastertoescpx.c
index 38ef623bc..d6e3b6b62 100644
--- a/driver/rastertoescpx.c
+++ b/driver/rastertoescpx.c
@@ -1787,7 +1787,15 @@ main(int argc, /* I - Number of command-line arguments */
if (!ppd)
{
- _cupsLangPuts(stderr, _("ERROR: Unable to open PPD file\n"));
+ ppd_status_t status; /* PPD error */
+ int linenum; /* Line number */
+
+ _cupsLangPrintf(stderr, _("ERROR: The PPD file could not be opened.\n"));
+
+ status = ppdLastError(&linenum);
+
+ fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
+
return (1);
}
@@ -1902,7 +1910,7 @@ main(int argc, /* I - Number of command-line arguments */
if (page == 0)
{
- _cupsLangPuts(stderr, _("ERROR: No pages found\n"));
+ _cupsLangPuts(stderr, _("ERROR: No pages were found.\n"));
return (1);
}
else
diff --git a/driver/rastertopclx.c b/driver/rastertopclx.c
index f522ac6fb..ce934c822 100644
--- a/driver/rastertopclx.c
+++ b/driver/rastertopclx.c
@@ -1812,7 +1812,15 @@ main(int argc, /* I - Number of command-line arguments */
if (!ppd)
{
- _cupsLangPuts(stderr, _("ERROR: Unable to open PPD file\n"));
+ ppd_status_t status; /* PPD error */
+ int linenum; /* Line number */
+
+ _cupsLangPrintf(stderr, _("ERROR: The PPD file could not be opened.\n"));
+
+ status = ppdLastError(&linenum);
+
+ fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
+
return (1);
}
@@ -1927,7 +1935,7 @@ main(int argc, /* I - Number of command-line arguments */
if (Page == 0)
{
- _cupsLangPuts(stderr, _("ERROR: No pages found\n"));
+ _cupsLangPuts(stderr, _("ERROR: No pages were found.\n"));
return (1);
}
else
diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c
index a367b28f4..a54080c2d 100644
--- a/filter/imagetoraster.c
+++ b/filter/imagetoraster.c
@@ -455,7 +455,7 @@ main(int argc, /* I - Number of command-line arguments */
if (cupsRasterInterpretPPD(&header, ppd, num_options, options, raster_cb))
{
- _cupsLangPuts(stderr, _("ERROR: Bad page setup\n"));
+ _cupsLangPuts(stderr, _("ERROR: The page setup information was not valid.\n"));
fprintf(stderr, "DEBUG: %s\n", cupsRasterErrorString());
return (1);
}
@@ -481,6 +481,7 @@ main(int argc, /* I - Number of command-line arguments */
switch (header.cupsColorSpace)
{
case CUPS_CSPACE_W :
+ case CUPS_CSPACE_SW :
if (header.cupsBitsPerColor >= 8)
{
primary = CUPS_IMAGE_WHITE;
@@ -493,10 +494,11 @@ main(int argc, /* I - Number of command-line arguments */
}
break;
- default :
case CUPS_CSPACE_RGB :
case CUPS_CSPACE_RGBA :
case CUPS_CSPACE_RGBW :
+ case CUPS_CSPACE_SRGB :
+ case CUPS_CSPACE_ADOBERGB :
if (header.cupsBitsPerColor >= 8)
{
primary = CUPS_IMAGE_RGB;
@@ -540,6 +542,42 @@ main(int argc, /* I - Number of command-line arguments */
primary = CUPS_IMAGE_CMY;
secondary = CUPS_IMAGE_CMY;
break;
+
+ case CUPS_CSPACE_CIEXYZ :
+ case CUPS_CSPACE_CIELab :
+ case CUPS_CSPACE_ICC1 :
+ case CUPS_CSPACE_ICC2 :
+ case CUPS_CSPACE_ICC3 :
+ case CUPS_CSPACE_ICC4 :
+ case CUPS_CSPACE_ICC5 :
+ case CUPS_CSPACE_ICC6 :
+ case CUPS_CSPACE_ICC7 :
+ case CUPS_CSPACE_ICC8 :
+ case CUPS_CSPACE_ICC9 :
+ case CUPS_CSPACE_ICCA :
+ case CUPS_CSPACE_ICCB :
+ case CUPS_CSPACE_ICCC :
+ case CUPS_CSPACE_ICCD :
+ case CUPS_CSPACE_ICCE :
+ case CUPS_CSPACE_ICCF :
+ case CUPS_CSPACE_DEVICE1 :
+ case CUPS_CSPACE_DEVICE2 :
+ case CUPS_CSPACE_DEVICE3 :
+ case CUPS_CSPACE_DEVICE4 :
+ case CUPS_CSPACE_DEVICE5 :
+ case CUPS_CSPACE_DEVICE6 :
+ case CUPS_CSPACE_DEVICE7 :
+ case CUPS_CSPACE_DEVICE8 :
+ case CUPS_CSPACE_DEVICE9 :
+ case CUPS_CSPACE_DEVICEA :
+ case CUPS_CSPACE_DEVICEB :
+ case CUPS_CSPACE_DEVICEC :
+ case CUPS_CSPACE_DEVICED :
+ case CUPS_CSPACE_DEVICEE :
+ case CUPS_CSPACE_DEVICEF :
+ fprintf(stderr, "ERROR: Colorspace %d not supported.\n",
+ header.cupsColorSpace);
+ exit(1);
break;
}
@@ -632,7 +670,7 @@ main(int argc, /* I - Number of command-line arguments */
if (img == NULL)
{
- _cupsLangPuts(stderr, _("ERROR: Unable to open image file for printing\n"));
+ _cupsLangPuts(stderr, _("ERROR: The image file to print could not be opened.\n"));
ppdClose(ppd);
return (1);
}
@@ -1195,8 +1233,8 @@ main(int argc, /* I - Number of command-line arguments */
header.cupsBytesPerLine)
{
_cupsLangPuts(stderr,
- _("ERROR: Unable to write raster data to "
- "driver\n"));
+ _("ERROR: The raster data could not be written "
+ "to the driver.\n"));
cupsImageClose(img);
exit(1);
}
@@ -1291,8 +1329,9 @@ main(int argc, /* I - Number of command-line arguments */
if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
header.cupsBytesPerLine)
{
- _cupsLangPuts(stderr,
- _("ERROR: Unable to write raster data to driver\n"));
+ _cupsLangPuts(stderr,
+ _("ERROR: The raster data could not be written to "
+ "the driver.\n"));
cupsImageClose(img);
exit(1);
}
@@ -1332,8 +1371,8 @@ main(int argc, /* I - Number of command-line arguments */
header.cupsBytesPerLine)
{
_cupsLangPuts(stderr,
- _("ERROR: Unable to write raster data to "
- "driver\n"));
+ _("ERROR: The raster data could not be written "
+ "to the driver.\n"));
cupsImageClose(img);
exit(1);
}
diff --git a/filter/pdftops.c b/filter/pdftops.c
index 67f0e9dc4..0868e6296 100644
--- a/filter/pdftops.c
+++ b/filter/pdftops.c
@@ -133,7 +133,7 @@ main(int argc, /* I - Number of command-line args */
if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
{
- _cupsLangPrintError(_("ERROR: Unable to copy PDF file"));
+ perror("DEBUG: Unable to copy PDF file");
return (1);
}
@@ -409,7 +409,7 @@ main(int argc, /* I - Number of command-line args */
if (pipe(pstops_pipe))
{
- _cupsLangPrintError(_("ERROR: Unable to create pipe"));
+ perror("DEBUG: Unable to create pipe");
exit_status = 1;
goto error;
@@ -427,10 +427,10 @@ main(int argc, /* I - Number of command-line args */
#ifdef HAVE_PDFTOPS
execv(CUPS_PDFTOPS, pdf_argv);
- _cupsLangPrintError(_("ERROR: Unable to execute pdftops program"));
+ perror("DEBUG: Unable to execute pdftops program");
#else
execv(CUPS_GHOSTSCRIPT, pdf_argv);
- _cupsLangPrintError(_("ERROR: Unable to execute gs program"));
+ perror("DEBUG: Unable to execute gs program");
#endif /* HAVE_PDFTOPS */
exit(1);
@@ -442,9 +442,9 @@ main(int argc, /* I - Number of command-line args */
*/
#ifdef HAVE_PDFTOPS
- _cupsLangPrintError(_("ERROR: Unable to execute pdftops program"));
+ perror("DEBUG: Unable to execute pdftops program");
#else
- _cupsLangPrintError(_("ERROR: Unable to execute gs program"));
+ perror("DEBUG: Unable to execute gs program");
#endif /* HAVE_PDFTOPS */
exit_status = 1;
@@ -464,7 +464,7 @@ main(int argc, /* I - Number of command-line args */
close(pstops_pipe[1]);
execv(pstops_path, pstops_argv);
- _cupsLangPrintError(_("ERROR: Unable to execute pstops program"));
+ perror("DEBUG: Unable to execute pstops program");
exit(1);
}
@@ -474,7 +474,7 @@ main(int argc, /* I - Number of command-line args */
* Unable to fork!
*/
- _cupsLangPrintError(_("ERROR: Unable to execute pstops program"));
+ perror("DEBUG: Unable to execute pstops program");
exit_status = 1;
goto error;
diff --git a/filter/pstops.c b/filter/pstops.c
index 6ed7bd044..96e1e66cb 100644
--- a/filter/pstops.c
+++ b/filter/pstops.c
@@ -308,7 +308,7 @@ main(int argc, /* I - Number of command-line args */
if ((len = cupsFileGetLine(fp, line, sizeof(line))) == 0)
{
- _cupsLangPuts(stderr, _("ERROR: Empty print file\n"));
+ fputs("DEBUG: The print file is empty.\n", stderr);
return (1);
}
@@ -651,9 +651,8 @@ copy_comments(cups_file_t *fp, /* I - File to read from */
{
int pages; /* Number of pages */
-
- if (saw_pages)
- _cupsLangPuts(stderr, _("ERROR: Duplicate %%Pages: comment seen\n"));
+ if (saw_pages)
+ fputs("DEBUG: A duplicate %%Pages: comment was seen.\n", stderr);
saw_pages = 1;
@@ -699,9 +698,8 @@ copy_comments(cups_file_t *fp, /* I - File to read from */
}
else if (!strncmp(line, "%%BoundingBox:", 14))
{
- if (saw_bounding_box)
- _cupsLangPuts(stderr,
- _("ERROR: Duplicate %%BoundingBox: comment seen\n"));
+ if (saw_bounding_box)
+ fputs("DEBUG: A duplicate %%BoundingBox: comment was seen.\n", stderr);
else if (strstr(line + 14, "(atend)"))
{
/*
@@ -712,7 +710,7 @@ copy_comments(cups_file_t *fp, /* I - File to read from */
doc->bounding_box + 1, doc->bounding_box + 2,
doc->bounding_box + 3) != 4)
{
- _cupsLangPuts(stderr, _("ERROR: Bad %%BoundingBox: comment seen\n"));
+ fputs("DEBUG: A bad %%BoundingBox: comment was seen.\n", stderr);
doc->bounding_box[0] = (int)PageLeft;
doc->bounding_box[1] = (int)PageBottom;
@@ -763,11 +761,12 @@ copy_comments(cups_file_t *fp, /* I - File to read from */
break;
}
- if (!saw_bounding_box)
- _cupsLangPuts(stderr, _("ERROR: No %%BoundingBox: comment in header\n"));
+ if (!saw_bounding_box)
+ fputs("DEBUG: There wasn't a %%BoundingBox: comment in the header.\n",
+ stderr);
- if (!saw_pages)
- _cupsLangPuts(stderr, _("ERROR: No %%Pages: comment in header\n"));
+ if (!saw_pages)
+ fputs("DEBUG: There wasn't a %%Pages: comment in the header.\n", stderr);
if (!saw_for)
WriteTextComment("For", doc->user);
@@ -1100,10 +1099,8 @@ copy_non_dsc(cups_file_t *fp, /* I - File to read from */
* that may not print correctly...
*/
- _cupsLangPuts(stderr,
- _("WARNING: This document does not conform to the Adobe "
- "Document Structuring Conventions and may not print "
- "correctly\n"));
+ fputs("DEBUG: This document does not conform to the Adobe Document "
+ "Structuring Conventions and may not print correctly.\n", stderr);
/*
* Then write a standard DSC comment section...
@@ -1291,13 +1288,13 @@ copy_page(cups_file_t *fp, /* I - File to read from */
if (!parse_text(line + 7, &ptr, label, sizeof(label)))
{
- _cupsLangPuts(stderr, _("ERROR: Bad %%Page: comment in file\n"));
+ fputs("DEBUG: There was a bad %%Page: comment in the file.\n", stderr);
label[0] = '\0';
number = doc->page;
}
else if (strtol(ptr, &ptr, 10) == LONG_MAX || !isspace(*ptr & 255))
{
- _cupsLangPuts(stderr, _("ERROR: Bad %%Page: comment in file\n"));
+ fputs("DEBUG: There was a bad %%Page: comment in the file.\n", stderr);
number = doc->page;
}
@@ -1391,8 +1388,7 @@ copy_page(cups_file_t *fp, /* I - File to read from */
bounding_box + 1, bounding_box + 2,
bounding_box + 3) != 4)
{
- _cupsLangPuts(stderr,
- _("ERROR: Bad %%PageBoundingBox: comment in file\n"));
+ fputs("DEBUG: There was a bad %%PageBoundingBox: comment in the file.\n", stderr);
memcpy(bounding_box, doc->bounding_box,
sizeof(bounding_box));
}
@@ -1799,8 +1795,8 @@ copy_prolog(cups_file_t *fp, /* I - File to read from */
if (!strncmp(line, "%%EndProlog", 11))
linelen = cupsFileGetLine(fp, line, linesize);
- else
- _cupsLangPuts(stderr, _("ERROR: Missing %%EndProlog\n"));
+ else
+ fputs("DEBUG: The %%EndProlog comment is missing.\n", stderr);
}
doc_puts(doc, "%%EndProlog\n");
@@ -1870,8 +1866,8 @@ copy_setup(cups_file_t *fp, /* I - File to read from */
if (!strncmp(line, "%%EndSetup", 10))
linelen = cupsFileGetLine(fp, line, linesize);
- else
- _cupsLangPuts(stderr, _("ERROR: Missing %%EndSetup\n"));
+ else
+ fputs("DEBUG: The %%EndSetup comment is missing.\n", stderr);
}
if (num_options > 0)
@@ -2249,7 +2245,7 @@ include_feature(
if (sscanf(line + 17, "%254s%254s", name, value) != 2)
{
- _cupsLangPuts(stderr, _("ERROR: Bad %%IncludeFeature: comment\n"));
+ fputs("DEBUG: The %%IncludeFeature: comment is not valid.\n", stderr);
return (num_options);
}
@@ -2755,7 +2751,7 @@ set_pstops_options(
if ((doc->temp = cupsTempFile2(doc->tempfile,
sizeof(doc->tempfile))) == NULL)
{
- _cupsLangPrintError(_("ERROR: Unable to create temporary file"));
+ perror("DEBUG: Unable to create temporary file");
exit(1);
}
}
diff --git a/filter/raster.c b/filter/raster.c
index dedc30325..c6d2fec3b 100644
--- a/filter/raster.c
+++ b/filter/raster.c
@@ -1,9 +1,9 @@
/*
* "$Id: raster.c 7720 2008-07-11 22:46:21Z mike $"
*
- * Raster file routines for the Common UNIX Printing System (CUPS).
+ * Raster file routines for CUPS.
*
- * Copyright 2007-2008 by Apple Inc.
+ * Copyright 2007-2010 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* This file is part of the CUPS Imaging library.
@@ -915,6 +915,7 @@ cups_raster_update(cups_raster_t *r) /* I - Raster stream */
case CUPS_CSPACE_WHITE :
case CUPS_CSPACE_GOLD :
case CUPS_CSPACE_SILVER :
+ case CUPS_CSPACE_SW :
r->header.cupsNumColors = 1;
break;
@@ -923,6 +924,8 @@ cups_raster_update(cups_raster_t *r) /* I - Raster stream */
case CUPS_CSPACE_YMC :
case CUPS_CSPACE_CIEXYZ :
case CUPS_CSPACE_CIELab :
+ case CUPS_CSPACE_SRGB :
+ case CUPS_CSPACE_ADOBERGB :
case CUPS_CSPACE_ICC1 :
case CUPS_CSPACE_ICC2 :
case CUPS_CSPACE_ICC3 :
@@ -957,6 +960,25 @@ cups_raster_update(cups_raster_t *r) /* I - Raster stream */
else
r->header.cupsNumColors = 4;
break;
+
+ case CUPS_CSPACE_DEVICE1 :
+ case CUPS_CSPACE_DEVICE2 :
+ case CUPS_CSPACE_DEVICE3 :
+ case CUPS_CSPACE_DEVICE4 :
+ case CUPS_CSPACE_DEVICE5 :
+ case CUPS_CSPACE_DEVICE6 :
+ case CUPS_CSPACE_DEVICE7 :
+ case CUPS_CSPACE_DEVICE8 :
+ case CUPS_CSPACE_DEVICE9 :
+ case CUPS_CSPACE_DEVICEA :
+ case CUPS_CSPACE_DEVICEB :
+ case CUPS_CSPACE_DEVICEC :
+ case CUPS_CSPACE_DEVICED :
+ case CUPS_CSPACE_DEVICEE :
+ case CUPS_CSPACE_DEVICEF :
+ r->header.cupsNumColors = r->header.cupsColorSpace -
+ CUPS_CSPACE_DEVICE1 + 1;
+ break;
}
}
diff --git a/filter/rastertoepson.c b/filter/rastertoepson.c
index e1d08ac30..f93b9bb33 100644
--- a/filter/rastertoepson.c
+++ b/filter/rastertoepson.c
@@ -1030,8 +1030,21 @@ main(int argc, /* I - Number of command-line arguments */
*/
ppd = ppdOpenFile(getenv("PPD"));
- if (ppd)
- Model = ppd->model_number;
+ if (!ppd)
+ {
+ ppd_status_t status; /* PPD error */
+ int linenum; /* Line number */
+
+ _cupsLangPrintf(stderr, _("ERROR: The PPD file could not be opened.\n"));
+
+ status = ppdLastError(&linenum);
+
+ fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
+
+ return (1);
+ }
+
+ Model = ppd->model_number;
Setup();
@@ -1123,7 +1136,7 @@ main(int argc, /* I - Number of command-line arguments */
if (page == 0)
{
- _cupsLangPuts(stderr, _("ERROR: No pages found\n"));
+ _cupsLangPuts(stderr, _("ERROR: No pages were found.\n"));
return (1);
}
else
diff --git a/filter/rastertohp.c b/filter/rastertohp.c
index 059a2e010..e39194f62 100644
--- a/filter/rastertohp.c
+++ b/filter/rastertohp.c
@@ -756,6 +756,19 @@ main(int argc, /* I - Number of command-line arguments */
*/
ppd = ppdOpenFile(getenv("PPD"));
+ if (!ppd)
+ {
+ ppd_status_t status; /* PPD error */
+ int linenum; /* Line number */
+
+ _cupsLangPrintf(stderr, _("ERROR: The PPD file could not be opened.\n"));
+
+ status = ppdLastError(&linenum);
+
+ fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
+
+ return (1);
+ }
Setup();
@@ -852,7 +865,7 @@ main(int argc, /* I - Number of command-line arguments */
if (Page == 0)
{
- _cupsLangPuts(stderr, _("ERROR: No pages found\n"));
+ _cupsLangPuts(stderr, _("ERROR: No pages were found.\n"));
return (1);
}
else
diff --git a/filter/rastertolabel.c b/filter/rastertolabel.c
index e69008917..917c0e381 100644
--- a/filter/rastertolabel.c
+++ b/filter/rastertolabel.c
@@ -1180,12 +1180,24 @@ main(int argc, /* I - Number of command-line arguments */
num_options = cupsParseOptions(argv[5], 0, &options);
- if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL)
+ ppd = ppdOpenFile(getenv("PPD"));
+ if (!ppd)
{
- ppdMarkDefaults(ppd);
- cupsMarkOptions(ppd, num_options, options);
+ ppd_status_t status; /* PPD error */
+ int linenum; /* Line number */
+
+ _cupsLangPrintf(stderr, _("ERROR: The PPD file could not be opened.\n"));
+
+ status = ppdLastError(&linenum);
+
+ fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);
+
+ return (1);
}
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, num_options, options);
+
/*
* Initialize the print device...
*/
@@ -1279,7 +1291,7 @@ main(int argc, /* I - Number of command-line arguments */
if (Page == 0)
{
- _cupsLangPuts(stderr, _("ERROR: No pages found\n"));
+ _cupsLangPuts(stderr, _("ERROR: No pages were found.\n"));
return (1);
}
else
diff --git a/filter/texttops.c b/filter/texttops.c
index 62117ad5e..bc3a9871e 100644
--- a/filter/texttops.c
+++ b/filter/texttops.c
@@ -176,13 +176,25 @@ WriteProlog(const char *title, /* I - Title of job */
if (SizeColumns <= 0 || SizeColumns > 32767 ||
SizeLines <= 0 || SizeLines > 32767)
{
- _cupsLangPrintf(stderr, _("ERROR: Unable to print %dx%d text page\n"),
+ _cupsLangPrintf(stderr, _("ERROR: Unable to print %dx%d text page.\n"),
+ SizeColumns, SizeLines);
+ exit(1);
+ }
+
+ if ((Page = calloc(sizeof(lchar_t *), SizeLines)) == NULL)
+ {
+ _cupsLangPrintf(stderr, _("ERROR: Unable to print %dx%d text page.\n"),
+ SizeColumns, SizeLines);
+ exit(1);
+ }
+
+ if ((Page[0] = calloc(sizeof(lchar_t), SizeColumns * SizeLines)) == NULL)
+ {
+ _cupsLangPrintf(stderr, _("ERROR: Unable to print %dx%d text page.\n"),
SizeColumns, SizeLines);
exit(1);
}
- Page = calloc(sizeof(lchar_t *), SizeLines);
- Page[0] = calloc(sizeof(lchar_t), SizeColumns * SizeLines);
for (i = 1; i < SizeLines; i ++)
Page[i] = Page[0] + i * SizeColumns;
diff --git a/man/Makefile b/man/Makefile
index 12dd67510..0d3c2edff 100644
--- a/man/Makefile
+++ b/man/Makefile
@@ -49,7 +49,6 @@ MAN5 = classes.conf.$(MAN5EXT) \
printers.conf.$(MAN5EXT) \
subscriptions.conf.$(MAN5EXT)
MAN7 = backend.$(MAN7EXT) \
- drv.$(MAN7EXT) \
filter.$(MAN7EXT) \
notifier.$(MAN7EXT)
MAN8 = cupsaccept.$(MAN8EXT) \
diff --git a/man/drv.man.in b/man/drv.man.in
deleted file mode 100644
index d28a58877..000000000
--- a/man/drv.man.in
+++ /dev/null
@@ -1,40 +0,0 @@
-.\"
-.\" "$Id$"
-.\"
-.\" drv man page for the Common UNIX Printing System.
-.\"
-.\" Copyright 2008-2009 by Apple Inc.
-.\"
-.\" These coded instructions, statements, and computer programs are the
-.\" property of Apple Inc. and are protected by Federal copyright
-.\" law. Distribution and use rights are outlined in the file "LICENSE.txt"
-.\" 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 drv 1 "CUPS" "9 March 2009" "Apple Inc."
-.SH NAME
-drv \- cups driver interface for ppd compiler files
-.SH SYNOPSIS
-.B drv list
-.br
-.B drv cat
-.I drv:///filename.drv/pcfilename
-.SH DESCRIPTION
-\fIdrv\fR lists and compiles PPDC source files installed in the
-@CUPS_DATADIR@/drv and (on Mac OS X) /Library/Printers/PPDs/Contents/Resources
-directories on behalf of the scheduler, \fIcupsd(8)\fR.
-.PP
-The first form of the command lists all of the PPD files that can be produced
-by the driver information files in the two directories.
-.PP
-The second form of the command compiles the requested PPD and sends it to the
-standard output.
-.SH SEE ALSO
-ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1), ppdcfile(5)
-.br
-http://localhost:631/help
-.SH COPYRIGHT
-Copyright 2008-2009 by Apple Inc.
-.\"
-.\" End of "$Id$".
-.\"
diff --git a/notifier/mailto.c b/notifier/mailto.c
index 0c9b8a6fd..8a2d2d386 100644
--- a/notifier/mailto.c
+++ b/notifier/mailto.c
@@ -368,8 +368,10 @@ email_message(const char *to, /* I - Recipient of message */
fputs("DEBUG: QUIT\n", stderr);
if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500)
- goto smtp_error;
- fprintf(stderr, "DEBUG: <<< %s\n", response);
+ fprintf(stderr, "ERROR: Got \"%s\" trying to QUIT connection.\n",
+ response);
+ else
+ fprintf(stderr, "DEBUG: <<< %s\n", response);
cupsFileClose(fp);
diff --git a/packaging/cups.list.in b/packaging/cups.list.in
index 6abdfe4b3..79b996edf 100644
--- a/packaging/cups.list.in
+++ b/packaging/cups.list.in
@@ -718,8 +718,6 @@ f 0444 root sys $MANDIR/man5/mime.convs.$MAN5EXT man/mime.convs.$MAN5EXT
f 0444 root sys $MANDIR/man5/mime.types.$MAN5EXT man/mime.types.$MAN5EXT
f 0444 root sys $MANDIR/man5/printers.conf.$MAN5EXT man/printers.conf.$MAN5EXT
-f 0444 root sys $MANDIR/man7/drv.$MAN7EXT man/drv.$MAN7EXT
-
l 0644 root sys $AMANDIR/man$MAN8DIR/accept.$MAN8EXT cupsaccept.$MAN8EXT
f 0444 root sys $AMANDIR/man$MAN8DIR/cupsaccept.$MAN8EXT man/cupsaccept.$MAN8EXT
l 0644 root sys $AMANDIR/man$MAN8DIR/cupsreject.$MAN8EXT cupsaccept.$MAN8EXT
diff --git a/ppdc/ppdc-source.cxx b/ppdc/ppdc-source.cxx
index 3530fed96..f68d1db9e 100644
--- a/ppdc/ppdc-source.cxx
+++ b/ppdc/ppdc-source.cxx
@@ -1363,17 +1363,17 @@ ppdcSource::get_integer(const char *v) // I - Value string
while (isspace(*newv & 255))
newv ++;
- if (strncmp(newv, "==", 2))
+ if (!strncmp(newv, "==", 2))
{
compop = PPDC_EQ;
newv += 2;
}
- else if (strncmp(newv, "!=", 2))
+ else if (!strncmp(newv, "!=", 2))
{
compop = PPDC_NE;
newv += 2;
}
- else if (strncmp(newv, "<=", 2))
+ else if (!strncmp(newv, "<=", 2))
{
compop = PPDC_LE;
newv += 2;
@@ -1383,7 +1383,7 @@ ppdcSource::get_integer(const char *v) // I - Value string
compop = PPDC_LT;
newv ++;
}
- else if (strncmp(newv, ">=", 2))
+ else if (!strncmp(newv, ">=", 2))
{
compop = PPDC_GE;
newv += 2;
@@ -1404,7 +1404,7 @@ ppdcSource::get_integer(const char *v) // I - Value string
if (*newv == ')' || !*newv)
return (-1);
- if (isdigit(*v & 255) || *v == '-' || *v == '+')
+ if (isdigit(*newv & 255) || *newv == '-' || *newv == '+')
{
// Get the second number...
temp2 = strtol(newv, &newv, 0);
@@ -2045,8 +2045,8 @@ ppdcSource::get_token(ppdcFile *fp, // I - File to read
var = find_variable(name);
if (var)
{
- strncpy(bufptr, var->value->value, bufend - bufptr);
- bufptr += strlen(var->value->value);
+ strlcpy(bufptr, var->value->value, bufend - bufptr + 1);
+ bufptr += strlen(bufptr);
}
else
{
@@ -2056,7 +2056,7 @@ ppdcSource::get_token(ppdcFile *fp, // I - File to read
"%s.\n"), name, fp->line, fp->filename);
snprintf(bufptr, bufend - bufptr + 1, "$%s", name);
- bufptr += strlen(name) + 1;
+ bufptr += strlen(bufptr);
}
}
}
diff --git a/scheduler/auth.c b/scheduler/auth.c
index 246130197..73a0c98c4 100644
--- a/scheduler/auth.c
+++ b/scheduler/auth.c
@@ -962,6 +962,67 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
con->type = CUPSD_AUTH_DIGEST;
}
#ifdef HAVE_GSSAPI
+# ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID
+ else if (con->http.hostaddr->addr.sa_family == AF_LOCAL &&
+ !strncmp(authorization, "Negotiate", 9))
+ {
+ /*
+ * Pull the credentials directly from the user...
+ */
+
+ krb5_error_code error; /* Kerberos error code */
+ cupsd_ucred_t peercred; /* Peer credentials */
+ socklen_t peersize; /* Size of peer credentials */
+ krb5_ccache peerccache; /* Peer Kerberos credentials */
+ const char *peername; /* Peer username */
+
+ peersize = sizeof(peercred);
+
+# ifdef __APPLE__
+ if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
+# else
+ if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred, &peersize))
+# endif /* __APPLE__ */
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s",
+ strerror(errno));
+ return;
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "cupsdAuthorize: Copying credentials for UID %d...",
+ CUPSD_UCRED_UID(peercred));
+
+ krb5_ipc_client_set_target_uid(CUPSD_UCRED_UID(peercred));
+
+ if ((error = krb5_cc_default(KerberosContext, &peerccache)) != 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to get credentials cache for UID %d (%d/%s)",
+ (int)CUPSD_UCRED_UID(peercred), error, strerror(errno));
+ return;
+ }
+
+ if ((peername = krb5_cc_get_name(KerberosContext, peerccache)) != NULL)
+ {
+ strlcpy(username, peername, sizeof(username));
+
+ con->have_gss = 1;
+ con->type = CUPSD_AUTH_NEGOTIATE;
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "cupsdAuthorize: Authorized as %s using Negotiate",
+ username);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to get Kerberos name for UID %d",
+ (int)CUPSD_UCRED_UID(peercred));
+
+ krb5_cc_close(KerberosContext, peerccache);
+ krb5_ipc_client_clear_target();
+ }
+# endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */
else if (!strncmp(authorization, "Negotiate", 9))
{
int len; /* Length of authorization string */
@@ -1003,7 +1064,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (!*authorization)
{
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdAuthorize: No authentication data specified.");
+ "cupsdAuthorize: No authentication data specified.");
return;
}
@@ -1014,7 +1075,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
len = strlen(authorization);
input_token.value = malloc(len);
input_token.value = httpDecode64_2(input_token.value, &len,
- authorization);
+ authorization);
input_token.length = len;
/*
@@ -1038,7 +1099,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (GSS_ERROR(major_status))
{
cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
- "cupsdAuthorize: Error accepting GSSAPI security "
+ "cupsdAuthorize: Error accepting GSSAPI security "
"context");
if (context != GSS_C_NO_CONTEXT)
@@ -1054,7 +1115,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (!con->gss_creds)
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: No delegated credentials!");
+ "cupsdAuthorize: No delegated credentials!");
if (major_status == GSS_S_CONTINUE_NEEDED)
cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
@@ -1067,7 +1128,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (GSS_ERROR(major_status))
{
cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
- "cupsdAuthorize: Error getting username");
+ "cupsdAuthorize: Error getting username");
gss_release_cred(&minor_status, &con->gss_creds);
gss_release_name(&minor_status, &client_name);
gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
diff --git a/scheduler/client.c b/scheduler/client.c
index 2400b57fe..631bc9eee 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -54,19 +54,25 @@
#ifdef HAVE_CDSASSL
# include <Security/Security.h>
+# include <Security/SecItem.h>
+# ifdef HAVE_SECITEMPRIV_H
+# include <Security/SecItemPriv.h>
+# else /* Declare constant from that header... */
+extern const CFTypeRef kSecClassIdentity;
+# endif /* HAVE_SECITEMPRIV_H */
# ifdef HAVE_SECIDENTITYSEARCHPRIV_H
# include <Security/SecIdentitySearchPriv.h>
# else /* Declare prototype for function in that header... */
-extern OSStatus SecIdentitySearchCreateWithPolicy(SecPolicyRef policy,
- CFStringRef idString, CSSM_KEYUSE keyUsage,
- CFTypeRef keychainOrArray,
- Boolean returnOnlyValidIdentities,
+extern OSStatus SecIdentitySearchCreateWithPolicy(SecPolicyRef policy,
+ CFStringRef idString, CSSM_KEYUSE keyUsage,
+ CFTypeRef keychainOrArray,
+ Boolean returnOnlyValidIdentities,
SecIdentitySearchRef* searchRef);
# endif /* HAVE_SECIDENTITYSEARCHPRIV_H */
# ifdef HAVE_SECPOLICYPRIV_H
# include <Security/SecPolicyPriv.h>
# else /* Declare prototype for function in that header... */
-extern OSStatus SecPolicySetValue(SecPolicyRef policyRef,
+extern OSStatus SecPolicySetValue(SecPolicyRef policyRef,
const CSSM_DATA *value);
# endif /* HAVE_SECPOLICYPRIV_H */
# ifdef HAVE_SECBASEPRIV_H
@@ -3353,49 +3359,125 @@ get_cdsa_certificate(
cupsd_client_t *con) /* I - Client connection */
{
OSStatus err; /* Error info */
- SecKeychainRef keychain; /* Keychain reference */
- SecIdentitySearchRef search; /* Search reference */
- SecIdentityRef identity; /* Identity */
+ SecKeychainRef keychain = NULL;/* Keychain reference */
+ SecIdentitySearchRef search = NULL; /* Search reference */
+ SecIdentityRef identity = NULL;/* Identity */
CFArrayRef certificates = NULL;
/* Certificate array */
+# if HAVE_SECPOLICYCREATESSL
+ SecPolicyRef policy = NULL; /* Policy ref */
+ CFStringRef servername = NULL;
+ /* Server name */
+ CFMutableDictionaryRef query = NULL; /* Query qualifiers */
+ char localname[1024];/* Local hostname */
+# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
+ SecPolicyRef policy = NULL; /* Policy ref */
+ SecPolicySearchRef policy_search = NULL;
+ /* Policy search ref */
+ CSSM_DATA options; /* Policy options */
+ CSSM_APPLE_TP_SSL_OPTIONS
+ ssl_options; /* SSL Option for hostname */
+ char localname[1024];/* Local hostname */
+# endif /* HAVE_SECPOLICYCREATESSL */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "get_cdsa_certificate: Looking for certs for \"%s\"...",
+ con->servername);
if ((err = SecKeychainOpen(ServerCertificate, &keychain)))
{
cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot open keychain \"%s\" - %s (%d)",
ServerCertificate, cssmErrorString(err), (int)err);
- return (NULL);
+ goto cleanup;
+ }
+
+# if HAVE_SECPOLICYCREATESSL
+ servername = CFStringCreateWithCString(kCFAllocatorDefault, con->servername,
+ kCFStringEncodingUTF8);
+
+ if ((policy = SecPolicyCreateSSL(1, servername)) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
+ goto cleanup;
+ }
+
+ if (servername)
+ CFRelease(servername);
+
+ if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create query dictionary");
+ goto cleanup;
+ }
+
+ CFDictionaryAddValue(query, kSecClass, kSecClassIdentity);
+ CFDictionaryAddValue(query, kSecMatchPolicy, policy);
+ CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue);
+ CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne);
+
+ err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
+
+ if (err && DNSSDHostName)
+ {
+ /*
+ * Search for the connection server name failed; try the DNS-SD .local
+ * hostname instead...
+ */
+
+ snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "get_cdsa_certificate: Looking for certs for \"%s\"...",
+ localname);
+
+ servername = CFStringCreateWithCString(kCFAllocatorDefault, localname,
+ kCFStringEncodingUTF8);
+
+ CFRelease(policy);
+
+ if ((policy = SecPolicyCreateSSL(1, servername)) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
+ goto cleanup;
+ }
+
+ if (servername)
+ CFRelease(servername);
+
+ CFDictionarySetValue(query, kSecMatchPolicy, policy);
+
+ err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
}
-# if HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY
+ if (err)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Cannot find signing key in keychain \"%s\": %s (%d)",
+ ServerCertificate, cssmErrorString(err), (int)err);
+ goto cleanup;
+ }
+
+# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
/*
* Use a policy to search for valid certificates who's common name matches the
* servername...
*/
- SecPolicySearchRef policy_search; /* Policy search ref */
- SecPolicyRef policy; /* Policy ref */
- CSSM_DATA options; /* Policy options */
- CSSM_APPLE_TP_SSL_OPTIONS
- ssl_options; /* SSL Option for hostname */
- char localname[1024];/* Local hostname */
-
-
- if (SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL,
+ if (SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL,
NULL, &policy_search))
{
cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create a policy search reference");
- CFRelease(keychain);
- return (NULL);
+ goto cleanup;
}
if (SecPolicySearchCopyNext(policy_search, &policy))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Cannot find a policy to use for searching");
- CFRelease(keychain);
- CFRelease(policy_search);
- return (NULL);
+ goto cleanup;
}
memset(&ssl_options, 0, sizeof(ssl_options));
@@ -3403,10 +3485,6 @@ get_cdsa_certificate(
ssl_options.ServerName = con->servername;
ssl_options.ServerNameLen = strlen(con->servername);
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "get_cdsa_certificate: Looking for certs for \"%s\"...",
- con->servername);
-
options.Data = (uint8 *)&ssl_options;
options.Length = sizeof(ssl_options);
@@ -3414,13 +3492,20 @@ get_cdsa_certificate(
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Cannot set policy value to use for searching");
- CFRelease(keychain);
- CFRelease(policy_search);
- return (NULL);
+ goto cleanup;
}
- err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
- keychain, FALSE, &search);
+ if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
+ keychain, FALSE, &search)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Cannot create identity search reference: %s (%d)",
+ cssmErrorString(err), (int)err);
+ goto cleanup;
+ }
+
+ err = SecIdentitySearchCopyNext(search, &identity);
+
if (err && DNSSDHostName)
{
/*
@@ -3441,13 +3526,18 @@ get_cdsa_certificate(
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Cannot set policy value to use for searching");
- CFRelease(keychain);
- CFRelease(policy_search);
- return (NULL);
+ goto cleanup;
}
- err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
- keychain, FALSE, &search);
+ err = SecIdentitySearchCopyNext(search, &identity);
+ }
+
+ if (err)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Cannot find signing key in keychain \"%s\": %s (%d)",
+ ServerCertificate, cssmErrorString(err), (int)err);
+ goto cleanup;
}
# else
@@ -3455,43 +3545,56 @@ get_cdsa_certificate(
* Assume there is exactly one SecIdentity in the keychain...
*/
- err = SecIdentitySearchCreate(keychain, CSSM_KEYUSE_SIGN, &search);
-# endif /* HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY */
-
- if (err)
+ if ((err = SecIdentitySearchCreate(keychain, CSSM_KEYUSE_SIGN, &search)))
+ {
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Cannot create keychain search reference: %s (%d)",
- cssmErrorString(err), (int)err);
- else
+ "Cannot create identity search reference (%d)", (int)err);
+ goto cleanup;
+ }
+
+ if ((err = SecIdentitySearchCopyNext(search, &identity)))
{
- if ((err = SecIdentitySearchCopyNext(search, &identity)))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Cannot find signing key in keychain \"%s\": %s (%d)",
- ServerCertificate, cssmErrorString(err), (int)err);
- }
- else
- {
- if (CFGetTypeID(identity) != SecIdentityGetTypeID())
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "SecIdentitySearchCopyNext CFTypeID failure!");
- else
- {
- if ((certificates = CFArrayCreate(NULL, (const void **)&identity,
- 1, &kCFTypeArrayCallBacks)) == NULL)
- cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create certificate array");
- }
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Cannot find signing key in keychain \"%s\": %s (%d)",
+ ServerCertificate, cssmErrorString(err), (int)err);
+ goto cleanup;
+ }
+# endif /* HAVE_SECPOLICYCREATESSL */
- CFRelease(identity);
- }
+ if (CFGetTypeID(identity) != SecIdentityGetTypeID())
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "SecIdentity CFTypeID failure!");
+ goto cleanup;
+ }
- CFRelease(search);
+ if ((certificates = CFArrayCreate(NULL, (const void **)&identity,
+ 1, &kCFTypeArrayCallBacks)) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create certificate array");
+ goto cleanup;
}
-# if HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY
- CFRelease(policy);
- CFRelease(policy_search);
-# endif /* HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY */
+ cleanup :
+
+ if (keychain)
+ CFRelease(keychain);
+ if (search)
+ CFRelease(search);
+ if (identity)
+ CFRelease(identity);
+
+# if HAVE_SECPOLICYCREATESSL
+ if (policy)
+ CFRelease(policy);
+ if (query)
+ CFRelease(query);
+
+# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
+ if (policy)
+ CFRelease(policy);
+ if (policy_search)
+ CFRelease(policy_search);
+# endif /* HAVE_SECPOLICYCREATESSL */
return (certificates);
}
@@ -4504,7 +4607,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
char argbuf[10240], /* Argument buffer */
*argv[100], /* Argument strings */
*envp[MAX_ENV + 20]; /* Environment variables */
- char auth_type[256], /* CUPSD_AUTH_TYPE environment variable */
+ char auth_type[256], /* AUTH_TYPE environment variable */
content_length[1024], /* CONTENT_LENGTH environment variable */
content_type[1024], /* CONTENT_TYPE environment variable */
http_cookie[32768], /* HTTP_COOKIE environment variable */
@@ -4550,7 +4653,12 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
argv[0] = command;
if (options)
- strlcpy(argbuf, options, sizeof(argbuf));
+ {
+ commptr = options;
+ if (*commptr == ' ')
+ commptr ++;
+ strlcpy(argbuf, commptr, sizeof(argbuf));
+ }
else
argbuf[0] = '\0';
@@ -4649,7 +4757,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
if (con->username[0])
{
- snprintf(auth_type, sizeof(auth_type), "CUPSD_AUTH_TYPE=%s",
+ snprintf(auth_type, sizeof(auth_type), "AUTH_TYPE=%s",
httpGetField(HTTP(con), HTTP_FIELD_AUTHORIZATION));
if ((uriptr = strchr(auth_type + 10, ' ')) != NULL)
diff --git a/scheduler/conf.c b/scheduler/conf.c
index a69e224d4..a10f1cdb3 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -1167,6 +1167,19 @@ cupsdReadConfiguration(void)
cupsdLogMessage(CUPSD_LOG_INFO, "<Policy default>");
cupsdLogMessage(CUPSD_LOG_INFO,
+ "<Limit Create-Job Print-Job Print-URI Validate-Job>");
+ cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow");
+
+ po = cupsdAddPolicyOp(p, NULL, IPP_CREATE_JOB);
+ po->order_type = CUPSD_AUTH_ALLOW;
+
+ cupsdAddPolicyOp(p, po, IPP_PRINT_JOB);
+ cupsdAddPolicyOp(p, po, IPP_PRINT_URI);
+ cupsdAddPolicyOp(p, po, IPP_VALIDATE_JOB);
+
+ cupsdLogMessage(CUPSD_LOG_INFO, "</Limit>");
+
+ cupsdLogMessage(CUPSD_LOG_INFO,
"<Limit Send-Document Send-URI Cancel-Job Hold-Job "
"Release-Job Restart-Job Purge-Jobs "
"Set-Job-Attributes Create-Job-Subscription "
@@ -3682,11 +3695,30 @@ read_policy(cups_file_t *fp, /* I - Configuration file */
linenum);
/*
- * Verify that we have an explicit policy for Cancel-Jobs, Cancel-My-Jobs,
- * Close-Job, and CUPS-Get-Document (ensures that upgrades do not
- * introduce new security issues...)
+ * Verify that we have an explicit policy for Validate-Job, Cancel-Jobs,
+ * Cancel-My-Jobs, Close-Job, and CUPS-Get-Document, which ensures that
+ * upgrades do not introduce new security issues...
*/
+ if ((op = cupsdFindPolicyOp(pol, IPP_VALIDATE_JOB)) == NULL ||
+ op->op == IPP_ANY_OPERATION)
+ {
+ if ((op = cupsdFindPolicyOp(pol, IPP_PRINT_JOB)) != NULL &&
+ op->op != IPP_ANY_OPERATION)
+ {
+ /*
+ * Add a new limit for Validate-Job using the Print-Job limit as a
+ * template...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "No limit for Validate-Job defined in policy %s "
+ "- using Print-Job's policy", pol->name);
+
+ cupsdAddPolicyOp(pol, op, IPP_VALIDATE_JOB);
+ }
+ }
+
if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_JOBS)) == NULL ||
op->op == IPP_ANY_OPERATION)
{
diff --git a/scheduler/cups.xml.in b/scheduler/cups.xml.in
index 81aa0b3ba..211c086b7 100644
--- a/scheduler/cups.xml.in
+++ b/scheduler/cups.xml.in
@@ -116,6 +116,10 @@
type='service'
version='1'>
+ <restarter>
+ <service_fmri value='svc:/network/inetd:default' />
+ </restarter>
+
<dependency
name='filesystem_minimal'
grouping='require_all'
@@ -155,10 +159,6 @@
timeout_seconds='60' />
<instance name='default' enabled='false' >
- <restarter>
- <service_fmri value='svc:/network/inetd:default' />
- </restarter>
-
<dependency
name='cupsd'
grouping='require_all'
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index 3fcabd681..9cc8fbc84 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -1257,7 +1257,7 @@ add_class(cupsd_client_t *con, /* I - Client connection */
if (modify)
{
- cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED | CUPSD_EVENT_PRINTER_CONFIG,
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED,
pclass, NULL, "Class \"%s\" modified by \"%s\".",
pclass->name, get_username(con));
@@ -1268,7 +1268,7 @@ add_class(cupsd_client_t *con, /* I - Client connection */
{
cupsdAddPrinterHistory(pclass);
- cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED | CUPSD_EVENT_PRINTER_CONFIG,
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED,
pclass, NULL, "New class \"%s\" added by \"%s\".",
pclass->name, get_username(con));
@@ -1536,22 +1536,10 @@ add_job(cupsd_client_t *con, /* I - Client connection */
* Do media selection as needed...
*/
- if (!ippFindAttribute(con->request, "InputSlot", IPP_TAG_ZERO) &&
- (ppd = _pwgGetInputSlot(printer->pwg, con->request, NULL)) != NULL)
- ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "InputSlot", NULL,
- ppd);
-
- if (!ippFindAttribute(con->request, "MediaType", IPP_TAG_ZERO) &&
- (ppd = _pwgGetMediaType(printer->pwg, con->request, NULL)) != NULL)
- ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "MediaType", NULL,
- ppd);
-
- if (!ippFindAttribute(con->request, "PageSize", IPP_TAG_ZERO) &&
+ if (!ippFindAttribute(con->request, "PageRegion", IPP_TAG_ZERO) &&
+ !ippFindAttribute(con->request, "PageSize", IPP_TAG_ZERO) &&
(ppd = _pwgGetPageSize(printer->pwg, con->request, NULL, &exact)) != NULL)
{
- ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "PageSize", NULL,
- ppd);
-
if (!exact &&
(media_col = ippFindAttribute(con->request, "media-col",
IPP_TAG_BEGIN_COLLECTION)) != NULL)
@@ -2951,7 +2939,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
{
/*
* If we changed the PPD/interface script, then remove the printer's cache
- * file...
+ * file and clear the printer-state-reasons...
*/
char cache_name[1024]; /* Cache filename for printer attrs */
@@ -2964,6 +2952,8 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
printer->name);
unlink(cache_name);
+ cupsdSetPrinterReasons(printer, "none");
+
#ifdef __APPLE__
/*
* (Re)register color profiles...
@@ -3040,7 +3030,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
if (modify)
{
- cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED | CUPSD_EVENT_PRINTER_CONFIG,
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED,
printer, NULL, "Printer \"%s\" modified by \"%s\".",
printer->name, get_username(con));
@@ -3051,7 +3041,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
{
cupsdAddPrinterHistory(printer);
- cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED | CUPSD_EVENT_PRINTER_CONFIG,
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED,
printer, NULL, "New printer \"%s\" added by \"%s\".",
printer->name, get_username(con));
@@ -9022,7 +9012,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */
type) != 2)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Could not scan type \"%s\""),
+ _("Bad document-format \"%s\""),
format->values[0].string.text);
return;
}
@@ -9038,7 +9028,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */
if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2)
{
send_ipp_status(con, IPP_BAD_REQUEST,
- _("Could not scan type \"%s\""),
+ _("Bad document-format \"%s\""),
default_format);
return;
}
@@ -9103,7 +9093,9 @@ print_job(cupsd_client_t *con, /* I - Client connection */
else if (!filetype)
{
send_ipp_status(con, IPP_DOCUMENT_FORMAT,
- _("Unsupported format \'%s/%s\'"), super, type);
+ _("Unsupported document-format \"%s\""),
+ format ? format->values[0].string.text :
+ "application/octet-stream");
cupsdLogMessage(CUPSD_LOG_INFO,
"Hint: Do you have the raw file printing rules enabled?");
@@ -11696,7 +11688,8 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
ipp_attribute_t *uri) /* I - Printer URI */
{
http_status_t status; /* Policy status */
- ipp_attribute_t *attr; /* Current attribute */
+ ipp_attribute_t *attr, /* Current attribute */
+ *auth_info; /* auth-info attribute */
ipp_attribute_t *format; /* Document-format attribute */
cups_ptype_t dtype; /* Destination type (printer/class) */
char super[MIME_MAX_SUPER],
@@ -11715,15 +11708,21 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
*/
if ((attr = ippFindAttribute(con->request, "compression",
- IPP_TAG_KEYWORD)) != NULL &&
- !strcmp(attr->values[0].string.text, "none"))
+ IPP_TAG_KEYWORD)) != NULL)
{
- send_ipp_status(con, IPP_ATTRIBUTES,
- _("Unsupported compression attribute %s"),
- attr->values[0].string.text);
- ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
- "compression", NULL, attr->values[0].string.text);
- return;
+ if (strcmp(attr->values[0].string.text, "none")
+#ifdef HAVE_LIBZ
+ && strcmp(attr->values[0].string.text, "gzip")
+#endif /* HAVE_LIBZ */
+ )
+ {
+ send_ipp_status(con, IPP_ATTRIBUTES,
+ _("Unsupported compression \"%s\""),
+ attr->values[0].string.text);
+ ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
+ "compression", NULL, attr->values[0].string.text);
+ return;
+ }
}
/*
@@ -11747,7 +11746,7 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_INFO,
"Hint: Do you have the raw file printing rules enabled?");
send_ipp_status(con, IPP_DOCUMENT_FORMAT,
- _("Unsupported format \"%s\""),
+ _("Unsupported document-format \"%s\""),
format->values[0].string.text);
ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
"document-format", NULL, format->values[0].string.text);
@@ -11774,11 +11773,32 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
* Check policy...
*/
+ auth_info = ippFindAttribute(con->request, "auth-info", IPP_TAG_TEXT);
+
if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK)
{
send_http_error(con, status, printer);
return;
}
+ else if (printer->num_auth_info_required == 1 &&
+ !strcmp(printer->auth_info_required[0], "negotiate") &&
+ !con->username[0])
+ {
+ send_http_error(con, HTTP_UNAUTHORIZED, printer);
+ return;
+ }
+#ifdef HAVE_SSL
+ else if (auth_info && !con->http.tls &&
+ !httpAddrLocalhost(con->http.hostaddr))
+ {
+ /*
+ * Require encryption of auth-info over non-local connections...
+ */
+
+ send_http_error(con, HTTP_UPGRADE_REQUIRED, printer);
+ return;
+ }
+#endif /* HAVE_SSL */
/*
* Everything was ok, so return OK status...
diff --git a/scheduler/job.c b/scheduler/job.c
index d5a47756f..9822ac581 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -173,7 +173,7 @@ static void free_job_history(cupsd_job_t *job);
static char *get_options(cupsd_job_t *job, int banner_page, char *copies,
size_t copies_size, char *title,
size_t title_size);
-static int ipp_length(ipp_t *ipp);
+static size_t ipp_length(ipp_t *ipp);
static void load_job_cache(const char *filename);
static void load_next_job_id(const char *filename);
static void load_request_root(void);
@@ -3020,39 +3020,159 @@ get_options(cupsd_job_t *job, /* I - Job */
size_t title_size) /* I - Size of title buffer */
{
int i; /* Looping var */
+ size_t newlength; /* New option buffer length */
char *optptr, /* Pointer to options */
*valptr; /* Pointer in value string */
ipp_attribute_t *attr; /* Current attribute */
+ _pwg_t *pwg; /* PWG->PPD mapping data */
+ int num_pwgppds; /* Number of PWG->PPD options */
+ cups_option_t *pwgppds, /* PWG->PPD options */
+ *pwgppd, /* Current PWG->PPD option */
+ *preset; /* Current preset option */
+ int output_mode, /* Output mode (if any) */
+ print_quality; /* Print quality (if any) */
+ const char *ppd; /* PPD option choice */
+ int exact; /* Did we get an exact match? */
static char *options = NULL;/* Full list of options */
- static int optlength = 0; /* Length of option buffer */
+ static size_t optlength = 0; /* Length of option buffer */
/*
- * Building the options string is harder than it needs to be, but
- * for the moment we need to pass strings for command-line args and
- * not IPP attribute pointers... :)
+ * Building the options string is harder than it needs to be, but for the
+ * moment we need to pass strings for command-line args and not IPP attribute
+ * pointers... :)
*
- * First allocate/reallocate the option buffer as needed...
+ * First build an options array for any PWG->PPD mapped option/choice pairs.
*/
- i = ipp_length(job->attrs);
+ pwg = job->printer->pwg;
+ num_pwgppds = 0;
+ pwgppds = NULL;
- if (i > optlength || !options)
+ if (pwg)
+ {
+ if ((attr = ippFindAttribute(job->attrs, "output-mode",
+ IPP_TAG_KEYWORD)) != NULL &&
+ !strcmp(attr->values[0].string.text, "monochrome"))
+ output_mode = _PWG_OUTPUT_MODE_MONOCHROME;
+ else
+ output_mode = _PWG_OUTPUT_MODE_COLOR;
+
+ if ((attr = ippFindAttribute(job->attrs, "print-quality",
+ IPP_TAG_INTEGER)) != NULL &&
+ attr->values[0].integer >= IPP_QUALITY_DRAFT &&
+ attr->values[0].integer <= IPP_QUALITY_HIGH)
+ print_quality = attr->values[0].integer - IPP_QUALITY_DRAFT;
+ else
+ print_quality = IPP_QUALITY_NORMAL;
+
+ if (pwg->num_presets[output_mode][print_quality] == 0)
+ {
+ /*
+ * Try to find a preset that works so that we maximize the chances of us
+ * getting a good print using IPP attributes.
+ */
+
+ if (pwg->num_presets[output_mode][_PWG_PRINT_QUALITY_NORMAL] > 0)
+ print_quality = _PWG_PRINT_QUALITY_NORMAL;
+ else if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][print_quality] > 0)
+ output_mode = _PWG_OUTPUT_MODE_COLOR;
+ else
+ {
+ print_quality = _PWG_PRINT_QUALITY_NORMAL;
+ output_mode = _PWG_OUTPUT_MODE_COLOR;
+ }
+ }
+
+ if (pwg->num_presets[output_mode][print_quality] > 0)
+ {
+ /*
+ * Copy the preset options as long as the corresponding names are not
+ * already defined in the IPP request...
+ */
+
+ for (i = pwg->num_presets[output_mode][print_quality],
+ preset = pwg->presets[output_mode][print_quality];
+ i > 0;
+ i --, preset ++)
+ {
+ if (!ippFindAttribute(job->attrs, preset->name, IPP_TAG_ZERO))
+ num_pwgppds = cupsAddOption(preset->name, preset->value, num_pwgppds,
+ &pwgppds);
+ }
+ }
+
+ if (pwg->sides_option &&
+ !ippFindAttribute(job->attrs, pwg->sides_option, IPP_TAG_ZERO) &&
+ (attr = ippFindAttribute(job->attrs, "sides", IPP_TAG_KEYWORD)) != NULL)
+ {
+ /*
+ * Add a duplex option...
+ */
+
+ if (!strcmp(attr->values[0].string.text, "one-sided"))
+ num_pwgppds = cupsAddOption(pwg->sides_option, pwg->sides_1sided,
+ num_pwgppds, &pwgppds);
+ else if (!strcmp(attr->values[0].string.text, "two-sided-long-edge"))
+ num_pwgppds = cupsAddOption(pwg->sides_option, pwg->sides_2sided_long,
+ num_pwgppds, &pwgppds);
+ else if (!strcmp(attr->values[0].string.text, "two-sided-short-edge"))
+ num_pwgppds = cupsAddOption(pwg->sides_option, pwg->sides_2sided_short,
+ num_pwgppds, &pwgppds);
+ }
+ }
+
+ if (!ippFindAttribute(job->attrs, "InputSlot", IPP_TAG_ZERO) &&
+ (ppd = _pwgGetInputSlot(job->printer->pwg, job->attrs, NULL)) != NULL)
+ num_pwgppds = cupsAddOption("InputSlot", ppd, num_pwgppds, &pwgppds);
+
+ if (!ippFindAttribute(job->attrs, "MediaType", IPP_TAG_ZERO) &&
+ (ppd = _pwgGetMediaType(job->printer->pwg, job->attrs, NULL)) != NULL)
+ num_pwgppds = cupsAddOption("MediaType", ppd, num_pwgppds, &pwgppds);
+
+ if (!ippFindAttribute(job->attrs, "PageRegion", IPP_TAG_ZERO) &&
+ !ippFindAttribute(job->attrs, "PageSize", IPP_TAG_ZERO) &&
+ (ppd = _pwgGetPageSize(job->printer->pwg, job->attrs, NULL,
+ &exact)) != NULL)
+ num_pwgppds = cupsAddOption("PageSize", ppd, num_pwgppds, &pwgppds);
+
+ if (!ippFindAttribute(job->attrs, "OutputBin", IPP_TAG_ZERO) &&
+ (attr = ippFindAttribute(job->attrs, "output-bin",
+ IPP_TAG_ZERO)) != NULL &&
+ (attr->value_tag == IPP_TAG_KEYWORD || attr->value_tag == IPP_TAG_NAME) &&
+ (ppd = _pwgGetOutputBin(pwg, attr->values[0].string.text)) != NULL)
+ num_pwgppds = cupsAddOption("OutputBin", ppd, num_pwgppds, &pwgppds);
+
+ /*
+ * Figure out how much room we need...
+ */
+
+ newlength = ipp_length(job->attrs);
+
+ for (i = num_pwgppds, pwgppd = pwgppds; i > 0; i --, pwgppd ++)
+ newlength += 1 + strlen(pwgppd->name) + 1 + strlen(pwgppd->value);
+
+ /*
+ * Then allocate/reallocate the option buffer as needed...
+ */
+
+ if (newlength > optlength || !options)
{
if (!options)
- optptr = malloc(i);
+ optptr = malloc(newlength);
else
- optptr = realloc(options, i);
+ optptr = realloc(options, newlength);
if (!optptr)
{
cupsdLogJob(job, CUPSD_LOG_CRIT,
- "Unable to allocate %d bytes for option buffer!", i);
+ "Unable to allocate " CUPS_LLFMT " bytes for option buffer!",
+ CUPS_LLCAST newlength);
return (NULL);
}
options = optptr;
- optlength = i;
+ optlength = newlength;
}
/*
@@ -3088,7 +3208,8 @@ get_options(cupsd_job_t *job, /* I - Job */
* Filter out other unwanted attributes...
*/
- if (attr->value_tag == IPP_TAG_MIMETYPE ||
+ if (attr->value_tag == IPP_TAG_NOVALUE ||
+ attr->value_tag == IPP_TAG_MIMETYPE ||
attr->value_tag == IPP_TAG_NAMELANG ||
attr->value_tag == IPP_TAG_TEXTLANG ||
(attr->value_tag == IPP_TAG_URI && strcmp(attr->name, "job-uuid")) ||
@@ -3096,8 +3217,7 @@ get_options(cupsd_job_t *job, /* I - Job */
attr->value_tag == IPP_TAG_BEGIN_COLLECTION) /* Not yet supported */
continue;
- if (!strncmp(attr->name, "time-", 5) ||
- !strcmp(attr->name, "job-hold-until"))
+ if (!strcmp(attr->name, "job-hold-until"))
continue;
if (!strncmp(attr->name, "job-", 4) &&
@@ -3155,11 +3275,6 @@ get_options(cupsd_job_t *job, /* I - Job */
if (!attr->values[i].boolean)
strlcat(optptr, "no", optlength - (optptr - options));
- case IPP_TAG_NOVALUE :
- strlcat(optptr, attr->name,
- optlength - (optptr - options));
- break;
-
case IPP_TAG_RANGE :
if (attr->values[i].range.lower == attr->values[i].range.upper)
snprintf(optptr, optlength - (optptr - options) - 1,
@@ -3204,6 +3319,25 @@ get_options(cupsd_job_t *job, /* I - Job */
}
}
+ /*
+ * Finally loop through the PWG->PPD mapped options and add them...
+ */
+
+ for (i = num_pwgppds, pwgppd = pwgppds; i > 0; i --, pwgppd ++)
+ {
+ *optptr++ = ' ';
+ strcpy(optptr, pwgppd->name);
+ optptr += strlen(optptr);
+ *optptr++ = '=';
+ strcpy(optptr, pwgppd->value);
+ optptr += strlen(optptr);
+ }
+
+ cupsFreeOptions(num_pwgppds, pwgppds);
+
+ /*
+ * Return the options string...
+ */
return (options);
}
@@ -3214,10 +3348,10 @@ get_options(cupsd_job_t *job, /* I - Job */
* the textual IPP attributes.
*/
-static int /* O - Size of attribute buffer */
+static size_t /* O - Size of attribute buffer */
ipp_length(ipp_t *ipp) /* I - IPP request */
{
- int bytes; /* Number of bytes */
+ size_t bytes; /* Number of bytes */
int i; /* Looping var */
ipp_attribute_t *attr; /* Current attribute */
@@ -3234,16 +3368,14 @@ ipp_length(ipp_t *ipp) /* I - IPP request */
* Skip attributes that won't be sent to filters...
*/
- if (attr->value_tag == IPP_TAG_MIMETYPE ||
+ if (attr->value_tag == IPP_TAG_NOVALUE ||
+ attr->value_tag == IPP_TAG_MIMETYPE ||
attr->value_tag == IPP_TAG_NAMELANG ||
attr->value_tag == IPP_TAG_TEXTLANG ||
attr->value_tag == IPP_TAG_URI ||
attr->value_tag == IPP_TAG_URISCHEME)
continue;
- if (strncmp(attr->name, "time-", 5) == 0)
- continue;
-
/*
* Add space for a leading space and commas between each value.
* For the first attribute, the leading space isn't used, so the
diff --git a/scheduler/main.c b/scheduler/main.c
index 6b2283c4b..8248c526c 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -770,8 +770,7 @@ main(int argc, /* I - Number of command-line args */
!cupsArrayCount(ActiveJobs) &&
(!Browsing ||
(!BrowseRemoteProtocols &&
- (!NumBrowsers || !BrowseLocalProtocols ||
- cupsArrayCount(Printers) == 0))))
+ (!BrowseLocalProtocols || !cupsArrayCount(Printers)))))
{
timeout = LaunchdTimeout;
launchd_idle_exit = 1;
@@ -1621,10 +1620,10 @@ launchd_checkout(void)
* shared printers to advertise...
*/
- if ((cupsArrayCount(ActiveJobs) || NumPolled ||
- (Browsing &&
- (BrowseRemoteProtocols ||
- (BrowseLocalProtocols && NumBrowsers && cupsArrayCount(Printers))))))
+ if (cupsArrayCount(ActiveJobs) || NumPolled ||
+ (Browsing &&
+ (BrowseRemoteProtocols ||
+ (BrowseLocalProtocols && cupsArrayCount(Printers)))))
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
"Creating launchd keepalive file \"" CUPS_KEEPALIVE
diff --git a/scheduler/printers.c b/scheduler/printers.c
index f11d9e758..76eb86028 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -2683,8 +2683,8 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
int /* O - 1 if something changed, 0 otherwise */
cupsdSetPrinterReasons(
- cupsd_printer_t *p, /* I - Printer */
- const char *s) /* I - Reasons strings */
+ cupsd_printer_t *p, /* I - Printer */
+ const char *s) /* I - Reasons strings */
{
int i, /* Looping var */
changed = 0; /* Did something change? */
diff --git a/scheduler/select.c b/scheduler/select.c
index cc553754f..03e47437a 100644
--- a/scheduler/select.c
+++ b/scheduler/select.c
@@ -3,7 +3,7 @@
*
* Select abstraction functions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007-2009 by Apple Inc.
+ * Copyright 2007-2010 by Apple Inc.
* Copyright 2006-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -241,11 +241,11 @@ static fd_set cupsd_global_input,
static int compare_fds(_cupsd_fd_t *a, _cupsd_fd_t *b);
static _cupsd_fd_t *find_fd(int fd);
-#define release_fd(f) { \
+#define release_fd(f) { \
(f)->use --; \
if (!(f)->use) free((f));\
}
-#define retain_fd(f) (f)->use++
+#define retain_fd(f) (f)->use++
/*
@@ -454,7 +454,8 @@ cupsdDoSelect(long timeout) /* I - Timeout in seconds */
if (fdptr->read_cb && event->filter == EVFILT_READ)
(*(fdptr->read_cb))(fdptr->data);
- if (fdptr->use > 1 && fdptr->write_cb && event->filter == EVFILT_WRITE)
+ if (fdptr->use > 1 && fdptr->write_cb && event->filter == EVFILT_WRITE &&
+ !cupsArrayFind(cupsd_inactive_fds, fdptr))
(*(fdptr->write_cb))(fdptr->data);
release_fd(fdptr);
@@ -500,7 +501,8 @@ cupsdDoSelect(long timeout) /* I - Timeout in seconds */
(*(fdptr->read_cb))(fdptr->data);
if (fdptr->use > 1 && fdptr->write_cb &&
- (event->events & (EPOLLOUT | EPOLLERR | EPOLLHUP)))
+ (event->events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) &&
+ !cupsArrayFind(cupsd_inactive_fds, fdptr))
(*(fdptr->write_cb))(fdptr->data);
release_fd(fdptr);
diff --git a/templates/admin.tmpl b/templates/admin.tmpl
index da89d54e2..477da139e 100644
--- a/templates/admin.tmpl
+++ b/templates/admin.tmpl
@@ -105,6 +105,6 @@
<THEAD><TR><TH>Name</TH><TH>Events</TH><TH>Queue Name</TH></TR></THEAD>
<TBODY>{[notify_subscription_id]
<TR><TD><A HREF="{notify_recipient_uri}">{notify_recipient_name}</A><BR>
-<FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="cancel-subscription"><INPUT TYPE="HIDDEN" NAME="notify_subscription_id" VALUE="{notify_subscription_id}"><INPUT TYPE="SUBMIT" VALUE="Cancel RSS Subscription"></FORM>&nbsp;</TD><TD>{notify_events}</TD><TD NOWRAP>&nbsp;{notify_printer_name?{notify_printer_name}:All Queues}</TD></TR>}
+<FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="org.cups.sid" VALUE="{$org.cups.sid}"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="cancel-subscription"><INPUT TYPE="HIDDEN" NAME="notify_subscription_id" VALUE="{notify_subscription_id}"><INPUT TYPE="SUBMIT" VALUE="Cancel RSS Subscription"></FORM>&nbsp;</TD><TD>{notify_events}</TD><TD NOWRAP>&nbsp;{notify_printer_name?{notify_printer_name}:All Queues}</TD></TR>}
</TBODY>
</TABLE>:}
diff --git a/test/ipp-1.1.test b/test/ipp-1.1.test
index a92a09dc4..fb1caf849 100644
--- a/test/ipp-1.1.test
+++ b/test/ipp-1.1.test
@@ -567,7 +567,7 @@
ATTR uri printer-uri $uri
ATTR name requesting-user-name $user
ATTR keyword which-jobs completed
- DELAY 10
+ DELAY 20
STATUS successful-ok
EXPECT job-id OF-TYPE integer IN-GROUP job-attributes-tag COUNT 1 WITH-VALUE >0
diff --git a/test/print-job-hold.test b/test/print-job-hold.test
index a46827928..d70e523e7 100644
--- a/test/print-job-hold.test
+++ b/test/print-job-hold.test
@@ -1,16 +1,13 @@
# Test print-job and job-hold-until attribute
{
# The name of the test...
- NAME "Print with print-job + job-hold-until"
-
- # The resource to use for the POST
- # RESOURCE /admin
+ NAME "Print-Job w/job-hold-until=indefinite"
# The operation to use
- OPERATION print-job
+ OPERATION Print-Job
# Attributes, starting in the operation group...
- GROUP operation
+ GROUP operation-attributes-tag
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $uri
@@ -21,10 +18,24 @@
FILE $filename
# What statuses are OK?
- STATUS ok
- STATUS ok-subst
+ STATUS successful-ok
+ STATUS successful-ok-ignored-or-substituted-attributes
# What attributes do we expect?
EXPECT job-id
EXPECT job-uri
}
+{
+ NAME "Release-Job"
+ OPERATION Release-Job
+
+ GROUP operation-attributes-tag
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR integer job-id $job-id
+ ATTR name requesting-user-name $user
+
+ # What statuses are OK?
+ STATUS successful-ok
+}
diff --git a/test/run-stp-tests.sh b/test/run-stp-tests.sh
index 11a011608..013e4283b 100755
--- a/test/run-stp-tests.sh
+++ b/test/run-stp-tests.sh
@@ -803,7 +803,7 @@ if grep -iq 'testfile.pdf na_letter_8.5x11in' /tmp/cups-$user/log/page_log; then
echo "<P>PASS: page_log formatted correctly.</P>" >>$strfile
else
echo "FAIL: page_log formatted incorrectly."
- echo "<P>FAIL: page_log formatted incorrectly.</P>" >>$strfile
+ echo "<P>FAIL: page_log formatted incorrectly - no page size information.</P>" >>$strfile
fail=`expr $fail + 1`
fi
diff --git a/tools/makeipptoolpkg b/tools/makeipptoolpkg
index 62cd199f2..1fe318380 100644
--- a/tools/makeipptoolpkg
+++ b/tools/makeipptoolpkg
@@ -28,7 +28,7 @@ if test $# = 0; then
svn up
rev=`svnversion . | sed -e '1,$s/[a-zA-Z]//g'`
fileversion="1.5svn-r$rev"
- version=snapshot
+ version=snapshots
else
fileversion=$1
version=$1
diff --git a/vcnet/libcups2.vcproj b/vcnet/libcups2.vcproj
index 13fa19872..17f8d67aa 100644
--- a/vcnet/libcups2.vcproj
+++ b/vcnet/libcups2.vcproj
@@ -1302,6 +1302,10 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\cups\sspi.c"
+ >
+ </File>
+ <File
RelativePath="..\cups\string.c"
>
<FileConfiguration
@@ -1374,6 +1378,10 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\cups\thread.c"
+ >
+ </File>
+ <File
RelativePath="..\cups\transcode.c"
>
<FileConfiguration
@@ -1572,10 +1580,18 @@
>
</File>
<File
+ RelativePath="..\cups\sspi-private.h"
+ >
+ </File>
+ <File
RelativePath="..\cups\string.h"
>
</File>
<File
+ RelativePath="..\cups\thread-private.h"
+ >
+ </File>
+ <File
RelativePath="..\cups\transcode.h"
>
</File>