diff --git a/cups-getnameddest.patch b/cups-getnameddest.patch new file mode 100644 index 0000000..237b636 --- /dev/null +++ b/cups-getnameddest.patch @@ -0,0 +1,1008 @@ +diff -up cups-1.3.7/cups/dest.c.getnameddest cups-1.3.7/cups/dest.c +--- cups-1.3.7/cups/dest.c.getnameddest 2007-07-11 22:46:42.000000000 +0100 ++++ cups-1.3.7/cups/dest.c 2008-06-17 11:00:50.000000000 +0100 +@@ -25,6 +25,7 @@ + * server. + * cupsGetDests2() - Get the list of destinations from the + * specified server. ++ * cupsGetNamedDest() - Get options for the named destination. + * cupsRemoveDest() - Remove a destination from the destination list. + * cupsDestSetDefaultDest() - Set the default destination. + * cupsSetDests() - Set the list of destinations for the default +@@ -39,6 +40,7 @@ + * Include necessary headers... + */ + ++#include "debug.h" + #include "globals.h" + #include + #include +@@ -53,10 +55,13 @@ + * Local functions... + */ + +-static int cups_get_dests(const char *filename, int num_dests, ++static const char *cups_get_default(const char *filename, char *namebuf, ++ size_t namesize, const char **instance); ++static int cups_get_dests(const char *filename, const char *match_name, ++ const char *match_inst, int num_dests, + cups_dest_t **dests); +-static int cups_get_sdests(http_t *http, ipp_op_t op, int num_dests, +- cups_dest_t **dests); ++static int cups_get_sdests(http_t *http, ipp_op_t op, const char *name, ++ int num_dests, cups_dest_t **dests); + + + /* +@@ -263,19 +268,17 @@ int /* O - Number of destinations */ + cupsGetDests(cups_dest_t **dests) /* O - Destinations */ + { + int num_dests; /* Number of destinations */ +- http_t *http; /* HTTP connection */ ++ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * Connect to the CUPS server and get the destination list and options... + */ + +- http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); ++ if (!cg->http) ++ cg->http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + +- num_dests = cupsGetDests2(http, dests); +- +- if (http) +- httpClose(http); ++ num_dests = cupsGetDests2(cg->http, dests); + + return (num_dests); + } +@@ -330,8 +333,8 @@ cupsGetDests2(http_t *http, /* I - + * Grab the printers and classes... + */ + +- num_dests = cups_get_sdests(http, CUPS_GET_PRINTERS, num_dests, dests); +- num_dests = cups_get_sdests(http, CUPS_GET_CLASSES, num_dests, dests); ++ num_dests = cups_get_sdests(http, CUPS_GET_PRINTERS, NULL, num_dests, dests); ++ num_dests = cups_get_sdests(http, CUPS_GET_CLASSES, NULL, num_dests, dests); + + /* + * Make a copy of the "real" queues for a later sanity check... +@@ -390,7 +393,7 @@ cupsGetDests2(http_t *http, /* I - + */ + + snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); +- num_dests = cups_get_dests(filename, num_dests, dests); ++ num_dests = cups_get_dests(filename, NULL, NULL, num_dests, dests); + + if ((home = getenv("HOME")) != NULL) + { +@@ -398,7 +401,7 @@ cupsGetDests2(http_t *http, /* I - + if (access(filename, 0)) + snprintf(filename, sizeof(filename), "%s/.lpoptions", home); + +- num_dests = cups_get_dests(filename, num_dests, dests); ++ num_dests = cups_get_dests(filename, NULL, NULL, num_dests, dests); + } + + /* +@@ -452,6 +455,136 @@ cupsGetDests2(http_t *http, /* I - + + + /* ++ * 'cupsGetNamedDest()' - Get options for the named destination. ++ * ++ * This function is optimized for retrieving a single destination and should ++ * be used instead of cupsGetDests() and cupsGetDest() when you either know ++ * the name of the destination or want to print to the default destination. ++ * If NULL is returned, the destination does not exist or there is no default ++ * destination. ++ * ++ * If "http" is NULL, the connection to the default print server will be used. ++ * ++ * If "name" is NULL, the default printer for the current user will be returned. ++ * ++ * The returned destination must be freed using cupsFreeDests() with a ++ * "num_dests" of 1. ++ * ++ * @since CUPS 1.4@ ++ */ ++ ++cups_dest_t * /* O - Destination or NULL */ ++cupsGetNamedDest(http_t *http, /* I - HTTP connection or NULL */ ++ const char *name, /* I - Destination name or NULL */ ++ const char *instance) /* I - Instance name or NULL */ ++{ ++ cups_dest_t *dest; /* Destination */ ++ char filename[1024], /* Path to lpoptions */ ++ defname[256]; /* Default printer name */ ++ const char *home = getenv("HOME"); /* Home directory */ ++ ipp_op_t op = IPP_GET_PRINTER_ATTRIBUTES; ++ /* IPP operation to get server ops */ ++ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ ++ ++ ++ /* ++ * Connect to the server as needed... ++ */ ++ ++ if (!http) ++ { ++ if (!cg->http && ++ (cg->http = httpConnectEncrypt(cupsServer(), ippPort(), ++ cupsEncryption())) == NULL) ++ return (NULL); ++ ++ http = cg->http; ++ } ++ ++ /* ++ * If "name" is NULL, find the default destination... ++ */ ++ ++ if (!name) ++ { ++ if ((name = getenv("LPDEST")) == NULL) ++ if ((name = getenv("PRINTER")) != NULL && !strcmp(name, "lp")) ++ name = NULL; ++ ++ if (!name && home) ++ { ++ /* ++ * No default in the environment, try the user's lpoptions files... ++ */ ++ ++ snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); ++ ++ if ((name = cups_get_default(filename, defname, sizeof(defname), ++ &instance)) == NULL) ++ { ++ snprintf(filename, sizeof(filename), "%s/.lpoptions", home); ++ name = cups_get_default(filename, defname, sizeof(defname), ++ &instance); ++ } ++ } ++ ++ if (!name) ++ { ++ /* ++ * Still not there? Try the system lpoptions file... ++ */ ++ ++ snprintf(filename, sizeof(filename), "%s/lpoptions", ++ cg->cups_serverroot); ++ name = cups_get_default(filename, defname, sizeof(defname), &instance); ++ } ++ ++ if (!name) ++ { ++ /* ++ * No locally-set default destination, ask the server... ++ */ ++ ++ op = CUPS_GET_DEFAULT; ++ } ++ } ++ ++ /* ++ * Get the printer's attributes... ++ */ ++ ++ if (!cups_get_sdests(http, op, name, 0, &dest)) ++ return (NULL); ++ ++ if (instance) ++ dest->instance = _cupsStrAlloc(instance); ++ ++ /* ++ * Then add local options... ++ */ ++ ++ snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); ++ cups_get_dests(filename, name, instance, 1, &dest); ++ ++ if (home) ++ { ++ snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); ++ ++ if (access(filename, 0)) ++ snprintf(filename, sizeof(filename), "%s/.lpoptions", home); ++ ++ cups_get_dests(filename, name, instance, 1, &dest); ++ } ++ ++ /* ++ * Return the result... ++ */ ++ ++ return (dest); ++} ++ ++ ++/* + * 'cupsRemoveDest()' - Remove a destination from the destination list. + * + * Removing a destination/instance does not delete the class or printer +@@ -548,19 +681,17 @@ void + cupsSetDests(int num_dests, /* I - Number of destinations */ + cups_dest_t *dests) /* I - Destinations */ + { +- http_t *http; /* HTTP connection */ ++ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * Connect to the CUPS server and save the destination list and options... + */ + +- http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); +- +- cupsSetDests2(http, num_dests, dests); ++ if (!cg->http) ++ cg->http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + +- if (http) +- httpClose(http); ++ cupsSetDests2(cg->http, num_dests, dests); + } + + +@@ -606,8 +737,8 @@ cupsSetDests2(http_t *http, /* I - + * Get the server destinations... + */ + +- num_temps = cups_get_sdests(http, CUPS_GET_PRINTERS, 0, &temps); +- num_temps = cups_get_sdests(http, CUPS_GET_CLASSES, num_temps, &temps); ++ num_temps = cups_get_sdests(http, CUPS_GET_PRINTERS, NULL, 0, &temps); ++ num_temps = cups_get_sdests(http, CUPS_GET_CLASSES, NULL, num_temps, &temps); + + /* + * Figure out which file to write to... +@@ -622,7 +753,7 @@ cupsSetDests2(http_t *http, /* I - + * Merge in server defaults... + */ + +- num_temps = cups_get_dests(filename, num_temps, &temps); ++ num_temps = cups_get_dests(filename, NULL, NULL, num_temps, &temps); + + /* + * Point to user defaults... +@@ -789,24 +920,88 @@ cupsSetDests2(http_t *http, /* I - + + + /* ++ * 'cups_get_default()' - Get the default destination from an lpoptions file. ++ */ ++ ++static const char * /* O - Default destination or NULL */ ++cups_get_default(const char *filename, /* I - File to read */ ++ char *namebuf, /* I - Name buffer */ ++ size_t namesize, /* I - Size of name buffer */ ++ const char **instance) /* I - Instance */ ++{ ++ cups_file_t *fp; /* lpoptions file */ ++ char line[8192], /* Line from file */ ++ *value, /* Value for line */ ++ *nameptr; /* Pointer into name */ ++ int linenum; /* Current line */ ++ ++ ++ *namebuf = '\0'; ++ ++ if ((fp = cupsFileOpen(filename, "r")) != NULL) ++ { ++ linenum = 0; ++ ++ while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) ++ { ++ if (!strcasecmp(line, "default") && value) ++ { ++ strlcpy(namebuf, value, namesize); ++ ++ if ((nameptr = strchr(namebuf, ' ')) != NULL) ++ *nameptr = '\0'; ++ if ((nameptr = strchr(namebuf, '\t')) != NULL) ++ *nameptr = '\0'; ++ ++ if ((nameptr = strchr(namebuf, '/')) != NULL) ++ *nameptr++ = '\0'; ++ ++ *instance = nameptr; ++ break; ++ } ++ } ++ ++ cupsFileClose(fp); ++ } ++ ++ return (*namebuf ? namebuf : NULL); ++} ++ ++ ++/* + * 'cups_get_dests()' - Get destinations from a file. + */ + + static int /* O - Number of destinations */ + cups_get_dests(const char *filename, /* I - File to read from */ ++ const char *match_name, /* I - Destination name we want */ ++ const char *match_inst, /* I - Instance name we want */ + int num_dests, /* I - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ + { + int i; /* Looping var */ + cups_dest_t *dest; /* Current destination */ +- FILE *fp; /* File pointer */ ++ cups_file_t *fp; /* File pointer */ + char line[8192], /* Line from file */ + *lineptr, /* Pointer into line */ + *name, /* Name of destination/option */ + *instance; /* Instance of destination */ ++ int linenum; /* Current line number */ + const char *printer; /* PRINTER or LPDEST */ + + ++ DEBUG_printf(("cups_get_dests(filename=\"%s\", match_name=\"%s\", " ++ "match_inst=\"%s\", num_dests=%d, dests=%p)\n", filename, ++ match_name ? match_name : "(null)", ++ match_inst ? match_inst : "(null)", num_dests, dests)); ++ ++ /* ++ * Try to open the file... ++ */ ++ ++ if ((fp = cupsFileOpen(filename, "r")) == NULL) ++ return (num_dests); ++ + /* + * Check environment variables... + */ +@@ -816,12 +1011,8 @@ cups_get_dests(const char *filename, /* + if (strcmp(printer, "lp") == 0) + printer = NULL; + +- /* +- * Try to open the file... +- */ +- +- if ((fp = fopen(filename, "r")) == NULL) +- return (num_dests); ++ DEBUG_printf(("cups_get_dests: printer=\"%s\"\n", ++ printer ? printer : "(null)")); + + /* + * Read each printer; each line looks like: +@@ -830,28 +1021,22 @@ cups_get_dests(const char *filename, /* + * Default name[/instance] options + */ + +- while (fgets(line, sizeof(line), fp) != NULL) ++ linenum = 0; ++ ++ while (cupsFileGetConf(fp, line, sizeof(line), &lineptr, &linenum)) + { + /* + * See what type of line it is... + */ + +- if (strncasecmp(line, "dest", 4) == 0 && isspace(line[4] & 255)) +- lineptr = line + 4; +- else if (strncasecmp(line, "default", 7) == 0 && isspace(line[7] & 255)) +- lineptr = line + 7; +- else +- continue; +- +- /* +- * Skip leading whitespace... +- */ +- +- while (isspace(*lineptr & 255)) +- lineptr ++; ++ DEBUG_printf(("cups_get_dests: linenum=%d line=\"%s\" lineptr=\"%s\"\n", ++ linenum, line, lineptr ? lineptr : "(null)")); + +- if (!*lineptr) ++ if ((strcasecmp(line, "dest") && strcasecmp(line, "default")) || !lineptr) ++ { ++ DEBUG_puts("cups_get_dests: Not a dest or default line..."); + continue; ++ } + + name = lineptr; + +@@ -862,9 +1047,6 @@ cups_get_dests(const char *filename, /* + while (!isspace(*lineptr & 255) && *lineptr && *lineptr != '/') + lineptr ++; + +- if (!*lineptr) +- continue; +- + if (*lineptr == '/') + { + /* +@@ -884,30 +1066,49 @@ cups_get_dests(const char *filename, /* + else + instance = NULL; + +- *lineptr++ = '\0'; ++ if (*lineptr) ++ *lineptr++ = '\0'; ++ ++ DEBUG_printf(("cups_get_dests: name=\"%s\", instance=\"%s\"\n", name, ++ instance)); + + /* + * See if the primary instance of the destination exists; if not, + * ignore this entry and move on... + */ + +- if (cupsGetDest(name, NULL, num_dests, *dests) == NULL) +- continue; +- +- /* +- * Add the destination... +- */ +- +- num_dests = cupsAddDest(name, instance, num_dests, dests); ++ if (match_name) ++ { ++ if (strcasecmp(name, match_name) || ++ (!instance && match_inst) || ++ (instance && !match_inst) || ++ (instance && strcasecmp(instance, match_inst))) ++ continue; + +- if ((dest = cupsGetDest(name, instance, num_dests, *dests)) == NULL) ++ dest = *dests; ++ } ++ else if (cupsGetDest(name, NULL, num_dests, *dests) == NULL) ++ { ++ DEBUG_puts("cups_get_dests: Not found!"); ++ continue; ++ } ++ else + { + /* +- * Out of memory! ++ * Add the destination... + */ + +- fclose(fp); +- return (num_dests); ++ num_dests = cupsAddDest(name, instance, num_dests, dests); ++ ++ if ((dest = cupsGetDest(name, instance, num_dests, *dests)) == NULL) ++ { ++ /* ++ * Out of memory! ++ */ ++ ++ DEBUG_puts("cups_get_dests: Out of memory!"); ++ break; ++ } + } + + /* +@@ -918,11 +1119,20 @@ cups_get_dests(const char *filename, /* + &(dest->options)); + + /* ++ * If we found what we were looking for, stop now... ++ */ ++ ++ if (match_name) ++ break; ++ ++ /* + * Set this as default if needed... + */ + +- if (strncasecmp(line, "default", 7) == 0 && printer == NULL) ++ if (!printer && !strcasecmp(line, "default")) + { ++ DEBUG_puts("cups_get_dests: Setting as default..."); ++ + for (i = 0; i < num_dests; i ++) + (*dests)[i].is_default = 0; + +@@ -934,7 +1144,7 @@ cups_get_dests(const char *filename, /* + * Close the file and return... + */ + +- fclose(fp); ++ cupsFileClose(fp); + + return (num_dests); + } +@@ -946,7 +1156,8 @@ cups_get_dests(const char *filename, /* + + static int /* O - Number of destinations */ + cups_get_sdests(http_t *http, /* I - HTTP connection */ +- ipp_op_t op, /* I - get-printers or get-classes */ ++ ipp_op_t op, /* I - IPP operation */ ++ const char *name, /* I - Name of destination */ + int num_dests, /* I - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ + { +@@ -963,8 +1174,9 @@ cups_get_sdests(http_t *http, /* I + const char *info, /* printer-info attribute */ + *location, /* printer-location attribute */ + *make_model, /* printer-make-and-model attribute */ +- *name; /* printer-name attribute */ +- char job_sheets[1024], /* job-sheets-default attribute */ ++ *printer_name; /* printer-name attribute */ ++ char uri[1024], /* printer-uri value */ ++ job_sheets[1024], /* job-sheets-default attribute */ + auth_info_req[1024], /* auth-info-required attribute */ + reasons[1024]; /* printer-state-reasons attribute */ + int num_options; /* Number of options */ +@@ -1008,6 +1220,14 @@ cups_get_sdests(http_t *http, /* I + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, cupsUser()); + ++ if (name) ++ { ++ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, ++ "localhost", ippPort(), "/printers/%s", name); ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, ++ uri); ++ } ++ + /* + * Do the request and get back a response... + */ +@@ -1030,17 +1250,17 @@ cups_get_sdests(http_t *http, /* I + * Pull the needed attributes from this printer... + */ + +- accepting = 0; +- change_time = 0; +- info = NULL; +- location = NULL; +- make_model = NULL; +- name = NULL; +- num_options = 0; +- options = NULL; +- shared = 1; +- state = IPP_PRINTER_IDLE; +- type = CUPS_PRINTER_LOCAL; ++ accepting = 0; ++ change_time = 0; ++ info = NULL; ++ location = NULL; ++ make_model = NULL; ++ printer_name = NULL; ++ num_options = 0; ++ options = NULL; ++ shared = 1; ++ state = IPP_PRINTER_IDLE; ++ type = CUPS_PRINTER_LOCAL; + + auth_info_req[0] = '\0'; + job_sheets[0] = '\0'; +@@ -1091,7 +1311,7 @@ cups_get_sdests(http_t *http, /* I + make_model = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-name") && + attr->value_tag == IPP_TAG_NAME) +- name = attr->values[0].string.text; ++ printer_name = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-state") && + attr->value_tag == IPP_TAG_ENUM) + state = attr->values[0].integer; +@@ -1196,7 +1416,7 @@ cups_get_sdests(http_t *http, /* I + * See if we have everything needed... + */ + +- if (!name) ++ if (!printer_name) + { + cupsFreeOptions(num_options, options); + +@@ -1206,9 +1426,9 @@ cups_get_sdests(http_t *http, /* I + continue; + } + +- num_dests = cupsAddDest(name, NULL, num_dests, dests); ++ num_dests = cupsAddDest(printer_name, NULL, num_dests, dests); + +- if ((dest = cupsGetDest(name, NULL, num_dests, *dests)) != NULL) ++ if ((dest = cupsGetDest(printer_name, NULL, num_dests, *dests)) != NULL) + { + dest->num_options = num_options; + dest->options = options; +diff -up cups-1.3.7/cups/cups.h.getnameddest cups-1.3.7/cups/cups.h +--- cups-1.3.7/cups/cups.h.getnameddest 2008-02-20 00:32:58.000000000 +0000 ++++ cups-1.3.7/cups/cups.h 2008-06-17 11:05:32.000000000 +0100 +@@ -248,6 +248,9 @@ extern void cupsSetDefaultDest(const ch + int num_dests, + cups_dest_t *dests); + ++/**** New in CUPS 1.4 ****/ ++extern cups_dest_t *cupsGetNamedDest(http_t *http, const char *name, ++ const char *instance); + + # ifdef __cplusplus + } +diff -up cups-1.3.7/cups/Makefile.getnameddest cups-1.3.7/cups/Makefile +--- cups-1.3.7/cups/Makefile.getnameddest 2008-02-20 20:18:33.000000000 +0000 ++++ cups-1.3.7/cups/Makefile 2008-06-17 11:00:50.000000000 +0100 +@@ -263,7 +263,7 @@ libcups.so.2 libcups.sl.2: $(LIBOBJS) + # libcups.2.dylib + # + +-libcups.2.dylib: $(LIBOBJS) $(LIBCUPSORDER) ++libcups.2.dylib: $(LIBOBJS) $(LIBCUPSORDER) libcups.exp + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ + -install_name $(libdir)/$@ \ +diff -up cups-1.3.7/cups/testcups.c.getnameddest cups-1.3.7/cups/testcups.c +--- cups-1.3.7/cups/testcups.c.getnameddest 2008-01-14 22:12:58.000000000 +0000 ++++ cups-1.3.7/cups/testcups.c 2008-06-17 11:00:50.000000000 +0100 +@@ -16,7 +16,8 @@ + * + * Contents: + * +- * main() - Main entry. ++ * main() - Main entry. ++ * dests_equal() - Determine whether two destinations are equal. + */ + + /* +@@ -29,6 +30,14 @@ + + + /* ++ * Local functions... ++ */ ++ ++static int dests_equal(cups_dest_t *a, cups_dest_t *b); ++static void show_diffs(cups_dest_t *a, cups_dest_t *b); ++ ++ ++/* + * 'main()' - Main entry. + */ + +@@ -37,9 +46,11 @@ main(int argc, /* I - Number of comm + char *argv[]) /* I - Command-line arguments */ + { + int status = 0, /* Exit status */ ++ i, /* Looping var */ + num_dests; /* Number of destinations */ + cups_dest_t *dests, /* Destinations */ +- *dest; /* Current destination */ ++ *dest, /* Current destination */ ++ *named_dest; /* Current named destination */ + const char *ppdfile; /* PPD file */ + ppd_file_t *ppd; /* PPD file data */ + int num_jobs; /* Number of jobs for queue */ +@@ -61,7 +72,78 @@ main(int argc, /* I - Number of comm + return (1); + } + else +- puts("PASS"); ++ { ++ printf("PASS (%d dests)\n", num_dests); ++ ++ for (i = num_dests, dest = dests; i > 0; i --, dest ++) ++ { ++ printf(" %s", dest->name); ++ ++ if (dest->instance) ++ printf(" /%s", dest->instance); ++ ++ if (dest->is_default) ++ puts(" ***DEFAULT***"); ++ else ++ putchar('\n'); ++ } ++ } ++ ++ /* ++ * cupsGetDest(NULL) ++ */ ++ ++ fputs("cupsGetDest(NULL): ", stdout); ++ fflush(stdout); ++ ++ if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL) ++ { ++ for (i = num_dests, dest = dests; i > 0; i --, dest ++) ++ if (dest->is_default) ++ break; ++ ++ if (i) ++ { ++ status = 1; ++ puts("FAIL"); ++ } ++ else ++ puts("PASS (no default)"); ++ ++ dest = NULL; ++ } ++ else ++ printf("PASS (%s)\n", dest->name); ++ ++ /* ++ * cupsGetNamedDest(NULL, NULL, NULL) ++ */ ++ ++ fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout); ++ fflush(stdout); ++ ++ if ((named_dest = cupsGetNamedDest(NULL, NULL, NULL)) == NULL || ++ !dests_equal(dest, named_dest)) ++ { ++ if (!dest) ++ puts("PASS (no default)"); ++ else if (named_dest) ++ { ++ puts("FAIL (different values)"); ++ show_diffs(dest, named_dest); ++ status = 1; ++ } ++ else ++ { ++ puts("FAIL (no default)"); ++ status = 1; ++ } ++ } ++ else ++ printf("PASS (%s)\n", named_dest->name); ++ ++ if (named_dest) ++ cupsFreeDests(1, named_dest); + + /* + * cupsGetDest(printer) +@@ -80,20 +162,34 @@ main(int argc, /* I - Number of comm + puts("PASS"); + + /* +- * cupsGetDest(NULL) ++ * cupsGetNamedDest(NULL, printer, instance) + */ + +- fputs("cupsGetDest(NULL): ", stdout); ++ printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest->name, ++ dest->instance ? dest->instance : "(null)"); + fflush(stdout); + +- if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL) ++ if ((named_dest = cupsGetNamedDest(NULL, dest->name, ++ dest->instance)) == NULL || ++ !dests_equal(dest, named_dest)) + { ++ if (named_dest) ++ { ++ puts("FAIL (different values)"); ++ show_diffs(dest, named_dest); ++ } ++ else ++ puts("FAIL (no destination)"); ++ ++ + status = 1; +- puts("FAIL"); + } + else + puts("PASS"); + ++ if (named_dest) ++ cupsFreeDests(1, named_dest); ++ + /* + * cupsPrintFile() + */ +@@ -171,5 +267,83 @@ main(int argc, /* I - Number of comm + + + /* ++ * 'dests_equal()' - Determine whether two destinations are equal. ++ */ ++ ++static int /* O - 1 if equal, 0 if not equal */ ++dests_equal(cups_dest_t *a, /* I - First destination */ ++ cups_dest_t *b) /* I - Second destination */ ++{ ++ int i; /* Looping var */ ++ cups_option_t *aoption; /* Current option */ ++ const char *bval; /* Option value */ ++ ++ ++ if (a == b) ++ return (1); ++ ++ if ((!a && b) || (a && !b)) ++ return (0); ++ ++ if (strcasecmp(a->name, b->name) || ++ (a->instance && !b->instance) || ++ (!a->instance && b->instance) || ++ (a->instance && strcasecmp(a->instance, b->instance)) || ++ a->num_options != b->num_options) ++ return (0); ++ ++ for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++) ++ if ((bval = cupsGetOption(aoption->name, b->num_options, ++ b->options)) == NULL || ++ strcmp(aoption->value, bval)) ++ return (0); ++ ++ return (1); ++} ++ ++ ++/* ++ * 'show_diffs()' - Show differences between two destinations. ++ */ ++ ++static void ++show_diffs(cups_dest_t *a, /* I - First destination */ ++ cups_dest_t *b) /* I - Second destination */ ++{ ++ int i; /* Looping var */ ++ cups_option_t *aoption; /* Current option */ ++ const char *bval; /* Option value */ ++ ++ ++ if (!a || !b) ++ return; ++ ++ puts(" Item cupsGetDest cupsGetNamedDest"); ++ puts(" -------------------- -------------------- --------------------"); ++ ++ if (strcasecmp(a->name, b->name)) ++ printf(" name %-20.20s %-20.20s\n", a->name, b->name); ++ ++ if ((a->instance && !b->instance) || ++ (!a->instance && b->instance) || ++ (a->instance && strcasecmp(a->instance, b->instance))) ++ printf(" instance %-20.20s %-20.20s\n", ++ a->instance ? a->instance : "(null)", ++ b->instance ? b->instance : "(null)"); ++ ++ if (a->num_options != b->num_options) ++ printf(" num_options %-20d %-20d\n", a->num_options, ++ b->num_options); ++ ++ for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++) ++ if ((bval = cupsGetOption(aoption->name, b->num_options, ++ b->options)) == NULL || ++ strcmp(aoption->value, bval)) ++ printf(" %-20.20s %-20.20s %-20.20s\n", aoption->name, ++ aoption->value, bval ? bval : "(null)"); ++} ++ ++ ++/* + * End of "$Id: testfile.c 6192 2007-01-10 19:26:48Z mike $". + */ +diff -up cups-1.3.7/cups/libcups.exp.getnameddest cups-1.3.7/cups/libcups.exp +--- cups-1.3.7/cups/libcups.exp.getnameddest 2008-01-22 22:02:46.000000000 +0000 ++++ cups-1.3.7/cups/libcups.exp 2008-06-17 11:00:50.000000000 +0100 +@@ -113,6 +113,7 @@ _cupsGetFd + _cupsGetFile + _cupsGetJobs + _cupsGetJobs2 ++_cupsGetNamedDest + _cupsGetOption + _cupsGetPassword + _cupsGetPPD +diff -up cups-1.3.7/CHANGES.txt.getnameddest cups-1.3.7/CHANGES.txt +diff -up cups-1.3.7/berkeley/lpr.c.getnameddest cups-1.3.7/berkeley/lpr.c +--- cups-1.3.7/berkeley/lpr.c.getnameddest 2008-06-17 11:00:11.000000000 +0100 ++++ cups-1.3.7/berkeley/lpr.c 2008-06-17 11:00:50.000000000 +0100 +@@ -92,9 +92,7 @@ main(int argc, /* I - Number of comm + int num_copies; /* Number of copies per file */ + int num_files; /* Number of files to print */ + const char *files[1000]; /* Files to print */ +- int num_dests; /* Number of destinations */ +- cups_dest_t *dests, /* Destinations */ +- *dest; /* Selected destination */ ++ cups_dest_t *dest; /* Selected destination */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + int deletefile; /* Delete file after print? */ +@@ -112,8 +110,7 @@ main(int argc, /* I - Number of comm + + deletefile = 0; + printer = NULL; +- num_dests = 0; +- dests = NULL; ++ dest = NULL; + num_options = 0; + options = NULL; + num_files = 0; +@@ -282,10 +279,7 @@ main(int argc, /* I - Number of comm + if ((instance = strrchr(printer, '/')) != NULL) + *instance++ = '\0'; + +- if (num_dests == 0) +- num_dests = cupsGetDests(&dests); +- +- if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL) ++ if ((dest = cupsGetNamedDest(NULL, printer, instance)) != NULL) + { + for (j = 0; j < dest->num_options; j ++) + if (cupsGetOption(dest->options[j].name, num_options, +@@ -385,10 +379,7 @@ main(int argc, /* I - Number of comm + + if (printer == NULL) + { +- if (num_dests == 0) +- num_dests = cupsGetDests(&dests); +- +- if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL) ++ if ((dest = cupsGetNamedDest(NULL, NULL, NULL)) != NULL) + { + printer = dest->name; + +@@ -417,7 +408,7 @@ main(int argc, /* I - Number of comm + else + val = "LPDEST"; + +- if (printer && !cupsGetDest(printer, NULL, num_dests, dests)) ++ if (printer && !cupsGetNamedDest(NULL, printer, NULL)) + _cupsLangPrintf(stderr, + _("%s: Error - %s environment variable names " + "non-existent destination \"%s\"!\n"), +diff -up cups-1.3.7/systemv/lp.c.getnameddest cups-1.3.7/systemv/lp.c +--- cups-1.3.7/systemv/lp.c.getnameddest 2007-07-11 22:46:42.000000000 +0100 ++++ cups-1.3.7/systemv/lp.c 2008-06-17 11:00:50.000000000 +0100 +@@ -73,9 +73,7 @@ main(int argc, /* I - Number of comm + int num_copies; /* Number of copies per file */ + int num_files; /* Number of files to print */ + const char *files[1000]; /* Files to print */ +- int num_dests; /* Number of destinations */ +- cups_dest_t *dests, /* Destinations */ +- *dest; /* Selected destination */ ++ cups_dest_t *dest; /* Selected destination */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + int end_options; /* No more options? */ +@@ -112,8 +110,7 @@ main(int argc, /* I - Number of comm + + silent = 0; + printer = NULL; +- num_dests = 0; +- dests = NULL; ++ dest = NULL; + num_options = 0; + options = NULL; + num_files = 0; +@@ -179,10 +176,7 @@ main(int argc, /* I - Number of comm + if ((instance = strrchr(printer, '/')) != NULL) + *instance++ = '\0'; + +- if (num_dests == 0) +- num_dests = cupsGetDests(&dests); +- +- if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL) ++ if ((dest = cupsGetNamedDest(NULL, printer, instance)) != NULL) + { + for (j = 0; j < dest->num_options; j ++) + if (cupsGetOption(dest->options[j].name, num_options, options) == NULL) +@@ -593,10 +587,7 @@ main(int argc, /* I - Number of comm + + if (printer == NULL) + { +- if (num_dests == 0) +- num_dests = cupsGetDests(&dests); +- +- if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL) ++ if ((dest = cupsGetNamedDest(NULL, NULL, NULL)) != NULL) + { + printer = dest->name; + +@@ -625,7 +616,7 @@ main(int argc, /* I - Number of comm + else + val = "LPDEST"; + +- if (printer && !cupsGetDest(printer, NULL, num_dests, dests)) ++ if (printer && !cupsGetNamedDest(NULL, printer, NULL)) + _cupsLangPrintf(stderr, + _("%s: Error - %s environment variable names " + "non-existent destination \"%s\"!\n"), diff --git a/cups.spec b/cups.spec index 9b864a3..0b236a7 100644 --- a/cups.spec +++ b/cups.spec @@ -7,7 +7,7 @@ Summary: Common Unix Printing System Name: cups Version: 1.3.7 -Release: 6%{?svn:.svn%{svn}}%{?dist} +Release: 7%{?svn:.svn%{svn}}%{?dist} License: GPLv2 Group: System Environment/Daemons Source: ftp://ftp.easysw.com/pub/cups/test//cups-%{version}%{?svn:svn-r%{svn}}-source.tar.bz2 @@ -49,6 +49,7 @@ Patch23: cups-logrotate.patch Patch25: cups-usb-paperout.patch Patch29: cups-CVE-2008-1373.patch Patch30: cups-CVE-2008-1722.patch +Patch31: cups-getnameddest.patch Patch100: cups-lspp.patch Epoch: 1 Url: http://www.cups.org/ @@ -168,6 +169,7 @@ lpd emulation. %patch25 -p1 -b .usb-paperout %patch29 -p1 -b .CVE-2008-1373 %patch30 -p1 -b .CVE-2008-1722 +%patch31 -p1 -b .getnameddest %if %lspp %patch100 -p1 -b .lspp @@ -444,6 +446,9 @@ rm -rf $RPM_BUILD_ROOT %{cups_serverbin}/daemon/cups-lpd %changelog +* Tue Jun 17 2008 Tim Waugh 1:1.3.7-7 +- Backported cupsGetNamedDest from 1.4 (bug #428086). + * Tue Jun 3 2008 Tim Waugh 1:1.3.7-6 - Applied patch to fix STR #2750 (IPP authentication).