Upstream patch for STR #2913 to limit Get-Jobs replies to 500 jobs (bug #421671).

Also includes:
- Upstream patch for STR #4396, pre-requisite for STR #2913 patch.

Resolves: rhbz#421671
This commit is contained in:
Tim Waugh 2014-08-20 17:02:00 +01:00
parent ba58bf89e4
commit 93ba33eb74
3 changed files with 683 additions and 1 deletions

399
cups-str2913.patch Normal file
View File

@ -0,0 +1,399 @@
diff -up cups-1.7.5/scheduler/ipp.c.str2913 cups-1.7.5/scheduler/ipp.c
--- cups-1.7.5/scheduler/ipp.c.str2913 2014-08-20 17:19:25.216908923 +0100
+++ cups-1.7.5/scheduler/ipp.c 2014-08-20 17:21:45.641812985 +0100
@@ -1531,8 +1531,7 @@ add_job(cupsd_client_t *con, /* I - Cl
}
if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_ZERO)) == NULL)
- ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
- "Untitled");
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, "Untitled");
else if ((attr->value_tag != IPP_TAG_NAME &&
attr->value_tag != IPP_TAG_NAMELANG) ||
attr->num_values != 1)
@@ -1612,6 +1611,9 @@ add_job(cupsd_client_t *con, /* I - Cl
ippDeleteAttribute(job->attrs, auth_info);
}
+ if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_NAME)) != NULL)
+ cupsdSetString(&(job->name), attr->values[0].string.text);
+
if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name",
IPP_TAG_ZERO)) != NULL)
{
@@ -1706,8 +1708,7 @@ add_job(cupsd_client_t *con, /* I - Cl
ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL,
printer->uri);
- if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
- IPP_TAG_INTEGER)) != NULL)
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
attr->values[0].integer = 0;
else
ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-k-octets", 0);
@@ -4357,8 +4358,9 @@ copy_banner(cupsd_client_t *con, /* I -
kbytes = (cupsFileTell(out) + 1023) / 1024;
- if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
- IPP_TAG_INTEGER)) != NULL)
+ job->koctets += kbytes;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
attr->values[0].integer += kbytes;
cupsFileClose(out);
@@ -4780,7 +4782,55 @@ copy_job_attrs(cupsd_client_t *con, /* I
"job-uri", NULL, job_uri);
}
- copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0, exclude);
+ if (job->attrs)
+ {
+ copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0, exclude);
+ }
+ else
+ {
+ /*
+ * Generate attributes from the job structure...
+ */
+
+ if (!ra || cupsArrayFind(ra, "job-id"))
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+
+ if (!ra || cupsArrayFind(ra, "job-k-octets"))
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-k-octets", job->koctets);
+
+ if (job->name && (!ra || cupsArrayFind(ra, "job-name")))
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, job->name);
+
+ if (job->username && (!ra || cupsArrayFind(ra, "job-originating-user-name")))
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_NAME, "job-originating-user-name", NULL, job->username);
+
+ if (!ra || cupsArrayFind(ra, "job-state"))
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state", (int)job->state_value);
+
+ if (!ra || cupsArrayFind(ra, "job-state-reasons"))
+ {
+ switch (job->state_value)
+ {
+ default : /* Should never get here for processing, pending, held, or stopped jobs since they don't get unloaded... */
+ break;
+ case IPP_JSTATE_ABORTED :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-aborted-by-system");
+ break;
+ case IPP_JSTATE_CANCELED :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-canceled-by-user");
+ break;
+ case IPP_JSTATE_COMPLETED :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-completed-successfully");
+ break;
+ }
+ }
+
+ if (job->completed_time && (!ra || cupsArrayFind(ra, "time-at-completed")))
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-completed", (int)job->completed_time);
+
+ if (job->completed_time && (!ra || cupsArrayFind(ra, "time-at-creation")))
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation", (int)job->creation_time);
+ }
}
@@ -6133,9 +6183,13 @@ get_jobs(cupsd_client_t *con, /* I - C
int port; /* Port portion of URI */
int job_comparison; /* Job comparison */
ipp_jstate_t job_state; /* job-state value */
- int first_job_id; /* First job ID */
- int limit; /* Maximum number of jobs to return */
+ int first_job_id = 1, /* First job ID */
+ first_index = 1, /* First index */
+ current_index = 0; /* Current index */
+ int limit = 0; /* Maximum number of jobs to return */
int count; /* Number of jobs that match */
+ int need_load_job = 0; /* Do we need to load the job? */
+ const char *job_attr; /* Job attribute requested */
ipp_attribute_t *job_ids; /* job-ids attribute */
cupsd_job_t *job; /* Current job pointer */
cupsd_printer_t *printer; /* Printer */
@@ -6301,8 +6355,7 @@ get_jobs(cupsd_client_t *con, /* I - C
* See if they want to limit the number of jobs reported...
*/
- if ((attr = ippFindAttribute(con->request, "limit",
- IPP_TAG_INTEGER)) != NULL)
+ if ((attr = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER)) != NULL)
{
if (job_ids)
{
@@ -6314,11 +6367,20 @@ get_jobs(cupsd_client_t *con, /* I - C
limit = attr->values[0].integer;
}
- else
- limit = 0;
- if ((attr = ippFindAttribute(con->request, "first-job-id",
- IPP_TAG_INTEGER)) != NULL)
+ if ((attr = ippFindAttribute(con->request, "first-index", IPP_TAG_INTEGER)) != NULL)
+ {
+ if (job_ids)
+ {
+ send_ipp_status(con, IPP_CONFLICT,
+ _("The %s attribute cannot be provided with job-ids."),
+ "first-index");
+ return;
+ }
+
+ first_index = attr->values[0].integer;
+ }
+ else if ((attr = ippFindAttribute(con->request, "first-job-id", IPP_TAG_INTEGER)) != NULL)
{
if (job_ids)
{
@@ -6330,15 +6392,12 @@ get_jobs(cupsd_client_t *con, /* I - C
first_job_id = attr->values[0].integer;
}
- else
- first_job_id = 1;
/*
* See if we only want to see jobs for a specific user...
*/
- if ((attr = ippFindAttribute(con->request, "my-jobs",
- IPP_TAG_BOOLEAN)) != NULL && job_ids)
+ if ((attr = ippFindAttribute(con->request, "my-jobs", IPP_TAG_BOOLEAN)) != NULL && job_ids)
{
send_ipp_status(con, IPP_CONFLICT,
_("The %s attribute cannot be provided with job-ids."),
@@ -6351,6 +6410,43 @@ get_jobs(cupsd_client_t *con, /* I - C
username[0] = '\0';
ra = create_requested_array(con->request);
+ for (job_attr = (char *)cupsArrayFirst(ra); job_attr; job_attr = (char *)cupsArrayNext(ra))
+ if (strcmp(job_attr, "job-id") &&
+ strcmp(job_attr, "job-k-octets") &&
+ strcmp(job_attr, "job-media-progress") &&
+ strcmp(job_attr, "job-more-info") &&
+ strcmp(job_attr, "job-name") &&
+ strcmp(job_attr, "job-originating-user-name") &&
+ strcmp(job_attr, "job-preserved") &&
+ strcmp(job_attr, "job-printer-up-time") &&
+ strcmp(job_attr, "job-printer-uri") &&
+ strcmp(job_attr, "job-state") &&
+ strcmp(job_attr, "job-state-reasons") &&
+ strcmp(job_attr, "job-uri") &&
+ strcmp(job_attr, "time-at-completed") &&
+ strcmp(job_attr, "time-at-creation") &&
+ strcmp(job_attr, "number-of-documents"))
+ {
+ need_load_job = 1;
+ break;
+ }
+
+ if (need_load_job && (limit == 0 || limit > 500) && (list == Jobs || delete_list))
+ {
+ /*
+ * Limit expensive Get-Jobs for job history to 500 jobs...
+ */
+
+ ippAddInteger(con->response, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "limit", 500);
+
+ if (limit)
+ ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER, "limit", limit);
+
+ limit = 500;
+
+ cupsdLogMessage(CUPSD_LOG_INFO,
+ "Limiting Get-Jobs response to %d jobs.", limit);
+ }
/*
* OK, build a list of jobs for this printer...
@@ -6377,13 +6473,15 @@ get_jobs(cupsd_client_t *con, /* I - C
{
job = cupsdFindJob(job_ids->values[i].integer);
- cupsdLoadJob(job);
-
- if (!job->attrs)
+ if (need_load_job && !job->attrs)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d",
- job->id);
- continue;
+ cupsdLoadJob(job);
+
+ if (!job->attrs)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d", job->id);
+ continue;
+ }
}
if (i > 0)
@@ -6433,13 +6531,19 @@ get_jobs(cupsd_client_t *con, /* I - C
if (job->id < first_job_id)
continue;
- cupsdLoadJob(job);
+ current_index ++;
+ if (current_index < first_index)
+ continue;
- if (!job->attrs)
+ if (need_load_job && !job->attrs)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d",
- job->id);
- continue;
+ cupsdLoadJob(job);
+
+ if (!job->attrs)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d", job->id);
+ continue;
+ }
}
if (username[0] && _cups_strcasecmp(username, job->username))
@@ -8173,8 +8277,9 @@ print_job(cupsd_client_t *con, /* I -
cupsdUpdateQuota(printer, job->username, 0, kbytes);
- if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
- IPP_TAG_INTEGER)) != NULL)
+ job->koctets += kbytes;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
attr->values[0].integer += kbytes;
/*
@@ -9410,8 +9515,9 @@ send_document(cupsd_client_t *con, /* I
cupsdUpdateQuota(printer, job->username, 0, kbytes);
- if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
- IPP_TAG_INTEGER)) != NULL)
+ job->koctets += kbytes;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
attr->values[0].integer += kbytes;
snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id,
diff -up cups-1.7.5/scheduler/job.c.str2913 cups-1.7.5/scheduler/job.c
--- cups-1.7.5/scheduler/job.c.str2913 2014-08-20 17:19:25.261909213 +0100
+++ cups-1.7.5/scheduler/job.c 2014-08-20 17:19:25.272909284 +0100
@@ -1707,9 +1707,10 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J
job->file_time = 0;
job->history_time = 0;
- if (job->state_value >= IPP_JOB_CANCELED &&
- (attr = ippFindAttribute(job->attrs, "time-at-completed",
- IPP_TAG_INTEGER)) != NULL)
+ if ((attr = ippFindAttribute(job->attrs, "time-at-creation", IPP_TAG_INTEGER)) != NULL)
+ job->creation_time = attr->values[0].integer;
+
+ if (job->state_value >= IPP_JOB_CANCELED && (attr = ippFindAttribute(job->attrs, "time-at-completed", IPP_TAG_INTEGER)) != NULL)
{
job->completed_time = attr->values[0].integer;
@@ -1858,6 +1859,12 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J
cupsdSetString(&job->username, attr->values[0].string.text);
}
+ if (!job->name)
+ {
+ if ((attr = ippFindAttribute(job->attrs, "job-name", IPP_TAG_NAME)) != NULL)
+ cupsdSetString(&job->name, attr->values[0].string.text);
+ }
+
/*
* Set the job hold-until time and state...
*/
@@ -1882,6 +1889,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J
job->state_value = IPP_JOB_PENDING;
}
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
+ job->koctets = attr->values[0].integer;
+
if (!job->num_files)
{
/*
@@ -2190,14 +2200,18 @@ cupsdSaveAllJobs(void)
{
cupsFilePrintf(fp, "<Job %d>\n", job->id);
cupsFilePrintf(fp, "State %d\n", job->state_value);
+ cupsFilePrintf(fp, "Created %ld\n", (long)job->creation_time);
if (job->completed_time)
cupsFilePrintf(fp, "Completed %ld\n", (long)job->completed_time);
cupsFilePrintf(fp, "Priority %d\n", job->priority);
if (job->hold_until)
cupsFilePrintf(fp, "HoldUntil %ld\n", (long)job->hold_until);
cupsFilePrintf(fp, "Username %s\n", job->username);
+ if (job->name)
+ cupsFilePutConf(fp, "Name", job->name);
cupsFilePrintf(fp, "Destination %s\n", job->dest);
cupsFilePrintf(fp, "DestType %d\n", job->dtype);
+ cupsFilePrintf(fp, "KOctets %d\n", job->koctets);
cupsFilePrintf(fp, "NumFiles %d\n", job->num_files);
for (i = 0; i < job->num_files; i ++)
cupsFilePrintf(fp, "File %d %s/%s %d\n", i + 1, job->filetypes[i]->super,
@@ -4138,7 +4152,7 @@ load_job_cache(const char *filename) /*
cupsArrayAdd(ActiveJobs, job);
else if (job->state_value > IPP_JOB_STOPPED)
{
- if (!job->completed_time)
+ if (!job->completed_time || !job->creation_time || !job->name || !job->koctets)
{
cupsdLoadJob(job);
unload_job(job);
@@ -4161,6 +4175,14 @@ load_job_cache(const char *filename) /*
else if (job->state_value > IPP_JOB_COMPLETED)
job->state_value = IPP_JOB_COMPLETED;
}
+ else if (!_cups_strcasecmp(line, "Name"))
+ {
+ cupsdSetString(&(job->name), value);
+ }
+ else if (!_cups_strcasecmp(line, "Created"))
+ {
+ job->creation_time = strtol(value, NULL, 10);
+ }
else if (!_cups_strcasecmp(line, "Completed"))
{
job->completed_time = strtol(value, NULL, 10);
@@ -4185,6 +4207,10 @@ load_job_cache(const char *filename) /*
{
job->dtype = (cups_ptype_t)atoi(value);
}
+ else if (!_cups_strcasecmp(line, "KOctets"))
+ {
+ job->koctets = atoi(value);
+ }
else if (!_cups_strcasecmp(line, "NumFiles"))
{
job->num_files = atoi(value);
diff -up cups-1.7.5/scheduler/job.h.str2913 cups-1.7.5/scheduler/job.h
--- cups-1.7.5/scheduler/job.h.str2913 2014-08-20 17:19:25.196908795 +0100
+++ cups-1.7.5/scheduler/job.h 2014-08-20 17:19:25.273909291 +0100
@@ -39,6 +39,8 @@ struct cupsd_job_s /**** Job request *
* waiting on files */
char *username; /* Printing user */
char *dest; /* Destination printer or class */
+ char *name; /* Job name/title */
+ int koctets; /* job-k-octets */
cups_ptype_t dtype; /* Destination type */
cupsd_printer_t *printer; /* Printer this job is assigned to */
int num_files; /* Number of files in job */
@@ -47,6 +49,7 @@ struct cupsd_job_s /**** Job request *
ipp_attribute_t *sheets; /* job-media-sheets-completed */
time_t access_time, /* Last access time */
cancel_time, /* When to cancel/send SIGTERM */
+ creation_time, /* When job was created */
completed_time, /* When job was completed (0 if not) */
file_time, /* Job file retain time */
history_time, /* Job history retain time */

271
cups-str4396.patch Normal file
View File

@ -0,0 +1,271 @@
diff -up cups-1.7.5/CHANGES.txt.str4396 cups-1.7.5/CHANGES.txt
diff -up cups-1.7.5/scheduler/ipp.c.str4396 cups-1.7.5/scheduler/ipp.c
--- cups-1.7.5/scheduler/ipp.c.str4396 2014-08-20 16:56:29.012022421 +0100
+++ cups-1.7.5/scheduler/ipp.c 2014-08-20 16:56:38.535084011 +0100
@@ -6595,6 +6595,7 @@ get_jobs(cupsd_client_t *con, /* I - C
cupsd_job_t *job; /* Current job pointer */
cupsd_printer_t *printer; /* Printer */
cups_array_t *list; /* Which job list... */
+ int delete_list = 0; /* Delete the list afterwards? */
cups_array_t *ra, /* Requested attributes array */
*exclude; /* Private attributes array */
cupsd_policy_t *policy; /* Current policy */
@@ -6694,13 +6695,15 @@ get_jobs(cupsd_client_t *con, /* I - C
{
job_comparison = 1;
job_state = IPP_JOB_CANCELED;
- list = Jobs;
+ list = cupsdGetCompletedJobs(printer);
+ delete_list = 1;
}
else if (!strcmp(attr->values[0].string.text, "aborted"))
{
job_comparison = 0;
job_state = IPP_JOB_ABORTED;
- list = Jobs;
+ list = cupsdGetCompletedJobs(printer);
+ delete_list = 1;
}
else if (!strcmp(attr->values[0].string.text, "all"))
{
@@ -6712,7 +6715,8 @@ get_jobs(cupsd_client_t *con, /* I - C
{
job_comparison = 0;
job_state = IPP_JOB_CANCELED;
- list = Jobs;
+ list = cupsdGetCompletedJobs(printer);
+ delete_list = 1;
}
else if (!strcmp(attr->values[0].string.text, "pending"))
{
@@ -6919,6 +6923,9 @@ get_jobs(cupsd_client_t *con, /* I - C
cupsArrayDelete(ra);
+ if (delete_list)
+ cupsArrayDelete(list);
+
con->response->request.status.status_code = IPP_OK;
}
diff -up cups-1.7.5/scheduler/job.c.str4396 cups-1.7.5/scheduler/job.c
--- cups-1.7.5/scheduler/job.c.str4396 2014-08-20 16:56:29.013022427 +0100
+++ cups-1.7.5/scheduler/job.c 2014-08-20 16:56:38.537084024 +0100
@@ -130,6 +130,7 @@ static mime_filter_t gziptoany_filter =
*/
static int compare_active_jobs(void *first, void *second, void *data);
+static int compare_completed_jobs(void *first, void *second, void *data);
static int compare_jobs(void *first, void *second, void *data);
static void dump_job_history(cupsd_job_t *job);
static void finalize_job(cupsd_job_t *job, int set_job_state);
@@ -1568,6 +1569,30 @@ cupsdFindJob(int id) /* I - Job ID */
/*
+ * 'cupsdGetCompletedJobs()'- Generate a completed jobs list.
+ */
+
+cups_array_t * /* O - Array of jobs */
+cupsdGetCompletedJobs(
+ cupsd_printer_t *p) /* I - Printer */
+{
+ cups_array_t *list; /* Array of jobs */
+ cupsd_job_t *job; /* Current job */
+
+
+ list = cupsArrayNew(compare_completed_jobs, NULL);
+
+ for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
+ job;
+ job = (cupsd_job_t *)cupsArrayNext(Jobs))
+ if ((!p || !_cups_strcasecmp(p->name, job->dest)) && job->state_value >= IPP_JOB_STOPPED && job->completed_time)
+ cupsArrayAdd(list, job);
+
+ return (list);
+}
+
+
+/*
* 'cupsdGetPrinterJobCount()' - Get the number of pending, processing,
* or held jobs in a printer or class.
*/
@@ -1766,6 +1791,8 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J
(attr = ippFindAttribute(job->attrs, "time-at-completed",
IPP_TAG_INTEGER)) != NULL)
{
+ job->completed_time = attr->values[0].integer;
+
if (JobHistory < INT_MAX)
job->history_time = attr->values[0].integer + JobHistory;
else
@@ -2257,8 +2284,11 @@ cupsdSaveAllJobs(void)
{
cupsFilePrintf(fp, "<Job %d>\n", job->id);
cupsFilePrintf(fp, "State %d\n", job->state_value);
+ if (job->completed_time)
+ cupsFilePrintf(fp, "Completed %ld\n", (long)job->completed_time);
cupsFilePrintf(fp, "Priority %d\n", job->priority);
- cupsFilePrintf(fp, "HoldUntil %d\n", (int)job->hold_until);
+ if (job->hold_until)
+ cupsFilePrintf(fp, "HoldUntil %ld\n", (long)job->hold_until);
cupsFilePrintf(fp, "Username %s\n", job->username);
cupsFilePrintf(fp, "Destination %s\n", job->dest);
cupsFilePrintf(fp, "DestType %d\n", job->dtype);
@@ -2993,6 +3023,28 @@ compare_active_jobs(void *first, /* I -
/*
+ * 'compare_completed_jobs()' - Compare the job IDs and completion times of two jobs.
+ */
+
+static int /* O - Difference */
+compare_completed_jobs(void *first, /* I - First job */
+ void *second, /* I - Second job */
+ void *data) /* I - App data (not used) */
+{
+ int diff; /* Difference */
+
+
+ (void)data;
+
+ if ((diff = ((cupsd_job_t *)second)->completed_time -
+ ((cupsd_job_t *)first)->completed_time) != 0)
+ return (diff);
+ else
+ return (((cupsd_job_t *)first)->id - ((cupsd_job_t *)second)->id);
+}
+
+
+/*
* 'compare_jobs()' - Compare the job IDs of two jobs.
*/
@@ -4268,6 +4320,14 @@ load_job_cache(const char *filename) /*
if (job->state_value <= IPP_JOB_STOPPED && cupsdLoadJob(job))
cupsArrayAdd(ActiveJobs, job);
+ else if (job->state_value > IPP_JOB_STOPPED)
+ {
+ if (!job->completed_time)
+ {
+ cupsdLoadJob(job);
+ unload_job(job);
+ }
+ }
job = NULL;
}
@@ -4285,9 +4345,13 @@ load_job_cache(const char *filename) /*
else if (job->state_value > IPP_JOB_COMPLETED)
job->state_value = IPP_JOB_COMPLETED;
}
+ else if (!_cups_strcasecmp(line, "Completed"))
+ {
+ job->completed_time = strtol(value, NULL, 10);
+ }
else if (!_cups_strcasecmp(line, "HoldUntil"))
{
- job->hold_until = atoi(value);
+ job->hold_until = strtol(value, NULL, 10);
}
else if (!_cups_strcasecmp(line, "Priority"))
{
@@ -4625,6 +4689,8 @@ set_time(cupsd_job_t *job, /* I - Job t
if (!strcmp(name, "time-at-completed"))
{
+ job->completed_time = curtime;
+
if (JobHistory < INT_MAX && attr)
job->history_time = attr->values[0].integer + JobHistory;
else
diff -up cups-1.7.5/scheduler/job.h.str4396 cups-1.7.5/scheduler/job.h
--- cups-1.7.5/scheduler/job.h.str4396 2014-08-20 16:56:29.013022427 +0100
+++ cups-1.7.5/scheduler/job.h 2014-08-20 16:56:38.538084031 +0100
@@ -54,6 +54,7 @@ struct cupsd_job_s /**** Job request *
ipp_attribute_t *sheets; /* job-media-sheets-completed */
time_t access_time, /* Last access time */
cancel_time, /* When to cancel/send SIGTERM */
+ completed_time, /* When job was completed (0 if not) */
file_time, /* Job file retain time */
history_time, /* Job history retain time */
hold_until, /* Hold expiration date/time */
@@ -156,6 +157,7 @@ extern void cupsdDeleteJob(cupsd_job_t
cupsd_jobaction_t action);
extern cupsd_job_t *cupsdFindJob(int id);
extern void cupsdFreeAllJobs(void);
+extern cups_array_t *cupsdGetCompletedJobs(cupsd_printer_t *p);
extern int cupsdGetPrinterJobCount(const char *dest);
extern int cupsdGetUserJobCount(const char *username);
extern void cupsdLoadAllJobs(void);
diff -up cups-1.7.5/systemv/lpstat.c.str4396 cups-1.7.5/systemv/lpstat.c
--- cups-1.7.5/systemv/lpstat.c.str4396 2014-05-22 14:59:21.000000000 +0100
+++ cups-1.7.5/systemv/lpstat.c 2014-08-20 16:56:38.539084037 +0100
@@ -1316,7 +1316,8 @@ show_jobs(const char *dests, /* I - Des
const char *dest, /* Pointer into job-printer-uri */
*username, /* Pointer to job-originating-user-name */
*title, /* Pointer to job-name */
- *message; /* Pointer to job-printer-state-message */
+ *message, /* Pointer to job-printer-state-message */
+ *time_at; /* time-at-xxx attribute name to use */
int rank, /* Rank in queue */
jobid, /* job-id */
size; /* job-k-octets */
@@ -1332,7 +1333,8 @@ show_jobs(const char *dests, /* I - Des
"job-printer-state-message",
"job-printer-uri",
"job-state-reasons",
- "time-at-creation"
+ "time-at-creation",
+ "time-at-completed"
};
@@ -1398,6 +1400,13 @@ show_jobs(const char *dests, /* I - Des
* Loop through the job list and display them...
*/
+ if (!strcmp(which, "aborted") ||
+ !strcmp(which, "canceled") ||
+ !strcmp(which, "completed"))
+ time_at = "time-at-completed";
+ else
+ time_at = "time-at-creation";
+
rank = -1;
for (attr = response->attrs; attr != NULL; attr = attr->next)
@@ -1433,8 +1442,7 @@ show_jobs(const char *dests, /* I - Des
else if (!strcmp(attr->name, "job-k-octets") &&
attr->value_tag == IPP_TAG_INTEGER)
size = attr->values[0].integer;
- else if (!strcmp(attr->name, "time-at-creation") &&
- attr->value_tag == IPP_TAG_INTEGER)
+ else if (!strcmp(attr->name, time_at) && attr->value_tag == IPP_TAG_INTEGER)
jobtime = attr->values[0].integer;
else if (!strcmp(attr->name, "job-printer-state-message") &&
attr->value_tag == IPP_TAG_TEXT)
diff -up cups-1.7.5/test/5.5-lp.sh.str4396 cups-1.7.5/test/5.5-lp.sh
--- cups-1.7.5/test/5.5-lp.sh.str4396 2013-11-06 20:09:03.000000000 +0000
+++ cups-1.7.5/test/5.5-lp.sh 2014-08-20 16:56:38.540084044 +0100
@@ -79,6 +79,19 @@ echo ""
./waitjobs.sh
+echo "LPSTAT Completed Jobs Order Test"
+echo ""
+echo " lpstat -W completed -o"
+$VALGRIND ../systemv/lpstat -W completed -o | tee $BASE/lpstat-completed.txt
+if test "`uniq -d $BASE/lpstat-completed.txt`" != ""; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+
#
# End of "$Id: 5.5-lp.sh 11396 2013-11-06 20:09:03Z msweet $".
#

View File

@ -11,7 +11,7 @@ Summary: CUPS printing system
Name: cups
Epoch: 1
Version: 1.7.5
Release: 2%{?dist}
Release: 3%{?dist}
License: GPLv2
Url: http://www.cups.org/
Source: http://www.cups.org/software/%{version}/cups-%{version}-source.tar.bz2
@ -30,6 +30,7 @@ Source8: macros.cups
Patch1: cups-no-gzip-man.patch
Patch2: cups-system-auth.patch
Patch3: cups-multilib.patch
Patch4: cups-str4396.patch
Patch5: cups-banners.patch
Patch6: cups-serverbin-compat.patch
Patch7: cups-no-export-ssllibs.patch
@ -66,6 +67,7 @@ Patch37: cups-final-content-type.patch
Patch38: cups-journal.patch
Patch39: cups-synconclose.patch
Patch40: cups-str4461.patch
Patch41: cups-str2913.patch
Patch100: cups-lspp.patch
@ -181,6 +183,8 @@ Sends IPP requests to the specified URI and tests and/or displays the results.
%patch2 -p1 -b .system-auth
# Prevent multilib conflict in cups-config script.
%patch3 -p1 -b .multilib
# Upstream patch for STR #4396, pre-requisite for STR #2913 patch.
%patch4 -p1 -b .str4396
# Ignore rpm save/new files in the banners directory.
%patch5 -p1 -b .banners
# Use compatibility fallback path for ServerBin.
@ -255,6 +259,9 @@ Sends IPP requests to the specified URI and tests and/or displays the results.
%patch39 -p1 -b .synconclose
# Fix conf/log file reading for authenticated users (STR #4461).
%patch40 -p1 -b .str4461
# Upstream patch for STR #2913 to limit Get-Jobs replies to 500 jobs
# (bug #421671).
%patch41 -p1 -b .str2913
%if %lspp
# LSPP support.
@ -643,6 +650,11 @@ rm -f %{cups_serverbin}/backend/smb
%{_mandir}/man5/ipptoolfile.5.gz
%changelog
* Wed Aug 20 2014 Tim Waugh <twaugh@redhat.com> - 1:1.7.5-3
- Upstream patch for STR #4396, pre-requisite for STR #2913 patch.
- Upstream patch for STR #2913 to limit Get-Jobs replies to 500 jobs
(bug #421671).
* Mon Aug 11 2014 Tim Waugh <twaugh@redhat.com> - 1:1.7.5-2
- Fix conf/log file reading for authenticated users (STR #4461).