From c7017eccd21da514f345a5c7a41156b1adf7cb35 Mon Sep 17 00:00:00 2001 From: msweet Date: Thu, 8 Jul 2010 20:45:48 +0000 Subject: [PATCH] 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 --- CHANGES-1.4.txt | 33 +++- CHANGES.txt | 5 +- backend/ipp.c | 51 ++++-- backend/lpd.c | 58 ++++--- backend/pap.c | 20 +-- backend/runloop.c | 2 +- backend/serial.c | 7 +- backend/socket.c | 37 +++-- backend/usb-darwin.c | 123 ++------------- backend/usb.c | 4 +- cgi-bin/admin.c | 6 +- cgi-bin/ipp-var.c | 8 +- cgi-bin/var.c | 5 +- conf/cupsd.conf.in | 6 +- config-scripts/cups-common.m4 | 8 + config-scripts/cups-sharedlibs.m4 | 15 ++ config-scripts/cups-ssl.m4 | 43 +++-- config.h.in | 15 ++ configure.in | 3 +- cups-config.in | 10 +- cups/dest.c | 3 +- cups/file.c | 110 ++++++++++++- cups/globals.c | 2 + cups/http-support.c | 3 + cups/http.c | 2 +- cups/http.h | 2 +- cups/ipp.h | 4 +- cups/language.c | 8 + cups/mark.c | 160 +++---------------- cups/ppd-private.h | 59 ++++++- cups/ppd.h | 2 +- cups/pwg-file.c | 72 ++++++++- cups/pwg-ppd.c | 200 ++++++++++++++++++++++-- cups/pwg-private.h | 39 +---- cups/raster.h | 58 ++++--- cups/testfile.c | 14 +- cups/thread-private.h | 86 ++++++++++ cups/thread.c | 144 +++++++++++++++++ cups/versioning.h | 2 + doc/Makefile | 1 - doc/help/spec-ppd.html | 88 ++++++++--- driver/rastertoescpx.c | 12 +- driver/rastertopclx.c | 12 +- filter/imagetoraster.c | 57 +++++-- filter/pdftops.c | 16 +- filter/pstops.c | 48 +++--- filter/raster.c | 26 ++- filter/rastertoepson.c | 19 ++- filter/rastertohp.c | 15 +- filter/rastertolabel.c | 20 ++- filter/texttops.c | 18 ++- man/Makefile | 1 - man/drv.man.in | 40 ----- notifier/mailto.c | 6 +- packaging/cups.list.in | 2 - ppdc/ppdc-source.cxx | 16 +- scheduler/auth.c | 71 ++++++++- scheduler/client.c | 252 +++++++++++++++++++++--------- scheduler/conf.c | 38 ++++- scheduler/cups.xml.in | 8 +- scheduler/ipp.c | 84 ++++++---- scheduler/job.c | 184 +++++++++++++++++++--- scheduler/main.c | 11 +- scheduler/printers.c | 4 +- scheduler/select.c | 12 +- templates/admin.tmpl | 2 +- test/ipp-1.1.test | 2 +- test/print-job-hold.test | 27 +++- test/run-stp-tests.sh | 2 +- tools/makeipptoolpkg | 2 +- vcnet/libcups2.vcproj | 16 ++ 71 files changed, 1820 insertions(+), 721 deletions(-) create mode 100644 cups/thread-private.h create mode 100644 cups/thread.c delete mode 100644 man/drv.man.in 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 #include #include +#include #ifdef WIN32 # include @@ -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 #ifdef __hpux # include @@ -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); @@ -750,86 +734,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... # Job-related operations must be done by the owner or an administrator... + + Order deny,allow + + Require user @OWNER @SYSTEM Order deny,allow @@ -79,7 +83,7 @@ DefaultAuthType Basic # Set the authenticated printer/job policies... # Job-related operations must be done by the owner or an administrator... - + AuthType Default Order deny,allow 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 ],[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 ],[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 @@ -302,6 +303,13 @@ #undef HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY +/* + * Do we have the SecPolicyCreateSSL function? + */ + +#undef HAVE_SECPOLICYCREATESSL + + /* * Do we have the SLP library? */ @@ -342,6 +350,13 @@ #undef HAVE_SYS_IOCTL_H +/* + * 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 +#include /* @@ -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 */ @@ -2208,6 +2226,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 # include # 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 */ /* @@ -547,6 +583,38 @@ _pwgWriteFile(_pwg_t *pwg, /* I - PWG mapping data */ cupsFilePrintf(fp, "Type %s %s\n", map->pwg, map->ppd); } + /* + * 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 +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 +# include +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 + + +/* + * '_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 @@