diff options
author | msweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2012-03-30 05:59:14 +0000 |
---|---|---|
committer | msweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2012-03-30 05:59:14 +0000 |
commit | 82cc1f9ac32564e92bfbbe7a1de416f4ebcc8584 (patch) | |
tree | af43377451e06dac91d6639e35b1b5bf41d14d4e /filter | |
parent | 3e7fe0ca760ad0054cf5c9ec7c90ca415cf6eb06 (diff) |
Merge changes from CUPS 1.6svn-r10390.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@3755 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'filter')
-rw-r--r-- | filter/commandtops.c | 207 | ||||
-rw-r--r-- | filter/spec-ppd.shtml | 20 |
2 files changed, 206 insertions, 21 deletions
diff --git a/filter/commandtops.c b/filter/commandtops.c index 467d3d092..e49a443b6 100644 --- a/filter/commandtops.c +++ b/filter/commandtops.c @@ -3,7 +3,7 @@ * * PostScript command filter for CUPS. * - * Copyright 2008-2011 by Apple Inc. + * Copyright 2008-2012 by Apple Inc. * * These coded instructions, statements, and computer programs are the * property of Apple Inc. and are protected by Federal copyright @@ -36,7 +36,7 @@ * Local functions... */ -static void auto_configure(ppd_file_t *ppd, const char *user); +static int auto_configure(ppd_file_t *ppd, const char *user); static void begin_ps(ppd_file_t *ppd, const char *user); static void end_ps(ppd_file_t *ppd); static void print_self_test_page(ppd_file_t *ppd, const char *user); @@ -51,6 +51,7 @@ int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { + int status = 0; /* Exit status */ cups_file_t *fp; /* Command file */ char line[1024], /* Line from file */ *value; /* Value on line */ @@ -113,16 +114,20 @@ main(int argc, /* I - Number of command-line arguments */ */ if (!_cups_strcasecmp(line, "AutoConfigure")) - auto_configure(ppd, argv[2]); + status |= auto_configure(ppd, argv[2]); else if (!_cups_strcasecmp(line, "PrintSelfTestPage")) print_self_test_page(ppd, argv[2]); else if (!_cups_strcasecmp(line, "ReportLevels")) report_levels(ppd, argv[2]); else - fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", line); + { + _cupsLangPrintFilter(stderr, "ERROR", + _("Invalid printer command \"%s\"."), line); + status = 1; + } } - return (0); + return (status); } @@ -131,12 +136,14 @@ main(int argc, /* I - Number of command-line arguments */ * query commands and/or SNMP lookups. */ -static void +static int /* O - Exit status */ auto_configure(ppd_file_t *ppd, /* I - PPD file */ const char *user) /* I - Printing user */ { + int status = 0; /* Exit status */ ppd_option_t *option; /* Current option in PPD */ ppd_attr_t *attr; /* Query command attribute */ + const char *valptr; /* Pointer into attribute value */ char buffer[1024], /* String buffer */ *bufptr; /* Pointer into buffer */ ssize_t bytes; /* Number of bytes read */ @@ -154,7 +161,7 @@ auto_configure(ppd_file_t *ppd, /* I - PPD file */ { fputs("DEBUG: Unable to auto-configure PostScript Printer - no " "bidirectional I/O available!\n", stderr); - return; + return (1); } /* @@ -162,6 +169,25 @@ auto_configure(ppd_file_t *ppd, /* I - PPD file */ */ begin_ps(ppd, user); + + /* + * (STR #4028) + * + * As a lot of PPDs contain bad PostScript query code, we need to prevent one + * bad query sequence from affecting all auto-configuration. The following + * error handler allows us to log PostScript errors to cupsd. + */ + + puts("/cups_handleerror {\n" + " $error /newerror false put\n" + " (:PostScript error in \") print cups_query_keyword print (\": ) " + "print\n" + " $error /errorname get 128 string cvs print\n" + " (; offending command:) print $error /command get 128 string cvs " + "print (\n) print flush\n" + "} bind def\n" + "errordict /timeout {} put\n" + "/cups_query_keyword (?Unknown) def\n"); fflush(stdout); /* @@ -202,7 +228,76 @@ auto_configure(ppd_file_t *ppd, /* I - PPD file */ */ fprintf(stderr, "DEBUG: Querying %s...\n", option->keyword); - fputs(attr->value, stdout); + + for (bufptr = buffer, valptr = attr->value; *valptr; valptr ++) + { + /* + * Log the query code, breaking at newlines... + */ + + if (*valptr == '\n') + { + *bufptr = '\0'; + fprintf(stderr, "DEBUG: %s\\n\n", buffer); + bufptr = buffer; + } + else if (*valptr < ' ') + { + if (bufptr >= (buffer + sizeof(buffer) - 4)) + { + *bufptr = '\0'; + fprintf(stderr, "DEBUG: %s\n", buffer); + bufptr = buffer; + } + + if (*valptr == '\r') + { + *bufptr++ = '\\'; + *bufptr++ = 'r'; + } + else if (*valptr == '\t') + { + *bufptr++ = '\\'; + *bufptr++ = 't'; + } + else + { + *bufptr++ = '\\'; + *bufptr++ = '0' + ((*valptr / 64) & 7); + *bufptr++ = '0' + ((*valptr / 8) & 7); + *bufptr++ = '0' + (*valptr & 7); + } + } + else + { + if (bufptr >= (buffer + sizeof(buffer) - 1)) + { + *bufptr = '\0'; + fprintf(stderr, "DEBUG: %s\n", buffer); + bufptr = buffer; + } + + *bufptr++ = *valptr; + } + } + + if (bufptr > buffer) + { + *bufptr = '\0'; + fprintf(stderr, "DEBUG: %s\n", buffer); + } + + printf("/cups_query_keyword (?%s) def\n", option->keyword); + /* Set keyword for error reporting */ + fputs("{ (", stdout); + for (valptr = attr->value; *valptr; valptr ++) + { + if (*valptr == '(' || *valptr == ')' || *valptr == '\\') + putchar('\\'); + putchar(*valptr); + } + fputs(") cvx exec } stopped { cups_handleerror } if clear\n", stdout); + /* Send query code */ fflush(stdout); datalen = 0; @@ -212,53 +307,119 @@ auto_configure(ppd_file_t *ppd, /* I - PPD file */ * Read the response data... */ - while ((bytes = cupsBackChannelRead(buffer, sizeof(buffer) - 1, 90.0)) > 0) + bufptr = buffer; + buffer[0] = '\0'; + while ((bytes = cupsBackChannelRead(bufptr, + sizeof(buffer) - (bufptr - buffer) - 1, + 10.0)) > 0) { /* - * Trim whitespace from both ends... + * No newline at the end? Go on reading ... */ - buffer[bytes] = '\0'; + bufptr += bytes; + *bufptr = '\0'; + + if (bytes == 0 || + (bufptr > buffer && bufptr[-1] != '\r' && bufptr[-1] != '\n')) + continue; - for (bufptr = buffer + bytes - 1; bufptr >= buffer; bufptr --) - if (isspace(*bufptr & 255)) + /* + * Trim whitespace and control characters from both ends... + */ + + bytes = bufptr - buffer; + + for (bufptr --; bufptr >= buffer; bufptr --) + if (isspace(*bufptr & 255) || iscntrl(*bufptr & 255)) *bufptr = '\0'; else break; - for (bufptr = buffer; isspace(*bufptr & 255); bufptr ++); + for (bufptr = buffer; isspace(*bufptr & 255) || iscntrl(*bufptr & 255); + bufptr ++); + + if (bufptr > buffer) + { + _cups_strcpy(buffer, bufptr); + bufptr = buffer; + } - fprintf(stderr, "DEBUG: Got \"%s\" (%d bytes)\n", bufptr, (int)bytes); + fprintf(stderr, "DEBUG: Got %d bytes.\n", (int)bytes); /* * Skip blank lines... */ - if (!*bufptr) + if (!buffer[0]) continue; /* + * Check the response... + */ + + if ((bufptr = strchr(buffer, ':')) != NULL) + { + /* + * PostScript code for this option in the PPD is broken; show the + * interpreter's error message that came back... + */ + + fprintf(stderr, "DEBUG%s\n", bufptr); + break; + } + + /* * Verify the result is a valid option choice... */ - if (!ppdFindChoice(option, bufptr)) + if (!ppdFindChoice(option, buffer)) + { + if (!strcasecmp(buffer, "Unknown")) + break; + + bufptr = buffer; + buffer[0] = '\0'; continue; + } /* * Write out the result and move on to the next option... */ - fprintf(stderr, "DEBUG: Default%s=%s\n", option->keyword, bufptr); - fprintf(stderr, "PPD: Default%s=%s\n", option->keyword, bufptr); + fprintf(stderr, "PPD: Default%s=%s\n", option->keyword, buffer); break; } + + /* + * Printer did not answer this option's query + */ + + if (bytes <= 0) + { + fprintf(stderr, + "DEBUG: No answer to query for option %s within 10 seconds.\n", + option->keyword); + status = 1; + } } /* * Finish the job... */ + fflush(stdout); end_ps(ppd); + + /* + * Return... + */ + + if (status) + _cupsLangPrintFilter(stderr, "WARNING", + _("Unable to configure printer options.")); + + return (0); } @@ -280,6 +441,7 @@ begin_ps(ppd_file_t *ppd, /* I - PPD file */ puts("%!"); puts("userdict dup(\\004)cvn{}put (\\004\\004)cvn{}put\n"); + fflush(stdout); } @@ -319,7 +481,12 @@ print_self_test_page(ppd_file_t *ppd, /* I - PPD file */ * the product/interpreter information... */ - puts("% You are using the wrong driver for your printer!\n" + puts("\r%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" + "%%%%%%%%%%%%%\n" + "\r%%%% If you can read this, you are using the wrong driver for your " + "printer. %%%%\n" + "\r%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" + "%%%%%%%%%%%%%\n" "0 setgray\n" "2 setlinewidth\n" "initclip newpath clippath gsave stroke grestore pathbbox\n" diff --git a/filter/spec-ppd.shtml b/filter/spec-ppd.shtml index 6daa361fe..5ef9f6a40 100644 --- a/filter/spec-ppd.shtml +++ b/filter/spec-ppd.shtml @@ -1481,7 +1481,7 @@ the standard SNMP Printer MIB OIDs for supply levels. The default value is <p>This required keyword describes which version of the CUPS PPD file extensions was used. Currently it must be the string -"1.0", "1.1", "1.2", or "1.3".</p> +"1.0", "1.1", "1.2", "1.3", "1.4", "1.5", or "1.6".</p> <p>Example:</p> @@ -1491,6 +1491,20 @@ PPD file extensions was used. Currently it must be the string </pre> +<h3><span class="info">CUPS 1.6</span><a name="JCLToPDFInterpreter">JCLToPDFInterpreter</a></h3> + +<p class="summary">*JCLToPDFInterpreter: "JCL"</p> + +<p>This keyword provfides the JCL command to insert a PDF job file into a printer-ready data stream. The JCL command is added after the <tt>JCLBegin</tt> value and any commands for JCL options in the PPD file.</p> + +<p>Example:</p> + +<pre class='command'> +<em>*% PJL command to start the PDF interpreter</em> +*JCLToPDFInterpreter: "@PJL ENTER LANGUAGE = PDF<0A>" +</pre> + + <h2 class='title'><a name='MACOSX'>Mac OS X Attributes</a></h2> <h3><span class='info'>Mac OS X 10.3</span><a name='APDialogExtension'>APDialogExtension</a></h3> @@ -1783,6 +1797,10 @@ the device.</p> <li>Added <a href="#cupsMaxCopies"><tt>cupsMaxCopies</tt></a> keyword.</li> + <li>Documented <a href="#JCLToPDFInterpreter"><tt>JCLToPDFInterpreter</tt></a> keyword.</li> + + <li>Updated <a href="#cupsVersion"><tt>cupsVersion</tt></a> keyword documentation to list all current releases of CUPS.</li> + </ul> |