diff -up cups-1.4b2/scheduler/job.c.str3078 cups-1.4b2/scheduler/job.c --- cups-1.4b2/scheduler/job.c.str3078 2009-01-28 16:59:45.000000000 +0000 +++ cups-1.4b2/scheduler/job.c 2009-01-28 17:00:04.000000000 +0000 @@ -1049,7 +1049,7 @@ cupsdLoadAllJobs(void) * 'cupsdLoadJob()' - Load a single job... */ -void +int /* O - 1 on success, 0 on failure */ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ { char jobfile[1024]; /* Job filename */ @@ -1067,14 +1067,14 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J if (job->state_value > IPP_JOB_STOPPED) job->access_time = time(NULL); - return; + return (1); } if ((job->attrs = ippNew()) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Ran out of memory for job attributes!", job->id); - return; + return (0); } /* @@ -1089,9 +1089,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Unable to open job control file \"%s\" - %s!", job->id, jobfile, strerror(errno)); - ippDelete(job->attrs); - job->attrs = NULL; - return; + goto error; } if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, job->attrs) != IPP_DATA) @@ -1100,10 +1098,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J "[Job %d] Unable to read job control file \"%s\"!", job->id, jobfile); cupsFileClose(fp); - ippDelete(job->attrs); - job->attrs = NULL; - unlink(jobfile); - return; + goto error; } cupsFileClose(fp); @@ -1117,10 +1112,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Missing or bad time-at-creation attribute in " "control file!", job->id); - ippDelete(job->attrs); - job->attrs = NULL; - unlink(jobfile); - return; + goto error; } if ((job->state = ippFindAttribute(job->attrs, "job-state", @@ -1129,10 +1121,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Missing or bad job-state attribute in control " "file!", job->id); - ippDelete(job->attrs); - job->attrs = NULL; - unlink(jobfile); - return; + goto error; } job->state_value = (ipp_jstate_t)job->state->values[0].integer; @@ -1145,10 +1134,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] No job-printer-uri attribute in control file!", job->id); - ippDelete(job->attrs); - job->attrs = NULL; - unlink(jobfile); - return; + goto error; } if ((dest = cupsdValidateDest(attr->values[0].string.text, &(job->dtype), @@ -1157,10 +1143,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Unable to queue job for destination \"%s\"!", job->id, attr->values[0].string.text); - ippDelete(job->attrs); - job->attrs = NULL; - unlink(jobfile); - return; + goto error; } cupsdSetString(&job->dest, dest); @@ -1170,10 +1153,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Unable to queue job for destination \"%s\"!", job->id, job->dest); - ippDelete(job->attrs); - job->attrs = NULL; - unlink(jobfile); - return; + goto error; } job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed", @@ -1188,10 +1168,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Missing or bad job-priority attribute in " "control file!", job->id); - ippDelete(job->attrs); - job->attrs = NULL; - unlink(jobfile); - return; + goto error; } job->priority = attr->values[0].integer; @@ -1205,10 +1182,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Missing or bad job-originating-user-name " "attribute in control file!", job->id); - ippDelete(job->attrs); - job->attrs = NULL; - unlink(jobfile); - return; + goto error; } cupsdSetString(&job->username, attr->values[0].string.text); @@ -1277,7 +1251,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Ran out of memory for job file types!", job->id); - return; + return (1); } job->compressions = compressions; @@ -1335,6 +1309,18 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J } job->access_time = time(NULL); + return (1); + + /* + * If we get here then something bad happened... + */ + + error: + + ippDelete(job->attrs); + job->attrs = NULL; + unlink(jobfile); + return (0); } diff -up cups-1.4b2/scheduler/job.h.str3078 cups-1.4b2/scheduler/job.h --- cups-1.4b2/scheduler/job.h.str3078 2008-08-28 21:38:13.000000000 +0100 +++ cups-1.4b2/scheduler/job.h 2009-01-28 17:00:04.000000000 +0000 @@ -3,7 +3,7 @@ * * Print job definitions for the Common UNIX Printing System (CUPS) scheduler. * - * Copyright 2007-2008 by Apple Inc. + * Copyright 2007-2009 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -117,7 +117,7 @@ extern int cupsdGetPrinterJobCount(cons extern int cupsdGetUserJobCount(const char *username); extern void cupsdHoldJob(cupsd_job_t *job); extern void cupsdLoadAllJobs(void); -extern void cupsdLoadJob(cupsd_job_t *job); +extern int cupsdLoadJob(cupsd_job_t *job); extern void cupsdMoveJob(cupsd_job_t *job, cupsd_printer_t *p); extern void cupsdReleaseJob(cupsd_job_t *job); extern void cupsdRestartJob(cupsd_job_t *job); diff -up cups-1.4b2/scheduler/quotas.c.str3078 cups-1.4b2/scheduler/quotas.c --- cups-1.4b2/scheduler/quotas.c.str3078 2007-09-12 22:09:49.000000000 +0100 +++ cups-1.4b2/scheduler/quotas.c 2009-01-28 17:00:04.000000000 +0000 @@ -3,7 +3,7 @@ * * Quota routines for the Common UNIX Printing System (CUPS). * - * Copyright 2007 by Apple Inc. + * Copyright 2007-2009 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -155,10 +155,22 @@ cupsdUpdateQuota( job; job = (cupsd_job_t *)cupsArrayNext(Jobs)) { + /* + * We only care about the current printer/class and user... + */ + if (strcasecmp(job->dest, p->name) != 0 || strcasecmp(job->username, q->username) != 0) continue; + /* + * Make sure attributes are loaded; we always call cupsdLoadJob() to ensure + * the access_time member is updated so the job isn't unloaded right away... + */ + + if (!cupsdLoadJob(job)) + continue; + if ((attr = ippFindAttribute(job->attrs, "time-at-completion", IPP_TAG_INTEGER)) == NULL) if ((attr = ippFindAttribute(job->attrs, "time-at-processing", @@ -166,11 +178,22 @@ cupsdUpdateQuota( attr = ippFindAttribute(job->attrs, "time-at-creation", IPP_TAG_INTEGER); - if (attr == NULL) - break; + if (!attr) + { + /* + * This should never happen since cupsdLoadJob() checks for + * time-at-creation, but if it does just ignore this job... + */ + + continue; + } if (attr->values[0].integer < curtime) { + /* + * This job is too old to count towards the quota, ignore it... + */ + if (JobAutoPurge) cupsdCancelJob(job, 1, IPP_JOB_CANCELED);