From 06d4e77b9b98bf529378c3670de8916982d938f1 Mon Sep 17 00:00:00 2001
From: msweet
Date: Tue, 26 Aug 2008 03:49:44 +0000
Subject: [PATCH] Merge changes from CUPS 1.4svn-r7864.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@921 a1ca3aef-8c08-0410-bb20-df032aa958be
---
CHANGES-1.3.txt | 6 +
Makefile | 2 +-
backend/snmp-supplies.c | 5 +-
cups/Makefile | 12 ++
cups/conflicts.c | 442 ++++++++++++++++++++++++--------------
cups/dest.c | 68 +++---
cups/emit.c | 2 +-
cups/testppd.c | 46 +++-
doc/help/api-cups.html | 2 +-
doc/help/api-filter.html | 31 +++
doc/help/api-httpipp.html | 47 +++-
doc/help/api-ppd.html | 37 ++--
filter/interpret.c | 4 +-
scheduler/cupsfilter.c | 2 +-
scheduler/main.c | 6 +-
scheduler/network.c | 29 +--
16 files changed, 502 insertions(+), 239 deletions(-)
diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt
index c12c81ba0..ced5b20d7 100644
--- a/CHANGES-1.3.txt
+++ b/CHANGES-1.3.txt
@@ -3,6 +3,12 @@ CHANGES-1.3.txt
CHANGES IN CUPS V1.3.9
+ - PJL panel messages were not reset correctly on older
+ printers (STR #2909)
+ - cupsfilter used the wrong default path (STR #2908)
+ - Fixed address matching for "BrowseAddress @IF(name)"
+ (STR #2910)
+ - Fixed compiles on AIX.
- Firefox 3 did not work with the CUPS web interface in SSL
mode (STR #2892)
- Custom options with multiple parameters were not emitted
diff --git a/Makefile b/Makefile
index 017378db3..9354f05ca 100644
--- a/Makefile
+++ b/Makefile
@@ -116,7 +116,7 @@ clang:
fi
$(MAKE) $(MFLAGS) CC="scan-build -o ../clang $(CC)" \
CXX="scan-build -o ../clang $(CXX)" clean all
- test `ls -1 clang | wc -l` != 0 || exit 1
+ test `ls -1 clang | wc -l` = 0
#
diff --git a/backend/snmp-supplies.c b/backend/snmp-supplies.c
index 366750928..1267d2502 100644
--- a/backend/snmp-supplies.c
+++ b/backend/snmp-supplies.c
@@ -169,7 +169,10 @@ backendSNMPSupplies(
if (i)
*ptr++ = ',';
- sprintf(ptr, "%d", 100 * supplies[i].level / supplies[i].max_capacity);
+ if (supplies[i].max_capacity > 0)
+ sprintf(ptr, "%d", 100 * supplies[i].level / supplies[i].max_capacity);
+ else
+ strcpy(ptr, "-1");
}
fprintf(stderr, "ATTR: marker-levels=%s\n", value);
diff --git a/cups/Makefile b/cups/Makefile
index 735c89dd9..584276a16 100644
--- a/cups/Makefile
+++ b/cups/Makefile
@@ -73,6 +73,7 @@ OBJS = \
$(LIB64OBJS) \
testadmin.o \
testarray.o \
+ testconflicts.o \
testcups.o \
testfile.o \
testhttp.o \
@@ -127,6 +128,7 @@ LIBTARGETS = \
TARGETS = \
$(LIBTARGETS) \
testadmin \
+ testconflicts \
testcups \
testsnmp
@@ -401,6 +403,16 @@ testarray: testarray.o libcups.a
./testarray
+#
+# testconflicts (dependency on static CUPS library is intentional)
+#
+
+testconflicts: testconflicts.o libcups.a
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ testconflicts.o libcups.a \
+ $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+
+
#
# testcups (dependency on static CUPS library is intentional)
#
diff --git a/cups/conflicts.c b/cups/conflicts.c
index f497f046f..aab26d1e7 100644
--- a/cups/conflicts.c
+++ b/cups/conflicts.c
@@ -18,11 +18,11 @@
*
* Contents:
*
+ * cupsResolveConflicts() - Resolve conflicts in a marked PPD.
* ppdConflicts() - Check to see if there are any conflicts among
* the marked option choices.
* ppdInstallableConflict() - Test whether an option choice conflicts with an
* installable option.
- * cupsResolveConflicts() - Resolve conflicts in a marked PPD.
* ppd_is_installable() - Determine whether an option is in the
* InstallableOptions group.
* ppd_load_constraints() - Load constraints from a PPD file.
@@ -57,139 +57,47 @@ enum
static int ppd_is_installable(ppd_group_t *installable,
const char *option);
static void ppd_load_constraints(ppd_file_t *ppd);
-static cups_array_t *ppd_test_constraints(ppd_file_t *ppd, int num_options,
+static cups_array_t *ppd_test_constraints(ppd_file_t *ppd,
+ const char *option,
+ const char *choice,
+ int num_options,
cups_option_t *options,
int which);
-/*
- * 'ppdConflicts()' - Check to see if there are any conflicts among the
- * marked option choices.
- *
- * The returned value is the same as returned by @link ppdMarkOption@.
- */
-
-int /* O - Number of conflicts found */
-ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */
-{
- int i, /* Looping variable */
- conflicts; /* Number of conflicts */
- cups_array_t *active; /* Active conflicts */
- _ppd_cups_uiconsts_t *c; /* Current constraints */
- _ppd_cups_uiconst_t *cptr; /* Current constraint */
- ppd_option_t *o; /* Current option */
-
-
- if (!ppd)
- return (0);
-
- /*
- * Clear all conflicts...
- */
-
- for (o = ppdFirstOption(ppd); o; o = ppdNextOption(ppd))
- o->conflicted = 0;
-
- /*
- * Test for conflicts...
- */
-
- active = ppd_test_constraints(ppd, 0, NULL, _PPD_ALL_CONSTRAINTS);
- conflicts = cupsArrayCount(active);
-
- /*
- * Loop through all of the UI constraints and flag any options
- * that conflict...
- */
-
- for (c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active);
- c;
- c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active))
- {
- for (i = c->num_constraints, cptr = c->constraints;
- i > 0;
- i --, cptr ++)
- cptr->option->conflicted = 1;
- }
-
- cupsArrayDelete(active);
-
- /*
- * Return the number of conflicts found...
- */
-
- return (conflicts);
-}
-
-
-/*
- * 'ppdInstallableConflict()' - Test whether an option choice conflicts with
- * an installable option.
- *
- * This function tests whether a particular option choice is available based
- * on constraints against options in the "InstallableOptions" group.
- *
- * @since CUPS 1.4@
- */
-
-int /* O - 1 if conflicting, 0 if not conflicting */
-ppdInstallableConflict(
- ppd_file_t *ppd, /* I - PPD file */
- const char *option, /* I - Option */
- const char *choice) /* I - Choice */
-{
- cups_array_t *active; /* Active conflicts */
- cups_option_t test; /* Test against this option */
-
-
- /*
- * Range check input...
- */
-
- if (!ppd || !option || !choice)
- return (0);
-
- /*
- * Test constraints using the new option...
- */
-
- test.name = (char *)option;
- test.value = (char *)choice;
- active = ppd_test_constraints(ppd, 1, &test,
- _PPD_INSTALLABLE_CONSTRAINTS);
-
- cupsArrayDelete(active);
-
- return (active != NULL);
-}
-
-
/*
* 'cupsResolveConflicts()' - Resolve conflicts in a marked PPD.
*
* This function attempts to resolve any conflicts in a marked PPD, returning
- * a list of option changes that are required to resolve any conflicts. On
- * input, "num_options" and "options" contain any pending option changes that
- * have not yet been marked, while "option" and "choice" contain the most recent
+ * a list of option changes that are required to resolve them. On input,
+ * "num_options" and "options" contain any pending option changes that have
+ * not yet been marked, while "option" and "choice" contain the most recent
* selection which may or may not be in "num_options" or "options".
*
* On successful return, "num_options" and "options" are updated to contain
* "option" and "choice" along with any changes required to resolve conflicts
- * specified in the PPD file. If option conflicts cannot be resolved,
- * "num_options" and "options" are not changed.
+ * specified in the PPD file and 1 is returned.
+ *
+ * If option conflicts cannot be resolved, "num_options" and "options" are not
+ * changed and 0 is returned.
*
- * @code ppdResolveConflicts@ uses one of two sources of option constraint
- * information. The preferred constraint information is defined by
+ * When resolving conflicts, @code cupsResolveConflicts@ does not consider
+ * changes to the current page size (@code media@, @code PageSize@, and
+ * @code PageRegion@) or to the most recent option specified in "option".
+ * Thus, if the only way to resolve a conflict is to change the page size
+ * or the option the user most recently changed, @code cupsResolveConflicts@
+ * will return 0 to indicate it was unable to resolve the conflicts.
+ *
+ * The @code cupsResolveConflicts@ function uses one of two sources of option
+ * constraint information. The preferred constraint information is defined by
* @code cupsUIConstraints@ and @code cupsUIResolver@ attributes - in this
- * case, the PPD file provides constraint resolution actions. In this case,
- * it should not be possible for @ppdResolveConflicts@ to fail, however it
- * will do so if a resolver loop is detected.
+ * case, the PPD file provides constraint resolution actions.
*
- * The backup constraint infomration is defined by the
+ * The backup constraint information is defined by the
* @code UIConstraints@ and @code NonUIConstraints@ attributes. These
- * constraints are resolved algorithmically by selecting the default choice
- * for the conflicting option. Unfortunately, this method is far more likely
- * to fail.
+ * constraints are resolved algorithmically by first selecting the default
+ * choice for the conflicting option, then iterating over all possible choices
+ * until a non-conflicting option choice is found.
*
* @since CUPS 1.4@
*/
@@ -203,8 +111,10 @@ cupsResolveConflicts(
cups_option_t **options) /* IO - Additional selected options */
{
int i, /* Looping var */
- num_newopts; /* Number of new options */
- cups_option_t *newopts; /* New options */
+ num_newopts, /* Number of new options */
+ num_resopts; /* Number of resolver options */
+ cups_option_t *newopts, /* New options */
+ *resopts; /* Resolver options */
cups_array_t *active, /* Active constraints */
*pass, /* Resolvers for this pass */
*resolvers; /* Resolvers we have used */
@@ -214,7 +124,6 @@ cupsResolveConflicts(
const char *value; /* Selected option value */
int changed; /* Did we change anything? */
ppd_choice_t *marked; /* Marked choice */
- ppd_option_t *ignored; /* Ignored option */
/*
@@ -246,7 +155,7 @@ cupsResolveConflicts(
resolvers = NULL;
pass = cupsArrayNew((cups_array_func_t)strcasecmp, NULL);
- while ((active = ppd_test_constraints(ppd, num_newopts, newopts,
+ while ((active = ppd_test_constraints(ppd, NULL, NULL, num_newopts, newopts,
_PPD_ALL_CONSTRAINTS)) != NULL)
{
if (!resolvers)
@@ -298,18 +207,39 @@ cupsResolveConflicts(
cupsArrayAdd(pass, consts->resolver);
cupsArrayAdd(resolvers, consts->resolver);
+ if (option && choice)
+ {
+ resopts = NULL;
+ num_resopts = _ppdParseOptions(resolver->value, 0, &resopts);
+
+ if ((value = cupsGetOption(option, num_newopts, newopts)) != NULL &&
+ !strcasecmp(value, choice))
+ {
+ DEBUG_printf(("cupsResolveConflicts: Resolver %s changes %s!\n",
+ consts->resolver, option));
+ cupsFreeOptions(num_resopts, resopts);
+ goto error;
+ }
+
+ cupsFreeOptions(num_resopts, resopts);
+ }
+
num_newopts = _ppdParseOptions(resolver->value, num_newopts, &newopts);
- changed = 1;
+ changed = 1;
}
else
{
/*
* Try resolving by choosing the default values for non-installable
- * options...
+ * options, then by iterating through the possible choices...
*/
- for (i = consts->num_constraints, constptr = consts->constraints,
- ignored = NULL;
+ int j; /* Looping var */
+ ppd_choice_t *cptr; /* Current choice */
+ cups_array_t *test; /* Test array for conflicts */
+
+
+ for (i = consts->num_constraints, constptr = consts->constraints;
i > 0;
i --, constptr ++)
{
@@ -319,10 +249,7 @@ cupsResolveConflicts(
continue;
if (option && !strcasecmp(constptr->option->keyword, option))
- {
- ignored = constptr->option;
continue;
- }
if ((value = cupsGetOption(constptr->option->keyword, num_newopts,
newopts)) == NULL)
@@ -331,35 +258,64 @@ cupsResolveConflicts(
value = marked ? marked->choice : "";
}
- if (strcasecmp(value, constptr->option->defchoice))
- {
- num_newopts = cupsAddOption(constptr->option->keyword,
- constptr->option->defchoice,
- num_newopts, &newopts);
- changed = 1;
- }
- }
-
- if (ignored && !changed)
- {
- /*
- * No choice, have to back out this selection...
+ /*
+ * Try the default choice...
*/
- if ((value = cupsGetOption(ignored->keyword, num_newopts,
- newopts)) == NULL)
- {
- marked = ppdFindMarkedChoice(ppd, ignored->keyword);
- value = marked ? marked->choice : "";
- }
+ test = NULL;
- if (strcasecmp(value, ignored->defchoice))
+ if (strcasecmp(value, constptr->option->defchoice) &&
+ (test = ppd_test_constraints(ppd, constptr->option->keyword,
+ constptr->option->defchoice,
+ num_newopts, newopts,
+ _PPD_ALL_CONSTRAINTS)) == NULL)
{
- num_newopts = cupsAddOption(ignored->keyword, ignored->defchoice,
+ /*
+ * That worked...
+ */
+
+ num_newopts = cupsAddOption(constptr->option->keyword,
+ constptr->option->defchoice,
num_newopts, &newopts);
changed = 1;
}
- }
+ else
+ {
+ /*
+ * Try each choice instead...
+ */
+
+ cupsArrayDelete(test);
+
+ for (j = constptr->option->num_choices,
+ cptr = constptr->option->choices;
+ j > 0;
+ j --, cptr ++)
+ {
+ test = NULL;
+
+ if (strcasecmp(value, cptr->choice) &&
+ strcasecmp(constptr->option->defchoice, cptr->choice) &&
+ (test = ppd_test_constraints(ppd, constptr->option->keyword,
+ cptr->choice, num_newopts,
+ newopts,
+ _PPD_ALL_CONSTRAINTS)) == NULL)
+ {
+ /*
+ * This choice works...
+ */
+
+ num_newopts = cupsAddOption(constptr->option->keyword,
+ cptr->choice, num_newopts,
+ &newopts);
+ changed = 1;
+ break;
+ }
+
+ cupsArrayDelete(test);
+ }
+ }
+ }
}
if (!changed)
@@ -422,6 +378,106 @@ cupsResolveConflicts(
}
+/*
+ * 'ppdConflicts()' - Check to see if there are any conflicts among the
+ * marked option choices.
+ *
+ * The returned value is the same as returned by @link ppdMarkOption@.
+ */
+
+int /* O - Number of conflicts found */
+ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */
+{
+ int i, /* Looping variable */
+ conflicts; /* Number of conflicts */
+ cups_array_t *active; /* Active conflicts */
+ _ppd_cups_uiconsts_t *c; /* Current constraints */
+ _ppd_cups_uiconst_t *cptr; /* Current constraint */
+ ppd_option_t *o; /* Current option */
+
+
+ if (!ppd)
+ return (0);
+
+ /*
+ * Clear all conflicts...
+ */
+
+ for (o = ppdFirstOption(ppd); o; o = ppdNextOption(ppd))
+ o->conflicted = 0;
+
+ /*
+ * Test for conflicts...
+ */
+
+ active = ppd_test_constraints(ppd, NULL, NULL, 0, NULL,
+ _PPD_ALL_CONSTRAINTS);
+ conflicts = cupsArrayCount(active);
+
+ /*
+ * Loop through all of the UI constraints and flag any options
+ * that conflict...
+ */
+
+ for (c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active);
+ c;
+ c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active))
+ {
+ for (i = c->num_constraints, cptr = c->constraints;
+ i > 0;
+ i --, cptr ++)
+ cptr->option->conflicted = 1;
+ }
+
+ cupsArrayDelete(active);
+
+ /*
+ * Return the number of conflicts found...
+ */
+
+ return (conflicts);
+}
+
+
+/*
+ * 'ppdInstallableConflict()' - Test whether an option choice conflicts with
+ * an installable option.
+ *
+ * This function tests whether a particular option choice is available based
+ * on constraints against options in the "InstallableOptions" group.
+ *
+ * @since CUPS 1.4@
+ */
+
+int /* O - 1 if conflicting, 0 if not conflicting */
+ppdInstallableConflict(
+ ppd_file_t *ppd, /* I - PPD file */
+ const char *option, /* I - Option */
+ const char *choice) /* I - Choice */
+{
+ cups_array_t *active; /* Active conflicts */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!ppd || !option || !choice)
+ return (0);
+
+ /*
+ * Test constraints using the new option...
+ */
+
+ active = ppd_test_constraints(ppd, option, choice, 0, NULL,
+ _PPD_INSTALLABLE_CONSTRAINTS);
+
+ cupsArrayDelete(active);
+
+ return (active != NULL);
+}
+
+
/*
* 'ppd_is_installable()' - Determine whether an option is in the
* InstallableOptions group.
@@ -700,7 +756,6 @@ ppd_load_constraints(ppd_file_t *ppd) /* I - PPD file */
}
-
/*
* 'ppd_test_constraints()' - See if any constraints are active.
*/
@@ -708,6 +763,8 @@ ppd_load_constraints(ppd_file_t *ppd) /* I - PPD file */
static cups_array_t * /* O - Array of active constraints */
ppd_test_constraints(
ppd_file_t *ppd, /* I - PPD file */
+ const char *option, /* I - Current option */
+ const char *choice, /* I - Current choice */
int num_options, /* I - Number of additional options */
cups_option_t *options, /* I - Additional options */
int which) /* I - Which constraints to test */
@@ -719,24 +776,48 @@ ppd_test_constraints(
*marked; /* Marked choice */
cups_array_t *active = NULL; /* Active constraints */
const char *value; /* Current value */
+ int option_conflict;/* Conflict with current option? */
+
+ DEBUG_printf(("ppd_test_constraints(ppd=%p, num_options=%d, options=%p, "
+ "which=%d)\n", ppd, num_options, options, which));
if (!ppd->cups_uiconstraints)
ppd_load_constraints(ppd);
+ DEBUG_printf(("ppd_test_constraints: %d constraints!\n",
+ cupsArrayCount(ppd->cups_uiconstraints)));
+
cupsArraySave(ppd->marked);
for (consts = (_ppd_cups_uiconsts_t *)cupsArrayFirst(ppd->cups_uiconstraints);
consts;
consts = (_ppd_cups_uiconsts_t *)cupsArrayNext(ppd->cups_uiconstraints))
{
+ DEBUG_printf(("ppd_test_constraints: installable=%d, resolver=\"%s\", "
+ "num_constraints=%d option1=\"%s\", choice1=\"%s\", "
+ "option2=\"%s\", choice2=\"%s\", ...\n",
+ consts->installable, consts->resolver, consts->num_constraints,
+ consts->constraints[0].option->keyword,
+ consts->constraints[0].choice ?
+ consts->constraints[0].choice->choice : "",
+ consts->constraints[1].option->keyword,
+ consts->constraints[1].choice ?
+ consts->constraints[1].choice->choice : ""));
+
if (which != _PPD_ALL_CONSTRAINTS && which != consts->installable)
continue;
- for (i = consts->num_constraints, constptr = consts->constraints;
+ DEBUG_puts("ppd_test_constraints: Testing...");
+
+ for (i = consts->num_constraints, constptr = consts->constraints,
+ option_conflict = 0;
i > 0;
i --, constptr ++)
{
+ DEBUG_printf(("ppd_test_constraints: %s=%s?\n", constptr->option->keyword,
+ constptr->choice ? constptr->choice->choice : ""));
+
if (constptr->choice &&
(!strcasecmp(constptr->option->keyword, "PageSize") ||
!strcasecmp(constptr->option->keyword, "PageRegion")))
@@ -747,7 +828,17 @@ ppd_test_constraints(
* of an individual option...
*/
- if ((value = cupsGetOption("PageSize", num_options, options)) == NULL)
+ if (option && choice &&
+ (!strcasecmp(option, "PageSize") ||
+ !strcasecmp(option, "PageRegion")))
+ {
+ value = choice;
+
+ if (!strcasecmp(value, constptr->choice->choice))
+ option_conflict = 1;
+ }
+ else if ((value = cupsGetOption("PageSize", num_options,
+ options)) == NULL)
if ((value = cupsGetOption("PageRegion", num_options,
options)) == NULL)
if ((value = cupsGetOption("media", num_options, options)) == NULL)
@@ -759,25 +850,53 @@ ppd_test_constraints(
}
if (!value || strcasecmp(value, constptr->choice->choice))
+ {
+ DEBUG_puts("ppd_test_constraints: NO");
break;
+ }
}
else if (constptr->choice)
{
- if ((value = cupsGetOption(constptr->option->keyword, num_options,
- options)) != NULL)
+ if (option && choice && !strcasecmp(option, constptr->option->keyword))
+ {
+ if (strcasecmp(choice, constptr->choice->choice))
+ break;
+
+ option_conflict = 1;
+ }
+ else if ((value = cupsGetOption(constptr->option->keyword, num_options,
+ options)) != NULL)
{
if (strcasecmp(value, constptr->choice->choice))
+ {
+ DEBUG_puts("ppd_test_constraints: NO");
break;
+ }
}
else if (!constptr->choice->marked)
+ {
+ DEBUG_puts("ppd_test_constraints: NO");
+ break;
+ }
+ }
+ else if (option && choice &&
+ !strcasecmp(option, constptr->option->keyword))
+ {
+ if (!strcasecmp(choice, "None") || !strcasecmp(choice, "Off") ||
+ !strcasecmp(choice, "False"))
break;
+
+ option_conflict = 1;
}
else if ((value = cupsGetOption(constptr->option->keyword, num_options,
options)) != NULL)
{
if (!strcasecmp(value, "None") || !strcasecmp(value, "Off") ||
!strcasecmp(value, "False"))
- break;
+ {
+ DEBUG_puts("ppd_test_constraints: NO");
+ break;
+ }
}
else
{
@@ -788,21 +907,28 @@ ppd_test_constraints(
(!strcasecmp(marked->choice, "None") ||
!strcasecmp(marked->choice, "Off") ||
!strcasecmp(marked->choice, "False")))
+ {
+ DEBUG_puts("ppd_test_constraints: NO");
break;
+ }
}
}
- if (i <= 0)
+ if (i <= 0 && (!option || option_conflict))
{
if (!active)
active = cupsArrayNew(NULL, NULL);
cupsArrayAdd(active, consts);
+ DEBUG_puts("ppd_test_constraints: Added...");
}
}
cupsArrayRestore(ppd->marked);
+ DEBUG_printf(("ppd_test_constraints: Found %d active constraints!\n",
+ cupsArrayCount(active)));
+
return (active);
}
diff --git a/cups/dest.c b/cups/dest.c
index cc8f6a35a..7c0953576 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -31,9 +31,9 @@
* server.
* cupsSetDests2() - Save the list of destinations for the specified
* server.
+ * appleCopyLocations() - Get the location history array.
* appleCopyNetwork() - Get the network ID for the current location.
* appleGetDefault() - Get the default printer for this location.
- * appleGetLocations() - Get the location history array.
* appleGetPrinter() - Get a printer from the history array.
* appleSetDefault() - Set the default printer for this location.
* appleUseLastPrinter() - Get the default printer preference value.
@@ -73,9 +73,9 @@
*/
#ifdef __APPLE__
+static CFArrayRef appleCopyLocations(void);
static CFStringRef appleCopyNetwork(void);
static char *appleGetDefault(char *name, int namesize);
-static CFArrayRef appleGetLocations(void);
static CFStringRef appleGetPrinter(CFArrayRef locations, CFStringRef network,
CFIndex *locindex);
static void appleSetDefault(const char *name);
@@ -935,6 +935,34 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
#ifdef __APPLE__
+/*
+ * 'appleCopyLocations()' - Copy the location history array.
+ */
+
+static CFArrayRef /* O - Location array or NULL */
+appleCopyLocations(void)
+{
+ CFArrayRef locations; /* Location array */
+
+
+ /*
+ * Look up the location array in the preferences...
+ */
+
+ if ((locations = CFPreferencesCopyAppValue(kLocationHistoryArrayKey,
+ kPMPrintingPreferences)) == NULL)
+ return (NULL);
+
+ if (CFGetTypeID(locations) != CFArrayGetTypeID())
+ {
+ CFRelease(locations);
+ return (NULL);
+ }
+
+ return (locations);
+}
+
+
/*
* 'appleCopyNetwork()' - Get the network ID for the current location.
*/
@@ -1016,7 +1044,7 @@ appleGetDefault(char *name, /* I - Name buffer */
* Lookup the network in the preferences...
*/
- if ((locations = appleGetLocations()) == NULL)
+ if ((locations = appleCopyLocations()) == NULL)
{
/*
* Missing or bad location array, so no location-based default...
@@ -1038,6 +1066,7 @@ appleGetDefault(char *name, /* I - Name buffer */
name[0] = '\0';
CFRelease(network);
+ CFRelease(locations);
DEBUG_printf(("appleGetDefault: Returning \"%s\"...\n", name));
@@ -1045,34 +1074,6 @@ appleGetDefault(char *name, /* I - Name buffer */
}
-/*
- * 'appleGetLocations()' - Get the location history array.
- */
-
-static CFArrayRef /* O - Location array or NULL */
-appleGetLocations(void)
-{
- CFArrayRef locations; /* Location array */
-
-
- /*
- * Look up the location array in the preferences...
- */
-
- if ((locations = CFPreferencesCopyAppValue(kLocationHistoryArrayKey,
- kPMPrintingPreferences)) == NULL)
- return (NULL);
-
- if (CFGetTypeID(locations) != CFArrayGetTypeID())
- {
- CFRelease(locations);
- return (NULL);
- }
-
- return (locations);
-}
-
-
/*
* 'appleGetPrinter()' - Get a printer from the history array.
*/
@@ -1149,7 +1150,7 @@ appleSetDefault(const char *name) /* I - Default printer/class name */
* Lookup the network in the preferences...
*/
- if ((locations = appleGetLocations()) != NULL)
+ if ((locations = appleCopyLocations()) != NULL)
locprinter = appleGetPrinter(locations, network, &locindex);
else
{
@@ -1212,6 +1213,9 @@ appleSetDefault(const char *name) /* I - Default printer/class name */
CFRelease(newlocation);
}
+ if (locations)
+ CFRelease(locations);
+
CFRelease(network);
CFRelease(newprinter);
}
diff --git a/cups/emit.c b/cups/emit.c
index f36a48d98..c76355593 100644
--- a/cups/emit.c
+++ b/cups/emit.c
@@ -549,7 +549,7 @@ ppdEmitJCLEnd(ppd_file_t *ppd, /* I - PPD file record */
*/
fputs("\033%-12345X@PJL\n", fp);
- fputs("@PJL RDYMSG DISPLAY = \"READY\"\n", fp);
+ fputs("@PJL RDYMSG DISPLAY = \"\"\n", fp);
fputs(ppd->jcl_end + 9, fp);
}
else
diff --git a/cups/testppd.c b/cups/testppd.c
index c52309e39..5318c4d24 100644
--- a/cups/testppd.c
+++ b/cups/testppd.c
@@ -222,14 +222,26 @@ main(int argc, /* I - Number of command-line arguments */
status ++;
}
- fputs("cupsResolveConflicts(): ", stdout);
+ fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout);
num_options = 0;
options = NULL;
if (cupsResolveConflicts(ppd, "InputSlot", "Envelope", &num_options,
- &options) &&
- num_options == 1 && !strcasecmp(options->name, "InputSlot") &&
- !strcasecmp(options->value, "Tray"))
- puts("PASS");
+ &options))
+ {
+ puts("FAIL (Resolved but shouldn't be able to!)");
+ status ++;
+ }
+ else
+ puts("PASS (Unable to resolve)");
+ cupsFreeOptions(num_options, options);
+
+ fputs("cupsResolveConflicts(No option/choice): ", stdout);
+ num_options = 0;
+ options = NULL;
+ if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
+ num_options == 1 && !strcasecmp(options[0].name, "InputSlot") &&
+ !strcasecmp(options[0].value, "Manual"))
+ puts("PASS (Resolved)");
else if (num_options > 0)
{
printf("FAIL (%d options:", num_options);
@@ -240,7 +252,7 @@ main(int argc, /* I - Number of command-line arguments */
}
else
{
- puts("FAIL (Unable to resolve!)");
+ puts("FAIL (Unable to resolve)");
status ++;
}
cupsFreeOptions(num_options, options);
@@ -452,11 +464,26 @@ main(int argc, /* I - Number of command-line arguments */
status ++;
}
- fputs("cupsResolveConflicts(): ", stdout);
+ fputs("cupsResolveConflicts(Quality=Photo): ", stdout);
num_options = 0;
options = NULL;
if (cupsResolveConflicts(ppd, "Quality", "Photo", &num_options,
- &options) &&
+ &options))
+ {
+ printf("FAIL (%d options:", num_options);
+ for (i = 0; i < num_options; i ++)
+ printf(" %s=%s", options[i].name, options[i].value);
+ puts(")");
+ status ++;
+ }
+ else
+ puts("PASS (Unable to resolve)");
+ cupsFreeOptions(num_options, options);
+
+ fputs("cupsResolveConflicts(No option/choice): ", stdout);
+ num_options = 0;
+ options = NULL;
+ if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
num_options == 1 && !strcasecmp(options->name, "Quality") &&
!strcasecmp(options->value, "Normal"))
puts("PASS");
@@ -480,8 +507,7 @@ main(int argc, /* I - Number of command-line arguments */
ppdMarkOption(ppd, "Quality", "Photo");
num_options = 0;
options = NULL;
- if (!cupsResolveConflicts(ppd, "Quality", "Photo", &num_options,
- &options))
+ if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options))
puts("PASS");
else if (num_options > 0)
{
diff --git a/doc/help/api-cups.html b/doc/help/api-cups.html
index b6eb2ab81..ec943f041 100644
--- a/doc/help/api-cups.html
+++ b/doc/help/api-cups.html
@@ -1955,7 +1955,7 @@ typedef struct cups_dest_s cups_dest_t;
Device callback
-typedef void (*cups_device_cb_t)(const char *device_class, const char *device_id, const char *device_info, const char *device_make_and_model, const char *device_uri, void *user_data);
+typedef void (*cups_device_cb_t)(const char *device_class, const char *device_id, const char *device_info, const char *device_make_and_model, const char *device_uri, const char *device_location, void *user_data);
Job
diff --git a/doc/help/api-filter.html b/doc/help/api-filter.html
index affeeb4e3..582871ec6 100644
--- a/doc/help/api-filter.html
+++ b/doc/help/api-filter.html
@@ -310,6 +310,7 @@ div.contents ul.subcontents li {
cupsBackChannelRead
cupsBackChannelWrite
cupsBackendDeviceURI
+cupsBackendReport
cupsSideChannelDoRequest
cupsSideChannelRead
cupsSideChannelSNMPGet
@@ -956,6 +957,36 @@ const char *cupsBackendDeviceURI (
function returns the device URI passed in the DEVICE_URI environment
variable or the device URI passed in argv[0], whichever is found
first.
+
+Write a device line from a backend.
+
+void cupsBackendReport (
+ const char *device_scheme,
+ const char *device_uri,
+ const char *device_make_and_model,
+ const char *device_info,
+ const char *device_id,
+ const char *device_location
+);
+Parameters
+
+- device_scheme
+- device-scheme string
+- device_uri
+- device-uri string
+- device_make_and_model
+- device-make-and-model string or
NULL
+- device_info
+- device-info string or
NULL
+- device_id
+- device-id string or
NULL
+- device_location
+- device-location string or
NULL
+
+Discussion
+This function writes a single device line to stdout for a backend.
+It handles quoting of special characters in the device-make-and-model,
+device-info, device-id, and device-location strings.
Send a side-channel command to a backend and wait for a response.
diff --git a/doc/help/api-httpipp.html b/doc/help/api-httpipp.html
index ab5fcc7e3..74aaaf9dd 100644
--- a/doc/help/api-httpipp.html
+++ b/doc/help/api-httpipp.html
@@ -423,6 +423,8 @@ in seconds.">ippDateToTime
ippReadFile
ippReadIO
ippSetPort
+ippTagString
+ippTagValue
ippTimeToDate
ippWrite
ippWriteFile
@@ -1447,7 +1449,7 @@ void httpClose (
http
Connection to server
-
+
Connect to a HTTP server.
http_t *httpConnect (
@@ -1463,6 +1465,10 @@ void httpClose (
Return Value
New HTTP connection
+Discussion
+This function is deprecated - use httpConnectEncrypt
instead.
+
+
Connect to a HTTP server using encryption.
@@ -2332,7 +2338,10 @@ const char *httpStatus (
HTTP status code
Return Value
-String or NULL
+Localized status string
+Discussion
+The returned string is localized to the current POSIX locale and is based
+on the status strings defined in RFC 2616.
Send an TRACE request to the server.
@@ -3040,6 +3049,40 @@ void ippSetPort (
p
Port number to use
+
+Return the tag name corresponding to a tag value.
+
+const char *ippTagString (
+ ipp_tag_t tag
+);
+Parameters
+
+- tag
+- Tag value
+
+Return Value
+Tag name
+Discussion
+The returned names are defined in RFC 2911 and 3382.
+
+
+
+Return the tag value corresponding to a tag name.
+
+ipp_tag_t ippTagValue (
+ const char *name
+);
+Parameters
+
+- name
+- Tag name
+
+Return Value
+Tag value
+Discussion
+The tag names are defined in RFC 2911 and 3382.
+
+
Convert from UNIX time to RFC 1903 format.
diff --git a/doc/help/api-ppd.html b/doc/help/api-ppd.html
index 2bb61a07d..20e51fc4e 100644
--- a/doc/help/api-ppd.html
+++ b/doc/help/api-ppd.html
@@ -664,28 +664,35 @@ int cupsResolveConflicts (
1 on success, 0 on failure
Discussion
This function attempts to resolve any conflicts in a marked PPD, returning
-a list of option changes that are required to resolve any conflicts. On
-input, "num_options" and "options" contain any pending option changes that
-have not yet been marked, while "option" and "choice" contain the most recent
+a list of option changes that are required to resolve them. On input,
+"num_options" and "options" contain any pending option changes that have
+not yet been marked, while "option" and "choice" contain the most recent
selection which may or may not be in "num_options" or "options".
On successful return, "num_options" and "options" are updated to contain
"option" and "choice" along with any changes required to resolve conflicts
-specified in the PPD file. If option conflicts cannot be resolved,
-"num_options" and "options" are not changed.
-
-ppdResolveConflicts
uses one of two sources of option constraint
-information. The preferred constraint information is defined by
+specified in the PPD file and 1 is returned.
+
+If option conflicts cannot be resolved, "num_options" and "options" are not
+changed and 0 is returned.
+
+When resolving conflicts, cupsResolveConflicts
does not consider
+changes to the current page size (media
, PageSize
, and
+PageRegion
) or to the most recent option specified in "option".
+Thus, if the only way to resolve a conflict is to change the page size
+or the option the user most recently changed, cupsResolveConflicts
+will return 0 to indicate it was unable to resolve the conflicts.
+
+The cupsResolveConflicts
function uses one of two sources of option
+constraint information. The preferred constraint information is defined by
cupsUIConstraints
and cupsUIResolver
attributes - in this
-case, the PPD file provides constraint resolution actions. In this case,
-it should not be possible for @ppdResolveConflicts@ to fail, however it
-will do so if a resolver loop is detected.
+case, the PPD file provides constraint resolution actions.
-The backup constraint infomration is defined by the
+The backup constraint information is defined by the
UIConstraints
and NonUIConstraints
attributes. These
-constraints are resolved algorithmically by selecting the default choice
-for the conflicting option. Unfortunately, this method is far more likely
-to fail.
+constraints are resolved algorithmically by first selecting the default
+choice for the conflicting option, then iterating over all possible choices
+until a non-conflicting option choice is found.
diff --git a/filter/interpret.c b/filter/interpret.c
index 72579b22c..1aaade812 100644
--- a/filter/interpret.c
+++ b/filter/interpret.c
@@ -258,7 +258,7 @@ cupsRasterInterpretPPD(
{
float sc = atof(val);
- if (sc >= 0.5 && sc <= 2.0)
+ if (sc >= 0.1 && sc <= 2.0)
h->cupsBorderlessScalingFactor = sc;
}
@@ -328,7 +328,7 @@ cupsRasterInterpretPPD(
(h->cupsBitsPerColor != 1 && h->cupsBitsPerColor != 2 &&
h->cupsBitsPerColor != 4 && h->cupsBitsPerColor != 8 &&
h->cupsBitsPerColor != 16) ||
- h->cupsBorderlessScalingFactor < 0.5 ||
+ h->cupsBorderlessScalingFactor < 0.1 ||
h->cupsBorderlessScalingFactor > 2.0)
{
_cupsRasterAddError("Page header uses unsupported values.\n");
diff --git a/scheduler/cupsfilter.c b/scheduler/cupsfilter.c
index f60c284fa..d387ecf7c 100644
--- a/scheduler/cupsfilter.c
+++ b/scheduler/cupsfilter.c
@@ -1053,7 +1053,7 @@ read_cupsd_conf(const char *filename) /* I - File to read */
}
snprintf(line, sizeof(line),
- "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR ":/bin/usr/bin",
+ "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR ":/bin:/usr/bin",
ServerBin);
set_string(&Path, line);
diff --git a/scheduler/main.c b/scheduler/main.c
index 571b3a7fc..417d98ef5 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -1390,9 +1390,9 @@ cupsdSetStringf(char **s, /* O - New string */
static void
launchd_checkin(void)
{
- int i, /* Looping var */
- count, /* Numebr of listeners */
- portnum; /* Port number */
+ size_t i, /* Looping var */
+ count; /* Numebr of listeners */
+ int portnum; /* Port number */
launch_data_t ld_msg, /* Launch data message */
ld_resp, /* Launch data response */
ld_array, /* Launch data array */
diff --git a/scheduler/network.c b/scheduler/network.c
index a68297d33..f93330b55 100644
--- a/scheduler/network.c
+++ b/scheduler/network.c
@@ -245,24 +245,29 @@ cupsdNetIFUpdate(void)
else if (addr->ifa_addr->sa_family == AF_INET &&
lis->address.addr.sa_family == AF_INET &&
(lis->address.ipv4.sin_addr.s_addr &
- temp->mask.ipv4.sin_addr.s_addr) ==
- temp->address.ipv4.sin_addr.s_addr)
+ temp->mask.ipv4.sin_addr.s_addr) ==
+ (temp->address.ipv4.sin_addr.s_addr &
+ temp->mask.ipv4.sin_addr.s_addr))
match = 1;
#ifdef AF_INET6
else if (addr->ifa_addr->sa_family == AF_INET6 &&
lis->address.addr.sa_family == AF_INET6 &&
(lis->address.ipv6.sin6_addr.s6_addr[0] &
- temp->mask.ipv6.sin6_addr.s6_addr[0]) ==
- temp->address.ipv6.sin6_addr.s6_addr[0] &&
+ temp->mask.ipv6.sin6_addr.s6_addr[0]) ==
+ (temp->address.ipv6.sin6_addr.s6_addr[0] &
+ temp->mask.ipv6.sin6_addr.s6_addr[0]) &&
(lis->address.ipv6.sin6_addr.s6_addr[1] &
- temp->mask.ipv6.sin6_addr.s6_addr[1]) ==
- temp->address.ipv6.sin6_addr.s6_addr[1] &&
+ temp->mask.ipv6.sin6_addr.s6_addr[1]) ==
+ (temp->address.ipv6.sin6_addr.s6_addr[1] &
+ temp->mask.ipv6.sin6_addr.s6_addr[1]) &&
(lis->address.ipv6.sin6_addr.s6_addr[2] &
- temp->mask.ipv6.sin6_addr.s6_addr[2]) ==
- temp->address.ipv6.sin6_addr.s6_addr[2] &&
+ temp->mask.ipv6.sin6_addr.s6_addr[2]) ==
+ (temp->address.ipv6.sin6_addr.s6_addr[2] &
+ temp->mask.ipv6.sin6_addr.s6_addr[2]) &&
(lis->address.ipv6.sin6_addr.s6_addr[3] &
- temp->mask.ipv6.sin6_addr.s6_addr[3]) ==
- temp->address.ipv6.sin6_addr.s6_addr[3])
+ temp->mask.ipv6.sin6_addr.s6_addr[3]) ==
+ (temp->address.ipv6.sin6_addr.s6_addr[3] &
+ temp->mask.ipv6.sin6_addr.s6_addr[3]))
match = 1;
#endif /* AF_INET6 */
@@ -284,8 +289,8 @@ cupsdNetIFUpdate(void)
cupsArrayAdd(NetIFList, temp);
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdNetIFUpdate: \"%s\" = %s...",
- temp->name, temp->hostname);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdNetIFUpdate: \"%s\" = %s:%d",
+ temp->name, temp->hostname, temp->port);
}
freeifaddrs(addrs);
--
2.39.2