diff --git a/cups-1.3.8-cupsfilter_path.patch b/cups-1.3.8-cupsfilter_path.patch new file mode 100644 index 0000000..765207e --- /dev/null +++ b/cups-1.3.8-cupsfilter_path.patch @@ -0,0 +1,25 @@ +cupsfilter PATH typo + +From: Johan Kiviniemi + +Fix a typo in scheduler/cupsfilter.c, which caused filters not to have /bin +in their PATH. +--- + + scheduler/cupsfilter.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + + +diff --git a/scheduler/cupsfilter.c b/scheduler/cupsfilter.c +index f60c284..d387ecf 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/cups-1.3.8-custom_ppd_fix.patch b/cups-1.3.8-custom_ppd_fix.patch new file mode 100644 index 0000000..9f657dc --- /dev/null +++ b/cups-1.3.8-custom_ppd_fix.patch @@ -0,0 +1,163 @@ +Index: cups/emit.c +=================================================================== +--- cups/emit.c (revision 7786) ++++ cups/emit.c (revision 7787) +@@ -547,8 +547,41 @@ + + for (i = 0, bufsize = 1; i < count; i ++) + { +- if (section != PPD_ORDER_EXIT && section != PPD_ORDER_JCL) ++ if (section == PPD_ORDER_JCL) + { ++ if (!strcasecmp(choices[i]->choice, "Custom") && ++ (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword)) ++ != NULL) ++ { ++ /* ++ * Add space to account for custom parameter substitution... ++ */ ++ ++ for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); ++ cparam; ++ cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) ++ { ++ switch (cparam->type) ++ { ++ case PPD_CUSTOM_CURVE : ++ case PPD_CUSTOM_INVCURVE : ++ case PPD_CUSTOM_POINTS : ++ case PPD_CUSTOM_REAL : ++ case PPD_CUSTOM_INT : ++ bufsize += 10; ++ break; ++ ++ case PPD_CUSTOM_PASSCODE : ++ case PPD_CUSTOM_PASSWORD : ++ case PPD_CUSTOM_STRING : ++ bufsize += strlen(cparam->current.custom_string); ++ break; ++ } ++ } ++ } ++ } ++ else if (section != PPD_ORDER_EXIT) ++ { + bufsize += 3; /* [{\n */ + + if ((!strcasecmp(choices[i]->option->keyword, "PageSize") || +@@ -626,8 +659,90 @@ + */ + + for (i = 0, bufptr = buffer; i < count; i ++, bufptr += strlen(bufptr)) +- if (section != PPD_ORDER_EXIT && section != PPD_ORDER_JCL) ++ if (section == PPD_ORDER_JCL) + { ++ if (!strcasecmp(choices[i]->choice, "Custom") && ++ (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword)) ++ != NULL) ++ { ++ /* ++ * Handle substitutions in custom JCL options... ++ */ ++ ++ char *cptr; /* Pointer into code */ ++ int pnum; /* Parameter number */ ++ ++ ++ for (cptr = choices[i]->code; *cptr && bufptr < bufend;) ++ { ++ if (*cptr == '\\') ++ { ++ cptr ++; ++ ++ if (isdigit(*cptr & 255)) ++ { ++ /* ++ * Substitute parameter... ++ */ ++ ++ pnum = *cptr++ - '0'; ++ while (isalnum(*cptr & 255)) ++ pnum = pnum * 10 + *cptr - '0'; ++ ++ for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); ++ cparam; ++ cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) ++ if (cparam->order == pnum) ++ break; ++ ++ if (cparam) ++ { ++ switch (cparam->type) ++ { ++ case PPD_CUSTOM_CURVE : ++ case PPD_CUSTOM_INVCURVE : ++ case PPD_CUSTOM_POINTS : ++ case PPD_CUSTOM_REAL : ++ bufptr = _cupsStrFormatd(bufptr, bufend, ++ cparam->current.custom_real, ++ loc); ++ break; ++ ++ case PPD_CUSTOM_INT : ++ snprintf(bufptr, bufend - bufptr, "%d", ++ cparam->current.custom_int); ++ bufptr += strlen(bufptr); ++ break; ++ ++ case PPD_CUSTOM_PASSCODE : ++ case PPD_CUSTOM_PASSWORD : ++ case PPD_CUSTOM_STRING : ++ strlcpy(bufptr, cparam->current.custom_string, ++ bufend - bufptr); ++ bufptr += strlen(bufptr); ++ break; ++ } ++ } ++ } ++ else if (*cptr) ++ *bufptr++ = *cptr++; ++ } ++ else ++ *bufptr++ = *cptr++; ++ } ++ } ++ else ++ { ++ /* ++ * Otherwise just copy the option code directly... ++ */ ++ ++ strlcpy(bufptr, choices[i]->code, bufend - bufptr + 1); ++ bufptr += strlen(bufptr); ++ } ++ } ++ else if (section != PPD_ORDER_EXIT) ++ { + /* + * Add wrapper commands to prevent printer errors for unsupported + * options... +@@ -759,8 +874,7 @@ + } + } + else if (!strcasecmp(choices[i]->choice, "Custom") && +- (coption = ppdFindCustomOption(ppd, +- choices[i]->option->keyword)) ++ (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword)) + != NULL) + { + /* +Index: cups/ppd.c +=================================================================== +--- cups/ppd.c (revision 7786) ++++ cups/ppd.c (revision 7787) +@@ -1050,6 +1050,9 @@ + sizeof(choice->text)); + + choice->code = strdup(string); ++ ++ if (custom_option->section == PPD_ORDER_JCL) ++ ppd_decode(choice->code); + } + + /* diff --git a/cups-1.3.8-hostlookup.patch b/cups-1.3.8-hostlookup.patch new file mode 100644 index 0000000..bdfbb2f --- /dev/null +++ b/cups-1.3.8-hostlookup.patch @@ -0,0 +1,29 @@ +Index: scheduler/client.c +=================================================================== +--- scheduler/client.c (revision 7949) ++++ scheduler/client.c (revision 7950) +@@ -437,14 +437,22 @@ + #ifdef AF_INET6 + if (temp.addr.sa_family == AF_INET6) + { +- httpAddrLookup(&temp, con->servername, sizeof(con->servername)); ++ if (HostNameLookups) ++ httpAddrLookup(&temp, con->servername, sizeof(con->servername)); ++ else ++ httpAddrString(&temp, con->servername, sizeof(con->servername)); ++ + con->serverport = ntohs(lis->address.ipv6.sin6_port); + } + else + #endif /* AF_INET6 */ + if (temp.addr.sa_family == AF_INET) + { +- httpAddrLookup(&temp, con->servername, sizeof(con->servername)); ++ if (HostNameLookups) ++ httpAddrLookup(&temp, con->servername, sizeof(con->servername)); ++ else ++ httpAddrString(&temp, con->servername, sizeof(con->servername)); ++ + con->serverport = ntohs(lis->address.ipv4.sin_port); + } + else diff --git a/cups-1.3.8-listener_compare.patch b/cups-1.3.8-listener_compare.patch new file mode 100644 index 0000000..01cb3b3 --- /dev/null +++ b/cups-1.3.8-listener_compare.patch @@ -0,0 +1,68 @@ +Index: Makefile +=================================================================== +--- Makefile (revision 7860) ++++ Makefile (working copy) +@@ -116,7 +116,7 @@ + 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 + + + # +Index: scheduler/network.c +=================================================================== +--- scheduler/network.c (revision 7860) ++++ scheduler/network.c (working copy) +@@ -245,24 +245,29 @@ + 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 @@ + + 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); diff --git a/cups-1.3.8-manyjob_finish.patch b/cups-1.3.8-manyjob_finish.patch new file mode 100644 index 0000000..bf94357 --- /dev/null +++ b/cups-1.3.8-manyjob_finish.patch @@ -0,0 +1,366 @@ +--- a/systemv/lpstat.c Sat Jul 12 00:48:49 2008 ++++ b/systemv/lpstat.c Wed Aug 27 22:32:02 2008 +@@ -1398,6 +1398,7 @@ + *title; /* Pointer to job-name */ + int rank, /* Rank in queue */ + jobid, /* job-id */ ++ first, /* first-job-id */ + size; /* job-k-octets */ + time_t jobtime; /* time-at-creation */ + struct tm *jobdate; /* Date & time */ +@@ -1405,7 +1406,8 @@ + *ptr; /* Pointer into printer name */ + int match; /* Non-zero if this job matches */ + char temp[255], /* Temporary buffer */ +- date[255]; /* Date buffer */ ++ date[255], /* Date buffer */ ++ joburi[HTTP_MAX_URI]; /* Job-URI */ + static const char *jattrs[] = /* Attributes we need for jobs... */ + { + "job-id", +@@ -1416,6 +1418,7 @@ + "job-originating-user-name", + "job-state-reasons" + }; ++ int limit = 25; /* Limit for IPP_GET_JOBS */ + + + DEBUG_printf(("show_jobs(%p, %p, %p)\n", http, dests, users)); +@@ -1426,6 +1429,13 @@ + if (dests != NULL && !strcmp(dests, "all")) + dests = NULL; + ++ rank = -1; ++ jobid = -1; ++ first = 1; ++ ++ while (jobid != 0) ++ { ++ + /* + * Build a IPP_GET_JOBS request, which requires the following + * attributes: +@@ -1442,18 +1452,34 @@ + "requested-attributes", sizeof(jattrs) / sizeof(jattrs[0]), + NULL, jattrs); + ++ snprintf(joburi,sizeof(joburi),"ipp://localhost/%s%s",dests ? "printers/" : ++ "jobs/", dests ? dests : ""); ++ + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", +- NULL, "ipp://localhost/jobs/"); ++ NULL, joburi); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs", + NULL, which); + ++ /* ++ * Search with Limits ++ */ ++ ++ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "limit", ++ limit); ++ ++ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "first-job-id", ++ first); ++ + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { ++ ++ jobid = 0; ++ + /* + * Loop through the job list and display them... + */ +@@ -1465,7 +1491,6 @@ + return (1); + } + +- rank = -1; + + for (attr = response->attrs; attr != NULL; attr = attr->next) + { +@@ -1681,7 +1706,10 @@ + if (attr == NULL) + break; + } +- ++ ++ if (jobid) ++ first = jobid + 1; ++ + ippDelete(response); + } + else +@@ -1689,6 +1717,8 @@ + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + return (1); + } ++ ++ } /* Loops until Jobs in List */ + + return (0); + } +diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c +index 1de7cae..9522667 100644 +--- a/cgi-bin/ipp-var.c ++++ b/cgi-bin/ipp-var.c +@@ -1217,48 +1217,92 @@ cgiShowJobs(http_t *http, /* I - Connection to server */ + ipp_attribute_t *job; /* Job object */ + int ascending, /* Order of jobs (0 = descending) */ + first, /* First job to show */ +- count; /* Number of jobs */ ++ final, /* This is the last request */ ++ returned, /* Number of jobs in response */ ++ count, /* Number of matching jobs */ ++ total; /* Total number of matching jobs */ + const char *var; /* Form variable */ + void *search; /* Search data */ + char url[1024], /* URL for prev/next/this */ + *urlptr, /* Position in URL */ + *urlend; /* End of URL */ ++ int *job_ids; /* Array of job IDs */ ++ size_t job_ids_alloc, /* Allocation size for array */ ++ n_job_ids; /* Elements in array */ + + ++ job_ids_alloc = 512; ++ n_job_ids = 0; ++ job_ids = malloc (sizeof (int) * job_ids_alloc); ++ first = 0; ++ final = 0; ++ total = 0; ++ ++ if ((var = cgiGetVariable("ORDER")) != NULL) ++ ascending = !strcasecmp(var, "asc"); ++ else ++ { ++ ascending = !which_jobs || !strcasecmp(which_jobs, "not-completed"); ++ cgiSetVariable("ORDER", ascending ? "asc" : "dec"); ++ } ++ + /* +- * Build an IPP_GET_JOBS request, which requires the following +- * attributes: +- * +- * attributes-charset +- * attributes-natural-language +- * printer-uri ++ * Fetch the jobs in batches, not all at once. This gives the ++ * scheduler time to process other requests in between ours. + */ ++ do ++ { ++ int first_job_id; + +- request = ippNewRequest(IPP_GET_JOBS); ++ /* ++ * Build an IPP_GET_JOBS request, which requires the following ++ * attributes: ++ * ++ * attributes-charset ++ * attributes-natural-language ++ * printer-uri ++ */ + +- if (dest) +- { +- httpAssembleURIf(HTTP_URI_CODING_ALL, url, sizeof(url), "ipp", NULL, +- "localhost", ippPort(), "/printers/%s", dest); +- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", +- NULL, url); +- } +- else +- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, +- "ipp://localhost/jobs"); ++ request = ippNewRequest(IPP_GET_JOBS); ++ ++ if (dest) ++ { ++ httpAssembleURIf(HTTP_URI_CODING_ALL, url, sizeof(url), "ipp", NULL, ++ "localhost", ippPort(), "/printers/%s", dest); ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", ++ NULL, url); ++ } ++ else ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, ++ "ipp://localhost/jobs"); + +- if ((which_jobs = cgiGetVariable("which_jobs")) != NULL) +- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs", +- NULL, which_jobs); ++ if ((which_jobs = cgiGetVariable("which_jobs")) != NULL) ++ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs", ++ NULL, which_jobs); + +- cgiGetAttributes(request, "jobs.tmpl"); ++ if (first > 0) ++ { ++ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, ++ "first-job-id", first); ++ first_job_id = first; ++ } + +- /* +- * Do the request and get back a response... +- */ ++ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, ++ "limit", CUPS_PAGE_MAX); ++ ++ cgiGetAttributes(request, "jobs.tmpl"); ++ ++ if ((response = cupsDoRequest(http, request, "/")) == NULL) ++ break; ++ ++ /* ++ * We need to know if we got as many jobs as we asked for to know ++ * when we've reached the end. ++ */ ++ jobs = cgiGetIPPObjects(response, NULL); ++ returned = cupsArrayCount(jobs); ++ cupsArrayDelete(jobs); + +- if ((response = cupsDoRequest(http, request, "/")) != NULL) +- { + /* + * Get a list of matching job objects. + */ +@@ -1274,44 +1318,107 @@ cgiShowJobs(http_t *http, /* I - Connection to server */ + if (search) + cgiFreeSearch(search); + +- /* +- * Figure out which jobs to display... +- */ ++ if (final) ++ /* ++ * We now have the jobs we need to display. ++ */ ++ break; ++ ++ total += count; ++ for (i = 0; i < count; i++) ++ { ++ ipp_attribute_t *attr; ++ for (attr = (ipp_attribute_t *) cupsArrayIndex (jobs, i); ++ attr && attr->group_tag != IPP_TAG_ZERO; ++ attr = attr->next) ++ { ++ if (!strcmp (attr->name, "job-id") && ++ attr->value_tag == IPP_TAG_INTEGER) ++ { ++ if (n_job_ids == job_ids_alloc) ++ { ++ int *old = job_ids; ++ job_ids_alloc *= 2; ++ job_ids = realloc (job_ids, sizeof (int) * job_ids_alloc); ++ if (job_ids == NULL) ++ { ++ job_ids = old; ++ break; ++ } ++ } ++ ++ job_ids[n_job_ids++] = attr->values[0].integer; ++ first = attr->values[0].integer + 1; ++ break; ++ } ++ } ++ } ++ ++ if (returned < CUPS_PAGE_MAX) ++ { ++ /* ++ * One last request to fetch the jobs we're really interested in. ++ */ ++ final = 1; ++ ++ /* ++ * Figure out which jobs we need. ++ */ ++ if ((var = cgiGetVariable("FIRST")) != NULL) ++ first = atoi(var); ++ else ++ first = 0; ++ ++ if (!ascending) ++ first = total - first - CUPS_PAGE_MAX; ++ ++ if (first >= total) ++ first = total - CUPS_PAGE_MAX; ++ ++ if (first < 0) ++ first = 0; ++ ++ first = job_ids[first]; ++ free (job_ids); ++ if (first == first_job_id) ++ /* ++ * We have just requested these jobs so no need to re-fetch. ++ */ ++ break; ++ ++ cupsArrayDelete(jobs); ++ ippDelete(response); ++ } ++ } while (final || (returned == CUPS_PAGE_MAX && first > 0)); ++ ++ if (response != NULL) ++ { ++ sprintf(url, "%d", total); ++ cgiSetVariable("TOTAL", url); + + if ((var = cgiGetVariable("FIRST")) != NULL) + first = atoi(var); + else + first = 0; + +- if (first >= count) +- first = count - CUPS_PAGE_MAX; ++ if (first >= total) ++ first = total - CUPS_PAGE_MAX; + + first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX; + + if (first < 0) + first = 0; + +- sprintf(url, "%d", count); +- cgiSetVariable("TOTAL", url); +- +- if ((var = cgiGetVariable("ORDER")) != NULL) +- ascending = !strcasecmp(var, "asc"); +- else +- { +- ascending = !which_jobs || !strcasecmp(which_jobs, "not-completed"); +- cgiSetVariable("ORDER", ascending ? "asc" : "dec"); +- } +- + if (ascending) + { +- for (i = 0, job = (ipp_attribute_t *)cupsArrayIndex(jobs, first); ++ for (i = 0, job = (ipp_attribute_t *)cupsArrayIndex(jobs, 0); + i < CUPS_PAGE_MAX && job; + i ++, job = (ipp_attribute_t *)cupsArrayNext(jobs)) + cgiSetIPPObjectVars(job, NULL, i); + } + else + { +- for (i = 0, job = (ipp_attribute_t *)cupsArrayIndex(jobs, count - first - 1); ++ for (i = 0, job = (ipp_attribute_t *)cupsArrayIndex(jobs, count - 1); + i < CUPS_PAGE_MAX && job; + i ++, job = (ipp_attribute_t *)cupsArrayPrev(jobs)) + cgiSetIPPObjectVars(job, NULL, i); +@@ -1371,7 +1478,7 @@ cgiShowJobs(http_t *http, /* I - Connection to server */ + cgiSetVariable("PREVURL", url); + } + +- if ((first + CUPS_PAGE_MAX) < count) ++ if ((first + CUPS_PAGE_MAX) < total) + { + snprintf(urlptr, urlend - urlptr, "FIRST=%d&ORDER=%s", + first + CUPS_PAGE_MAX, ascending ? "asc" : "dec"); diff --git a/cups-1.3.8-more_debuginfo.patch b/cups-1.3.8-more_debuginfo.patch new file mode 100644 index 0000000..12395f8 --- /dev/null +++ b/cups-1.3.8-more_debuginfo.patch @@ -0,0 +1,96 @@ +Index: doc/help/spec-ipp.html +=================================================================== +--- doc/help/spec-ipp.html (revision 7941) ++++ doc/help/spec-ipp.html (working copy) +@@ -793,16 +793,16 @@ + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + ++
"first-printer-name" (name(127)):CUPS 1.2 ++ ++
The client OPTIONALLY supplies this attribute to ++ select the first printer that is returned. ++ +
"limit" (integer (1:MAX)): + +
The client OPTIONALLY supplies this attribute limiting the + number of printers that are returned. + +-
"printer-info" (text(127)):CUPS 1.1 +- +-
The client OPTIONALLY supplies this attribute to +- select which printers are returned. +- +
"printer-location" (text(127)): CUPS 1.1.7 + +
The client OPTIONALLY supplies this attribute to +@@ -827,6 +827,11 @@ + responds as if this attribute had been supplied with a value of + 'all'. + ++
"requested-user-name" (name(127)) : CUPS 1.2 ++ ++
The client OPTIONALLY supplies a user name that is used to filter ++ the returned printers. ++ + + +

CUPS-Get-Printers Response

+@@ -1052,15 +1057,16 @@ + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + ++
"first-printer-name" (name(127)):CUPS 1.2 ++ ++
The client OPTIONALLY supplies this attribute to ++ select the first printer that is returned. ++ +
"limit" (integer (1:MAX)): + +
The client OPTIONALLY supplies this attribute limiting the + number of printer classes that are returned. + +-
"printer-info" (text(127)): CUPS 1.1.7 +-
The client OPTIONALLY supplies this attribute to +- select which printer classes are returned. +- +
"printer-location" (text(127)): CUPS 1.1.7 +
The client OPTIONALLY supplies this attribute to + select which printer classes are returned. +@@ -1081,6 +1087,11 @@ + interested. If the client omits this attribute, the server responds as + if this attribute had been supplied with a value of 'all'. + ++
"requested-user-name" (name(127)) : CUPS 1.2 ++ ++
The client OPTIONALLY supplies a user name that is used to filter ++ the returned printers. ++ + + +

CUPS-Get-Classes Response

+Index: scheduler/ipp.c +=================================================================== +--- scheduler/ipp.c (revision 7941) ++++ scheduler/ipp.c (working copy) +@@ -6746,8 +6746,8 @@ + { + if ((!type || (printer->type & CUPS_PRINTER_CLASS) == type) && + (printer->type & printer_mask) == printer_type && +- (!location || !printer->location || +- !strcasecmp(printer->location, location))) ++ (!location || ++ (printer->location && !strcasecmp(printer->location, location)))) + { + /* + * If HideImplicitMembers is enabled, see if this printer or class +@@ -7734,6 +7734,9 @@ + + cupsdSaveJob(job); + ++ cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Queued on \"%s\" by \"%s\".", ++ job->id, job->dest, job->username); ++ + /* + * Start the job if possible... + */ diff --git a/cups-1.3.8-noclobber_symlink.patch b/cups-1.3.8-noclobber_symlink.patch new file mode 100644 index 0000000..635db94 --- /dev/null +++ b/cups-1.3.8-noclobber_symlink.patch @@ -0,0 +1,84 @@ +Index: scheduler/conf.c +=================================================================== +--- scheduler/conf.c (revision 7911) ++++ scheduler/conf.c (working copy) +@@ -223,6 +223,7 @@ + int dir_created = 0; /* Did we create a directory? */ + char pathname[1024]; /* File name with prefix */ + struct stat fileinfo; /* Stat buffer */ ++ int is_symlink; /* Is "filename" a symlink? */ + + + /* +@@ -239,7 +240,7 @@ + * See if we can stat the file/directory... + */ + +- if (stat(filename, &fileinfo)) ++ if (lstat(filename, &fileinfo)) + { + if (errno == ENOENT && create_dir) + { +@@ -266,8 +267,18 @@ + return (create_dir ? -1 : 1); + } + ++ if ((is_symlink = S_ISLNK(fileinfo.st_mode)) != 0) ++ { ++ if (stat(filename, &fileinfo)) ++ { ++ cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is a bad symlink - %s", ++ filename, strerror(errno)); ++ return (-1); ++ } ++ } ++ + /* +- * Make sure it's a regular file... ++ * Make sure it's a regular file or a directory as needed... + */ + + if (!dir_created && !is_dir && !S_ISREG(fileinfo.st_mode)) +@@ -287,6 +298,13 @@ + } + + /* ++ * If the filename is a symlink, do not change permissions (STR #2937)... ++ */ ++ ++ if (is_symlink) ++ return (0); ++ ++ /* + * Fix owner, group, and mode as needed... + */ + +@@ -775,21 +793,18 @@ + if (ServerCertificate[0] != '/') + cupsdSetStringf(&ServerCertificate, "%s/%s", ServerRoot, ServerCertificate); + +- if (!strncmp(ServerRoot, ServerCertificate, strlen(ServerRoot))) +- { +- chown(ServerCertificate, RunUser, Group); +- chmod(ServerCertificate, 0600); +- } ++ if (!strncmp(ServerRoot, ServerCertificate, strlen(ServerRoot)) && ++ cupsdCheckPermissions(ServerCertificate, NULL, 0600, RunUser, Group, ++ 0, 0) < 0) ++ return (0); + + # if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS) + if (ServerKey[0] != '/') + cupsdSetStringf(&ServerKey, "%s/%s", ServerRoot, ServerKey); + +- if (!strncmp(ServerRoot, ServerKey, strlen(ServerRoot))) +- { +- chown(ServerKey, RunUser, Group); +- chmod(ServerKey, 0600); +- } ++ if (!strncmp(ServerRoot, ServerKey, strlen(ServerRoot)) && ++ cupsdCheckPermissions(ServerKey, NULL, 0600, RunUser, Group, 0, 0) < 0) ++ return (0); + # endif /* HAVE_LIBSSL || HAVE_GNUTLS */ + #endif /* HAVE_SSL */ + diff --git a/cups-1.3.8-pjl_ready_message.patch b/cups-1.3.8-pjl_ready_message.patch new file mode 100644 index 0000000..a40a53c --- /dev/null +++ b/cups-1.3.8-pjl_ready_message.patch @@ -0,0 +1,25 @@ +PJL display ready message + +From: Johan Kiviniemi + +According to the PJL spec, one should use "" (not "READY") to return the +display to the normal ready message. +--- + + cups/emit.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + + +diff --git a/cups/emit.c b/cups/emit.c +index 1f87460..c59f634 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-1.3.8-resolver_reinit.patch.bz2 b/cups-1.3.8-resolver_reinit.patch.bz2 new file mode 100644 index 0000000..a5d2328 --- /dev/null +++ b/cups-1.3.8-resolver_reinit.patch.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e63ecd85a5922ff98b38e7a1e878bd187a50bfcb4f6898b61a290a724535a86 +size 10166 diff --git a/cups-1.3.8-ssl_firefox.patch b/cups-1.3.8-ssl_firefox.patch new file mode 100644 index 0000000..c90ad27 --- /dev/null +++ b/cups-1.3.8-ssl_firefox.patch @@ -0,0 +1,88 @@ +Index: scheduler/client.c +=================================================================== +--- scheduler/client.c (revision 7820) ++++ scheduler/client.c (working copy) +@@ -28,6 +28,7 @@ + * cupsdUpdateCGI() - Read status messages from CGI scripts and programs. + * cupsdWriteClient() - Write data to a client as needed. + * check_if_modified() - Decode an "If-Modified-Since" line. ++ * data_ready() - Check whether data is available from a client. + * encrypt_client() - Enable encryption for the client... + * get_cdsa_certificate() - Convert a keychain name into the CFArrayRef + * required by SSLSetCertificate. +@@ -83,6 +84,7 @@ + + static int check_if_modified(cupsd_client_t *con, + struct stat *filestats); ++static int data_ready(cupsd_client_t *con); + #ifdef HAVE_SSL + static int encrypt_client(cupsd_client_t *con); + #endif /* HAVE_SSL */ +@@ -989,8 +991,7 @@ + */ + + while ((status = httpUpdate(HTTP(con))) == HTTP_CONTINUE) +- if (con->http.used == 0 || +- !memchr(con->http.buffer, '\n', con->http.used)) ++ if (!data_ready(con)) + break; + + if (status != HTTP_OK && status != HTTP_CONTINUE) +@@ -1889,7 +1890,7 @@ + } + } + } +- while (con->http.state == HTTP_PUT_RECV && con->http.used > 0); ++ while (con->http.state == HTTP_PUT_RECV && data_ready(con)); + + if (con->http.state == HTTP_WAITING) + { +@@ -2064,7 +2065,7 @@ + } + } + } +- while (con->http.state == HTTP_POST_RECV && con->http.used > 0); ++ while (con->http.state == HTTP_POST_RECV && data_ready(con)); + + if (con->http.state == HTTP_POST_SEND) + { +@@ -2914,7 +2915,39 @@ + } + + ++/* ++ * 'data_ready()' - Check whether data is available from a client. ++ */ ++ ++static int /* O - 1 if data is ready, 0 otherwise */ ++data_ready(cupsd_client_t *con) /* I - Client */ ++{ ++ if (con->http.used > 0) ++ return (1); + #ifdef HAVE_SSL ++ else if (con->http.tls) ++ { ++# ifdef HAVE_LIBSSL ++ if (SSL_pending((SSL *)(con->http.tls))) ++ return (1); ++# elif defined(HAVE_GNUTLS) ++ if (gnutls_record_check_pending(((http_tls_t *)(con->http.tls))->session)) ++ return (1); ++# elif defined(HAVE_CDSASSL) ++ size_t bytes; /* Bytes that are available */ ++ ++ if (!SSLGetBufferedReadSize(((http_tls_t *)(con->http.tls))->session, ++ &bytes) && bytes > 0) ++ return (1); ++# endif /* HAVE_LIBSSL */ ++ } ++#endif /* HAVE_SSL */ ++ ++ return (0); ++} ++ ++ ++#ifdef HAVE_SSL + /* + * 'encrypt_client()' - Enable encryption for the client... + */ diff --git a/cups-1.3.8-startstop_msg.patch b/cups-1.3.8-startstop_msg.patch new file mode 100644 index 0000000..c974bbf --- /dev/null +++ b/cups-1.3.8-startstop_msg.patch @@ -0,0 +1,61 @@ +Index: scheduler/main.c +=================================================================== +--- scheduler/main.c (revision 7911) ++++ scheduler/main.c (working copy) +@@ -655,6 +655,23 @@ + #endif /* __APPLE__ */ + + /* ++ * Send server-started event... ++ */ ++ ++#ifdef HAVE_LAUNCHD ++ if (Launchd) ++ cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, ++ "Scheduler started via launchd."); ++ else ++#endif /* HAVE_LAUNCHD */ ++ if (fg) ++ cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, ++ "Scheduler started in foreground."); ++ else ++ cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, ++ "Scheduler started in background."); ++ ++ /* + * Start any pending print jobs... + */ + +@@ -762,6 +779,13 @@ + */ + + cupsdStartServer(); ++ ++ /* ++ * Send a server-restarted event... ++ */ ++ ++ cupsdAddEvent(CUPSD_EVENT_SERVER_RESTARTED, NULL, NULL, ++ "Scheduler restarted."); + } + } + +@@ -1101,10 +1125,18 @@ + */ + + if (stop_scheduler) ++ { + cupsdLogMessage(CUPSD_LOG_INFO, "Scheduler shutting down normally."); ++ cupsdAddEvent(CUPSD_EVENT_SERVER_STOPPED, NULL, NULL, ++ "Scheduler shutting down normally."); ++ } + else ++ { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Scheduler shutting down due to program error."); ++ cupsdAddEvent(CUPSD_EVENT_SERVER_STOPPED, NULL, NULL, ++ "Scheduler shutting down due to program error."); ++ } + + /* + * Close all network clients... diff --git a/cups.changes b/cups.changes index cb16417..d762833 100644 --- a/cups.changes +++ b/cups.changes @@ -1,3 +1,19 @@ +------------------------------------------------------------------- +Thu Sep 25 12:33:59 CEST 2008 - kssingvo@suse.de + +- added und integrated latest patches from upstream bugzilla: + cups-1.3.8-custom_ppd_fix.patch (CUPS STR #2889) + cups-1.3.8-ssl_firefox.patch (CUPS STR #2892) + cups-1.3.8-cupsfilter_path.patch (CUPS STR #2908) + cups-1.3.8-pjl_ready_message.patch (CUPS STR #2909) + cups-1.3.8-listener_compare.patch (CUPS STR #2910) + cups-1.3.8-manyjob_finish.patch (CUPS STR #2913) + cups-1.3.8-resolver_reinit.patch (CUPS STR #2920) + cups-1.3.8-startstop_msg.patch (CUPS STR #2927) + cups-1.3.8-noclobber_symlink.patch (CUPS STR #2937) + cups-1.3.8-more_debuginfo.patch (CUPS STR #2943) + cups-1.3.8-hostlookup.patch (CUPS STR #2946) + ------------------------------------------------------------------- Thu Sep 11 11:50:47 CEST 2008 - kssingvo@suse.de diff --git a/cups.spec b/cups.spec index 6784758..4b5f1f4 100644 --- a/cups.spec +++ b/cups.spec @@ -30,7 +30,7 @@ License: GPL v2 or later Group: Hardware/Printing Summary: The Common UNIX Printing System Version: 1.3.8 -Release: 30 +Release: 33 Requires: cups-libs = %{version}, cups-client = %{version} Requires: ghostscript_any, ghostscript-fonts-std, foomatic-filters Requires: util-linux /usr/bin/pdftops @@ -80,6 +80,17 @@ Patch19: cups-1.4svn-pdftops_dont_fail_on_cancel.patch Patch20: cups-1.3.7-keeping_recommended.patch Patch21: cups-1.3.7-lppasswd_fixperm.patch Patch22: cups-1.3.7-additional_policies.patch +Patch23: cups-1.3.8-custom_ppd_fix.patch +Patch24: cups-1.3.8-ssl_firefox.patch +Patch25: cups-1.3.8-listener_compare.patch +Patch26: cups-1.3.8-cupsfilter_path.patch +Patch27: cups-1.3.8-pjl_ready_message.patch +Patch28: cups-1.3.8-manyjob_finish.patch +Patch29: cups-1.3.8-resolver_reinit.patch.bz2 +Patch30: cups-1.3.8-startstop_msg.patch +Patch31: cups-1.3.8-noclobber_symlink.patch +Patch32: cups-1.3.8-more_debuginfo.patch +Patch33: cups-1.3.8-hostlookup.patch Patch100: cups-1.1.23-testpage.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -181,6 +192,17 @@ mv pdftops pdftos.use_filter_pdftops_c %patch20 -p1 %patch21 -p1 %patch22 -p1 +%patch23 -p0 +%patch24 -p0 +%patch25 -p0 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p0 +%patch30 -p0 +%patch31 -p0 +%patch32 -p0 +%patch33 -p0 if [ -f /.buildenv ]; then . /.buildenv test -z "$BUILD_DISTRIBUTION_NAME" && BUILD_DISTRIBUTION_NAME="%{?distribution}" @@ -434,6 +456,19 @@ rm -rf $RPM_BUILD_ROOT/usr/share/locale/no %{_datadir}/locale/*/cups_* %changelog +* Thu Sep 25 2008 kssingvo@suse.de +- added und integrated latest patches from upstream bugzilla: + cups-1.3.8-custom_ppd_fix.patch (CUPS STR #2889) + cups-1.3.8-ssl_firefox.patch (CUPS STR #2892) + cups-1.3.8-cupsfilter_path.patch (CUPS STR #2908) + cups-1.3.8-pjl_ready_message.patch (CUPS STR #2909) + cups-1.3.8-listener_compare.patch (CUPS STR #2910) + cups-1.3.8-manyjob_finish.patch (CUPS STR #2913) + cups-1.3.8-resolver_reinit.patch (CUPS STR #2920) + cups-1.3.8-startstop_msg.patch (CUPS STR #2927) + cups-1.3.8-noclobber_symlink.patch (CUPS STR #2937) + cups-1.3.8-more_debuginfo.patch (CUPS STR #2943) + cups-1.3.8-hostlookup.patch (CUPS STR #2946) * Thu Sep 11 2008 kssingvo@suse.de - removed hplip in init script: hplip is no more (bnc#390663) * Tue Sep 09 2008 kssingvo@suse.de