summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2009-03-07 16:36:03 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2009-03-07 16:36:03 +0000
commit1340db2dab0b5ac933dec4796637ca3baa10bb4b (patch)
treed6c9ec39af99e162ee755e6369b5c222d6349cd6
parentb9faaae17cfc7cd8dfd6e82cf607c05b2f4def68 (diff)
Merge changes from CUPS 1.4svn-r8414.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@1277 a1ca3aef-8c08-0410-bb20-df032aa958be
-rw-r--r--CHANGES-1.3.txt5
-rw-r--r--CHANGES.txt6
-rw-r--r--backend/Makefile8
-rw-r--r--backend/dnssd.c2
-rw-r--r--backend/lpd.c2
-rw-r--r--backend/socket.c2
-rw-r--r--backend/testbackend.c10
-rw-r--r--berkeley/lpq.c15
-rw-r--r--cups/Makefile2
-rw-r--r--cups/conflicts.c95
-rw-r--r--cups/file.h1
-rw-r--r--cups/test.ppd8
-rw-r--r--cups/test2.ppd19
-rw-r--r--cups/testppd.c19
-rw-r--r--doc/help/spec-ppd.html49
-rw-r--r--driver/Dependencies6
-rw-r--r--man/cupsfilter.man8
-rw-r--r--man/cupstestppd.man6
-rw-r--r--scheduler/cupsd.h4
-rw-r--r--scheduler/cupsfilter.c40
-rw-r--r--scheduler/ipp.c6
-rw-r--r--scheduler/job.c61
-rw-r--r--scheduler/main.c22
-rw-r--r--scheduler/printers.c10
-rw-r--r--scheduler/process.c2
-rw-r--r--systemv/Dependencies4
-rw-r--r--systemv/cupstestppd.c588
27 files changed, 847 insertions, 153 deletions
diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt
index 8f4621f57..4a4147c1a 100644
--- a/CHANGES-1.3.txt
+++ b/CHANGES-1.3.txt
@@ -5,6 +5,11 @@ CHANGES IN CUPS V1.3.10
- Documentation fixes (STR #2994, STR #2995, STR #3008, STR #3056,
STR #3057)
+ - The lpq command did not work when showing all destinations (STR #3117)
+ - The scheduler used a codeset name of UTF8 which is not supported on
+ Solaris (STR #3113)
+ - cupsGetJobs() did not work with a NULL destination (STR #3107,
+ STR #)
- Fixed a localization problem for option choices (incorrectly) named
"Custom" (STR #3106)
- The fallback OpenSSL random number seeding would not work (STR #3079)
diff --git a/CHANGES.txt b/CHANGES.txt
index c1cedc32f..ef8e6ff69 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,9 +1,13 @@
-CHANGES.txt - 2009-02-25
+CHANGES.txt - 2009-03-04
------------------------
CHANGES IN CUPS V1.4b3
- Documentation fixes (STR #3044, STR #3057)
+ - The cupstestppd program did not validate the capitalization of
+ filenames in the PPD file.
+ - The cupstestppd program did not validate the PageSize and PageRegion
+ values.
- The cups-deviced helper program could miss reporting some backend
devices (STR #3108)
- The cupsSideChannelSNMP* functions did not work.
diff --git a/backend/Makefile b/backend/Makefile
index 6ea05fdb2..807b4c4e6 100644
--- a/backend/Makefile
+++ b/backend/Makefile
@@ -19,8 +19,8 @@ include ../Makedefs
RBACKENDS = ipp lpd $(DNSSD_BACKEND)
UBACKENDS = $(PAP) $(LEGACY_BACKENDS) serial snmp socket usb
-TARGETS = test1284 testbackend testsupplies \
- libbackend.a $(RBACKENDS) $(UBACKENDS)
+UNITTESTS = test1284 testbackend testsupplies
+TARGETS = libbackend.a $(RBACKENDS) $(UBACKENDS)
LIBOBJS = ieee1284.o network.o runloop.o snmp-supplies.o
OBJS = ipp.o lpd.o dnssd.o pap.o parallel.o scsi.o serial.o snmp.o \
socket.o test1284.o testbackend.o testsupplies.o usb.o
@@ -44,7 +44,7 @@ libs:
# Make unit tests...
#
-unittests:
+unittests: $(UNITTESTS)
#
@@ -52,7 +52,7 @@ unittests:
#
clean:
- $(RM) $(OBJS) $(TARGETS) $(LIBOBJS) http mdns
+ $(RM) $(OBJS) $(TARGETS) $(UNITTESTS) $(LIBOBJS) http mdns
#
diff --git a/backend/dnssd.c b/backend/dnssd.c
index 97c0d6071..f5687f3c3 100644
--- a/backend/dnssd.c
+++ b/backend/dnssd.c
@@ -19,6 +19,8 @@
* browse_callback() - Browse devices.
* browse_local_callback() - Browse local devices.
* compare_devices() - Compare two devices.
+ * exec_backend() - Execute the backend that corresponds to the
+ * resolved service name.
* get_device() - Create or update a device.
* query_callback() - Process query data.
* unquote() - Unquote a name string.
diff --git a/backend/lpd.c b/backend/lpd.c
index b39394c61..67a856a02 100644
--- a/backend/lpd.c
+++ b/backend/lpd.c
@@ -672,6 +672,8 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
sprintf(portname, "%d", port);
+ fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname);
+
if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL)
{
_cupsLangPrintf(stderr, _("ERROR: Unable to locate printer \'%s\'!\n"),
diff --git a/backend/socket.c b/backend/socket.c
index 09137f958..f3d20b9b4 100644
--- a/backend/socket.c
+++ b/backend/socket.c
@@ -261,6 +261,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
sprintf(portname, "%d", port);
+ fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname);
+
if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL)
{
_cupsLangPrintf(stderr, _("ERROR: Unable to locate printer \'%s\'!\n"),
diff --git a/backend/testbackend.c b/backend/testbackend.c
index e0f573ccd..74a0f1e5a 100644
--- a/backend/testbackend.c
+++ b/backend/testbackend.c
@@ -246,7 +246,7 @@ main(int argc, /* I - Number of command-line args */
write(1, ps_query, strlen(ps_query));
write(2, "DEBUG: START\n", 13);
- while ((bytes = cupsBackChannelRead(buffer, sizeof(buffer), 5.0)) > 0)
+ while ((bytes = cupsBackChannelRead(buffer, sizeof(buffer), 60.0)) > 0)
write(2, buffer, bytes);
write(2, "\nDEBUG: END\n", 12);
}
@@ -297,7 +297,7 @@ main(int argc, /* I - Number of command-line args */
close(side_fds[1]);
execv(backend, argv + first_arg);
- fprintf(stderr, "textbackend: Unable to execute \"%s\": %s\n", backend,
+ fprintf(stderr, "testbackend: Unable to execute \"%s\": %s\n", backend,
strerror(errno));
return (errno);
}
@@ -353,7 +353,7 @@ main(int argc, /* I - Number of command-line args */
length = 0;
scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_DRAIN_OUTPUT, buffer,
- &length, 5.0);
+ &length, 60.0);
printf("CUPS_SC_CMD_DRAIN_OUTPUT returned %s\n", statuses[scstatus]);
length = 1;
@@ -437,10 +437,12 @@ usage(void)
puts("Options:");
puts(" -d Show log messages from backend.");
puts(" -oid OID Lookup the specified SNMP OID.");
+ puts(" (.1.3.6.1.2.1.43.10.2.1.4.1.1 is a good one for printers)");
puts(" -ps Send PostScript query code to backend.");
- puts(" -s Do SNMP tests.");
+ puts(" -s Do side-channel + SNMP tests.");
puts(" -t Send spaces slowly to backend ('trickle').");
puts(" -walk OID Walk the specified SNMP OID.");
+ puts(" (.1.3.6.1.2.1.43 is a good one for printers)");
exit(1);
}
diff --git a/berkeley/lpq.c b/berkeley/lpq.c
index db089867e..50d240e12 100644
--- a/berkeley/lpq.c
+++ b/berkeley/lpq.c
@@ -3,7 +3,7 @@
*
* "lpq" command for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007-2008 by Apple Inc.
+ * Copyright 2007-2009 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -372,17 +372,13 @@ show_jobs(const char *command, /* I - Command name */
request = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS);
- if (dest == NULL)
+ if (id)
{
- if (id)
- sprintf(resource, "ipp://localhost/jobs/%d", id);
- else
- strcpy(resource, "ipp://localhost/jobs");
-
+ snprintf(resource, sizeof(resource), "ipp://localhost/jobs/%d", id);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
NULL, resource);
}
- else
+ else if (dest)
{
httpAssembleURIf(HTTP_URI_CODING_ALL, resource, sizeof(resource), "ipp",
NULL, "localhost", 0, "/printers/%s", dest);
@@ -390,6 +386,9 @@ show_jobs(const char *command, /* I - Command name */
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, resource);
}
+ else
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://localhost/");
if (user)
{
diff --git a/cups/Makefile b/cups/Makefile
index bec16188f..31be2be31 100644
--- a/cups/Makefile
+++ b/cups/Makefile
@@ -516,7 +516,7 @@ testoptions: testoptions.o libcups.a
# testppd (dependency on static CUPS library is intentional)
#
-testppd: testppd.o libcups.a
+testppd: testppd.o libcups.a test.ppd test2.ppd
echo Linking $@...
$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testppd.o libcups.a \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
diff --git a/cups/conflicts.c b/cups/conflicts.c
index 4c90f169e..138a0c119 100644
--- a/cups/conflicts.c
+++ b/cups/conflicts.c
@@ -181,16 +181,21 @@ cupsResolveConflicts(
cups_option_t **options) /* IO - Additional selected options */
{
int i, /* Looping var */
- num_newopts, /* Number of new options */
- num_resopts; /* Number of resolver options */
- cups_option_t *newopts, /* New options */
- *resopts; /* Resolver options */
+ num_newopts; /* Number of new options */
+ cups_option_t *newopts; /* New options */
cups_array_t *active, /* Active constraints */
*pass, /* Resolvers for this pass */
- *resolvers; /* Resolvers we have used */
+ *resolvers, /* Resolvers we have used */
+ *test; /* Test array for conflicts */
_ppd_cups_uiconsts_t *consts; /* Current constraints */
_ppd_cups_uiconst_t *constptr; /* Current constraint */
ppd_attr_t *resolver; /* Current resolver */
+ const char *resval; /* Pointer into resolver value */
+ char resoption[PPD_MAX_NAME],
+ /* Current resolver option */
+ reschoice[PPD_MAX_NAME],
+ /* Current resolver choice */
+ *resptr; /* Pointer into option/choice */
const char *value; /* Selected option value */
int changed; /* Did we change anything? */
ppd_choice_t *marked; /* Marked choice */
@@ -277,25 +282,74 @@ cupsResolveConflicts(
cupsArrayAdd(pass, consts->resolver);
cupsArrayAdd(resolvers, consts->resolver);
- if (option && choice)
+ for (resval = resolver->value; *resval && !changed;)
{
- resopts = NULL;
- num_resopts = _ppdParseOptions(resolver->value, 0, &resopts);
+ while (isspace(*resval & 255))
+ resval ++;
- if ((value = cupsGetOption(option, num_newopts, newopts)) != NULL &&
- !strcasecmp(value, choice))
+ if (*resval != '*')
+ break;
+
+ for (resval ++, resptr = resoption;
+ *resval && !isspace(*resval & 255);
+ resval ++)
+ if (resptr < (resoption + sizeof(resoption) - 1))
+ *resptr++ = *resval;
+
+ *resptr = '\0';
+
+ while (isspace(*resval & 255))
+ resval ++;
+
+ for (resptr = reschoice;
+ *resval && !isspace(*resval & 255);
+ resval ++)
+ if (resptr < (reschoice + sizeof(reschoice) - 1))
+ *resptr++ = *resval;
+
+ *resptr = '\0';
+
+ if (!resoption[0] || !reschoice[0])
+ break;
+
+ /*
+ * Is this the option we are changing?
+ */
+
+ if (option &&
+ (!strcasecmp(resoption, option) ||
+ (!strcasecmp(option, "PageSize") &&
+ !strcasecmp(resoption, "PageRegion")) ||
+ (!strcasecmp(option, "PageRegion") &&
+ !strcasecmp(resoption, "PageSize"))))
+ continue;
+
+ /*
+ * Try this choice...
+ */
+
+ if ((test = ppd_test_constraints(ppd, resoption, reschoice,
+ num_newopts, newopts,
+ _PPD_ALL_CONSTRAINTS)) == NULL)
{
- DEBUG_printf(("cupsResolveConflicts: Resolver %s changes %s!\n",
- consts->resolver, option));
- cupsFreeOptions(num_resopts, resopts);
- goto error;
- }
+ /*
+ * That worked...
+ */
- cupsFreeOptions(num_resopts, resopts);
- }
+ changed = 1;
+ }
+ else
+ cupsArrayDelete(test);
- num_newopts = _ppdParseOptions(resolver->value, num_newopts, &newopts);
- changed = 1;
+ /*
+ * Add the option/choice from the resolver regardless of whether it
+ * worked; this makes sure that we can cascade several changes to
+ * make things resolve...
+ */
+
+ num_newopts = cupsAddOption(resoption, reschoice, num_newopts,
+ &newopts);
+ }
}
else
{
@@ -306,7 +360,6 @@ cupsResolveConflicts(
int j; /* Looping var */
ppd_choice_t *cptr; /* Current choice */
- cups_array_t *test; /* Test array for conflicts */
ppd_size_t *size; /* Current page size */
@@ -1019,7 +1072,7 @@ ppd_test_constraints(
key.option = constptr->option;
if ((marked = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key))
- != NULL &&
+ == NULL ||
(!strcasecmp(marked->choice, "None") ||
!strcasecmp(marked->choice, "Off") ||
!strcasecmp(marked->choice, "False")))
diff --git a/cups/file.h b/cups/file.h
index c5eb357fa..c8a2b4667 100644
--- a/cups/file.h
+++ b/cups/file.h
@@ -91,7 +91,6 @@ extern ssize_t cupsFilePutConf(cups_file_t *fp, const char *directive,
const char *value) _CUPS_API_1_4;
extern int cupsFilePuts(cups_file_t *fp, const char *s) _CUPS_API_1_2;
extern ssize_t cupsFileRead(cups_file_t *fp, char *buf, size_t bytes) _CUPS_API_1_2;
-extern ssize_t cupsFileReady(cups_file_t *fp) _CUPS_API_1_4;
extern off_t cupsFileRewind(cups_file_t *fp) _CUPS_API_1_2;
extern off_t cupsFileSeek(cups_file_t *fp, off_t pos) _CUPS_API_1_2;
extern cups_file_t *cupsFileStderr(void) _CUPS_API_1_2;
diff --git a/cups/test.ppd b/cups/test.ppd
index 35743b0a2..45473fdac 100644
--- a/cups/test.ppd
+++ b/cups/test.ppd
@@ -5,14 +5,14 @@
*% Test PPD file for the Common UNIX Printing System (CUPS).
*%
*% This file is used to test the CUPS PPD API functions and cannot be
-*% used with any known printers. Look at the PPD files in the "ppd"
-*% subdirectory as well as the CUPS web site for working PPD files.
+*% used with any known printers. Look on the CUPS web site for working PPD
+*% files.
*%
*% If you are a PPD file developer, consider using the PPD compiler (ppdc)
*% to create your PPD files - not only will it save you time, it produces
*% consistently high-quality files.
*%
-*% Copyright 2007-2008 by Apple Inc.
+*% Copyright 2007-2009 by Apple Inc.
*% Copyright 2002-2006 by Easy Software Products.
*%
*% These coded instructions, statements, and computer programs are the
@@ -40,7 +40,7 @@
*LandscapeOrientation: Plus90
*TTRasterizer: Type42
-*% These constraints are used to test ppdConflicts() and ppdResolveConflicts()
+*% These constraints are used to test ppdConflicts() and cupsResolveConflicts()
*UIConstraints: *PageSize Letter *InputSlot Envelope
*UIConstraints: *InputSlot Envelope *PageSize Letter
*UIConstraints: *PageRegion Letter *InputSlot Envelope
diff --git a/cups/test2.ppd b/cups/test2.ppd
index fb32e4830..bd07c867b 100644
--- a/cups/test2.ppd
+++ b/cups/test2.ppd
@@ -5,14 +5,14 @@
*% Test PPD file #2 for the Common UNIX Printing System (CUPS).
*%
*% This file is used to test the CUPS PPD API functions and cannot be
-*% used with any known printers. Look at the PPD files in the "ppd"
-*% subdirectory as well as the CUPS web site for working PPD files.
+*% used with any known printers. Look on the CUPS web site for working PPD
+*% files.
*%
*% If you are a PPD file developer, consider using the PPD compiler (ppdc)
*% to create your PPD files - not only will it save you time, it produces
*% consistently high-quality files.
*%
-*% Copyright 2007-2008 by Apple Inc.
+*% Copyright 2007-2009 by Apple Inc.
*% Copyright 2002-2006 by Easy Software Products.
*%
*% These coded instructions, statements, and computer programs are the
@@ -40,25 +40,22 @@
*LandscapeOrientation: Plus90
*TTRasterizer: Type42
-*% These constraints are used to test ppdConflicts() and ppdResolveConflicts()
+*% These constraints are used to test ppdConflicts() and cupsResolveConflicts()
*cupsUIConstraints envelope: "*PageSize Letter *InputSlot Envelope"
-*cupsUIConstraints envelope: "*PageRegion Letter *InputSlot Envelope"
-*cupsUIResolver envelope: "*InputSlot Manual"
+*cupsUIConstraints envelope: "*PageSize A4 *InputSlot Envelope"
+*cupsUIResolver envelope: "*InputSlot Manual *PageSize Env10"
*cupsUIConstraints envphoto: "*PageSize Env10 *InputSlot Envelope *Quality Photo"
-*cupsUIConstraints envphoto: "*PageRegion Env10 *InputSlot Envelope *Quality Photo"
*cupsUIResolver envphoto: "*Quality Normal"
*% This constraint is used to test ppdInstallableConflict()
*cupsUIConstraints: "*Duplex *InstalledDuplexer False"
-*% These constraints are used to test the loop detection code in ppdResolveConflicts()
+*% These constraints are used to test the loop detection code in cupsResolveConflicts()
*cupsUIConstraints loop1: "*PageSize A4 *Quality Photo"
*cupsUIResolver loop1: "*Quality Normal"
*cupsUIConstraints loop2: "*PageSize A4 *Quality Normal"
-*cupsUIResolver loop2: "*PageSize Letter *Quality Draft"
-*cupsUIConstraints loop3: "*PageSize Letter *Quality Draft"
-*cupsUIResolver loop3: "*PageSize A4 *Quality Photo"
+*cupsUIResolver loop2: "*Quality Photo"
*% For PageSize, we have put all of the translations in-line...
*OpenUI *PageSize/Page Size: PickOne
diff --git a/cups/testppd.c b/cups/testppd.c
index 29565dec4..3a6bb8517 100644
--- a/cups/testppd.c
+++ b/cups/testppd.c
@@ -601,8 +601,8 @@ main(int argc, /* I - Number of command-line arguments */
ppdMarkOption(ppd, "InputSlot", "Envelope");
ppdMarkOption(ppd, "Quality", "Photo");
- if ((conflicts = ppdConflicts(ppd)) == 2)
- puts("PASS (2)");
+ if ((conflicts = ppdConflicts(ppd)) == 1)
+ puts("PASS (1)");
else
{
printf("FAIL (%d)\n", conflicts);
@@ -649,6 +649,7 @@ main(int argc, /* I - Number of command-line arguments */
fputs("cupsResolveConflicts(loop test): ", stdout);
ppdMarkOption(ppd, "PageSize", "A4");
+ ppdMarkOption(ppd, "InputSlot", "Tray");
ppdMarkOption(ppd, "Quality", "Photo");
num_options = 0;
options = NULL;
@@ -950,13 +951,23 @@ main(int argc, /* I - Number of command-line arguments */
}
}
- puts("Constraints:");
+ puts("\nConstraints:");
for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
printf(" *UIConstraints: *%s %s *%s %s\n", c->option1, c->choice1,
c->option2, c->choice2);
+ if (ppd->num_consts == 0)
+ puts(" NO CONSTRAINTS");
+
+ puts("\nFilters:");
+
+ for (i = 0; i < ppd->num_filters; i ++)
+ printf(" %s\n", ppd->filters[i]);
+
+ if (ppd->num_filters == 0)
+ puts(" NO FILTERS");
- puts("Attributes:");
+ puts("\nAttributes:");
for (attr = (ppd_attr_t *)cupsArrayFirst(ppd->sorted_attrs);
attr;
diff --git a/doc/help/spec-ppd.html b/doc/help/spec-ppd.html
index 11ff4a4cf..fe4b0cfd8 100644
--- a/doc/help/spec-ppd.html
+++ b/doc/help/spec-ppd.html
@@ -380,8 +380,18 @@ have to guess how a particular constraint is best resolved.</p>
<p>CUPS 1.4 and higher define two new attributes for constraints,
<tt>cupsUIConstraints</tt> and <tt>cupsUIResolver</tt>. Each
<tt>cupsUIConstraints</tt> attribute points to a <tt>cupsUIResolver</tt>
-attribute which corrects the conflict condition. The same
-<tt>cupsUIResolver</tt> can be used by multiple <tt>cupsUIConstraints</tt>.</p>
+attribute which specifies alternate options that resolve the conflict condition.
+The same <tt>cupsUIResolver</tt> can be used by multiple
+<tt>cupsUIConstraints</tt>.</p>
+
+<blockquote><b>Note:</b>
+
+ <p>When developing PPD files that contain constraints, it is very important
+ to use the <a href="man-cupstestppd.html">cupstestppd(1)</a> program to
+ verify that your constraints are accurate and cannot result in unresolvable
+ option selections.</p>
+
+</blockquote>
<h3><span class='info'>CUPS 1.4</span><a name='cupsUIConstraints'>cupsUIConstraints</a></h3>
@@ -393,9 +403,8 @@ attribute which corrects the conflict condition. The same
<p>Lists two or more options which conflict. The "resolver" string is a
(possibly unique) keyword which specifies which options to change when the
-constraint exists. When no resolver is provided, a "revert to defaults"
-change is assumed - this type of constraint is typically only used for
-installable options.</p>
+constraint exists. When no resolver is provided, CUPS first tries the default
+choice followed by testing each option choice to resolve the conflict.</p>
<p>Examples:</p>
@@ -403,6 +412,15 @@ installable options.</p>
<em>*% Specify that 2-sided printing cannot happen on transparencies</em>
*cupsUIConstraints transparency: "*Duplex *MediaType Transparency"
+<em>*% Specify that envelope printing cannot happen from the paper trays</em>
+*cupsUIConstraints envelope: "*PageSize Env10 *InputSlot Tray1"
+*cupsUIConstraints envelope: "*PageSize Env10 *InputSlot Tray1"
+*cupsUIConstraints envelope: "*PageSize EnvDL *InputSlot Tray2"
+*cupsUIConstraints envelope: "*PageSize EnvDL *InputSlot Tray2"
+
+<em>*% Specify an installable option constraint for the envelope feeder</em>
+*cupsUIConstraints: "*InputSlot EnvFeeder *InstalledEnvFeeder"
+
<em>*% Specify that photo printing cannot happen on plain paper or transparencies at 1200dpi</em>
*cupsUIConstraints photo: "*OutputMode Photo *MediaType Plain *Resolution 1200dpi"
*cupsUIConstraints photo: "*OutputMode Photo *MediaType Transparency *Resolution 1200dpi"
@@ -410,18 +428,29 @@ installable options.</p>
<h3><span class='info'>CUPS 1.4</span><a name='cupsUIResolver'>cupsUIResolver</a></h3>
-<p class='summary'>*cupsUIResolution resolver: "*Keyword OptionKeyword ..."</p>
+<p class='summary'>*cupsUIResolution resolver: "*Keyword1 OptionKeyword1 *Keyword2 OptionKeyword2 ..."</p>
-<p>Specifies one or more options to mark/select to resolve a constraint. The
+<p>Specifies two or more options to mark/select to resolve a constraint. The
"resolver" string identifies a particular action to take for one or more
<a href='#cupsUIConstraints'><tt>cupsUIConstraints</tt></a>. The same action
-can be used for multiple constraints.</p>
+can be used for multiple constraints. The option keyword pairs are treated as
+an ordered list of option selections to try - only the first N selections will
+be used, where N is the minimum number of selections required. Because
+<a href="api-ppd.html#cupsResolveConflicts"><code>cupsResolveConflicts()</code></a>
+will not change the most recent option selection passed to it, at least two
+options from the constraints must be listed to avoid situations where conflicts
+cannot be resolved.</p>
<p>Examples:</p>
<pre class='command'>
-<em>*% Specify the option to change for the 2-sided transparency constraint</em>
-*cupsUIResolver transparency: "*Duplex None"
+<em>*% Specify the options to change for the 2-sided transparency constraint</em>
+*cupsUIResolver transparency: "*Duplex None *MediaType Plain"
+
+<em>*% Specify the options to change for the envelope printing constraints. Notice
+*% that we try to change the InputSlot to either the envelope feeder or the
+*% manual feed first, then we change the page size...</em>
+*cupsUIResolver envelope: "*InputSlot EnvFeeder *InputSlot ManualFeed *PageSize Letter"
<em>*% Specify the options to change for the photo printing constraints</em>
*cupsUIResolver photo: "*OutputMode Best *Resolution 600dpi"
diff --git a/driver/Dependencies b/driver/Dependencies
index a89ca293f..2111f79f0 100644
--- a/driver/Dependencies
+++ b/driver/Dependencies
@@ -11,11 +11,13 @@ commandtopclx.o: ../cups/string.h ../config.h ../data/pcl.h
rastertoescpx.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
rastertoescpx.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
rastertoescpx.o: ../cups/file.h ../cups/language.h ../cups/raster.h
-rastertoescpx.o: ../cups/string.h ../config.h ../data/escp.h
+rastertoescpx.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h
+rastertoescpx.o: ../config.h ../data/escp.h
rastertopclx.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
rastertopclx.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
rastertopclx.o: ../cups/file.h ../cups/language.h ../cups/raster.h
-rastertopclx.o: pcl-common.h ../cups/string.h ../config.h ../data/pcl.h
+rastertopclx.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h
+rastertopclx.o: ../config.h pcl-common.h ../data/pcl.h
pcl-common.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
pcl-common.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
pcl-common.o: ../cups/file.h ../cups/language.h ../cups/raster.h pcl-common.h
diff --git a/man/cupsfilter.man b/man/cupsfilter.man
index 337c57e0d..9bd428d9f 100644
--- a/man/cupsfilter.man
+++ b/man/cupsfilter.man
@@ -11,14 +11,14 @@
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH cupsfilter 8 "Common UNIX Printing System" "10 September 2008" "Apple Inc."
+.TH cupsfilter 8 "Common UNIX Printing System" "26 February 2009" "Apple Inc."
.SH NAME
cupsfilter \- convert a file to another format using cups filters
.SH SYNOPSIS
.B cupsfilter
[ -c
.I config-file
-] -j
+] [ -e ] -j
.I job-id[,N]
[ -m
.I mime/type
@@ -42,6 +42,10 @@ through CUPS. By default, \fIcupsfilter\fR generates a PDF file.
.br
Uses the named cupsd.conf configuration file.
.TP 5
+-e
+.br
+Use every filter from the PPD file.
+.TP 5
-j job-id[,N]
.br
Converts document N from the specified job. If N is omitted, document 1 is
diff --git a/man/cupstestppd.man b/man/cupstestppd.man
index 4757c5d72..fd2b878b5 100644
--- a/man/cupstestppd.man
+++ b/man/cupstestppd.man
@@ -12,7 +12,7 @@
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH cupstestppd 1 "Common UNIX Printing System" "3 May 2007" "Apple Inc."
+.TH cupstestppd 1 "Common UNIX Printing System" "2 March 2009" "Apple Inc."
.SH NAME
cupstestppd \- test conformance of ppd files
.SH SYNOPSIS
@@ -63,6 +63,10 @@ Report all filter errors as warnings.
.br
Report all profile errors as warnings.
.TP 5
+-W sizes
+.br
+Report all media size errors as warnings.
+.TP 5
-W translations
.br
Report all translation errors as warnings.
diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h
index e9d8df1f0..8da2d9616 100644
--- a/scheduler/cupsd.h
+++ b/scheduler/cupsd.h
@@ -152,8 +152,10 @@ typedef void (*cupsd_selfunc_t)(void *data);
* Globals...
*/
-VAR int TestConfigFile VALUE(0);
+VAR int TestConfigFile VALUE(0),
/* Test the cupsd.conf file? */
+ UseProfiles VALUE(1);
+ /* Use security profiles for child procs? */
VAR int MaxFDs VALUE(0);
/* Maximum number of files */
diff --git a/scheduler/cupsfilter.c b/scheduler/cupsfilter.c
index d3c30210a..17f6f89ea 100644
--- a/scheduler/cupsfilter.c
+++ b/scheduler/cupsfilter.c
@@ -86,7 +86,8 @@ static int compare_pids(mime_filter_t *a, mime_filter_t *b);
static char *escape_options(int num_options, cups_option_t *options);
static int exec_filter(const char *filter, char **argv,
char **envp, int infd, int outfd);
-static int exec_filters(cups_array_t *filters, const char *infile,
+static int exec_filters(mime_type_t *srctype,
+ cups_array_t *filters, const char *infile,
const char *outfile, const char *ppdfile,
const char *printer, const char *user,
const char *title, int num_options,
@@ -133,7 +134,8 @@ main(int argc, /* I - Number of command-line args */
const char *ppdfile; /* PPD file */
const char *title, /* Title string */
*user; /* Username */
- int removeppd, /* Remove PPD file */
+ int all_filters, /* Use all filters */
+ removeppd, /* Remove PPD file */
removeinfile; /* Remove input file */
int status; /* Execution status */
@@ -159,6 +161,7 @@ main(int argc, /* I - Number of command-line args */
ppdfile = NULL;
title = NULL;
user = cupsUser();
+ all_filters = 0;
removeppd = 0;
removeinfile = 0;
@@ -213,6 +216,10 @@ main(int argc, /* I - Number of command-line args */
removeinfile = 1;
break;
+ case 'e' : /* Use every filter from the PPD file */
+ all_filters = 1;
+ break;
+
case 'f' : /* Specify input file... */
i ++;
if (i < argc && !infile)
@@ -380,8 +387,16 @@ main(int argc, /* I - Number of command-line args */
return (1);
}
- printer_type = add_printer_filters(command, mime, printer, ppdfile,
- &prefilter_type);
+ if (all_filters)
+ {
+ printer_type = add_printer_filters(command, mime, printer, ppdfile,
+ &prefilter_type);
+ }
+ else
+ {
+ printer_type = mimeType(mime, "application", "vnd.cups-postscript");
+ prefilter_type = NULL;
+ }
/*
* Get the source and destination types...
@@ -429,6 +444,8 @@ main(int argc, /* I - Number of command-line args */
filters = cupsArrayNew(NULL, NULL);
cupsArrayAdd(filters, &GZIPFilter);
+ GZIPFilter.src = src;
+ GZIPFilter.dst = dst;
}
else if ((filters = mimeFilter(mime, src, dst, &cost)) == NULL)
{
@@ -456,7 +473,8 @@ main(int argc, /* I - Number of command-line args */
filter;
filter = (mime_filter_t *)cupsArrayNext(filters))
{
- if ((prefilter = mimeFilterLookup(mime, filter->src, prefilter_type)))
+ if ((prefilter = mimeFilterLookup(mime, filter->src,
+ prefilter_type)) != NULL)
cupsArrayAdd(prefilters, prefilter);
cupsArrayAdd(prefilters, filter);
@@ -470,7 +488,7 @@ main(int argc, /* I - Number of command-line args */
* Do it!
*/
- status = exec_filters(filters, infile, outfile, ppdfile, printer, user,
+ status = exec_filters(src, filters, infile, outfile, ppdfile, printer, user,
title, num_options, options);
/*
@@ -610,6 +628,8 @@ add_printer_filters(
if (ppdattr->value)
add_printer_filter(command, mime, *prefilter_type, ppdattr->value);
}
+ else
+ *prefilter_type = NULL;
return (printer_type);
}
@@ -789,7 +809,8 @@ exec_filter(const char *filter, /* I - Filter to execute */
*/
static int /* O - 0 on success, 1 on error */
-exec_filters(cups_array_t *filters, /* I - Array of filters to run */
+exec_filters(mime_type_t *srctype, /* I - Source type */
+ cups_array_t *filters, /* I - Array of filters to run */
const char *infile, /* I - File to filter */
const char *outfile, /* I - File to create */
const char *ppdfile, /* I - PPD file, if any */
@@ -833,9 +854,8 @@ exec_filters(cups_array_t *filters, /* I - Array of filters to run */
optstr = escape_options(num_options, options);
- filter = cupsArrayFirst(filters);
snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s/%s",
- filter->src->super, filter->src->type);
+ srctype->super, srctype->type);
snprintf(cups_datadir, sizeof(cups_datadir), "CUPS_DATADIR=%s", DataDir);
snprintf(cups_fontpath, sizeof(cups_fontpath), "CUPS_FONTPATH=%s", FontPath);
snprintf(cups_serverbin, sizeof(cups_serverbin), "CUPS_SERVERBIN=%s",
@@ -1285,6 +1305,7 @@ usage(const char *command, /* I - Command name */
"Options:\n"
"\n"
" -c cupsd.conf Set cupsd.conf file to use\n"
+ " -e Use every filter from the PPD file\n"
" -j job-id[,N] Filter file N from the specified job (default is file 1)\n"
" -n copies Set number of copies\n"
" -o name=value Set option(s)\n"
@@ -1296,6 +1317,7 @@ usage(const char *command, /* I - Command name */
"\n"
"Options:\n"
"\n"
+ " -e Use every filter from the PPD file\n"
" -f filename Set file to be converted (otherwise stdin)\n"
" -o filename Set file to be generated (otherwise stdout)\n"
" -i mime/type Set input MIME type (otherwise auto-typed)\n"
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index 3fc1f33b0..c0160e2e9 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -360,7 +360,8 @@ cupsdProcessIPPRequest(
*/
attr = con->request->attrs;
- if (attr && !strcmp(attr->name, "attributes-charset") &&
+ if (attr && attr->name &&
+ !strcmp(attr->name, "attributes-charset") &&
(attr->value_tag & IPP_TAG_MASK) == IPP_TAG_CHARSET)
charset = attr;
else
@@ -369,7 +370,8 @@ cupsdProcessIPPRequest(
if (attr)
attr = attr->next;
- if (attr && !strcmp(attr->name, "attributes-natural-language") &&
+ if (attr && attr->name &&
+ !strcmp(attr->name, "attributes-natural-language") &&
(attr->value_tag & IPP_TAG_MASK) == IPP_TAG_LANGUAGE)
language = attr;
else
diff --git a/scheduler/job.c b/scheduler/job.c
index 25ddffd9f..cd185c473 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -22,7 +22,6 @@
* cupsdCleanJobs() - Clean out old jobs.
* cupsdContinueJob() - Continue printing with the next file in a job.
* cupsdDeleteJob() - Free all memory used by a job.
- * cupsdFinishJob() - Finish a job.
* cupsdFreeAllJobs() - Free all jobs from memory.
* cupsdFindJob() - Find the specified job.
* cupsdGetPrinterJobCount() - Get the number of pending, processing, or held
@@ -491,7 +490,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
FilterLevel -= job->cost;
- filters = NULL;
+ filters = NULL;
if (job->printer->raw)
{
@@ -827,7 +826,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
* Just the language code (ll)...
*/
- snprintf(lang, sizeof(lang), "LANG=%s.UTF8",
+ snprintf(lang, sizeof(lang), "LANG=%s.UTF-8",
attr->values[0].string.text);
break;
@@ -836,7 +835,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
* Language and country code (ll-cc)...
*/
- snprintf(lang, sizeof(lang), "LANG=%c%c_%c%c.UTF8",
+ snprintf(lang, sizeof(lang), "LANG=%c%c_%c%c.UTF-8",
attr->values[0].string.text[0],
attr->values[0].string.text[1],
toupper(attr->values[0].string.text[3] & 255),
@@ -2481,9 +2480,40 @@ finalize_job(cupsd_job_t *job) /* I - Job */
* Process the exit status...
*/
- printer_state = IPP_PRINTER_IDLE;
- job_state = IPP_JOB_COMPLETED;
- message = "Job completed.";
+ if (job->printer->state == IPP_PRINTER_PROCESSING)
+ printer_state = IPP_PRINTER_IDLE;
+ else
+ printer_state = job->printer->state;
+
+ switch (job_state = job->state_value)
+ {
+ case IPP_JOB_PENDING :
+ message = "Job paused.";
+ break;
+
+ case IPP_JOB_HELD :
+ message = "Job held.";
+ break;
+
+ default :
+ case IPP_JOB_PROCESSING :
+ case IPP_JOB_COMPLETED :
+ job_state = IPP_JOB_COMPLETED;
+ message = "Job completed.";
+ break;
+
+ case IPP_JOB_STOPPED :
+ message = "Job stopped.";
+ break;
+
+ case IPP_JOB_CANCELED :
+ message = "Job canceled.";
+ break;
+
+ case IPP_JOB_ABORTED :
+ message = "Job aborted.";
+ break;
+ }
if (job->status < 0)
{
@@ -2741,8 +2771,8 @@ get_options(cupsd_job_t *job, /* I - Job */
optptr = options;
*optptr = '\0';
- snprintf(title, sizeof(title), "%s-%d", job->printer->name, job->id);
- strcpy(copies, "1");
+ snprintf(title, title_size, "%s-%d", job->printer->name, job->id);
+ strlcpy(copies, "1", copies_size);
for (attr = job->attrs->attrs; attr != NULL; attr = attr->next)
{
@@ -2754,12 +2784,12 @@ get_options(cupsd_job_t *job, /* I - Job */
*/
if (!banner_page)
- sprintf(copies, "%d", attr->values[0].integer);
+ snprintf(copies, copies_size, "%d", attr->values[0].integer);
}
else if (!strcmp(attr->name, "job-name") &&
(attr->value_tag == IPP_TAG_NAME ||
attr->value_tag == IPP_TAG_NAMELANG))
- strlcpy(title, attr->values[0].string.text, sizeof(title));
+ strlcpy(title, attr->values[0].string.text, title_size);
else if (attr->group_tag == IPP_TAG_JOB)
{
/*
@@ -3494,10 +3524,11 @@ start_job(cupsd_job_t *job, /* I - Job ID */
cupsdSetJobState(job, IPP_JOB_PROCESSING, CUPSD_JOB_DEFAULT, NULL);
cupsdSetPrinterState(printer, IPP_PRINTER_PROCESSING, 0);
- job->cost = 0;
- job->progress = 0;
- job->printer = printer;
- printer->job = job;
+ job->cost = 0;
+ job->current_file = 0;
+ job->progress = 0;
+ job->printer = printer;
+ printer->job = job;
/*
* Setup the last exit status and security profiles...
diff --git a/scheduler/main.c b/scheduler/main.c
index 437f0f5ba..ccc395211 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -145,8 +145,9 @@ main(int argc, /* I - Number of command-line args */
struct stat statbuf; /* Needed for checking lpsched FIFO */
#endif /* __sgi */
#ifdef __APPLE__
- int run_as_child = 0;
+ int run_as_child = 0,
/* Needed for Mac OS X fork/exec */
+ use_sysman = 1; /* Use system management functions? */
#else
time_t netif_time = 0; /* Time since last network update */
#endif /* __APPLE__ */
@@ -188,6 +189,11 @@ main(int argc, /* I - Number of command-line args */
switch (*opt)
{
#ifdef __APPLE__
+ case 'S' : /* Disable system management functions */
+ puts("Warning: -S (disable system management) for internal testing use only!");
+ use_sysman = 0;
+ break;
+
case 'C' : /* Run as child with config file */
run_as_child = 1;
fg = -1;
@@ -270,11 +276,16 @@ main(int argc, /* I - Number of command-line args */
break;
case 'p' : /* Stop immediately for profiling */
- puts("Warning: -p option is for internal testing use only!");
+ puts("Warning: -p (startup profiling) is for internal testing use only!");
stop_scheduler = 1;
fg = 1;
break;
+ case 'P' : /* Disable security profiles */
+ puts("Warning: -P (disable security profiles) is for internal testing use only!");
+ UseProfiles = 0;
+ break;
+
case 't' : /* Test the cupsd.conf file... */
TestConfigFile = 1;
fg = 1;
@@ -630,7 +641,8 @@ main(int argc, /* I - Number of command-line args */
* Start power management framework...
*/
- cupsdStartSystemMonitor();
+ if (use_sysman)
+ cupsdStartSystemMonitor();
#endif /* __APPLE__ */
/*
@@ -1149,7 +1161,8 @@ main(int argc, /* I - Number of command-line args */
* Stop monitoring system event monitoring...
*/
- cupsdStopSystemMonitor();
+ if (use_sysman)
+ cupsdStopSystemMonitor();
#endif /* __APPLE__ */
#ifdef HAVE_GSSAPI
@@ -1742,6 +1755,7 @@ process_children(void)
cupsdContinueJob(job);
}
}
+ break;
}
}
diff --git a/scheduler/printers.c b/scheduler/printers.c
index c826120f1..47142db2b 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -2015,7 +2015,7 @@ cupsdSetPrinterAttr(
* Don't allow empty values...
*/
- if (!*value)
+ if (!*value && strcmp(name, "marker-message"))
{
cupsdLogMessage(CUPSD_LOG_ERROR, "Ignoring empty \"%s\" attribute", name);
return;
@@ -2736,10 +2736,6 @@ cupsdSetPrinterReasons(
* Found a match, so remove it...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdSetPrinterReasons: Removing \"%s\" at index %d",
- reason, i);
-
p->num_reasons --;
_cupsStrFree(p->reasons[i]);
@@ -2779,10 +2775,6 @@ cupsdSetPrinterReasons(
return;
}
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdSetPrinterReasons: Adding \"%s\" at index %d",
- reason, i);
-
p->reasons[i] = _cupsStrAlloc(reason);
p->num_reasons ++;
diff --git a/scheduler/process.c b/scheduler/process.c
index bd548ff06..45d3bcfb6 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -83,7 +83,7 @@ cupsdCreateProfile(int job_id) /* I - Job ID or 0 for none */
temp[1024]; /* Quoted TempDir */
- if (RunUser)
+ if (!UseProfiles || RunUser)
{
/*
* Only use sandbox profiles as root...
diff --git a/systemv/Dependencies b/systemv/Dependencies
index 79765c4b9..f0b180813 100644
--- a/systemv/Dependencies
+++ b/systemv/Dependencies
@@ -23,8 +23,8 @@ cupstestdsc.o: ../cups/file.h ../cups/i18n.h ../cups/transcode.h
cupstestppd.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
cupstestppd.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h
cupstestppd.o: ../cups/array.h ../cups/file.h ../cups/language.h
-cupstestppd.o: ../cups/ppd-private.h ../cups/cups.h ../cups/i18n.h
-cupstestppd.o: ../cups/transcode.h ../cups/raster.h
+cupstestppd.o: ../cups/dir.h ../cups/ppd-private.h ../cups/cups.h
+cupstestppd.o: ../cups/i18n.h ../cups/transcode.h ../cups/raster.h
lp.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
lp.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h
lp.o: ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h
diff --git a/systemv/cupstestppd.c b/systemv/cupstestppd.c
index 855c17fbf..4a619ebca 100644
--- a/systemv/cupstestppd.c
+++ b/systemv/cupstestppd.c
@@ -3,7 +3,7 @@
*
* PPD test program for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007-2008 by Apple Inc.
+ * Copyright 2007-2009 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -21,17 +21,19 @@
* main() - Main entry for test program.
* check_basics() - Check for CR LF, mixed line endings, and blank
* lines.
+ * check_constraints() - Check UIConstraints in the PPD file.
* check_case() - Check that there are no duplicate groups, options,
* or choices that differ only by case.
- * check_constraints() - Check UIConstraints in the PPD file.
* check_defaults() - Check default option keywords in the PPD file.
* check_duplex() - Check duplex keywords in the PPD file.
* check_filters() - Check filters in the PPD file.
* check_profiles() - Check ICC color profiles in the PPD file.
+ * check_sizes() - Check media sizes in the PPD file.
* check_translations() - Check translations in the PPD file.
* show_conflicts() - Show option conflicts in a PPD file.
* test_raster() - Test PostScript commands for raster printers.
* usage() - Show program usage...
+ * valid_path() - Check whether a path has the correct capitalization.
* valid_utf8() - Check whether a string contains valid UTF-8 text.
*/
@@ -41,12 +43,13 @@
#include <cups/string.h>
#include <cups/cups.h>
+#include <cups/dir.h>
#include <cups/ppd-private.h>
#include <cups/i18n.h>
#include <cups/raster.h>
#include <errno.h>
#include <stdlib.h>
-#include <sys/stat.h>
+#include <math.h>
/*
@@ -62,7 +65,8 @@ enum
WARN_PROFILES = 8,
WARN_TRANSLATIONS = 16,
WARN_DUPLEX = 32,
- WARN_ALL = 63
+ WARN_SIZES = 64,
+ WARN_ALL = 127
};
@@ -94,6 +98,168 @@ enum
/*
+ * Standard Adobe media keywords (must remain sorted)...
+ */
+
+static const char adobe_size_names[][PPD_MAX_NAME] =
+{
+ "10x11",
+ "10x13",
+ "10x14",
+ "12x11",
+ "15x11",
+ "7x9",
+ "8x10",
+ "9x11",
+ "9x12",
+ "A0",
+ "A1",
+ "A10",
+ "A2",
+ "A3",
+ "A3Extra",
+ "A3Rotated",
+ "A4",
+ "A4Extra",
+ "A4Plus",
+ "A4Rotated",
+ "A4Small",
+ "A5",
+ "A5Extra",
+ "A5Rotated",
+ "A6",
+ "A6Rotated",
+ "A7",
+ "A8",
+ "A9",
+ "ARCHA",
+ "ARCHB",
+ "ARCHC",
+ "ARCHD",
+ "ARCHE",
+ "AnsiA",
+ "AnsiB",
+ "AnsiC",
+ "AnsiD",
+ "AnsiE",
+ "B0",
+ "B1",
+ "B1",
+ "B10",
+ "B2",
+ "B3",
+ "B4",
+ "B4Rotated",
+ "B5",
+ "B5Rotated",
+ "B6",
+ "B6Rotated",
+ "B7",
+ "B8",
+ "B9",
+ "C4",
+ "C5",
+ "C6",
+ "DL",
+ "DoublePostcard",
+ "DoublePostcardRotated",
+ "Env10",
+ "Env11",
+ "Env12",
+ "Env14",
+ "Env9",
+ "EnvC0",
+ "EnvC1",
+ "EnvC2",
+ "EnvC3",
+ "EnvC4",
+ "EnvC5",
+ "EnvC6",
+ "EnvC65",
+ "EnvC7",
+ "EnvChou3",
+ "EnvChou3Rotated",
+ "EnvChou4",
+ "EnvChou4Rotated",
+ "EnvDL",
+ "EnvISOB4",
+ "EnvISOB5",
+ "EnvISOB6",
+ "EnvInvite",
+ "EnvItalian",
+ "EnvKaku2",
+ "EnvKaku2Rotated",
+ "EnvKaku3",
+ "EnvKaku3Rotated",
+ "EnvMonarch",
+ "EnvPRC1",
+ "EnvPRC10",
+ "EnvPRC10Rotated",
+ "EnvPRC1Rotated",
+ "EnvPRC2",
+ "EnvPRC2Rotated",
+ "EnvPRC3",
+ "EnvPRC3Rotated",
+ "EnvPRC4",
+ "EnvPRC4Rotated",
+ "EnvPRC5",
+ "EnvPRC5Rotated",
+ "EnvPRC6",
+ "EnvPRC6Rotated",
+ "EnvPRC7",
+ "EnvPRC7Rotated",
+ "EnvPRC8",
+ "EnvPRC8Rotated",
+ "EnvPRC9",
+ "EnvPRC9Rotated",
+ "EnvPersonal",
+ "EnvYou4",
+ "EnvYou4Rotated",
+ "Executive",
+ "FanFoldGerman",
+ "FanFoldGermanLegal",
+ "FanFoldUS",
+ "Folio",
+ "ISOB0",
+ "ISOB1",
+ "ISOB10",
+ "ISOB2",
+ "ISOB3",
+ "ISOB4",
+ "ISOB5",
+ "ISOB5Extra",
+ "ISOB6",
+ "ISOB7",
+ "ISOB8",
+ "ISOB9",
+ "Ledger",
+ "Legal",
+ "LegalExtra",
+ "Letter",
+ "LetterExtra",
+ "LetterPlus",
+ "LetterRotated",
+ "LetterSmall",
+ "Monarch",
+ "Note",
+ "PRC16K",
+ "PRC16KRotated",
+ "PRC32K",
+ "PRC32KBig",
+ "PRC32KBigRotated",
+ "PRC32KRotated",
+ "Postcard",
+ "PostcardRotated",
+ "Quarto",
+ "Statement",
+ "SuperA",
+ "SuperB",
+ "Tabloid",
+ "TabloidExtra"
+};
+
+
+/*
* Local functions...
*/
@@ -109,11 +275,14 @@ static int check_filters(ppd_file_t *ppd, const char *root, int errors,
int verbose, int warn);
static int check_profiles(ppd_file_t *ppd, const char *root, int errors,
int verbose, int warn);
-static int check_translations(ppd_file_t *ppd, int errors, int verbose,\
+static int check_sizes(ppd_file_t *ppd, int errors, int verbose, int warn);
+static int check_translations(ppd_file_t *ppd, int errors, int verbose,
int warn);
static void show_conflicts(ppd_file_t *ppd);
static int test_raster(ppd_file_t *ppd, int verbose);
static void usage(void);
+static int valid_path(const char *keyword, const char *path, int errors,
+ int verbose, int warn);
static int valid_utf8(const char *s);
@@ -203,6 +372,8 @@ main(int argc, /* I - Number of command-line args */
warn |= WARN_FILTERS;
else if (!strcmp(argv[i], "profiles"))
warn |= WARN_PROFILES;
+ else if (!strcmp(argv[i], "sizes"))
+ warn |= WARN_SIZES;
else if (!strcmp(argv[i], "translations"))
warn |= WARN_TRANSLATIONS;
else if (!strcmp(argv[i], "all"))
@@ -1088,6 +1259,9 @@ main(int argc, /* I - Number of command-line args */
if (!(warn & WARN_PROFILES))
errors = check_profiles(ppd, root, errors, verbose, 0);
+ if (!(warn & WARN_SIZES))
+ errors = check_sizes(ppd, errors, verbose, 0);
+
if (!(warn & WARN_TRANSLATIONS))
errors = check_translations(ppd, errors, verbose, 0);
@@ -1222,6 +1396,11 @@ main(int argc, /* I - Number of command-line args */
if (warn & WARN_FILTERS)
errors = check_filters(ppd, root, errors, verbose, 1);
+ if (warn & WARN_SIZES)
+ errors = check_sizes(ppd, errors, verbose, 1);
+ else
+ errors = check_sizes(ppd, errors, verbose, 2);
+
if (warn & WARN_TRANSLATIONS)
errors = check_translations(ppd, errors, verbose, 1);
@@ -1384,36 +1563,6 @@ main(int argc, /* I - Number of command-line args */
}
}
-#ifdef __APPLE__
- /*
- * APDialogExtension
- */
-
- for (attr = ppdFindAttr(ppd, "APDialogExtension", NULL);
- attr != NULL;
- attr = ppdFindNextAttr(ppd, "APDialogExtension", NULL))
- {
- if ((!attr->value || access(attr->value, 0)) && verbose >= 0)
- _cupsLangPrintf(stdout, _(" WARN Missing "
- "APDialogExtension file \"%s\"\n"),
- attr->value ? attr->value : "<NULL>");
- }
-
- /*
- * APPrinterIconPath
- */
-
- for (attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL);
- attr != NULL;
- attr = ppdFindNextAttr(ppd, "APPrinterIconPath", NULL))
- {
- if ((!attr->value || access(attr->value, 0)) && verbose >= 0)
- _cupsLangPrintf(stdout, _(" WARN Missing "
- "APPrinterIconPath file \"%s\"\n"),
- attr->value ? attr->value : "<NULL>");
- }
-#endif /* __APPLE__ */
-
if (verbose > 0)
{
if (errors)
@@ -1859,6 +2008,24 @@ check_constraints(ppd_file_t *ppd, /* I - PPD file */
}
/*
+ * Resolvers must list at least two options...
+ */
+
+ if (num_options < 2)
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ _cupsLangPrintf(stdout,
+ _(" %s cupsUIResolver %s does not list at least "
+ "two different options!\n"),
+ prefix, constattr->spec);
+
+ if (!warn)
+ errors ++;
+ }
+
+ /*
* Test the resolver...
*/
@@ -2245,6 +2412,10 @@ check_filters(ppd_file_t *ppd, /* I - PPD file */
prefix = warn ? " WARN " : "**FAIL**";
+ /*
+ * cupsFilter
+ */
+
for (i = 0; i < ppd->num_filters; i ++)
{
if (sscanf(ppd->filters[i], "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type,
@@ -2290,9 +2461,15 @@ check_filters(ppd_file_t *ppd, /* I - PPD file */
if (!warn)
errors ++;
}
+ else
+ errors = valid_path("cupsFilter", pathprog, errors, verbose, warn);
}
}
+ /*
+ * cupsPreFilter
+ */
+
for (attr = ppdFindAttr(ppd, "cupsPreFilter", NULL);
attr;
attr = ppdFindNextAttr(ppd, "cupsPreFilter", NULL))
@@ -2341,8 +2518,110 @@ check_filters(ppd_file_t *ppd, /* I - PPD file */
if (!warn)
errors ++;
}
+ else
+ errors = valid_path("cupsPreFilter", pathprog, errors, verbose, warn);
+ }
+ }
+
+#ifdef __APPLE__
+ /*
+ * APDialogExtension
+ */
+
+ for (attr = ppdFindAttr(ppd, "APDialogExtension", NULL);
+ attr != NULL;
+ attr = ppdFindNextAttr(ppd, "APDialogExtension", NULL))
+ {
+ if (!attr->value || access(attr->value, 0))
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout, _(" %s Missing "
+ "APDialogExtension file \"%s\"\n"),
+ prefix, attr->value ? attr->value : "<NULL>");
+
+ if (!warn)
+ errors ++;
+ }
+ else
+ errors = valid_path("APDialogExtension", attr->value, errors, verbose,
+ warn);
+ }
+
+ /*
+ * APPrinterIconPath
+ */
+
+ if ((attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL)
+ {
+ if (!attr->value || access(attr->value, 0))
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout, _(" %s Missing "
+ "APPrinterIconPath file \"%s\"\n"),
+ prefix, attr->value ? attr->value : "<NULL>");
+
+ if (!warn)
+ errors ++;
+ }
+ else
+ errors = valid_path("APPrinterIconPath", attr->value, errors, verbose,
+ warn);
+ }
+
+ /*
+ * APPrinterLowInkTool
+ */
+
+ if ((attr = ppdFindAttr(ppd, "APPrinterLowInkTool", NULL)) != NULL)
+ {
+ if (!attr->value || access(attr->value, 0))
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout, _(" %s Missing "
+ "APPrinterLowInkTool file \"%s\"\n"),
+ prefix, attr->value ? attr->value : "<NULL>");
+
+ if (!warn)
+ errors ++;
+ }
+ else
+ errors = valid_path("APPrinterLowInkTool", attr->value, errors, verbose,
+ warn);
+ }
+
+ /*
+ * APPrinterUtilityPath
+ */
+
+ if ((attr = ppdFindAttr(ppd, "APPrinterUtilityPath", NULL)) != NULL)
+ {
+ if (!attr->value || access(attr->value, 0))
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout, _(" %s Missing "
+ "APPrinterUtilityPath file \"%s\"\n"),
+ prefix, attr->value ? attr->value : "<NULL>");
+
+ if (!warn)
+ errors ++;
}
+ else
+ errors = valid_path("APPrinterUtilityPath", attr->value, errors, verbose,
+ warn);
}
+#endif /* __APPLE__ */
return (errors);
}
@@ -2430,6 +2709,8 @@ check_profiles(ppd_file_t *ppd, /* I - PPD file */
if (!warn)
errors ++;
}
+ else
+ errors = valid_path("cupsICCProfile", filename, errors, verbose, warn);
/*
* Check for hash collisions...
@@ -2476,6 +2757,158 @@ check_profiles(ppd_file_t *ppd, /* I - PPD file */
/*
+ * 'check_sizes()' - Check media sizes in the PPD file.
+ */
+
+static int /* O - Errors found */
+check_sizes(ppd_file_t *ppd, /* I - PPD file */
+ int errors, /* I - Errors found */
+ int verbose, /* I - Verbosity level */
+ int warn) /* I - Warnings only? */
+{
+ int i; /* Looping vars */
+ ppd_size_t *size; /* Current size */
+ int width, /* Custom width */
+ length; /* Custom length */
+ char name[PPD_MAX_NAME], /* Size name without dot suffix */
+ *nameptr; /* Pointer into name */
+ const char *prefix; /* WARN/FAIL prefix */
+ ppd_option_t *page_size, /* PageSize option */
+ *page_region; /* PageRegion option */
+
+
+ prefix = warn ? " WARN " : "**FAIL**";
+
+ if ((page_size = ppdFindOption(ppd, "PageSize")) == NULL && warn != 2)
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout,
+ _(" %s Missing REQUIRED PageSize option!\n"
+ " REF: Page 99, section 5.14.\n"),
+ prefix);
+
+ if (!warn)
+ errors ++;
+ }
+
+ if ((page_region = ppdFindOption(ppd, "PageRegion")) == NULL && warn != 2)
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout,
+ _(" %s Missing REQUIRED PageRegion option!\n"
+ " REF: Page 100, section 5.14.\n"),
+ prefix);
+
+ if (!warn)
+ errors ++;
+ }
+
+ for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
+ {
+ /*
+ * Check that the size name is standard...
+ */
+
+ if (!strcmp(size->name, "Custom"))
+ {
+ /*
+ * Skip custom page size...
+ */
+
+ continue;
+ }
+ else if (warn != 2 && size->name[0] == 'w' &&
+ sscanf(size->name, "w%dh%d", &width, &length) == 2)
+ {
+ /*
+ * Validate device-specific size wNNNhNNN should have proper width and
+ * length...
+ */
+
+ if (fabs(width - size->width) >= 1.0 ||
+ fabs(length - size->length) >= 1.0)
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout,
+ _(" %s Size \"%s\" has unexpected dimensions "
+ "(%gx%g)!\n"),
+ prefix, size->name, size->width, size->length);
+
+ if (!warn)
+ errors ++;
+ }
+ }
+ else if (warn && verbose >= 0)
+ {
+ /*
+ * Lookup the size name in the standard size table...
+ */
+
+ strlcpy(name, size->name, sizeof(name));
+ if ((nameptr = strchr(name, '.')) != NULL)
+ *nameptr = '\0';
+
+ if (!bsearch(name, adobe_size_names,
+ sizeof(adobe_size_names) /
+ sizeof(adobe_size_names[0]),
+ sizeof(adobe_size_names[0]),
+ (int (*)(const void *, const void *))strcmp))
+ {
+ _cupsLangPrintf(stdout,
+ _(" %s Non-standard size name \"%s\"!\n"
+ " REF: Page 187, section B.2.\n"),
+ prefix, size->name);
+ }
+ }
+
+ /*
+ * Verify that the size is defined for both PageSize and PageRegion...
+ */
+
+ if (warn != 2 && !ppdFindChoice(page_size, size->name))
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout,
+ _(" %s Size \"%s\" defined for %s but not for "
+ "%s!\n"),
+ prefix, size->name, "PageRegion", "PageSize");
+
+ if (!warn)
+ errors ++;
+ }
+ else if (warn != 2 && !ppdFindChoice(page_region, size->name))
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout,
+ _(" %s Size \"%s\" defined for %s but not for "
+ "%s!\n"),
+ prefix, size->name, "PageSize", "PageRegion");
+
+ if (!warn)
+ errors ++;
+ }
+ }
+
+ return (errors);
+}
+
+
+/*
* 'check_translations()' - Check translations in the PPD file.
*/
@@ -2933,7 +3366,7 @@ usage(void)
"\n"
" -R root-directory Set alternate root\n"
" -W {all,none,constraints,defaults,duplex,filters,"
- "translations}\n"
+ "profiles,sizes,translations}\n"
" Issue warnings instead of errors\n"
" -q Run silently\n"
" -r Use 'relaxed' open mode\n"
@@ -2945,6 +3378,89 @@ usage(void)
/*
+ * 'valid_path()' - Check whether a path has the correct capitalization.
+ */
+
+static int /* O - Errors found */
+valid_path(const char *keyword, /* I - Keyword using path */
+ const char *path, /* I - Path to check */
+ int errors, /* I - Errors found */
+ int verbose, /* I - Verbosity level */
+ int warn) /* I - Warnings only? */
+{
+ cups_dir_t *dir; /* Current directory */
+ cups_dentry_t *dentry; /* Current directory entry */
+ char temp[1024], /* Temporary path */
+ *ptr; /* Pointer into temporary path */
+ const char *prefix; /* WARN/FAIL prefix */
+
+
+ prefix = warn ? " WARN " : "**FAIL**";
+
+ /*
+ * Loop over the components of the path, checking that the entry exists with
+ * the same capitalization...
+ */
+
+ strlcpy(temp, path, sizeof(temp));
+
+ while ((ptr = strrchr(temp, '/')) != NULL)
+ {
+ /*
+ * Chop off the trailing component so temp == dirname and ptr == basename.
+ */
+
+ *ptr++ = '\0';
+
+ /*
+ * Try opening the directory containing the base name...
+ */
+
+ if (temp[0])
+ dir = cupsDirOpen(temp);
+ else
+ dir = cupsDirOpen("/");
+
+ if (!dir)
+ dentry = NULL;
+ else
+ {
+ while ((dentry = cupsDirRead(dir)) != NULL)
+ {
+ if (!strcmp(dentry->filename, ptr))
+ break;
+ }
+
+ cupsDirClose(dir);
+ }
+
+ /*
+ * Display an error if the filename doesn't exist with the same
+ * capitalization...
+ */
+
+ if (!dentry)
+ {
+ if (!warn && !errors && !verbose)
+ _cupsLangPuts(stdout, _(" FAIL\n"));
+
+ if (verbose >= 0)
+ _cupsLangPrintf(stdout,
+ _(" %s %s file \"%s\" has the wrong "
+ "capitalization!\n"), prefix, keyword, path);
+
+ if (!warn)
+ errors ++;
+
+ break;
+ }
+ }
+
+ return (errors);
+}
+
+
+/*
* 'valid_utf8()' - Check whether a string contains valid UTF-8 text.
*/