From c8fef167ba1e9d5d87fc77e4e99ca12ba9384cbb Mon Sep 17 00:00:00 2001 From: msweet Date: Fri, 25 Feb 2011 01:40:44 +0000 Subject: [PATCH] Merge changes from CUPS 1.5svn-r9567 git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@3015 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES-1.4.txt | 9 +- CHANGES.txt | 13 +- backend/backend-private.h | 20 +- backend/ipp.c | 163 ++++++--- backend/lpd.c | 176 ++++----- backend/parallel.c | 4 +- backend/runloop.c | 125 ++++++- backend/serial.c | 12 +- backend/snmp-supplies.c | 143 ++++++-- backend/socket.c | 46 ++- backend/usb-unix.c | 6 +- config.h.in | 1 + cups/Makefile | 2 +- cups/adminutil.c | 2 +- cups/cups-private.h | 15 +- cups/dest.c | 712 ++++++++++++++++++++---------------- cups/http-private.h | 3 +- cups/http.c | 35 +- cups/langprintf.c | 3 +- cups/language.c | 111 +++++- cups/libcups2.def | 18 + cups/libcups_s.exp | 3 + cups/raster.h | 22 +- cups/testppd.c | 17 +- doc/eu/index.html.in | 2 +- doc/help/api-raster.html | 55 ++- doc/help/options.html | 4 +- doc/help/spec-ppd.html | 101 +++-- filter/bannertops.c | 2 + filter/error.c | 2 +- filter/gziptoany.c | 8 +- filter/interpret.c | 46 ++- filter/pstext.c | 8 +- filter/raster.c | 270 ++++++++++---- filter/spec-ppd.shtml | 99 +++-- filter/testraster.c | 6 +- ppdc/sample.drv | 18 +- scheduler/auth.c | 110 ++++-- scheduler/client.c | 9 +- scheduler/conf.c | 91 ++--- scheduler/ipp.c | 10 +- scheduler/job.c | 10 +- scheduler/log.c | 5 +- scheduler/printers.c | 186 +++++++--- scheduler/printers.h | 5 +- scheduler/process.c | 45 ++- test/ipptool.c | 17 +- test/testhp.ppd | 11 +- tools/makeipptoolpkg | 3 +- vc2005/cups.sln | 22 +- vc2005/cupstestppd.vcproj | 173 ++++++++- vc2005/libcups2.vcproj | 218 ++++++----- vc2005/libcupsimage2.vcproj | 395 ++++++++++++++++++++ vcnet/cups.sln | 28 +- vcnet/cupstestppd.vcproj | 171 ++++++++- vcnet/ipptool.vcproj | 155 ++++++++ vcnet/libcups2.vcproj | 6 +- vcnet/libcupsimage2.vcproj | 388 ++++++++++++++++++++ 58 files changed, 3278 insertions(+), 1062 deletions(-) create mode 100644 vc2005/libcupsimage2.vcproj create mode 100644 vcnet/libcupsimage2.vcproj diff --git a/CHANGES-1.4.txt b/CHANGES-1.4.txt index ece5fcb70..3259a2970 100644 --- a/CHANGES-1.4.txt +++ b/CHANGES-1.4.txt @@ -4,11 +4,16 @@ CHANGES-1.4.txt CHANGES IN CUPS V1.4.7 - Documentation changes (STR #3710, STR #3720, STR #3745, STR #3750, - STR #3757, STR #3758) + STR #3757, STR #3758, STR #3782) - Web interface fixes (STR #3412, STR #3345, STR #3455, STR #3707, - STR #3755, STR #3769) + STR #3755, STR #3769, STR #3783) - Configure script fixes (STR #3659, STR #3691) - Compilation fixes (STR #3718, STR #3771, STR #3774) + - The gziptoany filter did not report the correct error if it was unable + to write the uncompressed document to the next filter or backend in + the chain (STR #3797) + - The Epson and Oki 9-pin drivers had a bad resolution option + (STR #3798) - The scheduler did not always register the correct default ICC profile on Mac OS X. - The scheduler did not use the job owner when authorizing access for diff --git a/CHANGES.txt b/CHANGES.txt index 6e2297203..662d77602 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,8 +1,17 @@ -CHANGES.txt - 2011-01-21 +CHANGES.txt - 2011-02-21 ------------------------ CHANGES IN CUPS V1.5b1 + - Added support for a new cupsIPPSupplies keyword in PPD files to allow + drivers to disable IPP supply level reporting. + - Added support for a new cupsFilter2 keyword in PPD files to allow for + the propagation of the actual MIME media type produced by a filter. + - The scheduler did not always get the correct Kerberos username when + authenticating (STR #3670) + - Added new cupsRasterOpenIO function and CUPS_RASTER_WRITE_PWG to the + CUPS imaging library to support printing to IPP Everywhere raster + printers. - The scheduler now provides default values for the pages-per-minute and pages-per-minute-color attributes for PPD files that lack a Throughput keyword. @@ -21,7 +30,7 @@ CHANGES IN CUPS V1.5b1 elements. - 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. + 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/backend-private.h b/backend/backend-private.h index cd1586f97..47f9b32ce 100644 --- a/backend/backend-private.h +++ b/backend/backend-private.h @@ -276,6 +276,14 @@ extern "C" { #define CUPS_TC_csUTF32LE 1019 +/* + * Types... + */ + +typedef int (*_cups_sccb_t)(int print_fd, int device_fd, int snmp_fd, + http_addr_t *addr, int use_bc); + + /* * Prototypes... */ @@ -295,16 +303,14 @@ extern int backendNetworkSideCB(int print_fd, int device_fd, int snmp_fd, http_addr_t *addr, int use_bc); extern ssize_t backendRunLoop(int print_fd, int device_fd, int snmp_fd, - http_addr_t *addr, int use_bc, - int update_state, - int (*side_cb)(int print_fd, - int device_fd, - int snmp_fd, - http_addr_t *addr, - int use_bc)); + http_addr_t *addr, int use_bc, + int update_state, _cups_sccb_t side_cb); extern int backendSNMPSupplies(int snmp_fd, http_addr_t *addr, int *page_count, int *printer_state); +extern int backendWaitLoop(int snmp_fd, http_addr_t *addr, + _cups_sccb_t side_cb); + # ifdef __cplusplus } diff --git a/backend/ipp.c b/backend/ipp.c index 13a688574..fb172cd2d 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -86,6 +86,7 @@ static const char * const pattrs[] = /* Printer attributes we want */ "marker-names", "marker-types", "media-col-supported", + "operations-supported", "printer-alert", "printer-alert-description", "printer-is-accepting-jobs", @@ -148,6 +149,7 @@ main(int argc, /* I - Number of command-line args */ *name, /* Name of option */ *value, /* Value of option */ sep; /* Separator character */ + http_addrlist_t *addrlist; /* Address of printer */ int snmp_fd, /* SNMP socket */ start_count, /* Page count via SNMP at start */ page_count, /* Page count via SNMP */ @@ -155,6 +157,7 @@ main(int argc, /* I - Number of command-line args */ int num_files; /* Number of files to print */ char **files; /* Files to print */ int port; /* Port number (not used) */ + char portname[255]; /* Port name */ char uri[HTTP_MAX_URI]; /* Updated URI without user/pass */ http_status_t http_status; /* Status of HTTP request */ ipp_status_t ipp_status; /* Status of IPP request */ @@ -503,29 +506,69 @@ main(int argc, /* I - Number of command-line args */ } /* - * Try connecting to the remote server... + * Try finding the remote server... */ - delay = 5; start_time = time(NULL); + sprintf(portname, "%d", port); + fputs("STATE: +connecting-to-device\n", stderr); + fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); + + while ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL) + { + _cupsLangPrintFilter(stderr, "INFO", + _("Unable to locate printer \"%s\"."), hostname); + sleep(10); + + if (getenv("CLASS") != NULL) + { + fputs("STATE: -connecting-to-device\n", stderr); + return (CUPS_BACKEND_STOP); + } + } + + http = _httpCreate(hostname, port, addrlist, cupsEncryption(), AF_UNSPEC); + + /* + * See if the printer supports SNMP... + */ + + if ((snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family)) >= 0) + { + have_supplies = !backendSNMPSupplies(snmp_fd, &(addrlist->addr), + &start_count, NULL); + } + else + have_supplies = start_count = 0; + + /* + * Wait for data from the filter... + */ + + if (num_files == 0) + if (!backendWaitLoop(snmp_fd, &(addrlist->addr), backendNetworkSideCB)) + return (CUPS_BACKEND_OK); + + /* + * Try connecting to the remote server... + */ + + delay = 5; do { fprintf(stderr, "DEBUG: Connecting to %s:%d\n", hostname, port); _cupsLangPrintFilter(stderr, "INFO", _("Connecting to printer.")); - if ((http = httpConnectEncrypt(hostname, port, - cupsEncryption())) == NULL) + if (httpReconnect(http)) { -#if 0 /* These need to go in here someplace when we see HTTP_PKI_ERROR or IPP_PKI_ERROR */ - fputs("STATE: +cups-certificate-error\n", stderr); - fputs("STATE: -cups-certificate-error\n", stderr); -#endif /* 0 */ - int error = errno; /* Connection error */ + if (http->status == HTTP_PKI_ERROR) + fputs("STATE: +cups-certificate-error\n", stderr); + if (job_canceled) break; @@ -548,6 +591,8 @@ main(int argc, /* I - Number of command-line args */ sleep(5); + fputs("STATE: -connecting-to-device\n", stderr); + return (CUPS_BACKEND_FAILED); } @@ -560,6 +605,7 @@ main(int argc, /* I - Number of command-line args */ { _cupsLangPrintFilter(stderr, "ERROR", _("The printer is not responding.")); + fputs("STATE: -connecting-to-device\n", stderr); return (CUPS_BACKEND_FAILED); } @@ -591,13 +637,6 @@ main(int argc, /* I - Number of command-line args */ if (delay < 30) delay += 5; } - else if (h_errno) - { - _cupsLangPrintFilter(stderr, "ERROR", - _("Unable to locate network printer \"%s\"."), - hostname); - return (CUPS_BACKEND_STOP); - } else { _cupsLangPrintFilter(stderr, "ERROR", @@ -609,8 +648,10 @@ main(int argc, /* I - Number of command-line args */ if (job_canceled) break; } + else + fputs("STATE: -cups-certificate-error\n", stderr); } - while (http == NULL); + while (http->fd < 0); if (job_canceled || !http) return (CUPS_BACKEND_FAILED); @@ -630,16 +671,6 @@ main(int argc, /* I - Number of command-line args */ httpAddrString(http->hostaddr, addrname, sizeof(addrname)), ntohs(http->hostaddr->ipv4.sin_port)); - /* - * See if the printer supports SNMP... - */ - - if ((snmp_fd = _cupsSNMPOpen(http->hostaddr->addr.sa_family)) >= 0) - have_supplies = !backendSNMPSupplies(snmp_fd, http->hostaddr, &start_count, - NULL); - else - have_supplies = start_count = 0; - /* * Build a URI for the printer and fill the standard IPP attributes for * an IPP_PRINT_FILE request. We can't use the URI in argv[0] because it @@ -957,6 +988,17 @@ main(int argc, /* I - Number of command-line args */ document_format = final_content_type; break; } + + if (!document_format) + { + for (i = 0; i < format_sup->num_values; i ++) + if (!strcasecmp("application/octet-stream", + format_sup->values[i].string.text)) + { + document_format = "application/octet-stream"; + break; + } + } } /* @@ -991,7 +1033,8 @@ main(int argc, /* I - Number of command-line args */ ipp_status = cupsLastError(); - if (ipp_status > IPP_OK_CONFLICT) + if (ipp_status > IPP_OK_CONFLICT && + ipp_status != IPP_OPERATION_NOT_SUPPORTED) { if (job_canceled) break; @@ -1330,7 +1373,7 @@ main(int argc, /* I - Number of command-line args */ if (job_state->values[0].integer > IPP_JOB_STOPPED) { - if ((job_sheets = ippFindAttribute(response, + if ((job_sheets = ippFindAttribute(response, "job-media-sheets-completed", IPP_TAG_INTEGER)) != NULL) fprintf(stderr, "PAGE: total %d\n", @@ -1394,7 +1437,7 @@ main(int argc, /* I - Number of command-line args */ * Collect the final page count as needed... */ - if (have_supplies && + if (have_supplies && !backendSNMPSupplies(snmp_fd, http->hostaddr, &page_count, NULL) && page_count > start_count) fprintf(stderr, "PAGE: total %d\n", page_count - start_count); @@ -1644,7 +1687,7 @@ monitor_printer( * Make a copy of the printer connection... */ - http = _httpCreate(monitor->hostname, monitor->port, monitor->encryption, + http = _httpCreate(monitor->hostname, monitor->port, NULL, monitor->encryption, AF_UNSPEC); cupsSetPasswordCB(password_cb); @@ -1754,7 +1797,7 @@ new_request( int num_options, /* I - Number of options to send */ cups_option_t *options, /* I - Options to send */ const char *compression, /* I - compression value or NULL */ - int copies, /* I - copies value or 0 */ + int copies, /* I - copies value or 0 */ const char *format, /* I - documet-format value or NULL */ _pwg_t *pwg, /* I - PWG<->PPD mapping data */ ipp_attribute_t *media_col_sup) /* I - media-col-supported values */ @@ -2083,6 +2126,8 @@ report_printer_state(ipp_t *ipp, /* I - IPP response */ const char *prefix; /* Prefix for STATE: line */ char value[1024], /* State/message string */ *valptr; /* Pointer into string */ + static int ipp_supplies = -1; + /* Report supply levels? */ /* @@ -2166,23 +2211,43 @@ report_printer_state(ipp_t *ipp, /* I - IPP response */ * Relay the current marker-* attribute values... */ - if ((marker = ippFindAttribute(ipp, "marker-colors", IPP_TAG_NAME)) != NULL) - report_attr(marker); - if ((marker = ippFindAttribute(ipp, "marker-high-levels", - IPP_TAG_INTEGER)) != NULL) - report_attr(marker); - if ((marker = ippFindAttribute(ipp, "marker-levels", - IPP_TAG_INTEGER)) != NULL) - report_attr(marker); - if ((marker = ippFindAttribute(ipp, "marker-low-levels", - IPP_TAG_INTEGER)) != NULL) - report_attr(marker); - if ((marker = ippFindAttribute(ipp, "marker-message", IPP_TAG_TEXT)) != NULL) - report_attr(marker); - if ((marker = ippFindAttribute(ipp, "marker-names", IPP_TAG_NAME)) != NULL) - report_attr(marker); - if ((marker = ippFindAttribute(ipp, "marker-types", IPP_TAG_KEYWORD)) != NULL) - report_attr(marker); + if (ipp_supplies < 0) + { + ppd_file_t *ppd; /* PPD file */ + ppd_attr_t *ppdattr; /* Attribute in PPD file */ + + if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL && + (ppdattr = ppdFindAttr(ppd, "cupsIPPSupplies", NULL)) != NULL && + ppdattr->value && strcasecmp(ppdattr->value, "true")) + ipp_supplies = 0; + else + ipp_supplies = 1; + + ppdClose(ppd); + } + + if (ipp_supplies > 0) + { + if ((marker = ippFindAttribute(ipp, "marker-colors", IPP_TAG_NAME)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-high-levels", + IPP_TAG_INTEGER)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-levels", + IPP_TAG_INTEGER)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-low-levels", + IPP_TAG_INTEGER)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-message", + IPP_TAG_TEXT)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-names", IPP_TAG_NAME)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-types", + IPP_TAG_KEYWORD)) != NULL) + report_attr(marker); + } return (count); } diff --git a/backend/lpd.c b/backend/lpd.c index 914ffc2cf..702c0fb9d 100644 --- a/backend/lpd.c +++ b/backend/lpd.c @@ -88,11 +88,12 @@ static int abort_job = 0; /* Non-zero if we get SIGTERM */ */ static int lpd_command(int lpd_fd, int timeout, char *format, ...); -static int lpd_queue(const char *hostname, int port, const char *printer, - int print_fd, int mode, const char *user, - const char *title, int copies, int banner, - int format, int order, int reserve, - int manual_copies, int timeout, int contimeout); +static int lpd_queue(const char *hostname, http_addrlist_t *addrlist, + const char *printer, int print_fd, int snmp_fd, + int mode, const char *user, const char *title, + int copies, int banner, int format, int order, + int reserve, int manual_copies, int timeout, + int contimeout); static void lpd_timeout(int sig); static int lpd_write(int lpd_fd, char *buffer, int length); #ifndef HAVE_RRESVPORT_AF @@ -125,6 +126,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ *filename, /* File to print */ title[256]; /* Title string */ int port; /* Port number */ + char portname[256]; /* Port name (string) */ + http_addrlist_t *addrlist; /* List of addresses for printer */ + int snmp_fd; /* SNMP socket */ int fd; /* Print file */ int status; /* Status of LPD job */ int mode; /* Print mode */ @@ -398,6 +402,38 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ if (mode == MODE_STREAM) order = ORDER_CONTROL_DATA; + /* + * Find the printer... + */ + + snprintf(portname, sizeof(portname), "%d", port); + + fputs("STATE: +connecting-to-device\n", stderr); + fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); + + while ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL) + { + _cupsLangPrintFilter(stderr, "INFO", + _("Unable to locate printer \"%s\"."), hostname); + sleep(10); + + if (getenv("CLASS") != NULL) + { + fputs("STATE: -connecting-to-device\n", stderr); + exit(CUPS_BACKEND_FAILED); + } + } + + snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family); + + /* + * Wait for data from the filter... + */ + + if (argc == 6) + if (!backendWaitLoop(snmp_fd, &(addrlist->addr), backendNetworkSideCB)) + return (CUPS_BACKEND_OK); + /* * If we have 7 arguments, print the file named on the command-line. * Otherwise, copy stdin to a temporary file and print the temporary @@ -410,25 +446,6 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ * Copy stdin to a temporary file... */ - http_addrlist_t *addrlist; /* Address list */ - int snmp_fd; /* SNMP socket */ - - - fputs("STATE: +connecting-to-device\n", stderr); - fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); - - while ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, "1")) == NULL) - { - _cupsLangPrintFilter(stderr, "INFO", - _("Unable to locate printer \"%s\"."), hostname); - sleep(10); - - if (getenv("CLASS") != NULL) - exit(CUPS_BACKEND_FAILED); - } - - snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family); - if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0) { perror("DEBUG: Unable to create temporary file"); @@ -439,11 +456,6 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ backendRunLoop(-1, fd, snmp_fd, &(addrlist->addr), 0, 0, backendNetworkSideCB); - - if (snmp_fd >= 0) - _cupsSNMPClose(snmp_fd); - - httpAddrFreeList(addrlist); } else if (argc == 6) { @@ -503,18 +515,16 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ copies = atoi(argv[4]); } - status = lpd_queue(hostname, port, resource + 1, fd, mode, - username, title, copies, - banner, format, order, reserve, manual_copies, - timeout, contimeout); + status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode, + username, title, copies, banner, format, order, reserve, + manual_copies, timeout, contimeout); if (!status) fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4])); } else - status = lpd_queue(hostname, port, resource + 1, fd, mode, - username, title, 1, - banner, format, order, reserve, 1, + status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode, + username, title, 1, banner, format, order, reserve, 1, timeout, contimeout); /* @@ -527,6 +537,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ if (fd) close(fd); + if (snmp_fd >= 0) + _cupsSNMPClose(snmp_fd); + /* * Return the queue status... */ @@ -552,7 +565,7 @@ lpd_command(int fd, /* I - Socket connection to LPD host */ /* - * Don't try to send commands if the job has been cancelled... + * Don't try to send commands if the job has been canceled... */ if (abort_job) @@ -609,21 +622,22 @@ lpd_command(int fd, /* I - Socket connection to LPD host */ */ static int /* O - Zero on success, non-zero on failure */ -lpd_queue(const char *hostname, /* I - Host to connect to */ - int port, /* I - Port to connect on */ - const char *printer, /* I - Printer/queue name */ - int print_fd, /* I - File to print */ - int mode, /* I - Print mode */ - const char *user, /* I - Requesting user */ - const char *title, /* I - Job title */ - int copies, /* I - Number of copies */ - int banner, /* I - Print LPD banner? */ - int format, /* I - Format specifier */ - int order, /* I - Order of data/control files */ - int reserve, /* I - Reserve ports? */ - int manual_copies, /* I - Do copies by hand... */ - int timeout, /* I - Timeout... */ - int contimeout) /* I - Connection timeout */ +lpd_queue(const char *hostname, /* I - Host to connect to */ + http_addrlist_t *addrlist, /* I - List of host addresses */ + const char *printer, /* I - Printer/queue name */ + int print_fd, /* I - File to print */ + int snmp_fd, /* I - SNMP socket */ + int mode, /* I - Print mode */ + const char *user, /* I - Requesting user */ + const char *title, /* I - Job title */ + int copies, /* I - Number of copies */ + int banner, /* I - Print LPD banner? */ + int format, /* I - Format specifier */ + int order, /* I - Order of data/control files */ + int reserve, /* I - Reserve ports? */ + int manual_copies,/* I - Do copies by hand... */ + int timeout, /* I - Timeout... */ + int contimeout) /* I - Connection timeout */ { char localhost[255]; /* Local host name */ int error; /* Error number */ @@ -633,13 +647,10 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ char control[10240], /* LPD control 'file' */ *cptr; /* Pointer into control file string */ char status; /* Status byte from command */ - char portname[255]; /* Port name */ int delay; /* Delay for retries... */ char addrname[256]; /* Address name */ - http_addrlist_t *addrlist, /* Address list */ - *addr; /* Socket address */ - int snmp_fd, /* SNMP socket */ - have_supplies; /* Printer supports supply levels? */ + http_addrlist_t *addr; /* Socket address */ + int have_supplies; /* Printer supports supply levels? */ int copy; /* Copies written */ time_t start_time; /* Time of first connect */ size_t nbytes; /* Number of bytes written */ @@ -666,25 +677,6 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ signal(SIGALRM, lpd_timeout); #endif /* HAVE_SIGSET */ - /* - * Find the printer... - */ - - sprintf(portname, "%d", port); - - fputs("STATE: +connecting-to-device\n", stderr); - fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); - - while ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL) - { - _cupsLangPrintFilter(stderr, "INFO", _("Unable to locate printer \"%s\"."), - hostname); - sleep(10); - - if (getenv("CLASS") != NULL) - exit(CUPS_BACKEND_FAILED); - } - /* * Remember when we started trying to connect to the printer... */ @@ -702,7 +694,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ */ fprintf(stderr, "DEBUG: Connecting to %s:%d for printer %s\n", hostname, - port, printer); + _httpAddrPort(&(addrlist->addr)), printer); _cupsLangPrintFilter(stderr, "INFO", _("Connecting to printer.")); for (lport = reserve == RESERVE_RFC1179 ? 732 : 1024, addr = addrlist, @@ -710,15 +702,11 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ addr = addr->next) { /* - * Stop if this job has been cancelled... + * Stop if this job has been canceled... */ if (abort_job) - { - httpAddrFreeList(addrlist); - return (CUPS_BACKEND_FAILED); - } /* * Choose the next priviledged port... @@ -776,8 +764,6 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ if (abort_job) { - httpAddrFreeList(addrlist); - close(fd); return (CUPS_BACKEND_FAILED); @@ -805,8 +791,6 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ _("Unable to contact printer, queuing on next " "printer in class.")); - httpAddrFreeList(addrlist); - /* * Sleep 5 seconds to keep the job from requeuing too rapidly... */ @@ -892,8 +876,9 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ * See if the printer supports SNMP... */ - if ((snmp_fd = _cupsSNMPOpen(addr->addr.addr.sa_family)) >= 0) - have_supplies = !backendSNMPSupplies(snmp_fd, &(addr->addr), NULL, NULL); + if (snmp_fd >= 0) + have_supplies = !backendSNMPSupplies(snmp_fd, &(addrlist->addr), NULL, + NULL); else have_supplies = 0; @@ -901,7 +886,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ * Check for side-channel requests... */ - backendCheckSideChannel(snmp_fd, &(addr->addr)); + backendCheckSideChannel(snmp_fd, &(addrlist->addr)); /* * Next, open the print file and figure out its size... @@ -915,7 +900,6 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ if (fstat(print_fd, &filestats)) { - httpAddrFreeList(addrlist); close(fd); perror("DEBUG: unable to stat print file"); @@ -946,7 +930,6 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ if (lpd_command(fd, timeout, "\002%s\n", printer)) /* Receive print job(s) */ { - httpAddrFreeList(addrlist); close(fd); return (CUPS_BACKEND_FAILED); } @@ -999,7 +982,6 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ if (lpd_command(fd, timeout, "\002%d cfA%03.3d%.15s\n", strlen(control), (int)getpid() % 1000, localhost)) { - httpAddrFreeList(addrlist); close(fd); return (CUPS_BACKEND_FAILED); @@ -1056,7 +1038,6 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ CUPS_LLCAST filestats.st_size, (int)getpid() % 1000, localhost)) { - httpAddrFreeList(addrlist); close(fd); return (CUPS_BACKEND_FAILED); @@ -1144,7 +1125,6 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ if (lpd_command(fd, timeout, "\002%d cfA%03.3d%.15s\n", strlen(control), (int)getpid() % 1000, localhost)) { - httpAddrFreeList(addrlist); close(fd); return (CUPS_BACKEND_FAILED); @@ -1196,11 +1176,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ close(fd); if (status == 0) - { - httpAddrFreeList(addrlist); - return (CUPS_BACKEND_OK); - } /* * Waiting for a retry... @@ -1209,10 +1185,8 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ sleep(30); } - httpAddrFreeList(addrlist); - /* - * If we get here, then the job has been cancelled... + * If we get here, then the job has been canceled... */ return (CUPS_BACKEND_FAILED); diff --git a/backend/parallel.c b/backend/parallel.c index 968a47556..3f9c33a94 100644 --- a/backend/parallel.c +++ b/backend/parallel.c @@ -3,7 +3,7 @@ * * Parallel port backend for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -295,7 +295,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ if (print_fd != 0) close(print_fd); - return (tbytes < 0 ? CUPS_BACKEND_FAILED : CUPS_BACKEND_OK); + return (CUPS_BACKEND_OK); } diff --git a/backend/runloop.c b/backend/runloop.c index 2f5b5eaee..fbc5a467f 100644 --- a/backend/runloop.c +++ b/backend/runloop.c @@ -1,9 +1,9 @@ /* - * "$Id: runloop.c 7895 2008-09-02 19:19:43Z mike $" + * "$Id: runloop.c 9565 2011-02-23 00:08:08Z mike $" * - * Common run loop APIs for CUPS. + * Common run loop APIs for CUPS backends. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 2006-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -18,6 +18,8 @@ * * backendDrainOutput() - Drain pending print data to the device. * backendRunLoop() - Read and write print and back-channel data. + * backendWaitLoop() - Wait for input from stdin while handling + * side-channel queries. */ /* @@ -141,14 +143,13 @@ backendDrainOutput(int print_fd, /* I - Print file descriptor */ ssize_t /* O - Total bytes on success, -1 on error */ backendRunLoop( - int print_fd, /* I - Print file descriptor */ - int device_fd, /* I - Device file descriptor */ - int snmp_fd, /* I - SNMP socket or -1 if none */ - http_addr_t *addr, /* I - Address of device */ - int use_bc, /* I - Use back-channel? */ - int update_state, /* I - Update printer-state-reasons? */ - int (*side_cb)(int, int, int, http_addr_t *, int)) - /* I - Side-channel callback */ + int print_fd, /* I - Print file descriptor */ + int device_fd, /* I - Device file descriptor */ + int snmp_fd, /* I - SNMP socket or -1 if none */ + http_addr_t *addr, /* I - Address of device */ + int use_bc, /* I - Use back-channel? */ + int update_state, /* I - Update printer-state-reasons? */ + _cups_sccb_t side_cb) /* I - Side-channel callback */ { int nfds; /* Maximum file descriptor value + 1 */ fd_set input, /* Input set for reading */ @@ -255,7 +256,7 @@ backendRunLoop( else if (errno == EINTR && total_bytes == 0) { fputs("DEBUG: Received an interrupt before any bytes were " - "written, aborting\n", stderr); + "written, aborting.\n", stderr); return (0); } @@ -422,5 +423,103 @@ backendRunLoop( /* - * End of "$Id: runloop.c 7895 2008-09-02 19:19:43Z mike $". + * 'backendWaitLoop()' - Wait for input from stdin while handling side-channel + * queries. + */ + +int /* O - 1 if data is ready, 0 if not */ +backendWaitLoop( + int snmp_fd, /* I - SNMP socket or -1 if none */ + http_addr_t *addr, /* I - Address of device */ + _cups_sccb_t side_cb) /* I - Side-channel callback */ +{ + fd_set input; /* Input set for reading */ + time_t curtime, /* Current time */ + snmp_update = 0; +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + fprintf(stderr, "DEBUG: backendWaitLoop(snmp_fd=%d, addr=%p, side_cb=%p)\n", + snmp_fd, addr, side_cb); + + /* + * Now loop until we receive data from stdin... + */ + + for (;;) + { + /* + * Use select() to determine whether we have data to copy around... + */ + + FD_ZERO(&input); + FD_SET(0, &input); + if (side_cb) + FD_SET(CUPS_SC_FD, &input); + + if (select(CUPS_SC_FD + 1, &input, NULL, NULL, NULL) < 0) + { + /* + * Pause printing to clear any pending errors... + */ + + if (errno == EINTR) + { + fputs("DEBUG: Received an interrupt before any bytes were " + "written, aborting.\n", stderr); + return (0); + } + + sleep(1); + continue; + } + + /* + * Check for input on stdin... + */ + + if (FD_ISSET(0, &input)) + break; + + /* + * Check if we have a side-channel request ready... + */ + + if (side_cb && FD_ISSET(CUPS_SC_FD, &input)) + { + /* + * Do the side-channel request, then start back over in the select + * loop since it may have read from print_fd... + */ + + if ((*side_cb)(0, -1, snmp_fd, addr, 0)) + side_cb = NULL; + continue; + } + + /* + * Do SNMP updates periodically... + */ + + if (snmp_fd >= 0 && time(&curtime) >= snmp_update) + { + if (backendSNMPSupplies(snmp_fd, addr, NULL, NULL)) + snmp_update = INT_MAX; + else + snmp_update = curtime + 5; + } + } + + /* + * Return with success... + */ + + return (1); +} + + +/* + * End of "$Id: runloop.c 9565 2011-02-23 00:08:08Z mike $". */ diff --git a/backend/serial.c b/backend/serial.c index 05b98913f..79a980d4b 100644 --- a/backend/serial.c +++ b/backend/serial.c @@ -3,7 +3,7 @@ * * Serial port backend for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -722,7 +722,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ if (print_fd != 0) close(print_fd); - return (total_bytes < 0 ? CUPS_BACKEND_FAILED : CUPS_BACKEND_OK); + return (CUPS_BACKEND_OK); } @@ -1217,11 +1217,11 @@ list_devices(void) /* Check if hidden... */ - hiddenVal = IORegistryEntrySearchCFProperty(serialService, + hiddenVal = IORegistryEntrySearchCFProperty(serialService, kIOServicePlane, CFSTR("HiddenPort"), kCFAllocatorDefault, - kIORegistryIterateRecursively | + kIORegistryIterateRecursively | kIORegistryIterateParents); if (hiddenVal) CFRelease(hiddenVal); /* This interface should not be used */ @@ -1237,7 +1237,7 @@ list_devices(void) sizeof(serialName), kCFStringEncodingASCII); CFRelease(serialNameAsCFString); - + if (result) { bsdPathAsCFString = @@ -1250,7 +1250,7 @@ list_devices(void) sizeof(bsdPath), kCFStringEncodingASCII); CFRelease(bsdPathAsCFString); - + if (result) printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", bsdPath, serialName); diff --git a/backend/snmp-supplies.c b/backend/snmp-supplies.c index af2ba7d95..990e54982 100644 --- a/backend/snmp-supplies.c +++ b/backend/snmp-supplies.c @@ -1,9 +1,9 @@ /* * "$Id$" * - * SNMP supplies functions for the Common UNIX Printing System (CUPS). + * SNMP supplies functions for CUPS. * - * Copyright 2008-2009 by Apple Inc. + * Copyright 2008-2011 by Apple Inc. * * These coded instructions, statements, and computer programs are the * property of Apple Inc. and are protected by Federal copyright @@ -36,6 +36,17 @@ #define CUPS_MAX_SUPPLIES 32 /* Maximum number of supplies for a printer */ #define CUPS_SUPPLY_TIMEOUT 2.0 /* Timeout for SNMP lookups */ +#define CUPS_DEVELOPER_LOW 1 +#define CUPS_DEVELOPER_EMPTY 2 +#define CUPS_MARKER_SUPPLY_LOW 4 +#define CUPS_MARKER_SUPPLY_EMPTY 8 +#define CUPS_MARKER_WASTE_ALMOST_FULL 16 +#define CUPS_MARKER_WASTE_FULL 32 +#define CUPS_OPC_NEAR_EOL 64 +#define CUPS_OPC_LIFE_OVER 128 +#define CUPS_TONER_LOW 256 +#define CUPS_TONER_EMPTY 512 + /* * Local structures... @@ -66,12 +77,12 @@ static http_addr_t current_addr; /* Current address */ static int current_state = -1; /* Current device state bits */ static int charset = -1; /* Character set for supply names */ -static int laser_printer = -1, - /* Laser printer with toner? */ - num_supplies = 0; +static int num_supplies = 0; /* Number of supplies found */ static backend_supplies_t supplies[CUPS_MAX_SUPPLIES]; /* Supply information */ +static int supply_state = -1; + /* Supply state info */ static const int hrDeviceDescr[] = { CUPS_OID_hrDeviceDescr, 1, -1 }; @@ -142,8 +153,8 @@ static const backend_state_t const printer_states[] = { { CUPS_TC_lowPaper, "media-low-report" }, { CUPS_TC_noPaper | CUPS_TC_inputTrayEmpty, "media-empty-warning" }, - { CUPS_TC_lowToner, "toner-low-report" }, - { CUPS_TC_noToner, "toner-empty-warning" }, + /* { CUPS_TC_lowToner, "toner-low-report" }, */ /* now use prtMarkerSupplies */ + /* { CUPS_TC_noToner, "toner-empty-warning" }, */ /* now use prtMarkerSupplies */ { CUPS_TC_doorOpen, "door-open-report" }, { CUPS_TC_jammed, "media-jam-warning" }, /* { CUPS_TC_offline, "offline-report" }, */ /* unreliable */ @@ -155,6 +166,20 @@ static const backend_state_t const printer_states[] = { CUPS_TC_outputFull, "output-area-full-warning" } }; +static const backend_state_t const supply_states[] = + { + { CUPS_DEVELOPER_LOW, "developer-low-report" }, + { CUPS_DEVELOPER_EMPTY, "developer-empty-warning" }, + { CUPS_MARKER_SUPPLY_LOW, "marker-supply-low-report" }, + { CUPS_MARKER_SUPPLY_EMPTY, "marker-supply-empty-warning" }, + { CUPS_MARKER_WASTE_ALMOST_FULL, "marker-waste-almost-full-report" }, + { CUPS_MARKER_WASTE_FULL, "marker-waste-full-warning" }, + { CUPS_OPC_NEAR_EOL, "opc-near-eol-report" }, + { CUPS_OPC_LIFE_OVER, "opc-life-over-warning" }, + { CUPS_TONER_LOW, "toner-low-report" }, + { CUPS_TONER_EMPTY, "toner-empty-warning" } + }; + /* * Local functions... @@ -193,8 +218,10 @@ backendSNMPSupplies( if (num_supplies > 0) { int i, /* Looping var */ + percent, /* Percent full */ new_state, /* New state value */ - change_state; /* State change */ + change_state, /* State change */ + new_supply_state = 0; /* Supply state */ char value[CUPS_MAX_SUPPLIES * 4], /* marker-levels value string */ *ptr; /* Pointer into value string */ @@ -206,17 +233,85 @@ backendSNMPSupplies( for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr)) { + percent = 100 * supplies[i].level / supplies[i].max_capacity; + + if (percent <= 10) + { + switch (supplies[i].type) + { + case CUPS_TC_toner : + case CUPS_TC_tonerCartridge : + if (percent <= 1) + new_supply_state |= CUPS_TONER_EMPTY; + else + new_supply_state |= CUPS_TONER_LOW; + break; + case CUPS_TC_wasteToner : + case CUPS_TC_wasteInk : + if (percent <= 1) + new_supply_state |= CUPS_MARKER_WASTE_FULL; + else + new_supply_state |= CUPS_MARKER_WASTE_ALMOST_FULL; + break; + case CUPS_TC_ink : + case CUPS_TC_inkCartridge : + case CUPS_TC_inkRibbon : + case CUPS_TC_solidWax : + case CUPS_TC_ribbonWax : + if (percent <= 1) + new_supply_state |= CUPS_MARKER_SUPPLY_EMPTY; + else + new_supply_state |= CUPS_MARKER_SUPPLY_LOW; + break; + case CUPS_TC_developer : + if (percent <= 1) + new_supply_state |= CUPS_DEVELOPER_EMPTY; + else + new_supply_state |= CUPS_DEVELOPER_LOW; + break; + case CUPS_TC_coronaWire : + case CUPS_TC_fuser : + case CUPS_TC_opc : + case CUPS_TC_transferUnit : + if (percent <= 1) + new_supply_state |= CUPS_OPC_LIFE_OVER; + else + new_supply_state |= CUPS_OPC_NEAR_EOL; + break; + } + } + if (i) *ptr++ = ','; if (supplies[i].max_capacity > 0) - sprintf(ptr, "%d", 100 * supplies[i].level / supplies[i].max_capacity); + sprintf(ptr, "%d", percent); else strcpy(ptr, "-1"); } fprintf(stderr, "ATTR: marker-levels=%s\n", value); + if (supply_state < 0) + change_state = 0xffff; + else + change_state = supply_state ^ new_supply_state; + + fprintf(stderr, "DEBUG: new_supply_state=%x, change_state=%x\n", + new_supply_state, change_state); + + for (i = 0; + i < (int)(sizeof(supply_states) / sizeof(supply_states[0])); + i ++) + if (change_state & supply_states[i].bit) + { + fprintf(stderr, "STATE: %c%s\n", + (new_supply_state & supply_states[i].bit) ? '+' : '-', + supply_states[i].keyword); + } + + supply_state = new_supply_state; + /* * Get the current printer status bits... */ @@ -243,32 +338,17 @@ backendSNMPSupplies( else change_state = current_state ^ new_state; - fprintf(stderr, "DEBUG: new_state=%x, change_state=%x, laser_printer=%d\n", - new_state, change_state, laser_printer); + fprintf(stderr, "DEBUG: new_state=%x, change_state=%x\n", new_state, + change_state); for (i = 0; i < (int)(sizeof(printer_states) / sizeof(printer_states[0])); i ++) if (change_state & printer_states[i].bit) { - if (!laser_printer && !strncmp(printer_states[i].keyword, "toner-", 6)) - { - /* - * Map toner-xxx to marker-supply-xxx to avoid confusing "out of toner" - * messages on inkjet print queues... - */ - - if (printer_states[i].bit == CUPS_TC_lowToner) - fprintf(stderr, "STATE: %cmarker-supply-low-report\n", - (new_state & CUPS_TC_lowToner) ? '+' : '-'); - else - fprintf(stderr, "STATE: %cmarker-supply-empty-warning\n", - (new_state & CUPS_TC_noToner) ? '+' : '-'); - } - else - fprintf(stderr, "STATE: %c%s\n", - (new_state & printer_states[i].bit) ? '+' : '-', - printer_states[i].keyword); + fprintf(stderr, "STATE: %c%s\n", + (new_state & printer_states[i].bit) ? '+' : '-', + printer_states[i].keyword); } current_state = new_state; @@ -611,8 +691,6 @@ backend_init_supplies( * Output the marker-types attribute... */ - laser_printer = 0; - for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr)) { if (i) @@ -620,9 +698,6 @@ backend_init_supplies( type = supplies[i].type; - if (type == CUPS_TC_toner) - laser_printer = 1; - if (type < CUPS_TC_other || type > CUPS_TC_covers) strcpy(ptr, "unknown"); else diff --git a/backend/socket.c b/backend/socket.c index 6f64fb0c0..7d9196b98 100644 --- a/backend/socket.c +++ b/backend/socket.c @@ -257,7 +257,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ } /* - * Then try to connect to the remote host... + * Then try finding the remote host... */ start_time = time(NULL); @@ -274,8 +274,35 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ sleep(10); if (getenv("CLASS") != NULL) + { + fputs("STATE: -connecting-to-device\n", stderr); return (CUPS_BACKEND_STOP); + } + } + + /* + * See if the printer supports SNMP... + */ + + if ((snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family)) >= 0) + { + have_supplies = !backendSNMPSupplies(snmp_fd, &(addr->addr), &start_count, + NULL); } + else + have_supplies = start_count = 0; + + /* + * Wait for data from the filter... + */ + + if (print_fd == 0) + if (!backendWaitLoop(snmp_fd, &(addrlist->addr), backendNetworkSideCB)) + return (CUPS_BACKEND_OK); + + /* + * Connect to the printer... + */ fprintf(stderr, "DEBUG: Connecting to %s:%d\n", hostname, port); _cupsLangPrintFilter(stderr, "INFO", _("Connecting to printer.")); @@ -376,18 +403,6 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ httpAddrString(&addr->addr, addrname, sizeof(addrname)), ntohs(addr->addr.ipv4.sin_port)); - /* - * See if the printer supports SNMP... - */ - - if ((snmp_fd = _cupsSNMPOpen(addr->addr.addr.sa_family)) >= 0) - { - have_supplies = !backendSNMPSupplies(snmp_fd, &(addr->addr), &start_count, - NULL); - } - else - have_supplies = start_count = 0; - /* * Print everything... */ @@ -459,10 +474,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ if (print_fd != 0) close(print_fd); - if (tbytes >= 0) - _cupsLangPrintFilter(stderr, "INFO", _("Ready to print.")); + _cupsLangPrintFilter(stderr, "INFO", _("Ready to print.")); - return (tbytes < 0 ? CUPS_BACKEND_FAILED : CUPS_BACKEND_OK); + return (CUPS_BACKEND_OK); } diff --git a/backend/usb-unix.c b/backend/usb-unix.c index 03b70d294..698457a39 100644 --- a/backend/usb-unix.c +++ b/backend/usb-unix.c @@ -1,11 +1,11 @@ /* * "$Id: usb-unix.c 7810 2008-07-29 01:11:15Z mike $" * - * USB port backend for the Common UNIX Printing System (CUPS). + * USB port backend for CUPS. * * This file is included from "usb.c" when compiled on UNIX/Linux. * - * Copyright 2007-2009 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -201,7 +201,7 @@ print_device(const char *uri, /* I - Device URI */ close(device_fd); - return (tbytes < 0 ? CUPS_BACKEND_FAILED : CUPS_BACKEND_OK); + return (CUPS_BACKEND_OK); } diff --git a/config.h.in b/config.h.in index 42a2b0f32..4c9b79856 100644 --- a/config.h.in +++ b/config.h.in @@ -311,6 +311,7 @@ #undef HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY + /* * Do we have the SecPolicyCreateSSL function? */ diff --git a/cups/Makefile b/cups/Makefile index e3f6ec241..5ce000916 100644 --- a/cups/Makefile +++ b/cups/Makefile @@ -3,7 +3,7 @@ # # API library Makefile for CUPS. # -# Copyright 2007-2010 by Apple Inc. +# Copyright 2007-2011 by Apple Inc. # Copyright 1997-2006 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the diff --git a/cups/adminutil.c b/cups/adminutil.c index 8ceb55086..cbb101201 100644 --- a/cups/adminutil.c +++ b/cups/adminutil.c @@ -901,7 +901,7 @@ cupsAdminGetServerSettings( if (!cg->http) { - if ((cg->http = _httpCreate(cupsServer(), ippPort(), + if ((cg->http = _httpCreate(cupsServer(), ippPort(), NULL, cupsEncryption(), AF_UNSPEC)) == NULL) { if (errno) diff --git a/cups/cups-private.h b/cups/cups-private.h index 87c396d81..d6a8bbba9 100644 --- a/cups/cups-private.h +++ b/cups/cups-private.h @@ -3,7 +3,7 @@ * * Private definitions for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -31,6 +31,10 @@ # include "language-private.h" # include "pwg-private.h" # include "thread-private.h" +# ifdef __APPLE__ +# include +# include +# endif /* __APPLE__ */ /* @@ -155,9 +159,18 @@ typedef struct _cups_globals_s /**** CUPS global state data ****/ * Prototypes... */ +# ifdef __APPLE__ +extern CFStringRef _cupsAppleCopyDefaultPaperID(void); +extern int _cupsAppleGetUseLastPrinter(void); +extern void _cupsAppleSetDefaultPaperID(CFStringRef name); +extern void _cupsAppleSetUseLastPrinter(int uselast); +# endif /* __APPLE__ */ + extern http_t *_cupsConnect(void); extern int _cupsGet1284Values(const char *device_id, cups_option_t **values); +extern int _cupsGetDests(http_t *http, ipp_op_t op, + const char *name, cups_dest_t **dests); extern const char *_cupsGetPassword(const char *prompt); extern void _cupsGlobalLock(void); extern _cups_globals_t *_cupsGlobals(void); diff --git a/cups/dest.c b/cups/dest.c index 551dc7341..1406c3420 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -3,7 +3,7 @@ * * User-defined destination (and option) support for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -16,34 +16,45 @@ * * Contents: * - * cupsAddDest() - Add a destination to the list of destinations. - * cupsFreeDests() - Free the memory used by the list of destinations. - * cupsGetDest() - Get the named destination from the list. - * cupsGetDests() - Get the list of destinations from the default - * server. - * cupsGetDests2() - Get the list of destinations from the specified - * server. - * cupsGetNamedDest() - Get options for the named destination. - * cupsRemoveDest() - Remove a destination from the destination list. - * cupsSetDefaultDest() - Set the default destination. - * cupsSetDests() - Save the list of destinations for the default - * server. - * cupsSetDests2() - Save the list of destinations for the specified - * server. - * appleCopyLocations() - Copy the location history array. - * appleCopyNetwork() - Get the network ID for the current location. - * appleGetPaperSize() - Get the default paper size. - * appleGetPrinter() - Get a printer from the history array. - * appleSetDefault() - Set the default printer for this location. - * appleUseLastPrinter() - Get the default printer preference value. - * cups_add_dest() - Add a destination to the array. - * cups_compare_dests() - Compare two destinations. - * cups_find_dest() - Find a destination using a binary search. - * cups_get_default() - Get the default destination from an lpoptions file. - * cups_get_dests() - Get destinations from a file. - * cups_get_sdests() - Get destinations from a server. - * cups_make_string() - Make a comma-separated string of values from an IPP - * attribute. + * cupsAddDest() - Add a destination to the list of + * destinations. + * _cupsAppleCopyDefaultPaperID() - Get the default paper ID. + * _cupsAppleGetUseLastPrinter() - Get whether to use the last used printer. + * _cupsAppleSetDefaultPaperID() - Set the default paper id. + * _cupsAppleSetUseLastPrinter() - Set whether to use the last used printer. + * cupsFreeDests() - Free the memory used by the list of + * destinations. + * cupsGetDest() - Get the named destination from the list. + * _cupsGetDests() - Get destinations from a server. + * cupsGetDests() - Get the list of destinations from the + * default server. + * cupsGetDests2() - Get the list of destinations from the + * specified server. + * cupsGetNamedDest() - Get options for the named destination. + * cupsRemoveDest() - Remove a destination from the destination + * list. + * cupsSetDefaultDest() - Set the default destination. + * cupsSetDests() - Save the list of destinations for the + * default server. + * cupsSetDests2() - Save the list of destinations for the + * specified server. + * _cupsUserDefault() - Get the user default printer from + * environment variables and location + * information. + * appleCopyLocations() - Copy the location history array. + * appleCopyNetwork() - Get the network ID for the current + * location. + * appleGetPaperSize() - Get the default paper size. + * appleGetPrinter() - Get a printer from the history array. + * appleSetDefault() - Set the default printer for this location. + * cups_add_dest() - Add a destination to the array. + * cups_compare_dests() - Compare two destinations. + * cups_find_dest() - Find a destination using a binary search. + * cups_get_default() - Get the default destination from an + * lpoptions file. + * cups_get_dests() - Get destinations from a file. + * cups_make_string() - Make a comma-separated string of values + * from an IPP attribute. */ /* @@ -58,14 +69,13 @@ #endif /* HAVE_NOTIFY_H */ #ifdef __APPLE__ -# include -# include # include # define kDefaultPaperIDKey CFSTR("DefaultPaperID") # define kLocationHistoryArrayKey CFSTR("kLocationHistoryArrayKeyTMP") # define kLocationNetworkKey CFSTR("kLocationNetworkKey") # define kLocationPrinterIDKey CFSTR("kLocationPrinterIDKey") # define kPMPrintingPreferences CFSTR("com.apple.print.PrintingPrefs") +# define kCUPSPrintingPreferences CFSTR("org.cups.PrintingPrefs") # define kUseLastPrinterAsCurrentPrinterKey CFSTR("UseLastPrinterAsCurrentPrinter") #endif /* __APPLE__ */ @@ -81,7 +91,6 @@ static char *appleGetPaperSize(char *name, int namesize); static CFStringRef appleGetPrinter(CFArrayRef locations, CFStringRef network, CFIndex *locindex); static void appleSetDefault(const char *name); -static int appleUseLastPrinter(void); #endif /* __APPLE__ */ static cups_dest_t *cups_add_dest(const char *name, const char *instance, int *num_dests, cups_dest_t **dests); @@ -94,8 +103,6 @@ static char *cups_get_default(const char *filename, char *namebuf, static int cups_get_dests(const char *filename, const char *match_name, const char *match_inst, int user_default_set, int num_dests, cups_dest_t **dests); -static int cups_get_sdests(http_t *http, ipp_op_t op, const char *name, - int num_dests, cups_dest_t **dests); static char *cups_make_string(ipp_attribute_t *attr, char *buffer, size_t bufsize); @@ -172,6 +179,83 @@ cupsAddDest(const char *name, /* I - Destination name */ } +#ifdef __APPLE__ +/* + * '_cupsAppleCopyDefaultPaperID()' - Get the default paper ID. + */ + +CFStringRef /* O - Default paper ID */ +_cupsAppleCopyDefaultPaperID(void) +{ + CFStringRef paper; /* Default paper ID */ + + + paper = CFPreferencesCopyAppValue(kDefaultPaperIDKey, + kCUPSPrintingPreferences); + + if (!paper) + paper = CFPreferencesCopyAppValue(kDefaultPaperIDKey, + kPMPrintingPreferences); + + return (paper); +} + + +/* + * '_cupsAppleGetUseLastPrinter()' - Get whether to use the last used printer. + */ + +int /* O - 1 to use last printer, 0 otherwise */ +_cupsAppleGetUseLastPrinter(void) +{ + Boolean uselast, /* Use last printer preference value */ + uselast_set; /* Valid is set? */ + + + if (getenv("CUPS_DISABLE_APPLE_DEFAULT")) + return (0); + + uselast = CFPreferencesGetAppBooleanValue(kUseLastPrinterAsCurrentPrinterKey, + kCUPSPrintingPreferences, + &uselast_set); + if (!uselast_set) + uselast = CFPreferencesGetAppBooleanValue(kUseLastPrinterAsCurrentPrinterKey, + kPMPrintingPreferences, + &uselast_set); + if (!uselast_set) + return (1); + else + return (uselast); +} + + +/* + * '_cupsAppleSetDefaultPaperID()' - Set the default paper id. + */ + +void +_cupsAppleSetDefaultPaperID( + CFStringRef name) /* I - New paper ID */ +{ + CFPreferencesSetAppValue(kDefaultPaperIDKey, name, kCUPSPrintingPreferences); +} + + +/* + * '_cupsAppleSetUseLastPrinter()' - Set whether to use the last used printer. + */ + +void +_cupsAppleSetUseLastPrinter( + int uselast) /* O - 1 to use last printer, 0 otherwise */ +{ + CFPreferencesSetAppValue(kUseLastPrinterAsCurrentPrinterKey, + uselast ? kCFBooleanTrue : kCFBooleanFalse, + kCUPSPrintingPreferences); +} +#endif /* __APPLE__ */ + + /* * 'cupsFreeDests()' - Free the memory used by the list of destinations. */ @@ -250,6 +334,271 @@ cupsGetDest(const char *name, /* I - Destination name or @code NULL@ for the d } +/* + * '_cupsGetDests()' - Get destinations from a server. + * + * "op" is CUPS_GET_PRINTERS to get a full list, CUPS_GET_DEFAULT to get the + * system-wide default printer, or IPP_GET_PRINTER_ATTRIBUTES for a known + * printer. + * + * "name" is the name of an existing printer and is only used when "op" is + * IPP_GET_PRINTER_ATTRIBUTES. + * + * "dest" is initialized to point to the array of destinations. + * + * 0 is returned if there are no printers, no default printer, or the named + * printer does not exist, respectively. + * + * Free the memory used by the destination array using the @link cupsFreeDests@ + * function. + * + * Note: On Mac OS X this function also gets the default paper from the system + * preferences (~/L/P/org.cups.PrintingPrefs.plist) and includes it in the + * options array for each destination that supports it. + */ + +int /* O - Number of destinations */ +_cupsGetDests(http_t *http, /* I - Connection to server or CUPS_HTTP_DEFAULT */ + ipp_op_t op, /* I - IPP operation */ + const char *name, /* I - Name of destination */ + cups_dest_t **dests) /* IO - Destinations */ +{ + int num_dests = 0; /* Number of destinations */ + cups_dest_t *dest; /* Current destination */ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + const char *printer_name; /* printer-name attribute */ + char uri[1024]; /* printer-uri value */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ +#ifdef __APPLE__ + char media_default[41]; /* Default paper size */ +#endif /* __APPLE__ */ + char optname[1024], /* Option name */ + value[2048], /* Option value */ + *ptr; /* Pointer into name/value */ + static const char * const pattrs[] = /* Attributes we're interested in */ + { + "auth-info-required", + "device-uri", + "job-sheets-default", + "marker-change-time", + "marker-colors", + "marker-high-levels", + "marker-levels", + "marker-low-levels", + "marker-message", + "marker-names", + "marker-types", +#ifdef __APPLE__ + "media-supported", +#endif /* __APPLE__ */ + "printer-commands", + "printer-defaults", + "printer-info", + "printer-is-accepting-jobs", + "printer-is-shared", + "printer-location", + "printer-make-and-model", + "printer-name", + "printer-state", + "printer-state-change-time", + "printer-state-reasons", + "printer-type", + "printer-uri-supported" + }; + + +#ifdef __APPLE__ + /* + * Get the default paper size... + */ + + appleGetPaperSize(media_default, sizeof(media_default)); +#endif /* __APPLE__ */ + + /* + * Build a CUPS_GET_PRINTERS or IPP_GET_PRINTER_ATTRIBUTES request, which + * require the following attributes: + * + * attributes-charset + * attributes-natural-language + * requesting-user-name + * printer-uri [for IPP_GET_PRINTER_ATTRIBUTES] + */ + + request = ippNewRequest(op); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), + NULL, pattrs); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, cupsUser()); + + if (name && op != CUPS_GET_DEFAULT) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", ippPort(), "/printers/%s", name); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, + uri); + } + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + for (attr = response->attrs; attr != NULL; attr = attr->next) + { + /* + * Skip leading attributes until we hit a printer... + */ + + while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) + attr = attr->next; + + if (attr == NULL) + break; + + /* + * Pull the needed attributes from this printer... + */ + + printer_name = NULL; + num_options = 0; + options = NULL; + + for (; attr && attr->group_tag == IPP_TAG_PRINTER; attr = attr->next) + { + if (attr->value_tag != IPP_TAG_INTEGER && + attr->value_tag != IPP_TAG_ENUM && + attr->value_tag != IPP_TAG_BOOLEAN && + attr->value_tag != IPP_TAG_TEXT && + attr->value_tag != IPP_TAG_TEXTLANG && + attr->value_tag != IPP_TAG_NAME && + attr->value_tag != IPP_TAG_NAMELANG && + attr->value_tag != IPP_TAG_KEYWORD && + attr->value_tag != IPP_TAG_RANGE && + attr->value_tag != IPP_TAG_URI) + continue; + + if (!strcmp(attr->name, "auth-info-required") || + !strcmp(attr->name, "device-uri") || + !strcmp(attr->name, "marker-change-time") || + !strcmp(attr->name, "marker-colors") || + !strcmp(attr->name, "marker-high-levels") || + !strcmp(attr->name, "marker-levels") || + !strcmp(attr->name, "marker-low-levels") || + !strcmp(attr->name, "marker-message") || + !strcmp(attr->name, "marker-names") || + !strcmp(attr->name, "marker-types") || + !strcmp(attr->name, "printer-commands") || + !strcmp(attr->name, "printer-info") || + !strcmp(attr->name, "printer-is-shared") || + !strcmp(attr->name, "printer-make-and-model") || + !strcmp(attr->name, "printer-state") || + !strcmp(attr->name, "printer-state-change-time") || + !strcmp(attr->name, "printer-type") || + !strcmp(attr->name, "printer-is-accepting-jobs") || + !strcmp(attr->name, "printer-location") || + !strcmp(attr->name, "printer-state-reasons") || + !strcmp(attr->name, "printer-uri-supported")) + { + /* + * Add a printer description attribute... + */ + + num_options = cupsAddOption(attr->name, + cups_make_string(attr, value, + sizeof(value)), + num_options, &options); + } +#ifdef __APPLE__ + else if (!strcmp(attr->name, "media-supported")) + { + /* + * See if we can set a default media size... + */ + + int i; /* Looping var */ + + for (i = 0; i < attr->num_values; i ++) + if (!strcasecmp(media_default, attr->values[i].string.text)) + { + num_options = cupsAddOption("media", media_default, num_options, + &options); + break; + } + } +#endif /* __APPLE__ */ + else if (!strcmp(attr->name, "printer-name") && + attr->value_tag == IPP_TAG_NAME) + printer_name = attr->values[0].string.text; + else if (strncmp(attr->name, "notify-", 7) && + (attr->value_tag == IPP_TAG_BOOLEAN || + attr->value_tag == IPP_TAG_ENUM || + attr->value_tag == IPP_TAG_INTEGER || + attr->value_tag == IPP_TAG_KEYWORD || + attr->value_tag == IPP_TAG_NAME || + attr->value_tag == IPP_TAG_RANGE) && + (ptr = strstr(attr->name, "-default")) != NULL) + { + /* + * Add a default option... + */ + + strlcpy(optname, attr->name, sizeof(optname)); + optname[ptr - attr->name] = '\0'; + + if (strcasecmp(optname, "media") || + !cupsGetOption("media", num_options, options)) + num_options = cupsAddOption(optname, + cups_make_string(attr, value, + sizeof(value)), + num_options, &options); + } + } + + /* + * See if we have everything needed... + */ + + if (!printer_name) + { + cupsFreeOptions(num_options, options); + + if (attr == NULL) + break; + else + continue; + } + + if ((dest = cups_add_dest(printer_name, NULL, &num_dests, dests)) != NULL) + { + dest->num_options = num_options; + dest->options = options; + } + else + cupsFreeOptions(num_options, options); + + if (attr == NULL) + break; + } + + ippDelete(response); + } + + /* + * Return the count... + */ + + return (num_dests); +} + + /* * 'cupsGetDests()' - Get the list of destinations from the default server. * @@ -315,20 +664,14 @@ cupsGetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ { _cupsSetError(IPP_INTERNAL_ERROR, _("Bad NULL dests pointer"), 1); return (0); - } - - /* - * Initialize destination array... - */ - - num_dests = 0; - *dests = (cups_dest_t *)0; + } /* * Grab the printers and classes... */ - num_dests = cups_get_sdests(http, CUPS_GET_PRINTERS, NULL, num_dests, dests); + *dests = (cups_dest_t *)0; + num_dests = _cupsGetDests(http, CUPS_GET_PRINTERS, NULL, dests); if (cupsLastError() >= IPP_REDIRECTION_OTHER_SITE) { @@ -550,7 +893,7 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT * Get the printer's attributes... */ - if (!cups_get_sdests(http, op, name, 0, &dest)) + if (!_cupsGetDests(http, op, name, &dest)) { if (op == CUPS_GET_DEFAULT || (name && !set_as_default)) return (NULL); @@ -560,7 +903,7 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT * configuration file does not exist. Find out the real default. */ - if (!cups_get_sdests(http, CUPS_GET_DEFAULT, NULL, 0, &dest)) + if (!_cupsGetDests(http, CUPS_GET_DEFAULT, NULL, &dest)) return (NULL); } @@ -737,7 +1080,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ * Get the server destinations... */ - num_temps = cups_get_sdests(http, CUPS_GET_PRINTERS, NULL, 0, &temps); + num_temps = _cupsGetDests(http, CUPS_GET_PRINTERS, NULL, &temps); if (cupsLastError() >= IPP_REDIRECTION_OTHER_SITE) { @@ -960,7 +1303,7 @@ _cupsUserDefault(char *name, /* I - Name buffer */ * system preferences... */ - if (!appleUseLastPrinter()) + if (!_cupsAppleGetUseLastPrinter()) { DEBUG_puts("1_cupsUserDefault: Not using last printer as default..."); name[0] = '\0'; @@ -1098,7 +1441,7 @@ appleCopyNetwork(void) * 'appleGetPaperSize()' - Get the default paper size. */ -static char * /* O - Default paper size */ +char * /* O - Default paper size */ appleGetPaperSize(char *name, /* I - Paper size name buffer */ int namesize) /* I - Size of buffer */ { @@ -1106,8 +1449,7 @@ appleGetPaperSize(char *name, /* I - Paper size name buffer */ _pwg_media_t *pwgmedia; /* PWG media size */ - defaultPaperID = CFPreferencesCopyAppValue(kDefaultPaperIDKey, - kPMPrintingPreferences); + defaultPaperID = _cupsAppleCopyDefaultPaperID(); if (!defaultPaperID || CFGetTypeID(defaultPaperID) != CFStringGetTypeID() || !CFStringGetCString(defaultPaperID, name, namesize, @@ -1272,30 +1614,6 @@ appleSetDefault(const char *name) /* I - Default printer/class name */ } -/* - * 'appleUseLastPrinter()' - Get the default printer preference value. - */ - -static int /* O - 1 to use last printer, 0 otherwise */ -appleUseLastPrinter(void) -{ - CFPropertyListRef uselast; /* Use last printer preference value */ - - - if (getenv("CUPS_DISABLE_APPLE_DEFAULT")) - return (0); - - if ((uselast = CFPreferencesCopyAppValue(kUseLastPrinterAsCurrentPrinterKey, - kPMPrintingPreferences)) != NULL) - { - CFRelease(uselast); - - if (uselast == kCFBooleanFalse) - return (0); - } - - return (1); -} #endif /* __APPLE__ */ @@ -1713,252 +2031,6 @@ cups_get_dests( } -/* - * 'cups_get_sdests()' - Get destinations from a server. - */ - -static int /* O - Number of destinations */ -cups_get_sdests(http_t *http, /* I - Connection to server or CUPS_HTTP_DEFAULT */ - ipp_op_t op, /* I - IPP operation */ - const char *name, /* I - Name of destination */ - int num_dests, /* I - Number of destinations */ - cups_dest_t **dests) /* IO - Destinations */ -{ - cups_dest_t *dest; /* Current destination */ - ipp_t *request, /* IPP Request */ - *response; /* IPP Response */ - ipp_attribute_t *attr; /* Current attribute */ - const char *printer_name; /* printer-name attribute */ - char uri[1024]; /* printer-uri value */ - int num_options; /* Number of options */ - cups_option_t *options; /* Options */ -#ifdef __APPLE__ - char media_default[41]; /* Default paper size */ -#endif /* __APPLE__ */ - char optname[1024], /* Option name */ - value[2048], /* Option value */ - *ptr; /* Pointer into name/value */ - static const char * const pattrs[] = /* Attributes we're interested in */ - { - "auth-info-required", - "device-uri", - "job-sheets-default", - "marker-change-time", - "marker-colors", - "marker-high-levels", - "marker-levels", - "marker-low-levels", - "marker-message", - "marker-names", - "marker-types", -#ifdef __APPLE__ - "media-supported", -#endif /* __APPLE__ */ - "printer-commands", - "printer-defaults", - "printer-info", - "printer-is-accepting-jobs", - "printer-is-shared", - "printer-location", - "printer-make-and-model", - "printer-name", - "printer-state", - "printer-state-change-time", - "printer-state-reasons", - "printer-type", - "printer-uri-supported" - }; - - -#ifdef __APPLE__ - /* - * Get the default paper size... - */ - - appleGetPaperSize(media_default, sizeof(media_default)); -#endif /* __APPLE__ */ - - /* - * Build a CUPS_GET_PRINTERS or IPP_GET_PRINTER_ATTRIBUTES request, which - * require the following attributes: - * - * attributes-charset - * attributes-natural-language - * requesting-user-name - * printer-uri [for IPP_GET_PRINTER_ATTRIBUTES] - */ - - request = ippNewRequest(op); - - ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, - "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), - NULL, pattrs); - - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, - "requesting-user-name", NULL, cupsUser()); - - if (name && op != CUPS_GET_DEFAULT) - { - httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, - "localhost", ippPort(), "/printers/%s", name); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, - uri); - } - - /* - * Do the request and get back a response... - */ - - if ((response = cupsDoRequest(http, request, "/")) != NULL) - { - for (attr = response->attrs; attr != NULL; attr = attr->next) - { - /* - * Skip leading attributes until we hit a printer... - */ - - while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) - attr = attr->next; - - if (attr == NULL) - break; - - /* - * Pull the needed attributes from this printer... - */ - - printer_name = NULL; - num_options = 0; - options = NULL; - - for (; attr && attr->group_tag == IPP_TAG_PRINTER; attr = attr->next) - { - if (attr->value_tag != IPP_TAG_INTEGER && - attr->value_tag != IPP_TAG_ENUM && - attr->value_tag != IPP_TAG_BOOLEAN && - attr->value_tag != IPP_TAG_TEXT && - attr->value_tag != IPP_TAG_TEXTLANG && - attr->value_tag != IPP_TAG_NAME && - attr->value_tag != IPP_TAG_NAMELANG && - attr->value_tag != IPP_TAG_KEYWORD && - attr->value_tag != IPP_TAG_RANGE && - attr->value_tag != IPP_TAG_URI) - continue; - - if (!strcmp(attr->name, "auth-info-required") || - !strcmp(attr->name, "device-uri") || - !strcmp(attr->name, "marker-change-time") || - !strcmp(attr->name, "marker-colors") || - !strcmp(attr->name, "marker-high-levels") || - !strcmp(attr->name, "marker-levels") || - !strcmp(attr->name, "marker-low-levels") || - !strcmp(attr->name, "marker-message") || - !strcmp(attr->name, "marker-names") || - !strcmp(attr->name, "marker-types") || - !strcmp(attr->name, "printer-commands") || - !strcmp(attr->name, "printer-info") || - !strcmp(attr->name, "printer-is-shared") || - !strcmp(attr->name, "printer-make-and-model") || - !strcmp(attr->name, "printer-state") || - !strcmp(attr->name, "printer-state-change-time") || - !strcmp(attr->name, "printer-type") || - !strcmp(attr->name, "printer-is-accepting-jobs") || - !strcmp(attr->name, "printer-location") || - !strcmp(attr->name, "printer-state-reasons") || - !strcmp(attr->name, "printer-uri-supported")) - { - /* - * Add a printer description attribute... - */ - - num_options = cupsAddOption(attr->name, - cups_make_string(attr, value, - sizeof(value)), - num_options, &options); - } -#ifdef __APPLE__ - else if (!strcmp(attr->name, "media-supported")) - { - /* - * See if we can set a default media size... - */ - - int i; /* Looping var */ - - for (i = 0; i < attr->num_values; i ++) - if (!strcasecmp(media_default, attr->values[i].string.text)) - { - num_options = cupsAddOption("media", media_default, num_options, - &options); - break; - } - } -#endif /* __APPLE__ */ - else if (!strcmp(attr->name, "printer-name") && - attr->value_tag == IPP_TAG_NAME) - printer_name = attr->values[0].string.text; - else if (strncmp(attr->name, "notify-", 7) && - (attr->value_tag == IPP_TAG_BOOLEAN || - attr->value_tag == IPP_TAG_ENUM || - attr->value_tag == IPP_TAG_INTEGER || - attr->value_tag == IPP_TAG_KEYWORD || - attr->value_tag == IPP_TAG_NAME || - attr->value_tag == IPP_TAG_RANGE) && - (ptr = strstr(attr->name, "-default")) != NULL) - { - /* - * Add a default option... - */ - - strlcpy(optname, attr->name, sizeof(optname)); - optname[ptr - attr->name] = '\0'; - - if (strcasecmp(optname, "media") || - !cupsGetOption("media", num_options, options)) - num_options = cupsAddOption(optname, - cups_make_string(attr, value, - sizeof(value)), - num_options, &options); - } - } - - /* - * See if we have everything needed... - */ - - if (!printer_name) - { - cupsFreeOptions(num_options, options); - - if (attr == NULL) - break; - else - continue; - } - - if ((dest = cups_add_dest(printer_name, NULL, &num_dests, dests)) != NULL) - { - dest->num_options = num_options; - dest->options = options; - } - else - cupsFreeOptions(num_options, options); - - if (attr == NULL) - break; - } - - ippDelete(response); - } - - /* - * Return the count... - */ - - return (num_dests); -} - - /* * 'cups_make_string()' - Make a comma-separated string of values from an IPP * attribute. diff --git a/cups/http-private.h b/cups/http-private.h index 31c76387a..6b8d031a5 100644 --- a/cups/http-private.h +++ b/cups/http-private.h @@ -313,7 +313,8 @@ extern int _httpAddrPort(http_addr_t *addr); extern http_tls_credentials_t _httpConvertCredentials(cups_array_t *credentials); extern http_t *_httpCreate(const char *host, int port, - http_encryption_t encryption, + http_addrlist_t *addrlist, + http_encryption_t encryption, int family); extern char *_httpDecodeURI(char *dst, const char *src, size_t dstsize); diff --git a/cups/http.c b/cups/http.c index 92997959d..bf56a0a8c 100644 --- a/cups/http.c +++ b/cups/http.c @@ -479,7 +479,7 @@ httpConnectEncrypt( * Create the HTTP structure... */ - if ((http = _httpCreate(host, port, encryption, AF_UNSPEC)) == NULL) + if ((http = _httpCreate(host, port, NULL, encryption, AF_UNSPEC)) == NULL) return (NULL); /* @@ -632,12 +632,12 @@ http_t * /* O - HTTP connection */ _httpCreate( const char *host, /* I - Hostname */ int port, /* I - Port number */ + http_addrlist_t *addrlist, /* I - Address list or NULL */ http_encryption_t encryption, /* I - Encryption to use */ int family) /* I - Address family or AF_UNSPEC */ { - http_t *http; /* New HTTP connection */ - http_addrlist_t *addrlist; /* Host address data */ - char service[255]; /* Service name */ + http_t *http; /* New HTTP connection */ + char service[255]; /* Service name */ DEBUG_printf(("4_httpCreate(host=\"%s\", port=%d, encryption=%d)", @@ -654,8 +654,9 @@ _httpCreate( sprintf(service, "%d", port); - if ((addrlist = httpAddrGetList(host, family, service)) == NULL) - return (NULL); + if (!addrlist) + if ((addrlist = httpAddrGetList(host, family, service)) == NULL) + return (NULL); /* * Allocate memory for the structure... @@ -2278,10 +2279,21 @@ httpReconnect(http_t *http) /* I - Connection to server */ if (http->timeout_value.tv_sec > 0) { +#ifdef WIN32 + DWORD timeout_value = http->timeout_value.tv_sec * 1000 + + http->timeout_value.tv_usec / 1000; + /* Timeout in milliseconds */ + + setsockopt(http->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout_value, + sizeof(timeout_value)); + setsockopt(http->fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_value, + sizeof(timeout_value)); +#else setsockopt(http->fd, SOL_SOCKET, SO_RCVTIMEO, &(http->timeout_value), sizeof(http->timeout_value)); setsockopt(http->fd, SOL_SOCKET, SO_SNDTIMEO, &(http->timeout_value), sizeof(http->timeout_value)); +#endif /* WIN32 */ } http->hostaddr = &(addr->addr); @@ -2563,10 +2575,21 @@ _httpSetTimeout( if (http->fd >= 0) { +#ifdef WIN32 + DWORD timeout_value = http->timeout_value.tv_sec * 1000 + + http->timeout_value.tv_usec / 1000; + /* Timeout in milliseconds */ + + setsockopt(http->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout_value, + sizeof(timeout_value)); + setsockopt(http->fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_value, + sizeof(timeout_value)); +#else setsockopt(http->fd, SOL_SOCKET, SO_RCVTIMEO, &(http->timeout_value), sizeof(http->timeout_value)); setsockopt(http->fd, SOL_SOCKET, SO_SNDTIMEO, &(http->timeout_value), sizeof(http->timeout_value)); +#endif /* WIN32 */ } } diff --git a/cups/langprintf.c b/cups/langprintf.c index c8a680c39..f072e3e02 100644 --- a/cups/langprintf.c +++ b/cups/langprintf.c @@ -72,7 +72,8 @@ _cupsLangPrintError(const char *prefix, /* I - Non-localized message prefix */ * Format the message... */ - snprintf(buffer, sizeof(buffer), "%s%s: %s\n", prefix ? prefix : "", + snprintf(buffer, sizeof(buffer), "%s%s%s: %s\n", prefix ? prefix : "", + prefix ? ": " : "", _cupsLangString(cg->lang_default, message), strerror(last_errno)); /* diff --git a/cups/language.c b/cups/language.c index 2d07c3184..efeb6058b 100644 --- a/cups/language.c +++ b/cups/language.c @@ -442,7 +442,7 @@ cupsLangGet(const char *language) /* I - Language or locale */ strcpy(charset, "UTF8"); /* - * Apple's setlocale doesn't give us the user's localization + * Apple's setlocale doesn't give us the user's localization * preference so we have to look it up this way... */ @@ -946,7 +946,7 @@ _cupsMessageLoad(const char *filename, /* I - Message catalog to load */ /* * Find start of value... */ - + if ((ptr = strchr(s, '\"')) == NULL) continue; @@ -1107,10 +1107,17 @@ _cupsMessageLookup(cups_array_t *a, /* I - Message array */ CFStringGetCString(cfstr, buffer, sizeof(buffer), kCFStringEncodingUTF8); match->str = strdup(buffer); + + DEBUG_printf(("1_cupsMessageLookup: Found \"%s\" as \"%s\"...", + m, buffer)); } else + { match->str = strdup(m); + DEBUG_printf(("1_cupsMessageLookup: Did not find \"%s\"...", m)); + } + cupsArrayAdd(a, match); if (cfm) @@ -1206,7 +1213,7 @@ appleLangDefault(void) { DEBUG_printf(("9appleLangDefault: mapping \"%s\" to \"%s\"...", cg->language, apple_language_locale[i].locale)); - strlcpy(cg->language, apple_language_locale[i].locale, + strlcpy(cg->language, apple_language_locale[i].locale, sizeof(cg->language)); break; } @@ -1227,7 +1234,7 @@ appleLangDefault(void) CFRelease(localizationList); } - + /* * If we didn't find the language, default to en_US... */ @@ -1264,8 +1271,14 @@ CF_RETURNS_RETAINED char filename[1024], /* Path to cups.strings file */ applelang[256]; /* Apple language ID */ CFURLRef url; /* URL to cups.strings file */ - CFReadStreamRef stream; /* File */ - CFDictionaryRef dict; /* Localization dictionary */ + CFReadStreamRef stream = NULL; /* File stream */ + CFPropertyListRef plist = NULL; /* Localization file */ +#ifdef DEBUG + CFErrorRef error = NULL; /* Error when opening file */ +#endif /* DEBUG */ + + + DEBUG_printf(("appleMessageLoad(locale=\"%s\")", locale)); /* * Load the cups.strings file... @@ -1274,23 +1287,87 @@ CF_RETURNS_RETAINED snprintf(filename, sizeof(filename), CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", _cupsAppleLanguage(locale, applelang, sizeof(applelang))); + DEBUG_printf(("1appleMessageLoad: filename=\"%s\"", filename)); + + if (access(filename, 0)) + { + /* + * Try alternate lproj directory names... + */ + + if (!strncmp(locale, "en", 2)) + locale = "English"; + else if (!strncmp(locale, "nb", 2) || !strncmp(locale, "nl", 2)) + locale = "Dutch"; + else if (!strncmp(locale, "fr", 2)) + locale = "French"; + else if (!strncmp(locale, "de", 2)) + locale = "German"; + else if (!strncmp(locale, "it", 2)) + locale = "Italian"; + else if (!strncmp(locale, "ja", 2)) + locale = "Japanese"; + else if (!strncmp(locale, "es", 2)) + locale = "Spanish"; + + snprintf(filename, sizeof(filename), + CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", locale); + DEBUG_printf(("1appleMessageLoad: alternate filename=\"%s\"", filename)); + } + + url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, + (UInt8 *)filename, + strlen(filename), false); + if (url) + { + stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url); + if (stream) + { + CFReadStreamOpen(stream); + +#ifdef DEBUG + plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, stream, 0, + kCFPropertyListImmutable, NULL, + &error); + if (error) + { + CFStringRef msg = CFErrorCopyDescription(error); + /* Error message */ + + CFStringGetCString(msg, filename, sizeof(filename), + kCFStringEncodingUTF8); + DEBUG_printf(("1appleMessageLoad: %s", filename)); + + CFRelease(error); + } + +#else + plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, stream, 0, + kCFPropertyListImmutable, NULL, + NULL); +#endif /* DEBUG */ + + if (plist && CFGetTypeID(plist) != CFDictionaryGetTypeID()) + { + CFRelease(plist); + plist = NULL; + } + + CFRelease(stream); + } + + CFRelease(url); + } - url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, - (UInt8 *)filename, - strlen(filename), false); - stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url); - dict = (CFDictionaryRef)CFPropertyListCreateWithStream( - kCFAllocatorDefault, stream, 0, kCFPropertyListImmutable, NULL, - NULL); - CFRelease(stream); - CFRelease(url); + DEBUG_printf(("1appleMessageLoad: url=%p, stream=%p, plist=%p", url, stream, + plist)); /* * Create and return an empty array to act as a cache for messages, passing the - * dictionary as the user data. + * plist as the user data. */ - return (cupsArrayNew3((cups_array_func_t)cups_message_compare, (void *)dict, + return (cupsArrayNew3((cups_array_func_t)cups_message_compare, (void *)plist, (cups_ahash_func_t)NULL, 0, (cups_acopy_func_t)NULL, (cups_afree_func_t)cups_message_free)); diff --git a/cups/libcups2.def b/cups/libcups2.def index 798c82f65..35c382576 100644 --- a/cups/libcups2.def +++ b/cups/libcups2.def @@ -1,8 +1,11 @@ LIBRARY libcups2 VERSION 2.9 EXPORTS +_cupsGet1284Values +_cupsGetDests _cupsGetPassword _cupsGlobals +_cupsLangPrintError _cupsLangPrintf _cupsLangPuts _cupsLangString @@ -18,13 +21,19 @@ _cupsStrAlloc _cupsStrFlush _cupsStrFormatd _cupsStrFree +_cupsStrRetain _cupsStrScand _cupsStrStatistics _cups_strcpy _cups_strlcat _cups_strlcpy +_httpAddrPort +_httpCreate +_httpEncodeURI +_httpPeek _httpResolveURI _httpSetTimeout +_httpWait _ippAddAttr _ippAttrString _ippFindOption @@ -33,6 +42,9 @@ _ppdFreeLanguages _ppdGetEncoding _ppdGetLanguages _ppdHashName +_ppdLocalizedAttr +_ppdNormalizeMakeAndModel +_ppdParseOptions _pwgCreateWithFile _pwgDestroy _pwgWriteFile @@ -66,10 +78,14 @@ cupsArrayDelete cupsArrayDup cupsArrayFind cupsArrayFirst +cupsArrayGetIndex +cupsArrayGetInsert cupsArrayIndex cupsArrayInsert cupsArrayLast cupsArrayNew +cupsArrayNew2 +cupsArrayNew3 cupsArrayNext cupsArrayPrev cupsArrayRemove @@ -155,12 +171,14 @@ cupsRemoveOption cupsResolveConflicts cupsSendRequest cupsServer +cupsSetClientCertCB cupsSetCredentials cupsSetDests cupsSetDests2 cupsSetEncryption cupsSetPasswordCB cupsSetServer +cupsSetServerCertCB cupsSetUser cupsTempFd cupsTempFile diff --git a/cups/libcups_s.exp b/cups/libcups_s.exp index db57eea66..b86fbe759 100644 --- a/cups/libcups_s.exp +++ b/cups/libcups_s.exp @@ -1,5 +1,6 @@ _cups_debug_fd _cupsGet1284Values +_cupsGetDests _cupsGetPassword _cupsGlobals _cupsLangPrintError @@ -44,8 +45,10 @@ _httpCreate _httpEncodeURI _httpPeek _httpResolveURI +_httpSetTimeout _httpWait _ippAddAttr +_ippFindOption _ippFreeAttr _ppdFreeLanguages _ppdGetEncoding diff --git a/cups/raster.h b/cups/raster.h index dbb7e30b8..eabd190be 100644 --- a/cups/raster.h +++ b/cups/raster.h @@ -55,6 +55,8 @@ extern "C" { # define CUPS_RASTER_SYNCv2 0x52615332 /* RaS2 */ # define CUPS_RASTER_REVSYNCv2 0x32536152 /* 2SaR */ +# define CUPS_RASTER_SYNC_PWG CUPS_RASTER_SYNCv2 + /* * The following definition can be used to determine if the @@ -171,7 +173,8 @@ enum cups_mode_e /**** cupsRasterOpen modes ****/ { CUPS_RASTER_READ = 0, /* Open stream for reading */ CUPS_RASTER_WRITE = 1, /* Open stream for writing */ - CUPS_RASTER_WRITE_COMPRESSED = 2 /* Open stream for compressed writing @since CUPS 1.3/Mac OS X 10.5@ */ + CUPS_RASTER_WRITE_COMPRESSED = 2, /* Open stream for compressed writing @since CUPS 1.3/Mac OS X 10.5@ */ + CUPS_RASTER_WRITE_PWG = 3 /* Open stream for compressed writing in PWG mode @since CUPS 1.5@ */ }; typedef enum cups_mode_e cups_mode_t; /**** cupsRasterOpen modes ****/ @@ -331,6 +334,19 @@ typedef int (*cups_interpret_cb_t)(cups_page_header2_t *header, int preferred_bi * dictionary and is 0 if undefined. ****/ +/**** New in CUPS 1.5 ****/ +typedef ssize_t (*cups_raster_iocb_t)(void *ctx, unsigned char *buffer, size_t length); + /**** cupsRasterOpenIO callback function + * + * This function is specified when + * creating a raster stream with + * @link cupsRasterOpenIO@ and handles + * generic reading and writing of raster + * data. It must return -1 on error or + * the number of bytes specified by + * "length" on success. + ****/ + /* * Prototypes... @@ -361,6 +377,10 @@ extern unsigned cupsRasterWriteHeader2(cups_raster_t *r, /**** New in CUPS 1.3 ****/ extern const char *cupsRasterErrorString(void) _CUPS_API_1_3; +/**** New in CUPS 1.5 ****/ +extern cups_raster_t *cupsRasterOpenIO(cups_raster_iocb_t iocb, void *ctx, + cups_mode_t mode); + # ifdef __cplusplus } # endif /* __cplusplus */ diff --git a/cups/testppd.c b/cups/testppd.c index bb5567e0f..47cfa01e9 100644 --- a/cups/testppd.c +++ b/cups/testppd.c @@ -826,10 +826,23 @@ main(int argc, /* I - Number of command-line arguments */ if (!strncmp(argv[1], "-d", 2)) { - filename = cupsGetPPD(argv[1] + 2); + const char *printer; /* Printer name */ + + if (argv[1][2]) + printer = argv[1] + 2; + else if (argv[2]) + printer = argv[2]; + else + { + puts("Usage: ./testppd -d printer"); + return (1); + } + + filename = cupsGetPPD(printer); + if (!filename) { - printf("%s: %s\n", argv[1], cupsLastErrorString()); + printf("%s: %s\n", printer, cupsLastErrorString()); return (1); } } diff --git a/doc/eu/index.html.in b/doc/eu/index.html.in index 42780f9af..5b79b6ae2 100644 --- a/doc/eu/index.html.in +++ b/doc/eu/index.html.in @@ -99,7 +99,7 @@ HEIGHT="128" ALT="CUPS">   -CUPS eta CUPSen logotipoa Apple Inc.en marka erregistratuaj dira. +CUPS eta CUPSen logotipoa Apple Inc. en marka erregistratuak dira. CUPSen copyright-a 2007-2011 Apple Inc. Eskubide guztiak gordeta. diff --git a/doc/help/api-raster.html b/doc/help/api-raster.html index 5e8eff47e..11ea0f2b7 100644 --- a/doc/help/api-raster.html +++ b/doc/help/api-raster.html @@ -388,7 +388,8 @@ div.contents ul.subcontents li {
  • Functions
  • Structures
      @@ -658,7 +660,7 @@ are supported.

      cupsRasterOpen

      -

      Open a raster stream.

      +

      Open a raster stream using a file descriptor.

      cups_raster_t *cupsRasterOpen (
          int fd,
      @@ -669,7 +671,10 @@ are supported.

      fd
      File descriptor
      mode
      -
      Mode - CUPS_RASTER_READ, CUPS_RASTER_WRITE, or CUPS_RASTER_WRITE_COMPRESSED
      +
      Mode - CUPS_RASTER_READ, +CUPS_RASTER_WRITE, +CUPS_RASTER_WRITE_COMPRESSED, +or CUPS_RASTER_WRITE_PWG

      Return Value

      New stream

      @@ -679,9 +684,40 @@ For most printer driver filters, "fd" will be 0 (stdin). For most ras image processor (RIP) filters that generate raster data, "fd" will be 1 (stdout).

      -When writing raster data, the CUPS_RASTER_WRITE or -CUPS_RASTER_WRITE_COMPRESS mode can be used - compressed output -is generally 25-50% smaller but adds a 100-300% execution time overhead.

      +When writing raster data, the CUPS_RASTER_WRITE, +CUPS_RASTER_WRITE_COMPRESS, or CUPS_RASTER_WRITE_PWG mode can +be used - compressed and PWG output is generally 25-50% smaller but adds a +100-300% execution time overhead.

      +

      cupsRasterOpenIO

      +

      Open a raster stream using a callback function.

      +

      +cups_raster_t *cupsRasterOpenIO (
      +    cups_raster_iocb_t iocb,
      +    void *ctx,
      +    cups_mode_t mode
      +);

      +

      Parameters

      +
      +
      iocb
      +
      Read/write callback
      +
      ctx
      +
      Context pointer for callback
      +
      mode
      +
      Mode - CUPS_RASTER_READ, +CUPS_RASTER_WRITE, +CUPS_RASTER_WRITE_COMPRESSED, +or CUPS_RASTER_WRITE_PWG
      +
      +

      Return Value

      +

      New stream

      +

      Discussion

      +

      This function associates a raster stream with the given callback function and +context pointer.
      +
      +When writing raster data, the CUPS_RASTER_WRITE, +CUPS_RASTER_WRITE_COMPRESS, or CUPS_RASTER_WRITE_PWG mode can +be used - compressed and PWG output is generally 25-50% smaller but adds a +100-300% execution time overhead.

       DEPRECATED cupsRasterReadHeader

      Read a raster page header and store it in a version 1 page header structure.

      @@ -873,6 +909,11 @@ typedef struct cups_page_header2_s cups_page_

      typedef struct cups_page_header_s cups_page_header_t;

      +

      cups_raster_iocb_t

      +

      cupsRasterOpenIO callback function

      +

      +typedef ssize_t (*cups_raster_iocb_t)(void *ctx, unsigned char *buffer, size_t length); +

      cups_raster_t

      Raster stream data

      @@ -1343,6 +1384,8 @@ factor not applied)

      Open stream for writing
      CUPS_RASTER_WRITE_COMPRESSED  CUPS 1.3/Mac OS X 10.5 
      Open stream for compressed writing
      +
      CUPS_RASTER_WRITE_PWG  CUPS 1.5 
      +
      Open stream for compressed writing in PWG mode

      cups_order_e

      cupsColorOrder attribute values

      diff --git a/doc/help/options.html b/doc/help/options.html index e3b5820be..83ca97528 100644 --- a/doc/help/options.html +++ b/doc/help/options.html @@ -416,7 +416,7 @@ assign a priority to your job from 1 (lowest) to 100 (highest), which influences where the job appears in the print queue. Higher priority jobs are printed before lower priority jobs, however submitting a new job with a high priority will not interrupt an -

      +already printing job.

      Specifying the Output Order

      @@ -548,7 +548,7 @@ for printers that print face up.

      Printing Mirrored Pages

      The -o mirror option flips each page along the -vertical access to produce a mirrored image:

      +vertical axis to produce a mirrored image:

       lp -o mirror filename
      diff --git a/doc/help/spec-ppd.html b/doc/help/spec-ppd.html
      index 02645d316..096bcff99 100644
      --- a/doc/help/spec-ppd.html
      +++ b/doc/help/spec-ppd.html
      @@ -404,9 +404,11 @@ div.contents ul.subcontents li {
       	
    • cupsEvenDuplex
    • cupsFax
    • cupsFilter
    • +
    • cupsFilter2
    • cupsFlipDuplex
    • cupsIPPFinishings
    • cupsIPPReason
    • +
    • cupsIPPSupplies
    • cupsLanguages
    • cupsManualCopies
    • cupsMarkerName
    • @@ -466,19 +468,14 @@ LINE-END = CR / LF / CR LF

      CUPS supports several methods of auto-configuration via PPD keywords.

      -

      DeprecatedAPAutoSetupTool

      +

      Mac OS X 10.5APAutoSetupTool

      *APAutoSetupTool: "/LibraryPrinters/vendor/filename"

      -

      This deprecated keyword defines a program that sets the default option choices. It is run when a printer is added from the Add Printer window or the Nearby Printers list in the Print dialog.

      +

      This Mac OS X keyword defines a program that sets the default option choices. It is run when a printer is added from the Add Printer window or the Nearby Printers list in the Print dialog.

      The program is provided with two arguments: the printer's device URI and the PPD file to be used for the printer. The program must write an updated PPD file to stdout.

      -
      Note: - -

      This keyword is deprecated. New printer drivers SHOULD provide a CUPS command filter and support the "AutoConfigure" command. Alternately, drivers MAY use the SNMP OID keywords to configure network printers or PostScript query keywords to configure PostScript printers.

      - -

      Examples:

      @@ -572,13 +569,13 @@ f(x) = density * x gamma
       

      Examples:

      -*% Specify a profile for printing at 360dpi on all media types 
      +*% Specify a profile for printing at 360dpi on all media types
       *cupsColorProfile 360dpi/-: "1.0 1.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
       
      -*% Specify a profile for printing at 720dpi on Glossy media 
      +*% Specify a profile for printing at 720dpi on Glossy media
       *cupsColorProfile 720dpi/Glossy: "1.0 2.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
       
      -*% Specify a default profile for printing at all other resolutions and media types 
      +*% Specify a default profile for printing at all other resolutions and media types
       *cupsColorProfile -/-: "0.9 2.0 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
       
      @@ -594,13 +591,13 @@ f(x) = density * x gamma

      Examples:

      -*% Specify a profile for CMYK printing at 360dpi on all media types 
      +*% Specify a profile for CMYK printing at 360dpi on all media types
       *cupsICCProfile CMYK..360dpi/360dpi CMYK: "/Library/Printers/vendor/Profiles/foo-360-cmyk.icc"
       
      -*% Specify a profile for RGB printing at 720dpi on Glossy media 
      +*% Specify a profile for RGB printing at 720dpi on Glossy media
       *cupsColorProfile RGB.Glossy.720dpi/720dpi Glossy: "/Library/Printers/vendor/Profiles/foo-720-glossy-rgb.icc"
       
      -*% Specify a default profile for printing at all other resolutions and media types 
      +*% Specify a default profile for printing at all other resolutions and media types
       *cupsICCProfile ../Default: "/Library/Printers/vendor/Profiles/foo-default.icc"
       
      @@ -734,10 +731,10 @@ f(x) = density * x gamma

      Examples:

      -*% Specify that 2-sided printing cannot happen on transparencies 
      +*% Specify that 2-sided printing cannot happen on transparencies
       *cupsUIConstraints transparency: "*Duplex *MediaType Transparency"
       
      -*% Specify that envelope printing cannot happen from the paper trays 
      +*% Specify that envelope printing cannot happen from the paper trays
       *cupsUIConstraints envelope: "*PageSize Env10 *InputSlot Tray1"
       *cupsUIConstraints envelope: "*PageSize Env10 *InputSlot Tray1"
       *cupsUIConstraints envelope: "*PageSize EnvDL *InputSlot Tray2"
      @@ -746,7 +743,7 @@ f(x) = density * x gamma
       *% Specify an installable option constraint for the envelope feeder
       *cupsUIConstraints: "*InputSlot EnvFeeder *InstalledEnvFeeder"
       
      -*% Specify that photo printing cannot happen on plain paper or transparencies at 1200dpi 
      +*% Specify that photo printing cannot happen on plain paper or transparencies at 1200dpi
       *cupsUIConstraints photo: "*OutputMode Photo *MediaType Plain *Resolution 1200dpi"
       *cupsUIConstraints photo: "*OutputMode Photo *MediaType Transparency *Resolution 1200dpi"
       
      @@ -760,7 +757,7 @@ f(x) = density * x gamma

      Examples:

      -*% Specify the options to change for the 2-sided transparency constraint 
      +*% Specify the options to change for the 2-sided transparency constraint
       *cupsUIResolver transparency: "*Duplex None *MediaType Plain"
       
       *% Specify the options to change for the envelope printing constraints.  Notice
      @@ -768,7 +765,7 @@ f(x) = density * x gamma
       *% manual feed first, then we change the page size...
       *cupsUIResolver envelope: "*InputSlot EnvFeeder *InputSlot ManualFeed *PageSize Letter"
       
      -*% Specify the options to change for the photo printing constraints 
      +*% Specify the options to change for the photo printing constraints
       *cupsUIResolver photo: "*OutputMode Best *Resolution 600dpi"
       
      @@ -895,7 +892,7 @@ option value is "1234" then CUPS will output the string "@PJL SET PASSCODE=1234"

      Examples:

      -*% Base JCL key code option 
      +*% Base JCL key code option
       *JCLOpenUI JCLPasscode/Key Code: PickOne
       *OrderDependency: 10 JCLSetup *JCLPasscode
       *DefaultJCLPasscode: None
      @@ -905,7 +902,7 @@ option value is "1234" then CUPS will output the string "@PJL SET PASSCODE=1234"
       *JCLPasscode 3333: "@PJL SET PASSCODE = 3333<0A>"
       *JCLCloseUI: *JCLPasscode
       
      -*% Custom JCL key code option 
      +*% Custom JCL key code option
       *CustomJCLPasscode True: "@PJL SET PASSCODE = \1<0A>"
       *ParamCustomJCLPasscode Code/Key Code: 1 passcode 4 4
       
      @@ -923,7 +920,7 @@ option value is "1234" then CUPS will output the string "@PJL SET PASSCODE=1234"
       *ParamCustomWatermarkText Text: 1 string 0 32
       
       
      -*% Base PostScript gamma/density option 
      +*% Base PostScript gamma/density option
       *OpenUI GammaDensity/Gamma and Density: PickOne
       *OrderDependency: 10 AnySetup *GammaDensity
       *DefaultGammaDensity: Normal
      @@ -932,7 +929,7 @@ option value is "1234" then CUPS will output the string "@PJL SET PASSCODE=1234"
       *GammaDensity Dark/Darker: "<</cupsReal1 1.1/cupsReal2 1.5>>setpagedevice"
       *CloseUI: *GammaDensity
       
      -*% Custom PostScript gamma/density option 
      +*% Custom PostScript gamma/density option
       *CustomGammaDensity True: "<</cupsReal1 3 -1 roll/cupsReal2 5 -1>>setpagedevice"
       *ParamCustomGammaDensity Gamma: 1 curve 0.1 10
       *ParamCustomGammaDensity Density: 2 real 0 2
      @@ -1484,10 +1481,10 @@ will be ignored.

      Examples:

      -*% Flip the page image for the back side of duplexed output 
      +*% Flip the page image for the back side of duplexed output
       *cupsBackSide: Flipped
       
      -*% Rotate the page image for the back side of duplexed output 
      +*% Rotate the page image for the back side of duplexed output
       *cupsBackSide: Rotated
       
      @@ -1505,7 +1502,7 @@ by whitespace.

      Example:

      -*% Specify the list of commands we support 
      +*% Specify the list of commands we support
       *cupsCommands: "AutoConfigure Clean PrintSelfTestPage ReportLevels com.vendor.foo"
       
      @@ -1521,7 +1518,7 @@ printing is selected. The default value is false.

      Example:

      -*% Always send an even number of pages when duplexing 
      +*% Always send an even number of pages when duplexing
       *cupsEvenDuplex: true
       
      @@ -1549,16 +1546,35 @@ the special filter program "-" may be specified.

      Examples:

      -*% Standard raster printer driver filter 
      +*% Standard raster printer driver filter
       *cupsFilter: "application/vnd.cups-raster 100 rastertofoo"
       
      -*% Plain text filter 
      +*% Plain text filter
       *cupsFilter: "text/plain 10 texttofoo"
       
      -*% Pass-through filter for PostScript printers 
      +*% Pass-through filter for PostScript printers
       *cupsFilter: "application/vnd.cups-postscript 0 -"
       
      +

      cupsFilter2

      + +

      *cupsFilter2: "source/type destination/type cost program"

      + +

      This string keyword provides a conversion rule from the given source type to the printer's native format using the filter "program". If a printer supports the source type directly, the special filter program "-" may be specified. The destination type is automatically created as needed and is passed to the filters and backend as the FINAL_CONTENT_TYPE value.

      + +

      Examples:

      + +
      +*% Standard raster printer driver filter
      +*cupsFilter2: "application/vnd.cups-raster application/vnd.foo 100 rastertofoo"
      +
      +*% Plain text filter
      +*cupsFilter2: "text/plain application/vnd.foo 10 texttofoo"
      +
      +*% Pass-through filter for PostScript printers
      +*cupsFilter2: "application/vnd.cups-postscript application/postscript 0 -"
      +
      +

      DeprecatedcupsFlipDuplex

      *cupsFlipDuplex: boolean

      @@ -1654,6 +1670,19 @@ http://www.vendor.com/help" *End
      +

      CUPS 1.5cupsIPPSupplies

      + +

      *cupsIPPSupplies: boolean

      + +

      This keyword tells the IPP backend whether it should report the current marker-xxx supply attribute values. The default value is True. + +

      Example:

      + +
      +*% Do not use IPP marker-xxx attributes to report supply levels
      +*cupsIPPSupplies: False
      +
      +

      CUPS 1.2/Mac OS X 10.5cupsLanguages

      *cupsLanguages: "locale list"

      @@ -1665,7 +1694,7 @@ list of locale names ("en", "en_US", "fr_CA", etc.)

      Example:

      -*% Specify Canadian, UK, and US English, and Candian and French French 
      +*% Specify Canadian, UK, and US English, and Candian and French French
       *cupsLanguages: "en_CA en_UK en_US fr_CA fr_FR"
       
      @@ -1680,7 +1709,7 @@ hardware. The default value is false.

      Example:

      -*% Tell the RIP filters to generate the copies for us 
      +*% Tell the RIP filters to generate the copies for us
       *cupsManualCopies: true
       
      @@ -1723,7 +1752,7 @@ the output for a specific model of printer.

      Example:

      -*% Specify an integer for a driver-specific model number 
      +*% Specify an integer for a driver-specific model number
       *cupsModelNumber: 1234
       
      @@ -1789,7 +1818,7 @@ to disable the port monitor for the given URI scheme.

      *cupsPortMonitor socket/AppSocket Printing: "tbcp" *cupsPortMonitor usb/USB Printing: "none" -*% Specify a printer-specific port monitor for an Epson USB printer +*% Specify a printer-specific port monitor for an Epson USB printer *cupsPortMonitor usb/USB Status Monitor: "epson-usb"
      @@ -1798,7 +1827,7 @@ to disable the port monitor for the given URI scheme.

      *cupsPreFilter: "source/type cost program"

      This string keyword provides a pre-filter rule. The pre-filter -program will be inserted in the conversion chain immediately +program will be inserted in the conversion chain immediately before the filter that accepts the given MIME type.

      Examples:

      @@ -1862,7 +1891,7 @@ PPD file extensions was used. Currently it must be the string

      Example:

      -*% Specify a CUPS 1.2 driver 
      +*% Specify a CUPS 1.2 driver
       *cupsVersion: "1.2"
       
      @@ -1970,7 +1999,7 @@ and the Tumble page attribute.

      *% Rotate the back side images *cupsBackSide: Rotated -*% Don't swap the top and bottom margins for the back side +*% Don't swap the top and bottom margins for the back side *APDuplexRequiresFlippedMargin: false
      diff --git a/filter/bannertops.c b/filter/bannertops.c index db485f1fb..9c94339cb 100644 --- a/filter/bannertops.c +++ b/filter/bannertops.c @@ -202,6 +202,8 @@ load_banner(const char *filename) /* I - Filename or NULL for stdin */ linenum ++; + fprintf(stderr, "DEBUG: %4d %s\n", linenum, line); + if (line[0] == '#' || !line[0]) continue; diff --git a/filter/error.c b/filter/error.c index 4f51d2bc0..2fbb0f24c 100644 --- a/filter/error.c +++ b/filter/error.c @@ -78,7 +78,7 @@ _cupsRasterAddError(const char *f, /* I - Printf-style error message */ if (bytes >= sizeof(s)) return; - if (bytes > (buf->end - buf->current)) + if (bytes > (size_t)(buf->end - buf->current)) { /* * Allocate more memory... diff --git a/filter/gziptoany.c b/filter/gziptoany.c index 4114511f9..404ce6e3a 100644 --- a/filter/gziptoany.c +++ b/filter/gziptoany.c @@ -3,7 +3,7 @@ * * GZIP/raw pre-filter for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1993-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -76,8 +76,6 @@ main(int argc, /* I - Number of command-line arguments */ * Copy the file to stdout... */ - setbuf(stdout, NULL); - while (copies > 0) { if (!getenv("FINAL_CONTENT_TYPE")) @@ -86,11 +84,11 @@ main(int argc, /* I - Number of command-line arguments */ cupsFileRewind(fp); while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0) - if (fwrite(buffer, 1, bytes, stdout) < bytes) + if (write(1, buffer, bytes) < bytes) { _cupsLangPrintFilter(stderr, "ERROR", _("Unable to write uncompressed print data: %s"), - strerror(ferror(stdout))); + strerror(errno)); cupsFileClose(fp); return (1); diff --git a/filter/interpret.c b/filter/interpret.c index 035de19fd..7d0cb570a 100644 --- a/filter/interpret.c +++ b/filter/interpret.c @@ -263,10 +263,10 @@ cupsRasterInterpretPPD( if ((val = cupsGetOption("cupsBorderlessScalingFactor", num_options, options)) != NULL) { - float sc = atof(val); + double sc = atof(val); /* Scale factor */ if (sc >= 0.1 && sc <= 2.0) - h->cupsBorderlessScalingFactor = sc; + h->cupsBorderlessScalingFactor = (float)sc; } /* @@ -301,20 +301,26 @@ cupsRasterInterpretPPD( top = 792.0f; } - h->PageSize[0] = h->cupsPageSize[0] * - h->cupsBorderlessScalingFactor; - h->PageSize[1] = h->cupsPageSize[1] * - h->cupsBorderlessScalingFactor; - h->Margins[0] = left * h->cupsBorderlessScalingFactor; - h->Margins[1] = bottom * h->cupsBorderlessScalingFactor; - h->ImagingBoundingBox[0] = left * h->cupsBorderlessScalingFactor; - h->ImagingBoundingBox[1] = bottom * h->cupsBorderlessScalingFactor; - h->ImagingBoundingBox[2] = right * h->cupsBorderlessScalingFactor; - h->ImagingBoundingBox[3] = top * h->cupsBorderlessScalingFactor; - h->cupsImagingBBox[0] = left; - h->cupsImagingBBox[1] = bottom; - h->cupsImagingBBox[2] = right; - h->cupsImagingBBox[3] = top; + h->PageSize[0] = (unsigned)(h->cupsPageSize[0] * + h->cupsBorderlessScalingFactor); + h->PageSize[1] = (unsigned)(h->cupsPageSize[1] * + h->cupsBorderlessScalingFactor); + h->Margins[0] = (unsigned)(left * + h->cupsBorderlessScalingFactor); + h->Margins[1] = (unsigned)(bottom * + h->cupsBorderlessScalingFactor); + h->ImagingBoundingBox[0] = (unsigned)(left * + h->cupsBorderlessScalingFactor); + h->ImagingBoundingBox[1] = (unsigned)(bottom * + h->cupsBorderlessScalingFactor); + h->ImagingBoundingBox[2] = (unsigned)(right * + h->cupsBorderlessScalingFactor); + h->ImagingBoundingBox[3] = (unsigned)(top * + h->cupsBorderlessScalingFactor); + h->cupsImagingBBox[0] = (float)left; + h->cupsImagingBBox[1] = (float)bottom; + h->cupsImagingBBox[2] = (float)right; + h->cupsImagingBBox[3] = (float)top; /* * Use the callback to validate the page header... @@ -1454,8 +1460,8 @@ setpagedevice( if (obj[1].type == CUPS_PS_NUMBER && obj[2].type == CUPS_PS_NUMBER && obj[3].type == CUPS_PS_END_ARRAY) { - h->cupsPageSize[0] = obj[1].value.number; - h->cupsPageSize[1] = obj[2].value.number; + h->cupsPageSize[0] = (float)obj[1].value.number; + h->cupsPageSize[1] = (float)obj[2].value.number; h->PageSize[0] = (unsigned)obj[1].value.number; h->PageSize[1] = (unsigned)obj[2].value.number; @@ -1492,7 +1498,7 @@ setpagedevice( h->cupsRowStep = (unsigned)obj->value.number; else if (!strcmp(name, "cupsBorderlessScalingFactor") && obj->type == CUPS_PS_NUMBER) - h->cupsBorderlessScalingFactor = obj->value.number; + h->cupsBorderlessScalingFactor = (float)obj->value.number; else if (!strncmp(name, "cupsInteger", 11) && obj->type == CUPS_PS_NUMBER) { if ((i = atoi(name + 11)) < 0 || i > 15) @@ -1505,7 +1511,7 @@ setpagedevice( if ((i = atoi(name + 8)) < 0 || i > 15) return (-1); - h->cupsReal[i] = obj->value.number; + h->cupsReal[i] = (float)obj->value.number; } else if (!strncmp(name, "cupsString", 10) && obj->type == CUPS_PS_STRING) { diff --git a/filter/pstext.c b/filter/pstext.c index 2b38b3af7..cfd8f08bb 100644 --- a/filter/pstext.c +++ b/filter/pstext.c @@ -85,8 +85,10 @@ psTextEmbedFonts(ps_text_t *fonts) /* I - Font data */ fclose(fp); } else - fprintf(stderr, "DEBUG: Unable to open font file \"%s\" - %s\n", - filename, strerror(errno)); + { + _cupsLangPrintError("ERROR", _("Unable to open print file")); + fprintf(stderr, "DEBUG: Unable to open \"%s\".\n", filename); + } puts("\n%%EndResource"); } @@ -245,6 +247,7 @@ psTextInitialize(void) else { _cupsLangPrintError("ERROR", _("Unable to open print file")); + fprintf(stderr, "DEBUG: Unable to open \"%s\".\n", filename); exit(1); } @@ -261,6 +264,7 @@ psTextInitialize(void) */ _cupsLangPrintError("ERROR", _("Unable to open print file")); + fprintf(stderr, "DEBUG: Unable to open \"%s\".\n", filename); exit(1); } diff --git a/filter/raster.c b/filter/raster.c index c6d2fec3b..d864634a9 100644 --- a/filter/raster.c +++ b/filter/raster.c @@ -3,7 +3,7 @@ * * Raster file routines for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * * This file is part of the CUPS Imaging library. @@ -19,7 +19,8 @@ * Contents: * * cupsRasterClose() - Close a raster stream. - * cupsRasterOpen() - Open a raster stream. + * cupsRasterOpen() - Open a raster stream using a file descriptor. + * cupsRasterOpenIO() - Open a raster stream using a callback function. * cupsRasterReadHeader() - Read a raster page header and store it in a * version 1 page header structure. * cupsRasterReadHeader2() - Read a raster page header and store it in a @@ -30,14 +31,14 @@ * cupsRasterWriteHeader2() - Write a raster page header from a version 2 * page header structure. * cupsRasterWritePixels() - Write raster pixels. - * cups_raster_read() - Read through the raster buffer. * cups_raster_read_header() - Read a raster page header. + * cups_raster_read() - Read through the raster buffer. * cups_raster_update() - Update the raster header and row count for the * current page. - * cups_raster_write() - Write a row of raster data... - * cups_read() - Read bytes from a file. + * cups_raster_write() - Write a row of compressed raster data... + * cups_read_fd() - Read bytes from a file. * cups_swap() - Swap bytes in raster data... - * cups_write() - Write bytes to a file. + * cups_write_fd() - Write bytes to a file. */ /* @@ -47,6 +48,7 @@ #include "image-private.h" #if defined(WIN32) || defined(__EMX__) # include +# include /* for htonl() definition */ #else # include #endif /* WIN32 || __EMX__ */ @@ -59,7 +61,8 @@ struct _cups_raster_s /**** Raster stream data ****/ { unsigned sync; /* Sync word from start of stream */ - int fd; /* File descriptor */ + void *ctx; /* File descriptor */ + cups_raster_iocb_t iocb; /* IO callback */ cups_mode_t mode; /* Read/write mode */ cups_page_header2_t header; /* Raster header for current page */ int count, /* Current row run-length count */ @@ -73,7 +76,7 @@ struct _cups_raster_s /**** Raster stream data ****/ unsigned char *buffer, /* Read/write buffer */ *bufptr, /* Current (read) position in buffer */ *bufend; /* End of current (read) buffer */ - int bufsize; /* Buffer size */ + size_t bufsize; /* Buffer size */ }; @@ -85,10 +88,11 @@ static unsigned cups_raster_read_header(cups_raster_t *r); static int cups_raster_read(cups_raster_t *r, unsigned char *buf, int bytes); static void cups_raster_update(cups_raster_t *r); -static int cups_raster_write(cups_raster_t *r, const unsigned char *pixels); -static int cups_read(int fd, unsigned char *buf, int bytes); +static int cups_raster_write(cups_raster_t *r, + const unsigned char *pixels); +static ssize_t cups_read_fd(void *ctx, unsigned char *buf, size_t bytes); static void cups_swap(unsigned char *buf, int bytes); -static int cups_write(int fd, const unsigned char *buf, int bytes); +static ssize_t cups_write_fd(void *ctx, unsigned char *buf, size_t bytes); /* @@ -115,21 +119,53 @@ cupsRasterClose(cups_raster_t *r) /* I - Stream to close */ /* - * 'cupsRasterOpen()' - Open a raster stream. + * 'cupsRasterOpen()' - Open a raster stream using a file descriptor. * * This function associates a raster stream with the given file descriptor. * For most printer driver filters, "fd" will be 0 (stdin). For most raster * image processor (RIP) filters that generate raster data, "fd" will be 1 * (stdout). * - * When writing raster data, the @code CUPS_RASTER_WRITE@ or - * @code CUPS_RASTER_WRITE_COMPRESS@ mode can be used - compressed output - * is generally 25-50% smaller but adds a 100-300% execution time overhead. + * When writing raster data, the @code CUPS_RASTER_WRITE@, + * @code CUPS_RASTER_WRITE_COMPRESS@, or @code CUPS_RASTER_WRITE_PWG@ mode can + * be used - compressed and PWG output is generally 25-50% smaller but adds a + * 100-300% execution time overhead. */ cups_raster_t * /* O - New stream */ cupsRasterOpen(int fd, /* I - File descriptor */ - cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@, @code CUPS_RASTER_WRITE@, or @code CUPS_RASTER_WRITE_COMPRESSED@ */ + cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@, + @code CUPS_RASTER_WRITE@, + @code CUPS_RASTER_WRITE_COMPRESSED@, + or @code CUPS_RASTER_WRITE_PWG@ */ +{ + if (mode == CUPS_RASTER_READ) + return (cupsRasterOpenIO(cups_read_fd, (void *)((intptr_t)fd), mode)); + else + return (cupsRasterOpenIO(cups_write_fd, (void *)((intptr_t)fd), mode)); +} + + +/* + * 'cupsRasterOpenIO()' - Open a raster stream using a callback function. + * + * This function associates a raster stream with the given callback function and + * context pointer. + * + * When writing raster data, the @code CUPS_RASTER_WRITE@, + * @code CUPS_RASTER_WRITE_COMPRESS@, or @code CUPS_RASTER_WRITE_PWG@ mode can + * be used - compressed and PWG output is generally 25-50% smaller but adds a + * 100-300% execution time overhead. + */ + +cups_raster_t * /* O - New stream */ +cupsRasterOpenIO( + cups_raster_iocb_t iocb, /* I - Read/write callback */ + void *ctx, /* I - Context pointer for callback */ + cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@, + @code CUPS_RASTER_WRITE@, + @code CUPS_RASTER_WRITE_COMPRESSED@, + or @code CUPS_RASTER_WRITE_PWG@ */ { cups_raster_t *r; /* New stream */ @@ -143,8 +179,9 @@ cupsRasterOpen(int fd, /* I - File descriptor */ return (NULL); } - r->fd = fd; - r->mode = mode == CUPS_RASTER_WRITE_COMPRESSED ? CUPS_RASTER_WRITE : mode; + r->ctx = ctx; + r->iocb = iocb; + r->mode = mode; if (mode == CUPS_RASTER_READ) { @@ -152,7 +189,8 @@ cupsRasterOpen(int fd, /* I - File descriptor */ * Open for read - get sync word... */ - if (!cups_read(r->fd, (unsigned char *)&(r->sync), sizeof(r->sync))) + if ((*r->iocb)(r->ctx, (unsigned char *)&(r->sync), sizeof(r->sync)) != + sizeof(r->sync)) { _cupsRasterAddError("Unable to read header from raster stream: %s\n", strerror(errno)); @@ -189,15 +227,26 @@ cupsRasterOpen(int fd, /* I - File descriptor */ * Open for write - put sync word... */ - if (mode == CUPS_RASTER_WRITE_COMPRESSED) + switch (mode) { - r->compressed = 1; - r->sync = CUPS_RASTER_SYNCv2; + default : + case CUPS_RASTER_WRITE : + r->sync = CUPS_RASTER_SYNC; + break; + + case CUPS_RASTER_WRITE_COMPRESSED : + r->compressed = 1; + r->sync = CUPS_RASTER_SYNCv2; + break; + + case CUPS_RASTER_WRITE_PWG : + r->compressed = 1; + r->sync = htonl(CUPS_RASTER_SYNC_PWG); + r->swapped = r->sync != CUPS_RASTER_SYNC_PWG; + break; } - else - r->sync = CUPS_RASTER_SYNC; - if (cups_write(r->fd, (unsigned char *)&(r->sync), sizeof(r->sync)) + if ((*r->iocb)(r->ctx, (unsigned char *)&(r->sync), sizeof(r->sync)) < sizeof(r->sync)) { _cupsRasterAddError("Unable to write raster stream header: %s\n", @@ -308,17 +357,17 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ r->remaining -= len / r->header.cupsBytesPerLine; - if (!cups_read(r->fd, p, len)) + if ((*r->iocb)(r->ctx, p, len) < (ssize_t)len) return (0); /* * Swap bytes as needed... */ - if ((r->header.cupsBitsPerColor == 16 || + if (r->swapped && + (r->header.cupsBitsPerColor == 16 || r->header.cupsBitsPerPixel == 12 || - r->header.cupsBitsPerPixel == 16) && - r->swapped) + r->header.cupsBitsPerPixel == 16)) cups_swap(p, len); /* @@ -349,7 +398,7 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ ptr = r->pixels; /* - * Read using a modified TIFF "packbits" compression... + * Read using a modified PackBits compression... */ if (!cups_raster_read(r, &byte, 1)) @@ -459,7 +508,7 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ * Copy fragment from buffer... */ - if ((bytes = r->pend - r->pcurrent) > remaining) + if ((unsigned)(bytes = r->pend - r->pcurrent) > remaining) bytes = remaining; memcpy(p, r->pcurrent, bytes); @@ -495,7 +544,7 @@ cupsRasterWriteHeader( cups_raster_t *r, /* I - Raster stream */ cups_page_header_t *h) /* I - Raster page header */ { - if (r == NULL || r->mode != CUPS_RASTER_WRITE) + if (r == NULL || r->mode == CUPS_RASTER_READ) return (0); /* @@ -512,8 +561,31 @@ cupsRasterWriteHeader( * Write the raster header... */ - return (cups_write(r->fd, (unsigned char *)&(r->header), sizeof(r->header)) - > 0); + if (r->mode == CUPS_RASTER_WRITE_PWG) + { + /* + * PWG raster data is always network byte order with most of the page header + * zeroed. + */ + + cups_page_header2_t fh; /* File page header */ + + memset(&fh, 0, sizeof(fh)); + fh.HWResolution[0] = htonl(r->header.HWResolution[0]); + fh.HWResolution[1] = htonl(r->header.HWResolution[1]); + fh.cupsWidth = htonl(r->header.cupsWidth); + fh.cupsHeight = htonl(r->header.cupsHeight); + fh.cupsBitsPerColor = htonl(r->header.cupsBitsPerColor); + fh.cupsBitsPerPixel = htonl(r->header.cupsBitsPerPixel); + fh.cupsBytesPerLine = htonl(r->header.cupsBytesPerLine); + fh.cupsColorOrder = htonl(r->header.cupsColorOrder); + fh.cupsColorSpace = htonl(r->header.cupsColorSpace); + + return ((*r->iocb)(r->ctx, (unsigned char *)&fh, sizeof(fh)) == sizeof(fh)); + } + else + return ((*r->iocb)(r->ctx, (unsigned char *)&(r->header), sizeof(r->header)) + == sizeof(r->header)); } @@ -531,7 +603,7 @@ cupsRasterWriteHeader2( cups_raster_t *r, /* I - Raster stream */ cups_page_header2_t *h) /* I - Raster page header */ { - if (r == NULL || r->mode != CUPS_RASTER_WRITE) + if (r == NULL || r->mode == CUPS_RASTER_READ) return (0); /* @@ -547,8 +619,31 @@ cupsRasterWriteHeader2( * Write the raster header... */ - return (cups_write(r->fd, (unsigned char *)&(r->header), sizeof(r->header)) - > 0); + if (r->mode == CUPS_RASTER_WRITE_PWG) + { + /* + * PWG raster data is always network byte order with most of the page header + * zeroed. + */ + + cups_page_header2_t fh; /* File page header */ + + memset(&fh, 0, sizeof(fh)); + fh.HWResolution[0] = htonl(r->header.HWResolution[0]); + fh.HWResolution[1] = htonl(r->header.HWResolution[1]); + fh.cupsWidth = htonl(r->header.cupsWidth); + fh.cupsHeight = htonl(r->header.cupsHeight); + fh.cupsBitsPerColor = htonl(r->header.cupsBitsPerColor); + fh.cupsBitsPerPixel = htonl(r->header.cupsBitsPerPixel); + fh.cupsBytesPerLine = htonl(r->header.cupsBytesPerLine); + fh.cupsColorOrder = htonl(r->header.cupsColorOrder); + fh.cupsColorSpace = htonl(r->header.cupsColorSpace); + + return ((*r->iocb)(r->ctx, (unsigned char *)&fh, sizeof(fh)) == sizeof(fh)); + } + else + return ((*r->iocb)(r->ctx, (unsigned char *)&(r->header), sizeof(r->header)) + == sizeof(r->header)); } @@ -572,18 +667,65 @@ cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */ DEBUG_printf(("cupsRasterWritePixels(r=%p, p=%p, len=%u), remaining=%u\n", r, p, len, r->remaining)); - if (r == NULL || r->mode != CUPS_RASTER_WRITE || r->remaining == 0) + if (r == NULL || r->mode == CUPS_RASTER_READ || r->remaining == 0) return (0); if (!r->compressed) { /* - * Without compression, just write the raster data raw... + * Without compression, just write the raster data raw unless the data needs + * to be swapped... */ r->remaining -= len / r->header.cupsBytesPerLine; - return (cups_write(r->fd, p, len)); + if (r->swapped && + (r->header.cupsBitsPerColor == 16 || + r->header.cupsBitsPerPixel == 12 || + r->header.cupsBitsPerPixel == 16)) + { + unsigned char *bufptr; /* Pointer into write buffer */ + unsigned count; /* Remaining count */ + + /* + * Allocate a write buffer as needed... + */ + + if ((size_t)len > r->bufsize) + { + if (r->buffer) + bufptr = realloc(r->buffer, len); + else + bufptr = malloc(len); + + if (!bufptr) + return (0); + + r->buffer = bufptr; + r->bufsize = len; + } + + /* + * Byte swap the pixels... + */ + + for (bufptr = r->buffer, count = len; count > 1; count -= 2, bufptr += 2) + { + bufptr[1] = *p++; + bufptr[0] = *p++; + } + + if (count) /* This should never happen... */ + *bufptr = *p; + + /* + * Write the byte-swapped buffer... + */ + + return ((*r->iocb)(r->ctx, r->buffer, len)); + } + else + return ((*r->iocb)(r->ctx, p, len)); } /* @@ -772,7 +914,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */ DEBUG_printf(("cups_raster_read(r=%p, buf=%p, bytes=%d)\n", r, buf, bytes)); if (!r->compressed) - return (cups_read(r->fd, buf, bytes)); + return ((*r->iocb)(r->ctx, buf, bytes)); /* * Allocate a read buffer as needed... @@ -780,7 +922,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */ count = 2 * r->header.cupsBytesPerLine; - if (count > r->bufsize) + if ((size_t)count > r->bufsize) { int offset = r->bufptr - r->buffer; /* Offset to current start of buffer */ int end = r->bufend - r->buffer; /* Offset to current end of buffer */ @@ -821,7 +963,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */ * Read into the raster buffer and then copy... */ - remaining = cups_read(r->fd, r->buffer, r->bufsize); + remaining = (*r->iocb)(r->ctx, r->buffer, r->bufsize); if (remaining <= 0) return (0); @@ -834,7 +976,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */ * Read directly into "buf"... */ - count = cups_read(r->fd, buf, count); + count = (*r->iocb)(r->ctx, buf, count); if (count <= 0) return (0); @@ -1042,7 +1184,7 @@ cups_raster_write( */ count = r->header.cupsBytesPerLine * 2; - if (count > r->bufsize) + if ((size_t)count > r->bufsize) { if (r->buffer) wptr = realloc(r->buffer, count); @@ -1123,21 +1265,23 @@ cups_raster_write( } } - return (cups_write(r->fd, r->buffer, wptr - r->buffer)); + return ((*r->iocb)(r->ctx, r->buffer, wptr - r->buffer)); } /* - * 'cups_read()' - Read bytes from a file. + * 'cups_read_fd()' - Read bytes from a file. */ -static int /* O - Bytes read or -1 */ -cups_read(int fd, /* I - File descriptor */ - unsigned char *buf, /* I - Buffer for read */ - int bytes) /* I - Number of bytes to read */ +static ssize_t /* O - Bytes read or -1 */ +cups_read_fd(void *ctx, /* I - File descriptor as pointer */ + unsigned char *buf, /* I - Buffer for read */ + size_t bytes) /* I - Number of bytes to read */ { - int count, /* Number of bytes read */ - total; /* Total bytes read */ + int fd = (int)((intptr_t)ctx); + /* File descriptor */ + ssize_t count; /* Number of bytes read */ + size_t total; /* Total bytes read */ for (total = 0; total < bytes; total += count, buf += count) @@ -1155,7 +1299,7 @@ cups_read(int fd, /* I - File descriptor */ } } - return (total); + return ((ssize_t)total); } @@ -1186,16 +1330,18 @@ cups_swap(unsigned char *buf, /* I - Buffer to swap */ /* - * 'cups_write()' - Write bytes to a file. + * 'cups_write_fd()' - Write bytes to a file. */ -static int /* O - Bytes written or -1 */ -cups_write(int fd, /* I - File descriptor */ - const unsigned char *buf, /* I - Bytes to write */ - int bytes) /* I - Number of bytes to write */ +static ssize_t /* O - Bytes written or -1 */ +cups_write_fd(void *ctx, /* I - File descriptor pointer */ + unsigned char *buf, /* I - Bytes to write */ + size_t bytes) /* I - Number of bytes to write */ { - int count, /* Number of bytes written */ - total; /* Total bytes written */ + int fd = (int)((intptr_t)ctx); + /* File descriptor */ + ssize_t count; /* Number of bytes written */ + size_t total; /* Total bytes written */ for (total = 0; total < bytes; total += count, buf += count) @@ -1211,7 +1357,7 @@ cups_write(int fd, /* I - File descriptor */ } } - return (total); + return ((ssize_t)total); } diff --git a/filter/spec-ppd.shtml b/filter/spec-ppd.shtml index 3e58a3b01..ea06d6490 100644 --- a/filter/spec-ppd.shtml +++ b/filter/spec-ppd.shtml @@ -30,19 +30,14 @@ LINE-END = CR / LF / CR LF

      CUPS supports several methods of auto-configuration via PPD keywords.

      -

      DeprecatedAPAutoSetupTool

      +

      Mac OS X 10.5APAutoSetupTool

      *APAutoSetupTool: "/LibraryPrinters/vendor/filename"

      -

      This deprecated keyword defines a program that sets the default option choices. It is run when a printer is added from the Add Printer window or the Nearby Printers list in the Print dialog.

      +

      This Mac OS X keyword defines a program that sets the default option choices. It is run when a printer is added from the Add Printer window or the Nearby Printers list in the Print dialog.

      The program is provided with two arguments: the printer's device URI and the PPD file to be used for the printer. The program must write an updated PPD file to stdout.

      -
      Note: - -

      This keyword is deprecated. New printer drivers SHOULD provide a CUPS command filter and support the "AutoConfigure" command. Alternately, drivers MAY use the SNMP OID keywords to configure network printers or PostScript query keywords to configure PostScript printers.

      - -

      Examples:

      @@ -136,13 +131,13 @@ f(x) = density * x gamma
       

      Examples:

      -*% Specify a profile for printing at 360dpi on all media types 
      +*% Specify a profile for printing at 360dpi on all media types
       *cupsColorProfile 360dpi/-: "1.0 1.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
       
      -*% Specify a profile for printing at 720dpi on Glossy media 
      +*% Specify a profile for printing at 720dpi on Glossy media
       *cupsColorProfile 720dpi/Glossy: "1.0 2.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
       
      -*% Specify a default profile for printing at all other resolutions and media types 
      +*% Specify a default profile for printing at all other resolutions and media types
       *cupsColorProfile -/-: "0.9 2.0 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
       
      @@ -158,13 +153,13 @@ f(x) = density * x gamma

      Examples:

      -*% Specify a profile for CMYK printing at 360dpi on all media types 
      +*% Specify a profile for CMYK printing at 360dpi on all media types
       *cupsICCProfile CMYK..360dpi/360dpi CMYK: "/Library/Printers/vendor/Profiles/foo-360-cmyk.icc"
       
      -*% Specify a profile for RGB printing at 720dpi on Glossy media 
      +*% Specify a profile for RGB printing at 720dpi on Glossy media
       *cupsColorProfile RGB.Glossy.720dpi/720dpi Glossy: "/Library/Printers/vendor/Profiles/foo-720-glossy-rgb.icc"
       
      -*% Specify a default profile for printing at all other resolutions and media types 
      +*% Specify a default profile for printing at all other resolutions and media types
       *cupsICCProfile ../Default: "/Library/Printers/vendor/Profiles/foo-default.icc"
       
      @@ -298,10 +293,10 @@ f(x) = density * x gamma

      Examples:

      -*% Specify that 2-sided printing cannot happen on transparencies 
      +*% Specify that 2-sided printing cannot happen on transparencies
       *cupsUIConstraints transparency: "*Duplex *MediaType Transparency"
       
      -*% Specify that envelope printing cannot happen from the paper trays 
      +*% Specify that envelope printing cannot happen from the paper trays
       *cupsUIConstraints envelope: "*PageSize Env10 *InputSlot Tray1"
       *cupsUIConstraints envelope: "*PageSize Env10 *InputSlot Tray1"
       *cupsUIConstraints envelope: "*PageSize EnvDL *InputSlot Tray2"
      @@ -310,7 +305,7 @@ f(x) = density * x gamma
       *% Specify an installable option constraint for the envelope feeder
       *cupsUIConstraints: "*InputSlot EnvFeeder *InstalledEnvFeeder"
       
      -*% Specify that photo printing cannot happen on plain paper or transparencies at 1200dpi 
      +*% Specify that photo printing cannot happen on plain paper or transparencies at 1200dpi
       *cupsUIConstraints photo: "*OutputMode Photo *MediaType Plain *Resolution 1200dpi"
       *cupsUIConstraints photo: "*OutputMode Photo *MediaType Transparency *Resolution 1200dpi"
       
      @@ -324,7 +319,7 @@ f(x) = density * x gamma

      Examples:

      -*% Specify the options to change for the 2-sided transparency constraint 
      +*% Specify the options to change for the 2-sided transparency constraint
       *cupsUIResolver transparency: "*Duplex None *MediaType Plain"
       
       *% Specify the options to change for the envelope printing constraints.  Notice
      @@ -332,7 +327,7 @@ f(x) = density * x gamma
       *% manual feed first, then we change the page size...
       *cupsUIResolver envelope: "*InputSlot EnvFeeder *InputSlot ManualFeed *PageSize Letter"
       
      -*% Specify the options to change for the photo printing constraints 
      +*% Specify the options to change for the photo printing constraints
       *cupsUIResolver photo: "*OutputMode Best *Resolution 600dpi"
       
      @@ -459,7 +454,7 @@ option value is "1234" then CUPS will output the string "@PJL SET PASSCODE=1234"

      Examples:

      -*% Base JCL key code option 
      +*% Base JCL key code option
       *JCLOpenUI JCLPasscode/Key Code: PickOne
       *OrderDependency: 10 JCLSetup *JCLPasscode
       *DefaultJCLPasscode: None
      @@ -469,7 +464,7 @@ option value is "1234" then CUPS will output the string "@PJL SET PASSCODE=1234"
       *JCLPasscode 3333: "@PJL SET PASSCODE = 3333<0A>"
       *JCLCloseUI: *JCLPasscode
       
      -*% Custom JCL key code option 
      +*% Custom JCL key code option
       *CustomJCLPasscode True: "@PJL SET PASSCODE = \1<0A>"
       *ParamCustomJCLPasscode Code/Key Code: 1 passcode 4 4
       
      @@ -487,7 +482,7 @@ option value is "1234" then CUPS will output the string "@PJL SET PASSCODE=1234"
       *ParamCustomWatermarkText Text: 1 string 0 32
       
       
      -*% Base PostScript gamma/density option 
      +*% Base PostScript gamma/density option
       *OpenUI GammaDensity/Gamma and Density: PickOne
       *OrderDependency: 10 AnySetup *GammaDensity
       *DefaultGammaDensity: Normal
      @@ -496,7 +491,7 @@ option value is "1234" then CUPS will output the string "@PJL SET PASSCODE=1234"
       *GammaDensity Dark/Darker: "<</cupsReal1 1.1/cupsReal2 1.5>>setpagedevice"
       *CloseUI: *GammaDensity
       
      -*% Custom PostScript gamma/density option 
      +*% Custom PostScript gamma/density option
       *CustomGammaDensity True: "<</cupsReal1 3 -1 roll/cupsReal2 5 -1>>setpagedevice"
       *ParamCustomGammaDensity Gamma: 1 curve 0.1 10
       *ParamCustomGammaDensity Density: 2 real 0 2
      @@ -1048,10 +1043,10 @@ will be ignored.

      Examples:

      -*% Flip the page image for the back side of duplexed output 
      +*% Flip the page image for the back side of duplexed output
       *cupsBackSide: Flipped
       
      -*% Rotate the page image for the back side of duplexed output 
      +*% Rotate the page image for the back side of duplexed output
       *cupsBackSide: Rotated
       
      @@ -1069,7 +1064,7 @@ by whitespace.

      Example:

      -*% Specify the list of commands we support 
      +*% Specify the list of commands we support
       *cupsCommands: "AutoConfigure Clean PrintSelfTestPage ReportLevels com.vendor.foo"
       
      @@ -1085,7 +1080,7 @@ printing is selected. The default value is false.

      Example:

      -*% Always send an even number of pages when duplexing 
      +*% Always send an even number of pages when duplexing
       *cupsEvenDuplex: true
       
      @@ -1113,16 +1108,35 @@ the special filter program "-" may be specified.

      Examples:

      -*% Standard raster printer driver filter 
      +*% Standard raster printer driver filter
       *cupsFilter: "application/vnd.cups-raster 100 rastertofoo"
       
      -*% Plain text filter 
      +*% Plain text filter
       *cupsFilter: "text/plain 10 texttofoo"
       
      -*% Pass-through filter for PostScript printers 
      +*% Pass-through filter for PostScript printers
       *cupsFilter: "application/vnd.cups-postscript 0 -"
       
      +

      cupsFilter2

      + +

      *cupsFilter2: "source/type destination/type cost program"

      + +

      This string keyword provides a conversion rule from the given source type to the printer's native format using the filter "program". If a printer supports the source type directly, the special filter program "-" may be specified. The destination type is automatically created as needed and is passed to the filters and backend as the FINAL_CONTENT_TYPE value.

      + +

      Examples:

      + +
      +*% Standard raster printer driver filter
      +*cupsFilter2: "application/vnd.cups-raster application/vnd.foo 100 rastertofoo"
      +
      +*% Plain text filter
      +*cupsFilter2: "text/plain application/vnd.foo 10 texttofoo"
      +
      +*% Pass-through filter for PostScript printers
      +*cupsFilter2: "application/vnd.cups-postscript application/postscript 0 -"
      +
      +

      DeprecatedcupsFlipDuplex

      *cupsFlipDuplex: boolean

      @@ -1218,6 +1232,19 @@ http://www.vendor.com/help" *End
      +

      CUPS 1.5cupsIPPSupplies

      + +

      *cupsIPPSupplies: boolean

      + +

      This keyword tells the IPP backend whether it should report the current marker-xxx supply attribute values. The default value is True. + +

      Example:

      + +
      +*% Do not use IPP marker-xxx attributes to report supply levels
      +*cupsIPPSupplies: False
      +
      +

      CUPS 1.2/Mac OS X 10.5cupsLanguages

      *cupsLanguages: "locale list"

      @@ -1229,7 +1256,7 @@ list of locale names ("en", "en_US", "fr_CA", etc.)

      Example:

      -*% Specify Canadian, UK, and US English, and Candian and French French 
      +*% Specify Canadian, UK, and US English, and Candian and French French
       *cupsLanguages: "en_CA en_UK en_US fr_CA fr_FR"
       
      @@ -1244,7 +1271,7 @@ hardware. The default value is false.

      Example:

      -*% Tell the RIP filters to generate the copies for us 
      +*% Tell the RIP filters to generate the copies for us
       *cupsManualCopies: true
       
      @@ -1287,7 +1314,7 @@ the output for a specific model of printer.

      Example:

      -*% Specify an integer for a driver-specific model number 
      +*% Specify an integer for a driver-specific model number
       *cupsModelNumber: 1234
       
      @@ -1353,7 +1380,7 @@ to disable the port monitor for the given URI scheme.

      *cupsPortMonitor socket/AppSocket Printing: "tbcp" *cupsPortMonitor usb/USB Printing: "none" -*% Specify a printer-specific port monitor for an Epson USB printer +*% Specify a printer-specific port monitor for an Epson USB printer *cupsPortMonitor usb/USB Status Monitor: "epson-usb"
      @@ -1362,7 +1389,7 @@ to disable the port monitor for the given URI scheme.

      *cupsPreFilter: "source/type cost program"

      This string keyword provides a pre-filter rule. The pre-filter -program will be inserted in the conversion chain immediately +program will be inserted in the conversion chain immediately before the filter that accepts the given MIME type.

      Examples:

      @@ -1426,7 +1453,7 @@ PPD file extensions was used. Currently it must be the string

      Example:

      -*% Specify a CUPS 1.2 driver 
      +*% Specify a CUPS 1.2 driver
       *cupsVersion: "1.2"
       
      @@ -1534,7 +1561,7 @@ and the Tumble page attribute.

      *% Rotate the back side images *cupsBackSide: Rotated -*% Don't swap the top and bottom margins for the back side +*% Don't swap the top and bottom margins for the back side *APDuplexRequiresFlippedMargin: false diff --git a/filter/testraster.c b/filter/testraster.c index 3f99b1d3a..48085c4fb 100644 --- a/filter/testraster.c +++ b/filter/testraster.c @@ -3,7 +3,7 @@ * * Raster test program routines for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -214,6 +214,7 @@ main(int argc, /* I - Number of command-line args */ errors = do_ps_tests(); errors += do_raster_tests(CUPS_RASTER_WRITE); errors += do_raster_tests(CUPS_RASTER_WRITE_COMPRESSED); + errors += do_raster_tests(CUPS_RASTER_WRITE_PWG); } else { @@ -543,7 +544,8 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ printf("cupsRasterOpen(%s): ", mode == CUPS_RASTER_WRITE ? "CUPS_RASTER_WRITE" : - "CUPS_RASTER_WRITE_COMPRESSED"); + mode == CUPS_RASTER_WRITE ? "CUPS_RASTER_WRITE_COMPRESSED" : + "CUPS_RASTER_WRITE_PWG"); fflush(stdout); if ((fp = fopen("test.raster", "wb")) == NULL) diff --git a/ppdc/sample.drv b/ppdc/sample.drv index 3a57bd211..7a4426b75 100644 --- a/ppdc/sample.drv +++ b/ppdc/sample.drv @@ -3,7 +3,7 @@ // // Driver info file for CUPS-supplied PPDs. // -// Copyright 2007-2010 by Apple Inc. +// Copyright 2007-2011 by Apple Inc. // Copyright 1993-2006 by Easy Software Products. // // These coded instructions, statements, and computer programs are the @@ -117,7 +117,7 @@ Attribute "FileSystem" "" "False" Attribute "LandscapeOrientation" "" "Plus90" Attribute "TTRasterizer" "" "Type42" -Copyright "Copyright 2007-2010 by Apple Inc." +Copyright "Copyright 2007-2011 by Apple Inc." Copyright "Copyright 1997-2007 by Easy Software Products." Copyright "" Copyright "These coded instructions, statements, and computer programs are the" @@ -154,9 +154,9 @@ Version "1.5" MediaSize w41h144 MediaSize w153h198 - Resolution k 1 0 0 0 136dpi - Resolution k 1 0 0 0 203dpi - *Resolution k 1 0 0 0 300dpi + Resolution k 1 0 0 0 136dpi + Resolution k 1 0 0 0 203dpi + *Resolution k 1 0 0 0 300dpi Darkness 0 Light Darkness 1 Medium @@ -211,7 +211,7 @@ Version "1.5" MediaSize A4 MediaSize FanFoldUS - Resolution k 1 8 0 0 60x720dpi + Resolution k 1 8 0 0 60x72dpi *Resolution k 1 8 0 0 120x72dpi Resolution k 1 8 0 0 240x72dpi } @@ -443,7 +443,7 @@ Version "1.5" Resolution - 1 0 0 0 600dpi *InputSlot 1 Tray - InputSlot 2 "Manual/Manual Feed" + InputSlot 2 "Manual/Manual Feed" InputSlot 3 "Envelope/Envelope Feed" *MediaType 0 "Plain/Plain Paper" @@ -527,7 +527,7 @@ Version "1.5" *MediaSize w288h432 - *Resolution k 1 0 0 0 300dpi + *Resolution k 1 0 0 0 300dpi Group "PrinterSettings/Printer Settings" Option "inPrintDensity/Print Density" PickOne DocumentSetup 20.0 @@ -652,7 +652,7 @@ Version "1.5" ModelNumber $EPSON_9PIN ColorDevice No - Resolution k 1 8 0 0 60x720dpi + Resolution k 1 8 0 0 60x72dpi *Resolution k 1 8 0 0 120x72dpi Resolution k 1 8 0 0 240x72dpi } diff --git a/scheduler/auth.c b/scheduler/auth.c index 8b3571f29..191e17fc2 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -3,7 +3,7 @@ * * Authorization routines for the CUPS scheduler. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * This file contains Kerberos support code, copyright 2006 by @@ -401,7 +401,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ return; } #ifdef HAVE_AUTHORIZATION_H - else if (!strncmp(authorization, "AuthRef", 6) && + else if (!strncmp(authorization, "AuthRef ", 8) && !strcasecmp(con->http.hostname, "localhost")) { OSStatus status; /* Status */ @@ -412,7 +412,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ * Get the Authorization Services data... */ - authorization += 7; + authorization += 8; while (isspace(*authorization & 255)) authorization ++; @@ -435,21 +435,58 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ return; } - strlcpy(username, "_AUTHREF_", sizeof(username)); + username[0] = '\0'; - if (!AuthorizationCopyInfo(con->authref, kAuthorizationEnvironmentUsername, + if (!AuthorizationCopyInfo(con->authref, kAuthorizationEnvironmentUsername, &authinfo)) { if (authinfo->count == 1 && authinfo->items[0].value && authinfo->items[0].valueLength >= 2) + { strlcpy(username, authinfo->items[0].value, sizeof(username)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Authorized as \"%s\" using AuthRef", + username); + } + AuthorizationFreeItemSet(authinfo); } - cupsdLogMessage(CUPSD_LOG_DEBUG, - "cupsdAuthorize: Authorized as \"%s\" using AuthRef", - username); + if (!username[0]) + { + /* + * No username in AuthRef, grab username using peer credentials... + */ + + struct passwd *pwd; /* Password entry for this user */ + cupsd_ucred_t peercred; /* Peer credentials */ + socklen_t peersize; /* Size of peer credentials */ + + peersize = sizeof(peercred); + + if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s", + strerror(errno)); + return; + } + + if ((pwd = getpwuid(CUPSD_UCRED_UID(peercred))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to find UID %d for peer credentials.", + (int)CUPSD_UCRED_UID(peercred)); + return; + } + + strlcpy(username, pwd->pw_name, sizeof(username)); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Authorized as \"%s\" using " + "AuthRef + PeerCred", username); + } + con->type = CUPSD_AUTH_BASIC; } #endif /* HAVE_AUTHORIZATION_H */ @@ -944,7 +981,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ #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)) + !strncmp(authorization, "Negotiate", 9)) { /* * Pull the credentials directly from the user... @@ -954,7 +991,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ cupsd_ucred_t peercred; /* Peer credentials */ socklen_t peersize; /* Size of peer credentials */ krb5_ccache peerccache; /* Peer Kerberos credentials */ - const char *peername; /* Peer username */ + krb5_principal peerprncpl; /* Peer's default principal */ + char *peername; /* Peer username */ peersize = sizeof(peercred); @@ -998,30 +1036,48 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get credentials cache for UID %d (%d/%s)", (int)CUPSD_UCRED_UID(peercred), error, strerror(errno)); + krb5_ipc_client_clear_target(); return; } - if ((peername = krb5_cc_get_name(KerberosContext, peerccache)) != NULL) + if ((error = krb5_cc_get_principal(KerberosContext, peerccache, + &peerprncpl)) != 0) { - 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); + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to get Kerberos principal for UID %d", + (int)CUPSD_UCRED_UID(peercred)); + krb5_cc_close(KerberosContext, peerccache); + krb5_ipc_client_clear_target(); + return; } - else + + if ((error = krb5_unparse_name(KerberosContext, peerprncpl, + &peername)) != 0) + { 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(); + return; + } + + strlcpy(username, peername, sizeof(username)); + + con->have_gss = 1; + con->type = CUPSD_AUTH_NEGOTIATE; + + free(peername); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Authorized as %s using Negotiate", + username); krb5_cc_close(KerberosContext, peerccache); krb5_ipc_client_clear_target(); } # endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */ - else if (!strncmp(authorization, "Negotiate", 9)) + else if (!strncmp(authorization, "Negotiate", 9)) { int len; /* Length of authorization string */ gss_ctx_id_t context; /* Authorization context */ @@ -1084,7 +1140,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ client_name = GSS_C_NO_NAME; major_status = gss_accept_sec_context(&minor_status, &context, - GSS_C_NO_CREDENTIAL, + GSS_C_NO_CREDENTIAL, &input_token, GSS_C_NO_CHANNEL_BINDINGS, &client_name, @@ -1120,7 +1176,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ "cupsdAuthorize: Credentials not complete"); else if (major_status == GSS_S_COMPLETE) { - major_status = gss_display_name(&minor_status, client_name, + major_status = gss_display_name(&minor_status, client_name, &output_token, NULL); if (GSS_ERROR(major_status)) @@ -2074,7 +2130,7 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */ if ((best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls && strcasecmp(con->http.hostname, "localhost") && best->satisfy == CUPSD_AUTH_SATISFY_ALL) && - !(type == CUPSD_AUTH_NEGOTIATE || + !(type == CUPSD_AUTH_NEGOTIATE || (type == CUPSD_AUTH_NONE && DefaultAuthType == CUPSD_AUTH_NEGOTIATE))) { cupsdLogMessage(CUPSD_LOG_DEBUG, @@ -2356,11 +2412,11 @@ check_authref(cupsd_client_t *con, /* I - Connection */ authrights.count = 1; authrights.items = &authright; - authflags = kAuthorizationFlagDefaults | + authflags = kAuthorizationFlagDefaults | kAuthorizationFlagExtendRights; - if ((status = AuthorizationCopyRights(con->authref, &authrights, - kAuthorizationEmptyEnvironment, + if ((status = AuthorizationCopyRights(con->authref, &authrights, + kAuthorizationEmptyEnvironment, authflags, NULL)) != 0) { cupsdLogMessage(CUPSD_LOG_ERROR, diff --git a/scheduler/client.c b/scheduler/client.c index 65ce4f25b..f1f219e0c 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -877,7 +877,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (line[0]) { cupsdLogMessage(CUPSD_LOG_ERROR, - "Bad request line \"%s\" from %s!", line, + "Bad request line \"%s\" from %s!", + _httpEncodeURI(buf, line, sizeof(buf)), con->http.hostname); cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE); cupsdCloseClient(con); @@ -890,7 +891,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (sscanf(version, "HTTP/%d.%d", &major, &minor) != 2) { cupsdLogMessage(CUPSD_LOG_ERROR, - "Bad request line \"%s\" from %s!", line, + "Bad request line \"%s\" from %s!", + _httpEncodeURI(buf, line, sizeof(buf)), con->http.hostname); cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE); cupsdCloseClient(con); @@ -909,7 +911,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ { cupsdLogMessage(CUPSD_LOG_ERROR, "Unsupported request line \"%s\" from %s!", - line, con->http.hostname); + _httpEncodeURI(buf, line, sizeof(buf)), + con->http.hostname); cupsdSendError(con, HTTP_NOT_SUPPORTED, CUPSD_AUTH_NONE); cupsdCloseClient(con); return; diff --git a/scheduler/conf.c b/scheduler/conf.c index 7205d3d15..26b80870c 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -316,16 +316,16 @@ cupsdCheckPermissions( if (!dir_created && !is_dir && !S_ISREG(fileinfo.st_mode)) { - cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a regular file!", filename); + cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a regular file.", filename); return (-1); } if (!dir_created && is_dir && !S_ISDIR(fileinfo.st_mode)) { if (create_dir >= 0) - cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a directory!", filename); + cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a directory.", filename); else - syslog(LOG_ERR, "\"%s\" is not a directory!", filename); + syslog(LOG_ERR, "\"%s\" is not a directory.", filename); return (-1); } @@ -864,7 +864,7 @@ cupsdReadConfiguration(void) */ cupsdLogMessage(CUPSD_LOG_NOTICE, - "Group and SystemGroup cannot use the same groups!"); + "Group and SystemGroup cannot use the same groups."); cupsdLogMessage(CUPSD_LOG_INFO, "Resetting Group to \"nobody\"..."); group = getgrnam("nobody"); @@ -897,7 +897,7 @@ cupsdReadConfiguration(void) cupsdLogMessage(CUPSD_LOG_EMERG, "No valid Listen or Port lines were found in the " - "configuration file!"); + "configuration file."); /* * Commit suicide... @@ -1002,13 +1002,13 @@ cupsdReadConfiguration(void) cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to access TMPDIR (%s): %s", tmpdir, strerror(errno)); else if (!S_ISDIR(tmpinfo.st_mode)) - cupsdLogMessage(CUPSD_LOG_ERROR, "TMPDIR (%s) is not a directory!", + cupsdLogMessage(CUPSD_LOG_ERROR, "TMPDIR (%s) is not a directory.", tmpdir); else if ((tmpinfo.st_uid != User || !(tmpinfo.st_mode & S_IWUSR)) && (tmpinfo.st_gid != Group || !(tmpinfo.st_mode & S_IWGRP)) && !(tmpinfo.st_mode & S_IWOTH)) cupsdLogMessage(CUPSD_LOG_ERROR, - "TMPDIR (%s) has the wrong permissions!", tmpdir); + "TMPDIR (%s) has the wrong permissions.", tmpdir); else cupsdSetString(&TempDir, tmpdir); } @@ -1132,7 +1132,7 @@ cupsdReadConfiguration(void) if (BrowseTimeout < (2 * BrowseInterval) || BrowseTimeout <= 0) { - cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid BrowseTimeout value %d!", + cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid BrowseTimeout value %d.", BrowseTimeout); if (BrowseInterval) @@ -1140,7 +1140,7 @@ cupsdReadConfiguration(void) else BrowseTimeout = DEFAULT_TIMEOUT; - cupsdLogMessage(CUPSD_LOG_ALERT, "Reset BrowseTimeout to %d!", + cupsdLogMessage(CUPSD_LOG_ALERT, "Reset BrowseTimeout to %d.", BrowseTimeout); } @@ -1159,14 +1159,14 @@ cupsdReadConfiguration(void) if (DefaultPolicy) - cupsdLogMessage(CUPSD_LOG_ERROR, "Default policy \"%s\" not found!", + cupsdLogMessage(CUPSD_LOG_ERROR, "Default policy \"%s\" not found.", DefaultPolicy); cupsdSetString(&DefaultPolicy, "default"); if ((DefaultPolicyPtr = cupsdFindPolicy("default")) != NULL) cupsdLogMessage(CUPSD_LOG_INFO, - "Using policy \"default\" as the default!"); + "Using policy \"default\" as the default."); else { cupsdLogMessage(CUPSD_LOG_INFO, @@ -1369,7 +1369,7 @@ cupsdReadConfiguration(void) if (!MimeDatabase) { cupsdLogMessage(CUPSD_LOG_EMERG, - "Unable to load MIME database from \"%s\" or \"%s\"!", + "Unable to load MIME database from \"%s\" or \"%s\".", mimedir, ServerRoot); if (FatalErrors & CUPSD_FATAL_CONFIG) return (0); @@ -1392,7 +1392,7 @@ cupsdReadConfiguration(void) if ((MimeTypes = calloc(NumMimeTypes, sizeof(const char *))) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to allocate memory for %d MIME types!", + "Unable to allocate memory for %d MIME types.", NumMimeTypes); NumMimeTypes = 0; } @@ -1522,7 +1522,7 @@ get_address(const char *value, /* I - Value string */ if (!*value) { - cupsdLogMessage(CUPSD_LOG_ERROR, "Bad (empty) address!"); + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad (empty) address."); return (NULL); } @@ -1571,7 +1571,7 @@ get_address(const char *value, /* I - Value string */ */ if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL) - cupsdLogMessage(CUPSD_LOG_ERROR, "Hostname lookup for \"%s\" failed!", + cupsdLogMessage(CUPSD_LOG_ERROR, "Hostname lookup for \"%s\" failed.", hostname ? hostname : "(nil)"); return (addrlist); @@ -2264,7 +2264,7 @@ parse_fatal_errors(const char *s) /* I - FatalErrors string */ fatal &= ~CUPSD_FATAL_PERMISSIONS; else if (strcasecmp(valstart, "none")) cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown FatalErrors kind \"%s\" ignored!", valstart); + "Unknown FatalErrors kind \"%s\" ignored.", valstart); for (valstart = valend; *valstart; valstart ++) if (!isspace(*valstart & 255) || *valstart != ',') @@ -2413,7 +2413,7 @@ parse_protocols(const char *s) /* I - Space-delimited protocols */ protocols |= BROWSE_ALL; else if (strcasecmp(valstart, "none")) cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown browse protocol \"%s\" ignored!", valstart); + "Unknown browse protocol \"%s\" ignored.", valstart); for (valstart = valend; *valstart; valstart ++) if (!isspace(*valstart & 255) || *valstart != ',') @@ -2570,7 +2570,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ { httpAddrString(&lis->address, temp, sizeof(temp)); cupsdLogMessage(CUPSD_LOG_WARN, - "Duplicate listen address \"%s\" ignored!", temp); + "Duplicate listen address \"%s\" ignored.", temp); continue; } @@ -2737,7 +2737,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ if (location == NULL) cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to initialize browse access control list!"); + "Unable to initialize browse access control list."); else if (!strncasecmp(value, "deny", 4)) location->order_type = CUPSD_AUTH_ALLOW; else if (!strncasecmp(value, "allow", 5)) @@ -2787,7 +2787,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ if (location == NULL) cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to initialize browse access control list!"); + "Unable to initialize browse access control list."); else { if (!strncasecmp(value, "from", 4)) @@ -3092,7 +3092,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ portnum = ntohs(service->s_port); else { - cupsdLogMessage(CUPSD_LOG_ERROR, "Lookup of service \"%s\" failed!", + cupsdLogMessage(CUPSD_LOG_ERROR, "Lookup of service \"%s\" failed.", portname); continue; } @@ -3218,7 +3218,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ } else cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown User \"%s\" on line %d, ignoring!", + "Unknown User \"%s\" on line %d, ignoring.", value, linenum); } } @@ -3239,7 +3239,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ Group = group->gr_gid; else cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown Group \"%s\" on line %d, ignoring!", + "Unknown Group \"%s\" on line %d, ignoring.", value, linenum); } } @@ -3251,7 +3251,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ if (!parse_groups(value)) cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown SystemGroup \"%s\" on line %d, ignoring!", + "Unknown SystemGroup \"%s\" on line %d, ignoring.", value, linenum); } else if (!strcasecmp(line, "HostNameLookups") && value) @@ -3481,7 +3481,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ case CUPSD_VARTYPE_INTEGER : if (!value) cupsdLogMessage(CUPSD_LOG_ERROR, - "Missing integer value for %s on line %d!", + "Missing integer value for %s on line %d.", line, linenum); else { @@ -3505,7 +3505,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ if (n < 0) cupsdLogMessage(CUPSD_LOG_ERROR, - "Bad negative integer value for %s on line %d!", + "Bad negative integer value for %s on line %d.", line, linenum); else *((int *)var->ptr) = n; @@ -3515,7 +3515,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ case CUPSD_VARTYPE_BOOLEAN : if (!value) cupsdLogMessage(CUPSD_LOG_ERROR, - "Missing boolean value for %s on line %d!", + "Missing boolean value for %s on line %d.", line, linenum); else if (!strcasecmp(value, "true") || !strcasecmp(value, "on") || @@ -3539,7 +3539,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ if (!value) { cupsdLogMessage(CUPSD_LOG_ERROR, - "Missing pathname value for %s on line %d!", + "Missing pathname value for %s on line %d.", line, linenum); break; } @@ -3553,7 +3553,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ { cupsdLogMessage(CUPSD_LOG_ERROR, "File or directory for \"%s %s\" on line %d " - "does not exist!", line, value, linenum); + "does not exist.", line, value, linenum); break; } @@ -3585,13 +3585,19 @@ read_location(cups_file_t *fp, /* I - Configuration file */ *valptr; /* Pointer into value */ - if ((parent = cupsdNewLocation(location)) == NULL) + if ((parent = cupsdFindLocation(location)) != NULL) + cupsdLogMessage(CUPSD_LOG_WARN, "Duplicate on line %d.", + location, linenum); + else if ((parent = cupsdNewLocation(location)) == NULL) return (0); + else + { + cupsdAddLocation(parent); - cupsdAddLocation(parent); + parent->limit = CUPSD_AUTH_LIMIT_ALL; + } - parent->limit = CUPSD_AUTH_LIMIT_ALL; - loc = parent; + loc = parent; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { @@ -3641,7 +3647,7 @@ read_location(cups_file_t *fp, /* I - Configuration file */ else if (!strcmp(value, "TRACE")) loc->limit |= CUPSD_AUTH_LIMIT_TRACE; else - cupsdLogMessage(CUPSD_LOG_WARN, "Unknown request type %s on line %d!", + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown request type %s on line %d.", value, linenum); for (value = valptr; isspace(*value & 255); value ++); @@ -3666,7 +3672,7 @@ read_location(cups_file_t *fp, /* I - Configuration file */ } cupsdLogMessage(CUPSD_LOG_ERROR, - "Unexpected end-of-file at line %d while reading location!", + "Unexpected end-of-file at line %d while reading location.", linenum); return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum); @@ -3697,7 +3703,10 @@ read_policy(cups_file_t *fp, /* I - Configuration file */ * Create the policy... */ - if ((pol = cupsdAddPolicy(policy)) == NULL) + if ((pol = cupsdFindPolicy(policy)) != NULL) + cupsdLogMessage(CUPSD_LOG_WARN, "Duplicate on line %d.", + policy, linenum); + else if ((pol = cupsdAddPolicy(policy)) == NULL) return (0); /* @@ -3717,7 +3726,7 @@ read_policy(cups_file_t *fp, /* I - Configuration file */ { if (op) cupsdLogMessage(CUPSD_LOG_WARN, - "Missing before on line %d!", + "Missing before on line %d.", linenum); set_policy_defaults(pol); @@ -3754,14 +3763,14 @@ read_policy(cups_file_t *fp, /* I - Configuration file */ ops[num_ops] = IPP_ANY_OPERATION; else if ((ops[num_ops] = ippOpValue(value)) == IPP_BAD_OPERATION) cupsdLogMessage(CUPSD_LOG_ERROR, - "Bad IPP operation name \"%s\" on line %d!", + "Bad IPP operation name \"%s\" on line %d.", value, linenum); else num_ops ++; } else cupsdLogMessage(CUPSD_LOG_ERROR, - "Too many operations listed on line %d!", + "Too many operations listed on line %d.", linenum); for (value = valptr; isspace(*value & 255); value ++); @@ -3929,8 +3938,8 @@ read_policy(cups_file_t *fp, /* I - Configuration file */ } cupsdLogMessage(CUPSD_LOG_ERROR, - "Unexpected end-of-file at line %d while reading policy \"%s\"!", - linenum, policy); + "Unexpected end-of-file at line %d while reading policy " + "\"%s\".", linenum, policy); return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum); } diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 64b953fb1..fd1c6b6b5 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -1979,7 +1979,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */ } else if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL) - job->sheets = attr; + job->job_sheets = attr; /* * Fill in the response info... @@ -3203,7 +3203,7 @@ apple_init_profile( # ifdef HAVE_COLORSYNCREGISTERDEVICE if (iccfile) { - url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, + url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)iccfile, strlen(iccfile), false); @@ -4177,7 +4177,11 @@ authenticate_job(cupsd_client_t *con, /* I - Client connection */ cupsdReleaseJob(job); + cupsdAddEvent(CUPSD_EVENT_JOB_STATE, NULL, job, "Job authenticated by user"); + cupsdLogJob(job, CUPSD_LOG_INFO, "Authenticated by \"%s\".", con->username); + + cupsdCheckJobs(); } @@ -5284,7 +5288,7 @@ copy_attrs(ipp_t *to, /* I - Destination request */ fromattr->group_tag != IPP_TAG_ZERO) || !fromattr->name) continue; - if (exclude && + if (exclude && (cupsArrayFind(exclude, fromattr->name) || cupsArrayFind(exclude, "all"))) { diff --git a/scheduler/job.c b/scheduler/job.c index 3d7eba1b3..efacdd318 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -904,9 +904,13 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */ if (filter && filter->dst) { - snprintf(final_content_type, sizeof(final_content_type), - "FINAL_CONTENT_TYPE=%s/%s", - filter->dst->super, filter->dst->type); + if (strchr(filter->dst->type, '/')) + snprintf(final_content_type, sizeof(final_content_type), + "FINAL_CONTENT_TYPE=%s", filter->dst->type); + else + snprintf(final_content_type, sizeof(final_content_type), + "FINAL_CONTENT_TYPE=%s/%s", filter->dst->super, + filter->dst->type); envp[envc ++] = final_content_type; } } diff --git a/scheduler/log.c b/scheduler/log.c index 80ee8e077..4de1dc30c 100644 --- a/scheduler/log.c +++ b/scheduler/log.c @@ -3,7 +3,7 @@ * * Log file routines for the CUPS scheduler. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -696,7 +696,8 @@ cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */ cupsFilePrintf(AccessFile, "%s - %s %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n", - con->http.hostname, con->username[0] != '\0' ? con->username : "-", + con->http.hostname, + con->username[0] != '\0' ? con->username : "-", cupsdGetDateTime(&(con->start), LogTimeFormat), states[con->operation], _httpEncodeURI(temp, con->uri, sizeof(temp)), diff --git a/scheduler/printers.c b/scheduler/printers.c index bc8dbd993..b04b75646 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -3589,26 +3589,44 @@ add_printer_filter( { char super[MIME_MAX_SUPER], /* Super-type for filter */ type[MIME_MAX_TYPE], /* Type for filter */ + dsuper[MIME_MAX_SUPER], /* Destination super-type for filter */ + dtype[MIME_MAX_TYPE], /* Destination type for filter */ + dest[MIME_MAX_SUPER + MIME_MAX_TYPE + 2], + /* Destination super/type */ program[1024]; /* Program/filter name */ int cost; /* Cost of filter */ - mime_type_t *temptype; /* MIME type looping var */ + mime_type_t *temptype, /* MIME type looping var */ + *desttype; /* Destination MIME type */ char filename[1024], /* Full filter filename */ *dirsep; /* Pointer to directory separator */ struct stat fileinfo; /* File information */ /* - * Parse the filter string; it should be in the following format: + * Parse the filter string; it should be in one of the following formats: * - * super/type cost program + * source/type cost program + * source/type dest/type cost program */ - if (sscanf(filter, "%15[^/]/%31s%d%*[ \t]%1023[^\n]", super, type, &cost, - program) != 4) + if (sscanf(filter, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]", + super, type, dsuper, dtype, &cost, program) == 6) { - cupsdLogMessage(CUPSD_LOG_ERROR, "%s: invalid filter string \"%s\"!", - p->name, filter); - return; + snprintf(dest, sizeof(dest), "%s/%s", dsuper, dtype); + } + else + { + if (sscanf(filter, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, &cost, + program) == 4) + { + strlcpy(dest, p->name, sizeof(dest)); + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, "%s: invalid filter string \"%s\"!", + p->name, filter); + return; + } } /* @@ -3628,38 +3646,34 @@ add_printer_filter( memset(&fileinfo, 0, sizeof(fileinfo)); snprintf(p->state_message, sizeof(p->state_message), - "Filter \"%s\" for printer \"%s\" not available: %s", - filename, p->name, strerror(errno)); + "Printer driver \"%s\" not available: %s", filename, + strerror(errno)); cupsdSetPrinterReasons(p, "+cups-missing-filter-warning"); - cupsdLogMessage(CUPSD_LOG_ERROR, "%s", p->state_message); + cupsdLogMessage(CUPSD_LOG_ERROR, "%s: %s", p->name, p->state_message); } /* * When running as root, do additional security checks... */ - if (!RunUser) + else if (!RunUser) { /* * Only use filters that are owned by root and do not have world write * permissions. */ - if (fileinfo.st_uid || (fileinfo.st_mode & (S_ISUID | S_IWOTH)) != 0) + if (fileinfo.st_uid || + (fileinfo.st_mode & (S_ISUID | S_IWGRP | S_IWOTH)) != 0) { - if (fileinfo.st_uid) - snprintf(p->state_message, sizeof(p->state_message), - "Filter \"%s\" for printer \"%s\" not owned by root", - filename, p->name); - else - snprintf(p->state_message, sizeof(p->state_message), - "Filter \"%s\" for printer \"%s\" has insecure permissions " - "(0%o)", filename, p->name, fileinfo.st_mode); + snprintf(p->state_message, sizeof(p->state_message), + "Printer driver \"%s\" has insecure permissions (%d/0%o).", + filename, (int)fileinfo.st_uid, fileinfo.st_mode); cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning"); - cupsdLogMessage(CUPSD_LOG_ERROR, "%s", p->state_message); + cupsdLogMessage(CUPSD_LOG_WARN, "%s: %s", p->name, p->state_message); } else if (fileinfo.st_mode) { @@ -3675,18 +3689,14 @@ add_printer_filter( (fileinfo.st_uid || (fileinfo.st_mode & (S_ISUID | S_IWOTH)) != 0)) { - if (fileinfo.st_uid) - snprintf(p->state_message, sizeof(p->state_message), - "Filter directory \"%s\" for printer \"%s\" not owned by " - "root", filename, p->name); - else - snprintf(p->state_message, sizeof(p->state_message), - "Filter directory \"%s\" for printer \"%s\" has insecure " - "permissions (0%o)", filename, p->name, fileinfo.st_mode); + snprintf(p->state_message, sizeof(p->state_message), + "Printer driver directory \"%s\" has insecure permissions " + "(%d/0%o).", filename, (int)fileinfo.st_uid, + fileinfo.st_mode); cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning"); - cupsdLogMessage(CUPSD_LOG_ERROR, "%s", p->state_message); + cupsdLogMessage(CUPSD_LOG_WARN, "%s: %s", p->name, p->state_message); } } } @@ -3696,6 +3706,15 @@ add_printer_filter( * Add the filter to the MIME database, supporting wildcards as needed... */ + if ((desttype = mimeType(MimeDatabase, "printer", dest)) == NULL) + { + desttype = mimeAddType(MimeDatabase, "printer", dest); + if (!p->dest_types) + p->dest_types = cupsArrayNew(NULL, NULL); + + cupsArrayAdd(p->dest_types, desttype); + } + for (temptype = mimeFirstType(MimeDatabase); temptype; temptype = mimeNextType(MimeDatabase)) @@ -3703,12 +3722,33 @@ add_printer_filter( !strcasecmp(temptype->super, super)) && (type[0] == '*' || !strcasecmp(temptype->type, type))) { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "add_printer_filter: %s: adding filter %s/%s %s/%s %d %s", - p->name, temptype->super, temptype->type, - filtertype->super, filtertype->type, - cost, program); - mimeAddFilter(MimeDatabase, temptype, filtertype, cost, program); + if (desttype != filtertype) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "add_printer_filter: %s: adding filter %s/%s %s/%s %d " + "%s", p->name, temptype->super, temptype->type, + desttype->super, desttype->type, + cost, program); + mimeAddFilter(MimeDatabase, temptype, desttype, cost, program); + + if (!mimeFilterLookup(MimeDatabase, desttype, filtertype)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "add_printer_filter: %s: adding filter %s/%s %s/%s " + "0 -", p->name, desttype->super, desttype->type, + filtertype->super, filtertype->type); + mimeAddFilter(MimeDatabase, desttype, filtertype, cost, "-"); + } + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "add_printer_filter: %s: adding filter %s/%s %s/%s %d " + "%s", p->name, temptype->super, temptype->type, + filtertype->super, filtertype->type, + cost, program); + mimeAddFilter(MimeDatabase, temptype, filtertype, cost, program); + } } } @@ -3758,6 +3798,9 @@ add_printer_formats(cupsd_printer_t *p) /* I - Printer */ type; type = mimeNextType(MimeDatabase)) { + if (!strcasecmp(type->super, "printer")) + continue; + snprintf(mimetype, sizeof(mimetype), "%s/%s", type->super, type->type); if ((filters = mimeFilter(MimeDatabase, type, p->filetype, NULL)) != NULL) @@ -3851,6 +3894,8 @@ add_printer_formats(cupsd_printer_t *p) /* I - Printer */ strlcat(pdl, "image/jpeg,", sizeof(pdl)); else if (!strcasecmp(type->type, "png")) strlcat(pdl, "image/png,", sizeof(pdl)); + else if (!strcasecmp(type->type, "pwg-raster")) + strlcat(pdl, "image/pwg-raster,", sizeof(pdl)); } } @@ -3901,6 +3946,7 @@ delete_printer_filters( cupsd_printer_t *p) /* I - Printer to remove from */ { mime_filter_t *filter; /* MIME filter looping var */ + mime_type_t *type; /* Destination types for filters */ /* @@ -3918,7 +3964,8 @@ delete_printer_filters( for (filter = mimeFirstFilter(MimeDatabase); filter; filter = mimeNextFilter(MimeDatabase)) - if (filter->dst == p->filetype || filter->dst == p->prefiltertype) + if (filter->dst == p->filetype || filter->dst == p->prefiltertype || + cupsArrayFind(p->dest_types, filter->dst)) { /* * Delete the current filter... @@ -3927,6 +3974,14 @@ delete_printer_filters( mimeDeleteFilter(MimeDatabase, filter); } + for (type = (mime_type_t *)cupsArrayFirst(p->dest_types); + type; + type = (mime_type_t *)cupsArrayNext(p->dest_types)) + mimeDeleteType(MimeDatabase, type); + + cupsArrayDelete(p->dest_types); + p->dest_types = NULL; + cupsdSetPrinterReasons(p, "-cups-insecure-filter-warning" ",cups-missing-filter-warning"); } @@ -4761,15 +4816,37 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ * Add any filters in the PPD file... */ - DEBUG_printf(("ppd->num_filters = %d\n", ppd->num_filters)); - for (i = 0; i < ppd->num_filters; i ++) + if ((ppd_attr = ppdFindAttr(ppd, "cupsFilter2", NULL)) != NULL) { - DEBUG_printf(("ppd->filters[%d] = \"%s\"\n", i, ppd->filters[i])); - add_string_array(&(p->filters), ppd->filters[i]); + /* + * Use new cupsFilter2 filter syntax... + */ + + for (; ppd_attr; ppd_attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) + { + add_string_array(&(p->filters), ppd_attr->value); - if (!strncasecmp(ppd->filters[i], "application/vnd.cups-command", 28) && - isspace(ppd->filters[i][28] & 255)) - p->type |= CUPS_PRINTER_COMMANDS; + if (!strncasecmp(ppd_attr->value, "application/vnd.cups-command", 28) && + isspace(ppd_attr->value[28] & 255)) + p->type |= CUPS_PRINTER_COMMANDS; + } + } + else + { + /* + * Use old cupsFilter syntax... + */ + + DEBUG_printf(("ppd->num_filters = %d\n", ppd->num_filters)); + for (i = 0; i < ppd->num_filters; i ++) + { + DEBUG_printf(("ppd->filters[%d] = \"%s\"\n", i, ppd->filters[i])); + add_string_array(&(p->filters), ppd->filters[i]); + + if (!strncasecmp(ppd->filters[i], "application/vnd.cups-command", 28) && + isspace(ppd->filters[i][28] & 255)) + p->type |= CUPS_PRINTER_COMMANDS; + } } if ((ppd_attr = ppdFindAttr(ppd, "cupsCommands", NULL)) != NULL && @@ -4815,7 +4892,8 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ */ add_string_array(&(p->filters), - "application/vnd.cups-command 0 commandtops"); + "application/vnd.cups-command application/postscript " + "0 commandtops"); p->type |= CUPS_PRINTER_COMMANDS; } } @@ -4986,8 +5064,10 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ for (i = 0; i < CGImageSourceGetCount(sourceRef); i ++) { imageRef = CGImageSourceCreateImageAtIndex(sourceRef, i, NULL); - if (imageRef && - CGImageGetWidth(imageRef) == CGImageGetHeight(imageRef)) + if (!imageRef) + continue; + + if (CGImageGetWidth(imageRef) == CGImageGetHeight(imageRef)) { /* * Loop through remembering the icon closest to 128 but >= 128 @@ -5011,9 +5091,9 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ CGImageRetain(imageRef); biggestIconRef = imageRef; } + } - CGImageRelease(imageRef); - } + CGImageRelease(imageRef); } if (biggestIconRef) @@ -5028,7 +5108,8 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ biggestIconRef; CGImageRetain(imageRef); CGImageRelease(biggestIconRef); - CGImageRelease(closestTo128IconRef); + if (closestTo128IconRef) + CGImageRelease(closestTo128IconRef); destRef = CGImageDestinationCreateWithURL(outUrl, kUTTypePNG, 1, NULL); if (destRef) @@ -5056,10 +5137,9 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ CGImageDestinationFinalize(destRef); CFRelease(destRef); } - } - if (imageRef) CGImageRelease(imageRef); + } CFRelease(sourceRef); } diff --git a/scheduler/printers.h b/scheduler/printers.h index 5a62a5da9..dcbf302f4 100644 --- a/scheduler/printers.h +++ b/scheduler/printers.h @@ -3,7 +3,7 @@ * * Printer definitions for the CUPS scheduler. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -94,7 +94,8 @@ struct cupsd_printer_s *alert_description; /* PSX printer-alert-description value */ time_t marker_time; /* Last time marker attributes were updated */ cups_array_t *filters, /* Filters for queue */ - *pre_filters; /* Pre-filters for queue */ + *pre_filters, /* Pre-filters for queue */ + *dest_types; /* Destination types for queue */ _pwg_t *pwg; /* PWG<->PPD mapping data */ #ifdef HAVE_DNSSD diff --git a/scheduler/process.c b/scheduler/process.c index 506ef13bc..10dd999e0 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -354,20 +354,23 @@ cupsdStartProcess( "profile=%p, job=%p(%d), pid=%p) = %d", command, argv, envp, infd, outfd, errfd, backfd, sidefd, root, profile, job, job ? job->id : 0, pid, *pid); - cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to execute %s: %s", command, - strerror(errno)); + cupsdLogMessage(CUPSD_LOG_ERROR, + "%s%s \"%s\" not available: %s", + job && job->printer ? job->printer->name : "", + job && job->printer ? ": Printer driver" : "Program", + command, strerror(errno)); if (job && job->printer) { if (cupsdSetPrinterReasons(job->printer, "+cups-missing-filter-warning")) cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, - "Printer driver %s is missing.", command); + "Printer driver \"%s\" not available.", command); } return (0); } else if (!RunUser && - ((commandinfo.st_mode & (S_ISUID | S_IWGRP | S_IWOTH)) || + ((commandinfo.st_mode & (S_ISUID | S_IWOTH)) || commandinfo.st_uid)) { *pid = 0; @@ -379,15 +382,18 @@ cupsdStartProcess( command, argv, envp, infd, outfd, errfd, backfd, sidefd, root, profile, job, job ? job->id : 0, pid, *pid); cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to execute %s: insecure file permissions (0%o)", - command, commandinfo.st_mode); + "%s%s \"%s\" has insecure permissions (%d/0%o).", + job && job->printer ? job->printer->name : "", + job && job->printer ? ": Printer driver" : "Program", + command, (int)commandinfo.st_uid, commandinfo.st_mode); if (job && job->printer) { if (cupsdSetPrinterReasons(job->printer, "+cups-insecure-filter-warning")) cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, - "Printer driver %s has insecure file permissions (0%o).", - command, commandinfo.st_mode); + "Printer driver \"%s\" has insecure permissions " + "(%d/0%o).", command, + (int)commandinfo.st_uid, commandinfo.st_mode); } errno = EPERM; @@ -407,12 +413,31 @@ cupsdStartProcess( command, argv, envp, infd, outfd, errfd, backfd, sidefd, root, profile, job, job ? job->id : 0, pid, *pid); cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to execute %s: no execute permissions (0%o)", - command, commandinfo.st_mode); + "%s%s \"%s\" does not have execute permissions (%d/0%o).", + job && job->printer ? job->printer->name : "", + job && job->printer ? ": Printer driver" : "Program", + command, (int)commandinfo.st_uid, commandinfo.st_mode); errno = EPERM; return (0); } + else if (!RunUser && (commandinfo.st_mode & S_IWGRP)) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "%s%s \"%s\" has insecure permissions (%d/0%o).", + job && job->printer ? job->printer->name : "", + job && job->printer ? ": Printer driver" : "Program", + command, (int)commandinfo.st_uid, commandinfo.st_mode); + + if (job && job->printer) + { + if (cupsdSetPrinterReasons(job->printer, "+cups-insecure-filter-warning")) + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, + "Printer driver \"%s\" has insecure permissions " + "(%d/0%o).", command, (int)commandinfo.st_uid, + commandinfo.st_mode); + } + } #if defined(__APPLE__) if (envp) diff --git a/test/ipptool.c b/test/ipptool.c index 969f15435..f7cde8d8c 100644 --- a/test/ipptool.c +++ b/test/ipptool.c @@ -656,7 +656,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ * Connect to the server... */ - if ((http = _httpCreate(vars->hostname, vars->port, vars->encryption, + if ((http = _httpCreate(vars->hostname, vars->port, NULL, vars->encryption, vars->family)) == NULL) { print_fatal_error("Unable to connect to %s on port %d - %s", vars->hostname, @@ -1858,12 +1858,15 @@ do_tests(_cups_vars_t *vars, /* I - Variables */ print_xml_string("string", ippOpString(op)); puts("RequestAttributes"); puts(""); - puts(""); - for (attrptr = request->attrs, group = attrptr->group_tag; - attrptr; - attrptr = attrptr->next) - print_attr(attrptr, &group); - puts(""); + if (request->attrs) + { + puts(""); + for (attrptr = request->attrs, group = attrptr->group_tag; + attrptr; + attrptr = attrptr->next) + print_attr(attrptr, &group); + puts(""); + } puts(""); } else if (Output == _CUPS_OUTPUT_TEST) diff --git a/test/testhp.ppd b/test/testhp.ppd index 7392bc294..6200c7aba 100644 --- a/test/testhp.ppd +++ b/test/testhp.ppd @@ -2,9 +2,9 @@ *% *% "$Id: testhp.ppd 6649 2007-07-11 21:46:42Z mike $" *% -*% Test HP PPD file for the Common UNIX Printing System (CUPS). +*% Test HP PPD file for CUPS. *% -*% Copyright 2007 by Apple Inc. +*% Copyright 2007-2011 by Apple Inc. *% Copyright 1997-2005 by Easy Software Products. *% *% These coded instructions, statements, and computer programs are the @@ -15,14 +15,15 @@ *% *FormatVersion: "4.3" *FileVersion: "1.1" -*LanguageVersion: English +*LanguageVersion: English *LanguageEncoding: ISOLatin1 *PCFileName: "TESTHP.PPD" *Manufacturer: "ESP" -*Product: "(CUPS v1.1)" +*Product: "(CUPS v1.5)" *cupsVersion: 1.1 *cupsManualCopies: True *cupsFilter: "application/vnd.cups-raster 50 rastertohp" +*cupsFilter2: "application/vnd.cups-raster application/vnd.hp-pcl 50 rastertohp" *ModelName: "Test HP Printer" *ShortNickName: "Test HP Printer" *NickName: "Test HP Printer CUPS v1.1" @@ -82,7 +83,7 @@ *PageRegion EnvMonarch/Envelope Monarch: "<>setpagedevice" *CloseUI: *PageRegion -*DefaultImageableArea: Letter +*DefaultImageableArea: Letter *ImageableArea Letter/US Letter: "18 36 594 756" *ImageableArea Legal/US Legal: "18 36 594 972" *ImageableArea Executive/US Executive: "18 36 504 684" diff --git a/tools/makeipptoolpkg b/tools/makeipptoolpkg index 1fe318380..46fdf2fa6 100644 --- a/tools/makeipptoolpkg +++ b/tools/makeipptoolpkg @@ -4,7 +4,7 @@ # # Make an ipptool package for CUPS. # -# Copyright 2007-2010 by Apple Inc. +# Copyright 2007-2011 by Apple Inc. # Copyright 1997-2007 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the @@ -51,6 +51,7 @@ cp IPPTOOL.txt LICENSE.txt $pkgdir cp doc/help/man-ipptool*.html $pkgdir cp test/create-printer-subscription.test $pkgdir cp test/get-completed-jobs.test test/get-jobs.test $pkgdir +cp test/get-printer-attributes.test $pkgdir cp test/ipp-[12].*.test $pkgdir cp test/ipptool-static $pkgdir/ipptool cp test/testfile.* $pkgdir diff --git a/vc2005/cups.sln b/vc2005/cups.sln index 00353516b..e510e163c 100644 --- a/vc2005/cups.sln +++ b/vc2005/cups.sln @@ -1,7 +1,12 @@ Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual C++ Express 2005 +# Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcups2", "libcups2.vcproj", "{CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcupsimage2", "libcupsimage2.vcproj", "{CB4AA6F2-3E84-45BE-B505-95CD375E1234}" + ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testfile", "testfile.vcproj", "{CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}" ProjectSection(ProjectDependencies) = postProject {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} @@ -15,6 +20,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cupstestppd", "cupstestppd.vcproj", "{6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}" ProjectSection(ProjectDependencies) = postProject {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + {CB4AA6F2-3E84-45BE-B505-95CD375E1234} = {CB4AA6F2-3E84-45BE-B505-95CD375E1234} EndProjectSection EndProject Global @@ -33,6 +39,14 @@ Global {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|Win32.Build.0 = Debug|Win32 {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|x64.ActiveCfg = Debug|x64 {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|x64.Build.0 = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|Win32.Build.0 = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|x64.ActiveCfg = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|x64.Build.0 = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|Win32.ActiveCfg = Release|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|Win32.Build.0 = Release|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|x64.ActiveCfg = Release|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|x64.Build.0 = Release|x64 {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|Win32.ActiveCfg = Debug|Win32 {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|Win32.Build.0 = Debug|Win32 {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|x64.ActiveCfg = Debug|x64 @@ -51,10 +65,12 @@ Global {90B0058C-8393-411F-BD3B-E2C831D4E883}.Release|x64.Build.0 = Debug|x64 {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|Win32.ActiveCfg = Debug|Win32 {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|Win32.Build.0 = Debug|Win32 - {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|x64.ActiveCfg = Debug|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|x64.ActiveCfg = Debug|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|x64.Build.0 = Debug|x64 {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|Win32.ActiveCfg = Release|Win32 {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|Win32.Build.0 = Release|Win32 - {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.ActiveCfg = Release|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.ActiveCfg = Release|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/vc2005/cupstestppd.vcproj b/vc2005/cupstestppd.vcproj index 6fb4cfaff..479afcc1d 100644 --- a/vc2005/cupstestppd.vcproj +++ b/vc2005/cupstestppd.vcproj @@ -11,6 +11,9 @@ + @@ -167,6 +170,160 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -180,28 +337,12 @@ RelativePath="..\systemv\cupstestppd.c" > - - - - - - - - + + + + + + @@ -1312,7 +1324,7 @@ /> + + @@ -1384,7 +1400,7 @@ /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vcnet/cups.sln b/vcnet/cups.sln index 5c318adb6..9dabb8926 100644 --- a/vcnet/cups.sln +++ b/vcnet/cups.sln @@ -2,6 +2,11 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcups2", "libcups2.vcproj", "{CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcupsimage2", "libcupsimage2.vcproj", "{CB4AA6F2-3E84-45BE-B505-95CD375E1234}" + ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testfile", "testfile.vcproj", "{CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}" ProjectSection(ProjectDependencies) = postProject {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} @@ -14,6 +19,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testhttp", "testhttp.vcproj EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cupstestppd", "cupstestppd.vcproj", "{6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}" ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E1234} = {CB4AA6F2-3E84-45BE-B505-95CD375E1234} {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} EndProjectSection EndProject @@ -38,6 +44,14 @@ Global {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|Win32.Build.0 = Release|Win32 {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|x64.ActiveCfg = Debug|x64 {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|x64.Build.0 = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|Win32.Build.0 = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|x64.ActiveCfg = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|x64.Build.0 = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|Win32.ActiveCfg = Release|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|Win32.Build.0 = Release|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|x64.ActiveCfg = Release|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|x64.Build.0 = Release|x64 {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|Win32.ActiveCfg = Debug|Win32 {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|Win32.Build.0 = Debug|Win32 {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|x64.ActiveCfg = Debug|x64 @@ -56,18 +70,20 @@ Global {90B0058C-8393-411F-BD3B-E2C831D4E883}.Release|x64.Build.0 = Debug|x64 {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|Win32.ActiveCfg = Debug|Win32 {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|Win32.Build.0 = Debug|Win32 - {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|x64.ActiveCfg = Debug|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|x64.ActiveCfg = Debug|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|x64.Build.0 = Debug|x64 {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|Win32.ActiveCfg = Release|Win32 {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|Win32.Build.0 = Release|Win32 - {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.ActiveCfg = Release|Win32 - {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.Build.0 = Release|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.ActiveCfg = Release|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.Build.0 = Release|x64 {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Debug|Win32.ActiveCfg = Debug|Win32 {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Debug|Win32.Build.0 = Debug|Win32 - {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Debug|x64.ActiveCfg = Debug|Win32 + {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Debug|x64.ActiveCfg = Debug|x64 + {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Debug|x64.Build.0 = Debug|x64 {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Release|Win32.ActiveCfg = Release|Win32 {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Release|Win32.Build.0 = Release|Win32 - {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Release|x64.ActiveCfg = Release|Win32 - {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Release|x64.Build.0 = Release|Win32 + {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Release|x64.ActiveCfg = Release|x64 + {B246D91E-61F2-4433-BFD2-6C2A96FBD4D4}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/vcnet/cupstestppd.vcproj b/vcnet/cupstestppd.vcproj index 2dd8c9141..8c3416963 100644 --- a/vcnet/cupstestppd.vcproj +++ b/vcnet/cupstestppd.vcproj @@ -12,6 +12,9 @@ + @@ -166,6 +169,158 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -179,28 +334,12 @@ RelativePath="..\systemv\cupstestppd.c" > - - - - - - - - + @@ -166,6 +169,158 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vcnet/libcups2.vcproj b/vcnet/libcups2.vcproj index 17f8d67aa..e5d04af72 100644 --- a/vcnet/libcups2.vcproj +++ b/vcnet/libcups2.vcproj @@ -152,7 +152,7 @@ AdditionalDependencies="ws2_32.lib advapi32.lib" OutputFile="$(OutDir)\libcups2.dll" LinkIncremental="2" - ModuleDefinitionFile="..\vc2005\libcups2.def" + ModuleDefinitionFile="..\cups\libcups2.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\libcups2.pdb" SubSystem="2" @@ -260,7 +260,7 @@ /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.39.2