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;

 CUPS 1.4 cups_device_cb_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);

cups_job_t

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.

    +

    cupsBackendReport

    +

    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.

     CUPS 1.3 cupsSideChannelDoRequest

    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
    -

    httpConnect

    +

     DEPRECATED httpConnect

    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. + +

    httpConnectEncrypt

    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.

    httpTrace

    Send an TRACE request to the server.

    @@ -3040,6 +3049,40 @@ void ippSetPort (

    p
    Port number to use
    +

     CUPS 1.4 ippTagString

    +

    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. + +

    +

     CUPS 1.4 ippTagValue

    +

    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. + +

    ippTimeToDate

    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.

    ppdClose

    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