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@.

+

LogTimeFormat

+ +

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.

+ +

MaxClients

Examples

@@ -2210,6 +2227,22 @@ HREF="#LimitRequestBody">LimitRequestBody directive instead.

+

CUPS 1.4MultipleOperationTimeout

+ +

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.

+ +

Order

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