summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2012-03-30 05:59:14 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2012-03-30 05:59:14 +0000
commit82cc1f9ac32564e92bfbbe7a1de416f4ebcc8584 (patch)
treeaf43377451e06dac91d6639e35b1b5bf41d14d4e /filter
parent3e7fe0ca760ad0054cf5c9ec7c90ca415cf6eb06 (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.c207
-rw-r--r--filter/spec-ppd.shtml20
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&lt;0A&gt;"
+</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>