- Documentation fixes (STR #2994, STR #2995, STR #3008, STR #3056,
STR #3057)
+ - The fallback OpenSSL random number seeding would not work (STR #3079)
+ - The scheduler might miss a child signal, causing high CPU usage.
+ - The scheduler did not enforce quotas after the job history was
+ unloaded (STR #3078)
+ - The job-k-limit, job-page-limit, and job-quota-period attributes
+ could not be set using the lpadmin command (STR #3077)
+ - httpSeparateURI() did not error out on URIs with a missing port
+ number after a colon.
- Fixed a Valgrind-detected initialization error when creating a
missing directory on startup.
- The scheduler did not always read all of the HTTP headers from a
-CHANGES.txt - 2009-01-23
+CHANGES.txt - 2009-01-28
------------------------
CHANGES IN CUPS V1.4b3
- Documentation fixes (STR #3044, STR #3057)
+ - The scheduler now provides a LogTimeFormat directive to enable
+ microseconds in the date and time that are logged.
+ - The scheduler now provides a MultipleOperationTimeout directive to
+ control the timeout for multi-file print jobs.
- The configure script incorrectly allowed Avahi to be used for DNS-SD
printer discovery (STR #3065)
- The web interface and scheduler did not support URIs up to 1024 bytes
{ 0, "hue-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 1, "include-schemes", IPP_TAG_NAME, IPP_TAG_OPERATION },
{ 0, "job-impressions", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { 0, "job-k-limit", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { 0, "job-page-limit", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "job-k-limit", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "job-page-limit", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "job-priority", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { 0, "job-quota-period", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "job-quota-period", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 1, "job-sheets", IPP_TAG_NAME, IPP_TAG_JOB },
{ 1, "job-sheets-default", IPP_TAG_NAME, IPP_TAG_PRINTER },
{ 0, "job-uuid", IPP_TAG_URI, IPP_TAG_JOB },
*
* HTTP support routines 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
* Yes, collect the port number...
*/
+ if (!isdigit(uri[1] & 255))
+ {
+ *port = 0;
+ return (HTTP_URI_BAD_PORT);
+ }
+
*port = strtol(uri + 1, (char **)&uri, 10);
if (*uri != '/' && *uri)
const char *uri, /* I - DNS-SD URI */
char *resolved_uri, /* I - Buffer for resolved URI */
size_t resolved_size, /* I - Size of URI buffer */
- int log) /* I - Log progress to stderr? */
+ int logit) /* I - Log progress to stderr? */
{
char scheme[32], /* URI components... */
userpass[256],
sizeof(resource)) < HTTP_URI_OK)
#endif /* DEBUG */
{
- if (log)
+ if (logit)
_cupsLangPrintf(stderr, _("Bad device URI \"%s\"!\n"), uri);
DEBUG_printf(("_httpResolveURI: httpSeparateURI returned %d!\n", status));
DEBUG_printf(("_httpResolveURI: Resolving hostname=\"%s\", regtype=\"%s\", "
"domain=\"%s\"\n", hostname, regtype, domain));
- if (log)
+ if (logit)
{
fputs("STATE: +connecting-to-device\n", stderr);
fprintf(stderr, "DEBUG: Resolving %s, regtype=%s, domain=%s...\n",
else
uri = NULL;
- if (log)
+ if (logit)
fputs("STATE: -connecting-to-device\n", stderr);
#else
uri = NULL;
#endif /* HAVE_DNSSD */
- if (log && !uri)
+ if (logit && !uri)
_cupsLangPuts(stderr, _("Unable to find printer!\n"));
}
* it is the best we can do (on others, this seed isn't even used...)
*/
-#ifdef WIN32
-#else
+# ifdef WIN32
+# else
gettimeofday(&curtime, NULL);
srand(curtime.tv_sec + curtime.tv_usec);
-#endif /* WIN32 */
+# endif /* WIN32 */
for (i = 0; i < sizeof(data); i ++)
- data[i] = rand(); /* Yes, this is a poor source of random data... */
+ data[i] = rand();
- RAND_seed(&data, sizeof(data));
+ RAND_seed(data, sizeof(data));
#endif /* HAVE_LIBSSL */
}
*
* CUPS API test program for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007-2008 by Apple Inc.
+ * Copyright 2007-2009 by Apple Inc.
* Copyright 2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
#include <stdio.h>
#include <stdlib.h>
#include "cups.h"
+#include "string.h"
+#include <errno.h>
/*
cups_job_t *jobs; /* Jobs for queue */
+ if (argc > 1)
+ {
+ /*
+ * ./testcups printer file interval
+ */
+
+ int interval, /* Interval between writes */
+ job_id; /* Job ID */
+ cups_file_t *fp; /* Print file */
+ char buffer[16384]; /* Read/write buffer */
+ ssize_t bytes; /* Bytes read/written */
+
+
+ if (argc != 4)
+ {
+ puts("Usage: ./testcups");
+ puts(" ./testcups printer file interval");
+ return (1);
+ }
+
+ if ((fp = cupsFileOpen(argv[2], "r")) == NULL)
+ {
+ printf("Unable to open \"%s\": %s\n", argv[2], strerror(errno));
+ return (1);
+ }
+
+ if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, argv[1], "testcups", 0,
+ NULL)) <= 0)
+ {
+ printf("Unable to create print job on %s: %s\n", argv[1],
+ cupsLastErrorString());
+ return (1);
+ }
+
+ interval = atoi(argv[3]);
+
+ if (cupsStartDocument(CUPS_HTTP_DEFAULT, argv[1], job_id, argv[2],
+ CUPS_FORMAT_AUTO, 1) != HTTP_CONTINUE)
+ {
+ puts("Unable to start document!");
+ return (1);
+ }
+
+ while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
+ {
+ printf("Writing %d bytes...\n", (int)bytes);
+
+ if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer,
+ bytes) != HTTP_CONTINUE)
+ {
+ puts("Unable to write bytes!");
+ return (1);
+ }
+
+ sleep(interval);
+ }
+
+ cupsFileClose(fp);
+
+ if (cupsFinishDocument(CUPS_HTTP_DEFAULT, argv[1]) != HTTP_OK)
+ {
+ puts("Unable to finish document!");
+ return (1);
+ }
+
+ return (0);
+ }
+
/*
* cupsGetDests()
*/
*
* HTTP test program for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007-2008 by Apple Inc.
+ * Copyright 2007-2009 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
return (0);
}
}
+ else if (!strcmp(argv[1], "-u") && argc == 3)
+ {
+ /*
+ * Test URI separation...
+ */
+
+ uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, argv[2], scheme,
+ sizeof(scheme), username, sizeof(username),
+ hostname, sizeof(hostname), &port,
+ resource, sizeof(resource));
+ printf("uri_status = %s\n", uri_status_strings[uri_status + 8]);
+ printf("scheme = \"%s\"\n", scheme);
+ printf("username = \"%s\"\n", username);
+ printf("hostname = \"%s\"\n", hostname);
+ printf("port = %d\n", port);
+ printf("resource = \"%s\"\n", resource);
+
+ return (0);
+ }
/*
* Test HTTP GET requests...
<p>The default <code>LogLevel</code> is <code>@CUPS_LOG_LEVEL@</code>.</p>
+<H2 CLASS="title"><A NAME="LogTimeFormat">LogTimeFormat</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+LogTimeFormat standard
+LogTimeFormat usecs
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>LogTimeFormat</CODE> directive specifies the format used for the
+date and time in the log files. <CODE>Standard</CODE> uses the standard Apache
+Common Log Format date and time while <CODE>usecs</CODE> adds microseconds.
+The default is <CODE>standard</CODE>.</P>
+
+
<H2 CLASS="title"><A NAME="MaxClients">MaxClients</A></H2>
<H3>Examples</H3>
directive instead.</P>
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.4</SPAN><A NAME="MultipleOperationTimeout">MultipleOperationTimeout</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+MultipleOperationTimeout 60
+MultipleOperationTimeout 300
+MultipleOperationTimeout 86400
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>MultipleOperationTimeout</CODE> directive sets the maximum amount
+of time between files in a multi-file print job. The default is 300 seconds.</P>
+
+
<H2 CLASS="title"><A NAME="Order">Order</A></H2>
<H3>Examples</H3>
int num_options; /* Number of options */
cups_option_t *options; /* Options */
const char *val; /* Option value */
- int orientation; /* Output orientation */
+ int orientation, /* Output orientation */
+ fit; /* Fit output to default page size? */
ppd_file_t *ppd; /* PPD file */
ppd_size_t *size; /* Current page size */
int pdfpid, /* Process ID for pdftops */
pdfargv[pdfargc++] = (char *)"-dLanguageLevel=3";
#endif /* HAVE_PDFTOPS */
+ if ((val = cupsGetOption("fitplot", num_options, options)) == NULL)
+ val = cupsGetOption("fit-to-page", num_options, options);
+
+ if (val && strcasecmp(val, "no") && strcasecmp(val, "off") &&
+ strcasecmp(val, "false"))
+ fit = 1;
+ else
+ fit = 0;
+
/*
* Set output page size...
*/
size = ppdPageSize(ppd, NULL);
- if (size &&
- (cupsGetOption("media", num_options, options) ||
- cupsGetOption("media-col", num_options, options) ||
- cupsGetOption("PageRegion", num_options, options) ||
- cupsGetOption("PageSize", num_options, options))
+ if (size && fit)
{
/*
* Got the size, now get the orientation...
pdfargv[pdfargc++] = pdfwidth;
pdfargv[pdfargc++] = (char *)"-paperh";
pdfargv[pdfargc++] = pdfheight;
-
- if ((val = cupsGetOption("fitplot", num_options, options)) != NULL &&
- strcasecmp(val, "no") && strcasecmp(val, "off") &&
- strcasecmp(val, "false"))
- pdfargv[pdfargc++] = (char *)"-expand";
+ pdfargv[pdfargc++] = (char *)"-expand";
#else
if (orientation & 1)
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH cupsd.conf 5 "Common UNIX Printing System" "8 December 2008" "Apple Inc."
+.TH cupsd.conf 5 "Common UNIX Printing System" "28 January 2009" "Apple Inc."
.SH NAME
cupsd.conf \- server configuration file for cups
.SH DESCRIPTION
.br
Specifies the logging level for the ErrorLog file.
.TP 5
+LogTimeFormat standard
+.TP 5
+LogTimeFormat usecs
+.br
+Specifies the format of the date and time in the log files.
+.TP 5
MaxClients number
.br
Specifies the maximum number of simultaneous clients to support.
.br
Specifies the maximum request/file size in bytes (0 for no limit)
.TP 5
+MultipleOperationTimeout seconds
+.br
+Specifies the maximum amount of time to allow between files in a multiple file
+print job.
+.TP 5
Order allow,deny
.TP 5
Order deny,allow
return;
}
- con->start = time(NULL);
+ gettimeofday(&(con->start), NULL);
con->operation = con->http.state;
cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %d %s %s HTTP/%d.%d",
ipp_t *request, /* IPP request information */
*response; /* IPP response information */
cupsd_location_t *best; /* Best match for AAA */
- time_t start; /* Request start time */
+ struct timeval start; /* Request start time */
http_state_t operation; /* Request operation */
off_t bytes; /* Bytes transferred for this request */
int type; /* AuthType for username */
{ "MaxSubscriptionsPerJob", &MaxSubscriptionsPerJob, CUPSD_VARTYPE_INTEGER },
{ "MaxSubscriptionsPerPrinter",&MaxSubscriptionsPerPrinter, CUPSD_VARTYPE_INTEGER },
{ "MaxSubscriptionsPerUser", &MaxSubscriptionsPerUser, CUPSD_VARTYPE_INTEGER },
+ { "MultipleOperationTimeout", &MultipleOperationTimeout, CUPSD_VARTYPE_INTEGER },
{ "PageLog", &PageLog, CUPSD_VARTYPE_STRING },
{ "PageLogFormat", &PageLogFormat, CUPSD_VARTYPE_STRING },
{ "PreserveJobFiles", &JobFiles, CUPSD_VARTYPE_BOOLEAN },
* Numeric options...
*/
- AccessLogLevel = CUPSD_ACCESSLOG_ACTIONS;
- ConfigFilePerm = CUPS_DEFAULT_CONFIG_FILE_PERM;
- FatalErrors = parse_fatal_errors(CUPS_DEFAULT_FATAL_ERRORS);
- DefaultAuthType = CUPSD_AUTH_BASIC;
+ AccessLogLevel = CUPSD_ACCESSLOG_ACTIONS;
+ ConfigFilePerm = CUPS_DEFAULT_CONFIG_FILE_PERM;
+ FatalErrors = parse_fatal_errors(CUPS_DEFAULT_FATAL_ERRORS);
+ DefaultAuthType = CUPSD_AUTH_BASIC;
#ifdef HAVE_SSL
- DefaultEncryption = HTTP_ENCRYPT_REQUIRED;
- SSLOptions = CUPSD_SSL_NONE;
+ DefaultEncryption = HTTP_ENCRYPT_REQUIRED;
+ SSLOptions = CUPSD_SSL_NONE;
#endif /* HAVE_SSL */
- DirtyCleanInterval = DEFAULT_KEEPALIVE;
- JobRetryLimit = 5;
- JobRetryInterval = 300;
- FileDevice = FALSE;
- FilterLevel = 0;
- FilterLimit = 0;
- FilterNice = 0;
- HostNameLookups = FALSE;
- ImplicitClasses = CUPS_DEFAULT_IMPLICIT_CLASSES;
- ImplicitAnyClasses = FALSE;
- HideImplicitMembers = TRUE;
- KeepAlive = TRUE;
- KeepAliveTimeout = DEFAULT_KEEPALIVE;
- ListenBackLog = SOMAXCONN;
- LogFilePerm = CUPS_DEFAULT_LOG_FILE_PERM;
- LogLevel = CUPSD_LOG_WARN;
- MaxClients = 100;
- MaxClientsPerHost = 0;
- MaxLogSize = 1024 * 1024;
- MaxPrinterHistory = 10;
- MaxRequestSize = 0;
- ReloadTimeout = DEFAULT_KEEPALIVE;
- RootCertDuration = 300;
- Timeout = DEFAULT_TIMEOUT;
- NumSystemGroups = 0;
-
- BrowseInterval = DEFAULT_INTERVAL;
- BrowsePort = ippPort();
- BrowseLocalProtocols = parse_protocols(CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS);
- BrowseRemoteProtocols = parse_protocols(CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS);
- BrowseShortNames = CUPS_DEFAULT_BROWSE_SHORT_NAMES;
- BrowseTimeout = DEFAULT_TIMEOUT;
- BrowseWebIF = FALSE;
- Browsing = CUPS_DEFAULT_BROWSING;
- DefaultShared = CUPS_DEFAULT_DEFAULT_SHARED;
+ DirtyCleanInterval = DEFAULT_KEEPALIVE;
+ JobRetryLimit = 5;
+ JobRetryInterval = 300;
+ FileDevice = FALSE;
+ FilterLevel = 0;
+ FilterLimit = 0;
+ FilterNice = 0;
+ HostNameLookups = FALSE;
+ ImplicitClasses = CUPS_DEFAULT_IMPLICIT_CLASSES;
+ ImplicitAnyClasses = FALSE;
+ HideImplicitMembers = TRUE;
+ KeepAlive = TRUE;
+ KeepAliveTimeout = DEFAULT_KEEPALIVE;
+ ListenBackLog = SOMAXCONN;
+ LogFilePerm = CUPS_DEFAULT_LOG_FILE_PERM;
+ LogLevel = CUPSD_LOG_WARN;
+ LogTimeFormat = CUPSD_TIME_STANDARD;
+ MaxClients = 100;
+ MaxClientsPerHost = 0;
+ MaxLogSize = 1024 * 1024;
+ MaxPrinterHistory = 10;
+ MaxRequestSize = 0;
+ MultipleOperationTimeout = DEFAULT_TIMEOUT;
+ ReloadTimeout = DEFAULT_KEEPALIVE;
+ RootCertDuration = 300;
+ Timeout = DEFAULT_TIMEOUT;
+ NumSystemGroups = 0;
+
+ BrowseInterval = DEFAULT_INTERVAL;
+ BrowsePort = ippPort();
+ BrowseLocalProtocols = parse_protocols(CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS);
+ BrowseRemoteProtocols = parse_protocols(CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS);
+ BrowseShortNames = CUPS_DEFAULT_BROWSE_SHORT_NAMES;
+ BrowseTimeout = DEFAULT_TIMEOUT;
+ BrowseWebIF = FALSE;
+ Browsing = CUPS_DEFAULT_BROWSING;
+ DefaultShared = CUPS_DEFAULT_DEFAULT_SHARED;
cupsdSetString(&LPDConfigFile, CUPS_DEFAULT_LPD_CONFIG_FILE);
cupsdSetString(&SMBConfigFile, CUPS_DEFAULT_SMB_CONFIG_FILE);
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogLevel %s on line %d.",
value, linenum);
}
+ else if (!strcasecmp(line, "LogTimeFormat") && value)
+ {
+ /*
+ * Amount of logging to do to error log...
+ */
+
+ if (!strcasecmp(value, "standard"))
+ LogTimeFormat = CUPSD_TIME_STANDARD;
+ else if (!strcasecmp(value, "usecs"))
+ LogTimeFormat = CUPSD_TIME_USECS;
+ else
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogTimeFormat %s on line %d.",
+ value, linenum);
+ }
else if (!strcasecmp(line, "PrintcapFormat") && value)
{
/*
* Configuration file 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
CUPSD_ACCESSLOG_ALL /* Log everything */
} cupsd_accesslog_t;
+typedef enum
+{
+ CUPSD_TIME_STANDARD, /* "Standard" Apache/CLF format */
+ CUPSD_TIME_USECS /* Standard format with microseconds */
+} cupsd_time_t;
+
/*
* FatalErrors flags...
/* User ID for server */
VAR gid_t Group VALUE(0);
/* Group ID for server */
-VAR int AccessLogLevel VALUE(CUPSD_ACCESSLOG_ACTIONS),
+VAR cupsd_accesslog_t AccessLogLevel VALUE(CUPSD_ACCESSLOG_ACTIONS);
/* Access log level */
- ClassifyOverride VALUE(0),
+VAR int ClassifyOverride VALUE(0),
/* Allow overrides? */
ConfigFilePerm VALUE(0640),
/* Permissions for config files */
FatalErrors VALUE(CUPSD_FATAL_CONFIG),
/* Which errors are fatal? */
- LogFilePerm VALUE(0644),
+ LogFilePerm VALUE(0644);
/* Permissions for log files */
- LogLevel VALUE(CUPSD_LOG_WARN),
+VAR cupsd_loglevel_t LogLevel VALUE(CUPSD_LOG_WARN);
/* Error log level */
- MaxClients VALUE(100),
+VAR cupsd_time_t LogTimeFormat VALUE(CUPSD_TIME_STANDARD);
+ /* Log file time format */
+VAR int MaxClients VALUE(100),
/* Maximum number of clients */
MaxClientsPerHost VALUE(0),
/* Maximum number of clients per host */
/* User to run as, used for files */
PrintcapFormat VALUE(PRINTCAP_BSD),
/* Format of printcap file? */
- DefaultShared VALUE(TRUE);
+ DefaultShared VALUE(TRUE),
/* Share printers by default? */
+ MultipleOperationTimeout VALUE(DEFAULT_TIMEOUT);
+ /* multiple-operation-time-out value */
VAR cups_file_t *AccessFile VALUE(NULL),
/* Access log file */
*ErrorFile VALUE(NULL),
const char *suffix, int mode,
int user, int group, int is_dir,
int create_dir);
-extern char *cupsdGetDateTime(time_t t);
+extern char *cupsdGetDateTime(struct timeval *t, cupsd_time_t format);
#ifdef HAVE_GSSAPI
extern int cupsdLogGSSMessage(int level, int major_status,
int minor_status,
}
else if (job->attrs->request.op.operation_id == IPP_CREATE_JOB)
{
- job->hold_until = time(NULL) + 60;
+ job->hold_until = time(NULL) + MultipleOperationTimeout;
job->state->values[0].integer = IPP_JOB_HELD;
job->state_value = IPP_JOB_HELD;
}
case IPP_TAG_INTEGER :
case IPP_TAG_ENUM :
if (!strncmp(s, "time-at-", 8))
- cupsFilePuts(out, cupsdGetDateTime(attr->values[i].integer));
+ {
+ struct timeval tv = { attr->values[i].integer, 0 };
+ cupsFilePuts(out, cupsdGetDateTime(&tv, CUPSD_TIME_STANDARD));
+ }
else
cupsFilePrintf(out, "%d", attr->values[i].integer);
break;
{
job->state->values[0].integer = IPP_JOB_HELD;
job->state_value = IPP_JOB_HELD;
- job->hold_until = time(NULL) + 60;
+ job->hold_until = time(NULL) + MultipleOperationTimeout;
job->dirty = 1;
cupsdMarkDirty(CUPSD_DIRTY_JOBS);
{
if (job->pending_timeout)
{
- /* Add trailing banner as needed */
+ /*
+ * This job is pending; check that we don't have an active Send-Document
+ * operation in progress on any of the client connections, then timeout
+ * the job so we can start printing...
+ */
+
+ cupsd_client_t *con; /* Current client connection */
+
+
+ for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
+ con;
+ con = (cupsd_client_t *)cupsArrayNext(Clients))
+ if (con->request &&
+ con->request->request.op.operation_id == IPP_SEND_DOCUMENT)
+ break;
+
+ if (con)
+ continue;
+
if (cupsdTimeoutJob(job))
continue;
}
* '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 */
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);
}
/*
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)
"[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);
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",
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;
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),
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);
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",
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;
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);
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Ran out of memory for job file types!",
job->id);
- return;
+ return (1);
}
job->compressions = compressions;
}
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);
}
*
* 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
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);
*
* Log file routines for the Common UNIX Printing System (CUPS).
*
- * 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
*/
char * /* O - Date/time string */
-cupsdGetDateTime(time_t t) /* I - Time value */
+cupsdGetDateTime(struct timeval *t, /* I - Time value or NULL for current */
+ cupsd_time_t format) /* I - Format to use */
{
- struct tm *date; /* Date/time value */
- static time_t last_time = -1; /* Last time value */
- static char s[1024]; /* Date/time string */
+ struct timeval curtime; /* Current time value */
+ struct tm *date; /* Date/time value */
+ static struct timeval last_time = { 0, 0 };
+ /* Last time we formatted */
+ static char s[1024]; /* Date/time string */
static const char * const months[12] =/* Months */
{
"Jan",
*/
if (!t)
- t = time(NULL);
+ {
+ gettimeofday(&curtime, NULL);
+ t = &curtime;
+ }
- if (t != last_time)
+ if (t->tv_sec != last_time.tv_sec ||
+ (LogTimeFormat == CUPSD_TIME_USECS && t->tv_usec != last_time.tv_usec))
{
- last_time = t;
+ last_time = *t;
/*
* Get the date and time from the UNIX time value, and then format it
* (*BSD and Darwin store the timezone offset in the tm structure)
*/
- date = localtime(&t);
+ date = localtime(&(t->tv_sec));
- snprintf(s, sizeof(s), "[%02d/%s/%04d:%02d:%02d:%02d %+03ld%02ld]",
- date->tm_mday, months[date->tm_mon], 1900 + date->tm_year,
- date->tm_hour, date->tm_min, date->tm_sec,
+ if (format == CUPSD_TIME_STANDARD)
+ snprintf(s, sizeof(s), "[%02d/%s/%04d:%02d:%02d:%02d %+03ld%02ld]",
+ date->tm_mday, months[date->tm_mon], 1900 + date->tm_year,
+ date->tm_hour, date->tm_min, date->tm_sec,
+#ifdef HAVE_TM_GMTOFF
+ date->tm_gmtoff / 3600, (date->tm_gmtoff / 60) % 60);
+#else
+ timezone / 3600, (timezone / 60) % 60);
+#endif /* HAVE_TM_GMTOFF */
+ else
+ snprintf(s, sizeof(s), "[%02d/%s/%04d:%02d:%02d:%02d.%06d %+03ld%02ld]",
+ date->tm_mday, months[date->tm_mon], 1900 + date->tm_year,
+ date->tm_hour, date->tm_min, date->tm_sec, t->tv_usec,
#ifdef HAVE_TM_GMTOFF
- date->tm_gmtoff / 3600, (date->tm_gmtoff / 60) % 60);
+ date->tm_gmtoff / 3600, (date->tm_gmtoff / 60) % 60);
#else
- timezone / 3600, (timezone / 60) % 60);
+ timezone / 3600, (timezone / 60) % 60);
#endif /* HAVE_TM_GMTOFF */
}
break;
case 'T' : /* Date and time */
- strlcpy(bufptr, cupsdGetDateTime(time(NULL)),
+ strlcpy(bufptr, cupsdGetDateTime(NULL, LogTimeFormat),
sizeof(buffer) - (bufptr - buffer));
bufptr += strlen(bufptr);
break;
cupsFilePrintf(AccessFile,
"%s - %s %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n",
con->http.hostname, con->username[0] != '\0' ? con->username : "-",
- cupsdGetDateTime(con->start), states[con->operation],
+ cupsdGetDateTime(&(con->start), LogTimeFormat),
+ states[con->operation],
_httpEncodeURI(temp, con->uri, sizeof(temp)),
con->http.version / 100, con->http.version % 100,
code, CUPS_LLCAST con->bytes,
*/
cupsFilePrintf(ErrorFile, "%c %s %s\n", levels[level],
- cupsdGetDateTime(time(NULL)), message);
+ cupsdGetDateTime(NULL, LogTimeFormat), message);
cupsFileFlush(ErrorFile);
return (1);
*
* Scheduler main loop for the Common UNIX Printing System (CUPS).
*
- * 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
cupsdLogMessage(CUPSD_LOG_DEBUG, "PID %d (%s) exited with no errors.",
pid, name);
}
+
+ /*
+ * If wait*() is interrupted by a signal, tell main() to call us again...
+ */
+
+ if (pid < 0 && errno == EINTR)
+ dead_children = 1;
}
/* multiple-operation-time-out */
ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
- "multiple-operation-time-out", 60);
+ "multiple-operation-time-out", MultipleOperationTimeout);
/* natural-language-configured */
ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE | IPP_TAG_COPY,
*
* 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
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",
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);