From dfd5680b8770f4dd462a90a7a6579aa9523e484f Mon Sep 17 00:00:00 2001
From: msweet
Date: Thu, 29 Jan 2009 18:07:00 +0000
Subject: [PATCH] Merge changes from CUPS 1.4svn-r8305.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@1166 a1ca3aef-8c08-0410-bb20-df032aa958be
---
CHANGES-1.3.txt | 8 +++
CHANGES.txt | 6 +-
cups/encode.c | 6 +-
cups/http-support.c | 18 ++++--
cups/http.c | 10 ++--
cups/testcups.c | 72 +++++++++++++++++++++++-
cups/testhttp.c | 21 ++++++-
doc/help/ref-cupsd-conf.html.in | 33 +++++++++++
filter/pdftops.c | 24 ++++----
man/cupsd.conf.man.in | 13 ++++-
scheduler/client.c | 2 +-
scheduler/client.h | 2 +-
scheduler/conf.c | 99 +++++++++++++++++++--------------
scheduler/conf.h | 26 ++++++---
scheduler/ipp.c | 9 ++-
scheduler/job.c | 84 +++++++++++++++-------------
scheduler/job.h | 4 +-
scheduler/log.c | 52 +++++++++++------
scheduler/main.c | 9 ++-
scheduler/printers.c | 2 +-
scheduler/quotas.c | 29 +++++++++-
21 files changed, 382 insertions(+), 147 deletions(-)
diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt
index 84ea4a62c..a61242939 100644
--- a/CHANGES-1.3.txt
+++ b/CHANGES-1.3.txt
@@ -5,6 +5,14 @@ CHANGES IN CUPS V1.3.10
- 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
diff --git a/CHANGES.txt b/CHANGES.txt
index cdf0e7445..e5318137d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,9 +1,13 @@
-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
diff --git a/cups/encode.c b/cups/encode.c
index f098844e6..7ef63c915 100644
--- a/cups/encode.c
+++ b/cups/encode.c
@@ -70,10 +70,10 @@ static const _ipp_option_t ipp_options[] =
{ 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 },
diff --git a/cups/http-support.c b/cups/http-support.c
index a2d227e53..7bcdd4fca 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -3,7 +3,7 @@
*
* 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
@@ -1088,6 +1088,12 @@ httpSeparateURI(
* 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)
@@ -1291,7 +1297,7 @@ _httpResolveURI(
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],
@@ -1323,7 +1329,7 @@ _httpResolveURI(
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));
@@ -1386,7 +1392,7 @@ _httpResolveURI(
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",
@@ -1409,7 +1415,7 @@ _httpResolveURI(
else
uri = NULL;
- if (log)
+ if (logit)
fputs("STATE: -connecting-to-device\n", stderr);
#else
@@ -1420,7 +1426,7 @@ _httpResolveURI(
uri = NULL;
#endif /* HAVE_DNSSD */
- if (log && !uri)
+ if (logit && !uri)
_cupsLangPuts(stderr, _("Unable to find printer!\n"));
}
diff --git a/cups/http.c b/cups/http.c
index 459730ef9..4d4ef2a7a 100644
--- a/cups/http.c
+++ b/cups/http.c
@@ -1188,16 +1188,16 @@ httpInitialize(void)
* 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 */
}
diff --git a/cups/testcups.c b/cups/testcups.c
index 834e08a90..555df69a5 100644
--- a/cups/testcups.c
+++ b/cups/testcups.c
@@ -3,7 +3,7 @@
*
* 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
@@ -27,6 +27,8 @@
#include
#include
#include "cups.h"
+#include "string.h"
+#include
/*
@@ -57,6 +59,74 @@ main(int argc, /* I - Number of command-line arguments */
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()
*/
diff --git a/cups/testhttp.c b/cups/testhttp.c
index a197d5a87..fda2147b2 100644
--- a/cups/testhttp.c
+++ b/cups/testhttp.c
@@ -3,7 +3,7 @@
*
* 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
@@ -479,6 +479,25 @@ main(int argc, /* I - Number of command-line arguments */
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...
diff --git a/doc/help/ref-cupsd-conf.html.in b/doc/help/ref-cupsd-conf.html.in
index 6c51b9d99..8cefdf43d 100644
--- a/doc/help/ref-cupsd-conf.html.in
+++ b/doc/help/ref-cupsd-conf.html.in
@@ -2032,6 +2032,23 @@ everything under the preceding levels):
The default LogLevel
is @CUPS_LOG_LEVEL@
.
+
+
+Examples
+
+
+LogTimeFormat standard
+LogTimeFormat usecs
+
+
+Description
+
+The LogTimeFormat
directive specifies the format used for the
+date and time in the log files. Standard
uses the standard Apache
+Common Log Format date and time while usecs
adds microseconds.
+The default is standard
.
+
+
Examples
@@ -2210,6 +2227,22 @@ HREF="#LimitRequestBody">LimitRequestBody
directive instead.
+
+
+Examples
+
+
+MultipleOperationTimeout 60
+MultipleOperationTimeout 300
+MultipleOperationTimeout 86400
+
+
+Description
+
+The MultipleOperationTimeout
directive sets the maximum amount
+of time between files in a multi-file print job. The default is 300 seconds.
+
+
Examples
diff --git a/filter/pdftops.c b/filter/pdftops.c
index 7e67895ba..03f453d81 100644
--- a/filter/pdftops.c
+++ b/filter/pdftops.c
@@ -61,7 +61,8 @@ main(int argc, /* I - Number of command-line args */
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 */
@@ -206,16 +207,21 @@ main(int argc, /* I - Number of command-line args */
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...
@@ -261,11 +267,7 @@ main(int argc, /* I - Number of command-line args */
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)
diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in
index 0aa299ff1..a2f15a36a 100644
--- a/man/cupsd.conf.man.in
+++ b/man/cupsd.conf.man.in
@@ -12,7 +12,7 @@
.\" 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
@@ -467,6 +467,12 @@ LogLevel warn
.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.
@@ -501,6 +507,11 @@ MaxRequestSize number-bytes
.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
diff --git a/scheduler/client.c b/scheduler/client.c
index a00ee62f7..40434d9be 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -1029,7 +1029,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
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",
diff --git a/scheduler/client.h b/scheduler/client.h
index 3e447aeb0..0ad9b1d19 100644
--- a/scheduler/client.h
+++ b/scheduler/client.h
@@ -28,7 +28,7 @@ struct cupsd_client_s
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 */
diff --git a/scheduler/conf.c b/scheduler/conf.c
index 3d8b14b07..26ca30b96 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -150,6 +150,7 @@ static const cupsd_var_t variables[] =
{ "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 },
@@ -549,49 +550,51 @@ cupsdReadConfiguration(void)
* 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);
@@ -3182,6 +3185,20 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
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)
{
/*
diff --git a/scheduler/conf.h b/scheduler/conf.h
index 025f6a915..8139c8b48 100644
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -4,7 +4,7 @@
* 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
@@ -44,6 +44,12 @@ typedef enum
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...
@@ -151,19 +157,21 @@ VAR uid_t User VALUE(1);
/* 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 */
@@ -205,8 +213,10 @@ VAR int AccessLogLevel VALUE(CUPSD_ACCESSLOG_ACTIONS),
/* 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),
@@ -259,7 +269,7 @@ extern int cupsdCheckPermissions(const char *filename,
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,
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index a867cbbc8..9bb2f0e89 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -1731,7 +1731,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
}
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;
}
@@ -4910,7 +4910,10 @@ copy_banner(cupsd_client_t *con, /* I - Client connection */
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;
@@ -10063,7 +10066,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */
{
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);
diff --git a/scheduler/job.c b/scheduler/job.c
index d5c1cfe44..daf082a36 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -395,7 +395,25 @@ cupsdCheckJobs(void)
{
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;
}
@@ -1056,7 +1074,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 */
@@ -1074,14 +1092,14 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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);
}
/*
@@ -1096,9 +1114,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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)
@@ -1107,10 +1123,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
"[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);
@@ -1124,10 +1137,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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",
@@ -1136,10 +1146,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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;
@@ -1152,10 +1159,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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),
@@ -1164,10 +1168,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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);
@@ -1177,10 +1178,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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",
@@ -1195,10 +1193,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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;
@@ -1212,10 +1207,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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);
@@ -1284,7 +1276,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Ran out of memory for job file types!",
job->id);
- return;
+ return (1);
}
job->compressions = compressions;
@@ -1342,6 +1334,18 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
}
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 --git a/scheduler/job.h b/scheduler/job.h
index 931667879..e3f2faa3b 100644
--- a/scheduler/job.h
+++ b/scheduler/job.h
@@ -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(const char *dest);
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 --git a/scheduler/log.c b/scheduler/log.c
index 47eb67b12..7bb52cc61 100644
--- a/scheduler/log.c
+++ b/scheduler/log.c
@@ -3,7 +3,7 @@
*
* 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
@@ -55,11 +55,14 @@ static int format_log_line(const char *message, va_list ap);
*/
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",
@@ -82,11 +85,15 @@ cupsdGetDateTime(time_t t) /* I - Time value */
*/
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
@@ -102,15 +109,25 @@ cupsdGetDateTime(time_t t) /* I - Time value */
* (*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 */
}
@@ -322,7 +339,7 @@ cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */
break;
case 'T' : /* Date and time */
- strlcpy(bufptr, cupsdGetDateTime(time(NULL)),
+ strlcpy(bufptr, cupsdGetDateTime(NULL, LogTimeFormat),
sizeof(buffer) - (bufptr - buffer));
bufptr += strlen(bufptr);
break;
@@ -627,7 +644,8 @@ cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */
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,
@@ -705,7 +723,7 @@ cupsdWriteErrorLog(int level, /* I - Log level */
*/
cupsFilePrintf(ErrorFile, "%c %s %s\n", levels[level],
- cupsdGetDateTime(time(NULL)), message);
+ cupsdGetDateTime(NULL, LogTimeFormat), message);
cupsFileFlush(ErrorFile);
return (1);
diff --git a/scheduler/main.c b/scheduler/main.c
index afbf149e2..7748afc99 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -3,7 +3,7 @@
*
* 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
@@ -1764,6 +1764,13 @@ process_children(void)
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;
}
diff --git a/scheduler/printers.c b/scheduler/printers.c
index 7c57f0761..c6465aba9 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -544,7 +544,7 @@ cupsdCreateCommonData(void)
/* 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,
diff --git a/scheduler/quotas.c b/scheduler/quotas.c
index 4286f0e22..6d45b300d 100644
--- a/scheduler/quotas.c
+++ b/scheduler/quotas.c
@@ -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);
--
2.39.2