2
* "$Id: log.c 10996 2013-05-29 11:51:34Z msweet $"
4
* Log file routines for the CUPS scheduler.
6
* Copyright 2007-2012 by Apple Inc.
7
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
9
* These coded instructions, statements, and computer programs are the
10
* property of Apple Inc. and are protected by Federal copyright
11
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
12
* which should have been included with this file. If this file is
13
* file is missing or damaged, see the license at "http://www.cups.org/".
17
* cupsdCheckLogFile() - Open/rotate a log file if it needs it.
18
* cupsdGetDateTime() - Returns a pointer to a date/time string.
19
* cupsdLogGSSMessage() - Log a GSSAPI error...
20
* cupsdLogJob() - Log a job message.
21
* cupsdLogMessage() - Log a message to the error log file.
22
* cupsdLogPage() - Log a page to the page log file.
23
* cupsdLogRequest() - Log an HTTP request in Common Log Format.
24
* cupsdWriteErrorLog() - Write a line to the ErrorLog.
25
* format_log_line() - Format a line for a log file.
29
* Include necessary headers...
41
static int log_linesize = 0; /* Size of line for output file */
42
static char *log_line = NULL; /* Line for output file */
45
static const int syslevels[] = /* SYSLOG levels... */
58
#endif /* HAVE_VSYSLOG */
65
static int format_log_line(const char *message, va_list ap);
69
* 'cupsdCheckLogFile()' - Open/rotate a log file if it needs it.
72
int /* O - 1 if log file open */
73
cupsdCheckLogFile(cups_file_t **lf, /* IO - Log file */
74
const char *logname) /* I - Log filename */
76
char backname[1024], /* Backup log filename */
77
filename[1024], /* Formatted log filename */
78
*ptr; /* Pointer into filename */
79
const char *logptr; /* Pointer into log filename */
83
* See if we have a log file to check...
86
if (!lf || !logname || !logname[0])
90
* Format the filename as needed...
94
(strncmp(logname, "/dev/", 5) && cupsFileTell(*lf) > MaxLogSize &&
98
* Handle format strings...
101
filename[sizeof(filename) - 1] = '\0';
103
if (logname[0] != '/')
105
strlcpy(filename, ServerRoot, sizeof(filename));
106
strlcat(filename, "/", sizeof(filename));
111
for (logptr = logname, ptr = filename + strlen(filename);
112
*logptr && ptr < (filename + sizeof(filename) - 1);
124
* Insert the server name...
127
strlcpy(ptr, ServerName, sizeof(filename) - (ptr - filename));
133
* Otherwise just insert the character...
146
* See if the log file is open...
152
* Nope, open the log file...
155
if ((*lf = cupsFileOpen(filename, "a")) == NULL)
158
* If the file is in CUPS_LOGDIR then try to create a missing directory...
161
if (!strncmp(filename, CUPS_LOGDIR, strlen(CUPS_LOGDIR)))
164
* Try updating the permissions of the containing log directory, using
165
* the log file permissions as a basis...
168
int log_dir_perm = 0300 | LogFilePerm;
169
/* LogFilePerm + owner write/search */
170
if (log_dir_perm & 0040)
171
log_dir_perm |= 0010; /* Add group search */
172
if (log_dir_perm & 0004)
173
log_dir_perm |= 0001; /* Add other search */
175
cupsdCheckPermissions(CUPS_LOGDIR, NULL, log_dir_perm, RunUser, Group,
178
*lf = cupsFileOpen(filename, "a");
183
syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename,
186
if (FatalErrors & CUPSD_FATAL_LOG)
187
cupsdEndProcess(getpid(), 0);
193
if (strncmp(filename, "/dev/", 5))
196
* Change ownership and permissions of non-device logs...
199
fchown(cupsFileNumber(*lf), RunUser, Group);
200
fchmod(cupsFileNumber(*lf), LogFilePerm);
205
* Do we need to rotate the log?
208
if (strncmp(logname, "/dev/", 5) && cupsFileTell(*lf) > MaxLogSize &&
217
strlcpy(backname, filename, sizeof(backname));
218
strlcat(backname, ".O", sizeof(backname));
221
rename(filename, backname);
223
if ((*lf = cupsFileOpen(filename, "a")) == NULL)
225
syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename,
228
if (FatalErrors & CUPSD_FATAL_LOG)
229
cupsdEndProcess(getpid(), 0);
235
* Change ownership and permissions of non-device logs...
238
fchown(cupsFileNumber(*lf), RunUser, Group);
239
fchmod(cupsFileNumber(*lf), LogFilePerm);
247
* 'cupsdGetDateTime()' - Returns a pointer to a date/time string.
250
char * /* O - Date/time string */
251
cupsdGetDateTime(struct timeval *t, /* I - Time value or NULL for current */
252
cupsd_time_t format) /* I - Format to use */
254
struct timeval curtime; /* Current time value */
255
struct tm *date; /* Date/time value */
256
static struct timeval last_time = { 0, 0 };
257
/* Last time we formatted */
258
static char s[1024]; /* Date/time string */
259
static const char * const months[12] =/* Months */
277
* Make sure we have a valid time...
282
gettimeofday(&curtime, NULL);
286
if (t->tv_sec != last_time.tv_sec ||
287
(LogTimeFormat == CUPSD_TIME_USECS && t->tv_usec != last_time.tv_usec))
292
* Get the date and time from the UNIX time value, and then format it
293
* into a string. Note that we *can't* use the strftime() function since
294
* it is localized and will seriously confuse automatic programs if the
295
* month names are in the wrong language!
297
* Also, we use the "timezone" variable that contains the current timezone
298
* offset from GMT in seconds so that we are reporting local time in the
299
* log files. If you want GMT, set the TZ environment variable accordingly
300
* before starting the scheduler.
302
* (*BSD and Darwin store the timezone offset in the tm structure)
305
date = localtime(&(t->tv_sec));
307
if (format == CUPSD_TIME_STANDARD)
308
snprintf(s, sizeof(s), "[%02d/%s/%04d:%02d:%02d:%02d %+03ld%02ld]",
309
date->tm_mday, months[date->tm_mon], 1900 + date->tm_year,
310
date->tm_hour, date->tm_min, date->tm_sec,
311
#ifdef HAVE_TM_GMTOFF
312
date->tm_gmtoff / 3600, (date->tm_gmtoff / 60) % 60);
314
timezone / 3600, (timezone / 60) % 60);
315
#endif /* HAVE_TM_GMTOFF */
317
snprintf(s, sizeof(s), "[%02d/%s/%04d:%02d:%02d:%02d.%06d %+03ld%02ld]",
318
date->tm_mday, months[date->tm_mon], 1900 + date->tm_year,
319
date->tm_hour, date->tm_min, date->tm_sec, (int)t->tv_usec,
320
#ifdef HAVE_TM_GMTOFF
321
date->tm_gmtoff / 3600, (date->tm_gmtoff / 60) % 60);
323
timezone / 3600, (timezone / 60) % 60);
324
#endif /* HAVE_TM_GMTOFF */
332
* 'cupsdLogFCMessage()' - Log a file checking message.
337
void *context, /* I - Printer (if any) */
338
_cups_fc_result_t result, /* I - Check result */
339
const char *message) /* I - Message to log */
341
cupsd_printer_t *p = (cupsd_printer_t *)context;
343
cupsd_loglevel_t level; /* Log level */
346
if (result == _CUPS_FILE_CHECK_OK)
347
level = CUPSD_LOG_DEBUG2;
349
level = CUPSD_LOG_ERROR;
353
cupsdLogMessage(level, "%s: %s", p->name, message);
355
if (result == _CUPS_FILE_CHECK_MISSING ||
356
result == _CUPS_FILE_CHECK_WRONG_TYPE)
358
strlcpy(p->state_message, message, sizeof(p->state_message));
360
if (cupsdSetPrinterReasons(p, "+cups-missing-filter-warning"))
361
cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, p, NULL, "%s", message);
363
else if (result == _CUPS_FILE_CHECK_PERMISSIONS ||
364
result == _CUPS_FILE_CHECK_RELATIVE_PATH)
366
strlcpy(p->state_message, message, sizeof(p->state_message));
368
if (cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning"))
369
cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, p, NULL, "%s", message);
373
cupsdLogMessage(level, "%s", message);
379
* 'cupsdLogGSSMessage()' - Log a GSSAPI error...
382
int /* O - 1 on success, 0 on error */
384
int level, /* I - Log level */
385
int major_status, /* I - Major GSSAPI status */
386
int minor_status, /* I - Minor GSSAPI status */
387
const char *message, /* I - printf-style message string */
388
...) /* I - Additional args as needed */
390
OM_uint32 err_major_status, /* Major status code for display */
391
err_minor_status; /* Minor status code for display */
392
OM_uint32 msg_ctx; /* Message context */
393
gss_buffer_desc major_status_string = GSS_C_EMPTY_BUFFER,
394
/* Major status message */
395
minor_status_string = GSS_C_EMPTY_BUFFER;
396
/* Minor status message */
397
int ret; /* Return value */
398
char buffer[8192]; /* Buffer for vsnprintf */
401
if (strchr(message, '%'))
404
* Format the message string...
407
va_list ap; /* Pointer to arguments */
409
va_start(ap, message);
410
vsnprintf(buffer, sizeof(buffer), message, ap);
417
err_major_status = gss_display_status(&err_minor_status,
422
&major_status_string);
424
if (!GSS_ERROR(err_major_status))
425
gss_display_status(&err_minor_status, minor_status, GSS_C_MECH_CODE,
426
GSS_C_NULL_OID, &msg_ctx, &minor_status_string);
428
ret = cupsdLogMessage(level, "%s: %s, %s", message,
429
(char *)major_status_string.value,
430
(char *)minor_status_string.value);
431
gss_release_buffer(&err_minor_status, &major_status_string);
432
gss_release_buffer(&err_minor_status, &minor_status_string);
436
#endif /* HAVE_GSSAPI */
440
* 'cupsdLogJob()' - Log a job message.
443
int /* O - 1 on success, 0 on error */
444
cupsdLogJob(cupsd_job_t *job, /* I - Job */
445
int level, /* I - Log level */
446
const char *message, /* I - Printf-style message string */
447
...) /* I - Additional arguments as needed */
449
va_list ap, ap2; /* Argument pointers */
450
char jobmsg[1024]; /* Format string for job message */
451
int status; /* Formatting status */
455
* See if we want to log this message...
458
if (TestConfigFile || !ErrorLog)
461
if ((level > LogLevel ||
462
(level == CUPSD_LOG_INFO && LogLevel < CUPSD_LOG_DEBUG)) &&
463
LogDebugHistory <= 0)
467
* Format and write the log message...
471
snprintf(jobmsg, sizeof(jobmsg), "[Job %d] %s", job->id, message);
473
strlcpy(jobmsg, message, sizeof(jobmsg));
475
va_start(ap, message);
480
status = format_log_line(jobmsg, ap2);
491
(level == CUPSD_LOG_INFO && LogLevel < CUPSD_LOG_DEBUG)) &&
495
* Add message to the job history...
498
cupsd_joblog_t *temp; /* Copy of log message */
501
if ((temp = malloc(sizeof(cupsd_joblog_t) + strlen(log_line))) != NULL)
503
temp->time = time(NULL);
504
strlcpy(temp->message, log_line, sizeof(temp->message));
508
job->history = cupsArrayNew(NULL, NULL);
510
if (job->history && temp)
512
cupsArrayAdd(job->history, temp);
514
if (cupsArrayCount(job->history) > LogDebugHistory)
517
* Remove excess messages...
520
temp = cupsArrayFirst(job->history);
521
cupsArrayRemove(job->history, temp);
530
else if (level <= LogLevel &&
531
(level != CUPSD_LOG_INFO || LogLevel >= CUPSD_LOG_DEBUG))
532
return (cupsdWriteErrorLog(level, log_line));
537
return (cupsdWriteErrorLog(CUPSD_LOG_ERROR,
538
"Unable to allocate memory for log line!"));
543
* 'cupsdLogMessage()' - Log a message to the error log file.
546
int /* O - 1 on success, 0 on error */
547
cupsdLogMessage(int level, /* I - Log level */
548
const char *message, /* I - printf-style message string */
549
...) /* I - Additional args as needed */
551
va_list ap, ap2; /* Argument pointers */
552
int status; /* Formatting status */
556
* See if we want to log this message...
559
if ((TestConfigFile || !ErrorLog) && level <= CUPSD_LOG_WARN)
561
va_start(ap, message);
563
vsyslog(LOG_LPR | syslevels[level], message, ap);
565
vfprintf(stderr, message, ap);
567
#endif /* HAVE_VSYSLOG */
573
if (level > LogLevel || !ErrorLog)
577
* Format and write the log message...
580
va_start(ap, message);
585
status = format_log_line(message, ap2);
593
return (cupsdWriteErrorLog(level, log_line));
595
return (cupsdWriteErrorLog(CUPSD_LOG_ERROR,
596
"Unable to allocate memory for log line!"));
601
* 'cupsdLogPage()' - Log a page to the page log file.
604
int /* O - 1 on success, 0 on error */
605
cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */
606
const char *page) /* I - Page being printed */
608
int i; /* Looping var */
609
char buffer[2048], /* Buffer for page log */
610
*bufptr, /* Pointer into buffer */
611
name[256]; /* Attribute name */
612
const char *format, /* Pointer into PageLogFormat */
613
*nameend; /* End of attribute name */
614
ipp_attribute_t *attr; /* Current attribute */
615
char number[256]; /* Page number */
616
int copies; /* Number of copies */
620
* Format the line going into the page log...
626
strlcpy(number, "1", sizeof(number));
628
sscanf(page, "%255s%d", number, &copies);
630
for (format = PageLogFormat, bufptr = buffer; *format; format ++)
638
case '%' : /* Literal % */
639
if (bufptr < (buffer + sizeof(buffer) - 1))
643
case 'p' : /* Printer name */
644
strlcpy(bufptr, job->printer->name,
645
sizeof(buffer) - (bufptr - buffer));
646
bufptr += strlen(bufptr);
649
case 'j' : /* Job ID */
650
snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), "%d", job->id);
651
bufptr += strlen(bufptr);
654
case 'u' : /* Username */
655
strlcpy(bufptr, job->username ? job->username : "-",
656
sizeof(buffer) - (bufptr - buffer));
657
bufptr += strlen(bufptr);
660
case 'T' : /* Date and time */
661
strlcpy(bufptr, cupsdGetDateTime(NULL, LogTimeFormat),
662
sizeof(buffer) - (bufptr - buffer));
663
bufptr += strlen(bufptr);
666
case 'P' : /* Page number */
667
strlcpy(bufptr, number, sizeof(buffer) - (bufptr - buffer));
668
bufptr += strlen(bufptr);
671
case 'C' : /* Number of copies */
672
snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), "%d", copies);
673
bufptr += strlen(bufptr);
676
case '{' : /* {attribute} */
677
if ((nameend = strchr(format, '}')) != NULL &&
678
(nameend - format - 2) < (sizeof(name) - 1))
681
* Pull the name from inside the brackets...
684
memcpy(name, format + 1, nameend - format - 1);
685
name[nameend - format - 1] = '\0';
689
if ((attr = ippFindAttribute(job->attrs, name,
690
IPP_TAG_ZERO)) != NULL)
693
* Add the attribute value...
697
i < attr->num_values &&
698
bufptr < (buffer + sizeof(buffer) - 1);
704
switch (attr->value_tag)
706
case IPP_TAG_INTEGER :
708
snprintf(bufptr, sizeof(buffer) - (bufptr - buffer),
709
"%d", attr->values[i].integer);
710
bufptr += strlen(bufptr);
713
case IPP_TAG_BOOLEAN :
714
snprintf(bufptr, sizeof(buffer) - (bufptr - buffer),
715
"%d", attr->values[i].boolean);
716
bufptr += strlen(bufptr);
719
case IPP_TAG_TEXTLANG :
720
case IPP_TAG_NAMELANG :
723
case IPP_TAG_KEYWORD :
725
case IPP_TAG_URISCHEME :
726
case IPP_TAG_CHARSET :
727
case IPP_TAG_LANGUAGE :
728
case IPP_TAG_MIMETYPE :
729
strlcpy(bufptr, attr->values[i].string.text,
730
sizeof(buffer) - (bufptr - buffer));
731
bufptr += strlen(bufptr);
735
strlcpy(bufptr, "???",
736
sizeof(buffer) - (bufptr - buffer));
737
bufptr += strlen(bufptr);
742
else if (bufptr < (buffer + sizeof(buffer) - 1))
748
if (bufptr < (buffer + sizeof(buffer) - 2))
756
else if (bufptr < (buffer + sizeof(buffer) - 1))
764
* See if we are logging pages via syslog...
767
if (!strcmp(PageLog, "syslog"))
769
syslog(LOG_INFO, "%s", buffer);
773
#endif /* HAVE_VSYSLOG */
776
* Not using syslog; check the log file...
779
if (!cupsdCheckLogFile(&PageFile, PageLog))
783
* Print a page log entry of the form:
785
* printer user job-id [DD/MON/YYYY:HH:MM:SS +TTTT] page num-copies \
789
cupsFilePrintf(PageFile, "%s\n", buffer);
790
cupsFileFlush(PageFile);
797
* 'cupsdLogRequest()' - Log an HTTP request in Common Log Format.
800
int /* O - 1 on success, 0 on error */
801
cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */
802
http_status_t code) /* I - Response code */
804
char temp[2048]; /* Temporary string for URI */
805
static const char * const states[] = /* HTTP client states... */
825
* Filter requests as needed...
828
if (AccessLogLevel < CUPSD_ACCESSLOG_ALL)
831
* Eliminate simple GET, POST, and PUT requests...
834
if ((con->operation == HTTP_GET &&
835
strncmp(con->uri, "/admin/conf", 11) &&
836
strncmp(con->uri, "/admin/log", 10)) ||
837
(con->operation == HTTP_POST && !con->request &&
838
strncmp(con->uri, "/admin", 6)) ||
839
(con->operation != HTTP_GET && con->operation != HTTP_POST &&
840
con->operation != HTTP_PUT))
843
if (con->request && con->response &&
844
(con->response->request.status.status_code < IPP_REDIRECTION_OTHER_SITE ||
845
con->response->request.status.status_code == IPP_NOT_FOUND))
848
* Check successful requests...
851
ipp_op_t op = con->request->request.op.operation_id;
852
static cupsd_accesslog_t standard_ops[] =
854
CUPSD_ACCESSLOG_ALL, /* reserved */
855
CUPSD_ACCESSLOG_ALL, /* reserved */
856
CUPSD_ACCESSLOG_ACTIONS,/* Print-Job */
857
CUPSD_ACCESSLOG_ACTIONS,/* Print-URI */
858
CUPSD_ACCESSLOG_ACTIONS,/* Validate-Job */
859
CUPSD_ACCESSLOG_ACTIONS,/* Create-Job */
860
CUPSD_ACCESSLOG_ACTIONS,/* Send-Document */
861
CUPSD_ACCESSLOG_ACTIONS,/* Send-URI */
862
CUPSD_ACCESSLOG_ACTIONS,/* Cancel-Job */
863
CUPSD_ACCESSLOG_ALL, /* Get-Job-Attributes */
864
CUPSD_ACCESSLOG_ALL, /* Get-Jobs */
865
CUPSD_ACCESSLOG_ALL, /* Get-Printer-Attributes */
866
CUPSD_ACCESSLOG_ACTIONS,/* Hold-Job */
867
CUPSD_ACCESSLOG_ACTIONS,/* Release-Job */
868
CUPSD_ACCESSLOG_ACTIONS,/* Restart-Job */
869
CUPSD_ACCESSLOG_ALL, /* reserved */
870
CUPSD_ACCESSLOG_CONFIG, /* Pause-Printer */
871
CUPSD_ACCESSLOG_CONFIG, /* Resume-Printer */
872
CUPSD_ACCESSLOG_CONFIG, /* Purge-Jobs */
873
CUPSD_ACCESSLOG_CONFIG, /* Set-Printer-Attributes */
874
CUPSD_ACCESSLOG_ACTIONS,/* Set-Job-Attributes */
875
CUPSD_ACCESSLOG_CONFIG, /* Get-Printer-Supported-Values */
876
CUPSD_ACCESSLOG_ACTIONS,/* Create-Printer-Subscription */
877
CUPSD_ACCESSLOG_ACTIONS,/* Create-Job-Subscription */
878
CUPSD_ACCESSLOG_ALL, /* Get-Subscription-Attributes */
879
CUPSD_ACCESSLOG_ALL, /* Get-Subscriptions */
880
CUPSD_ACCESSLOG_ACTIONS,/* Renew-Subscription */
881
CUPSD_ACCESSLOG_ACTIONS,/* Cancel-Subscription */
882
CUPSD_ACCESSLOG_ALL, /* Get-Notifications */
883
CUPSD_ACCESSLOG_ACTIONS,/* Send-Notifications */
884
CUPSD_ACCESSLOG_ALL, /* reserved */
885
CUPSD_ACCESSLOG_ALL, /* reserved */
886
CUPSD_ACCESSLOG_ALL, /* reserved */
887
CUPSD_ACCESSLOG_ALL, /* Get-Print-Support-Files */
888
CUPSD_ACCESSLOG_CONFIG, /* Enable-Printer */
889
CUPSD_ACCESSLOG_CONFIG, /* Disable-Printer */
890
CUPSD_ACCESSLOG_CONFIG, /* Pause-Printer-After-Current-Job */
891
CUPSD_ACCESSLOG_ACTIONS,/* Hold-New-Jobs */
892
CUPSD_ACCESSLOG_ACTIONS,/* Release-Held-New-Jobs */
893
CUPSD_ACCESSLOG_CONFIG, /* Deactivate-Printer */
894
CUPSD_ACCESSLOG_CONFIG, /* Activate-Printer */
895
CUPSD_ACCESSLOG_CONFIG, /* Restart-Printer */
896
CUPSD_ACCESSLOG_CONFIG, /* Shutdown-Printer */
897
CUPSD_ACCESSLOG_CONFIG, /* Startup-Printer */
898
CUPSD_ACCESSLOG_ACTIONS,/* Reprocess-Job */
899
CUPSD_ACCESSLOG_ACTIONS,/* Cancel-Current-Job */
900
CUPSD_ACCESSLOG_ACTIONS,/* Suspend-Current-Job */
901
CUPSD_ACCESSLOG_ACTIONS,/* Resume-Job */
902
CUPSD_ACCESSLOG_ACTIONS,/* Promote-Job */
903
CUPSD_ACCESSLOG_ACTIONS /* Schedule-Job-After */
905
static cupsd_accesslog_t cups_ops[] =
907
CUPSD_ACCESSLOG_ALL, /* CUPS-Get-Default */
908
CUPSD_ACCESSLOG_ALL, /* CUPS-Get-Printers */
909
CUPSD_ACCESSLOG_CONFIG, /* CUPS-Add-Modify-Printer */
910
CUPSD_ACCESSLOG_CONFIG, /* CUPS-Delete-Printer */
911
CUPSD_ACCESSLOG_ALL, /* CUPS-Get-Classes */
912
CUPSD_ACCESSLOG_CONFIG, /* CUPS-Add-Modify-Class */
913
CUPSD_ACCESSLOG_CONFIG, /* CUPS-Delete-Class */
914
CUPSD_ACCESSLOG_CONFIG, /* CUPS-Accept-Jobs */
915
CUPSD_ACCESSLOG_CONFIG, /* CUPS-Reject-Jobs */
916
CUPSD_ACCESSLOG_CONFIG, /* CUPS-Set-Default */
917
CUPSD_ACCESSLOG_CONFIG, /* CUPS-Get-Devices */
918
CUPSD_ACCESSLOG_CONFIG, /* CUPS-Get-PPDs */
919
CUPSD_ACCESSLOG_ACTIONS,/* CUPS-Move-Job */
920
CUPSD_ACCESSLOG_ACTIONS,/* CUPS-Authenticate-Job */
921
CUPSD_ACCESSLOG_ALL /* CUPS-Get-PPD */
925
if ((op <= IPP_SCHEDULE_JOB_AFTER && standard_ops[op] > AccessLogLevel) ||
926
(op >= CUPS_GET_DEFAULT && op <= CUPS_GET_PPD &&
927
cups_ops[op - CUPS_GET_DEFAULT] > AccessLogLevel))
934
* See if we are logging accesses via syslog...
937
if (!strcmp(AccessLog, "syslog"))
940
"REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n",
941
con->http.hostname, con->username[0] != '\0' ? con->username : "-",
942
states[con->operation], _httpEncodeURI(temp, con->uri, sizeof(temp)),
943
con->http.version / 100, con->http.version % 100,
944
code, CUPS_LLCAST con->bytes,
946
ippOpString(con->request->request.op.operation_id) : "-",
948
ippErrorString(con->response->request.status.status_code) : "-");
952
#endif /* HAVE_VSYSLOG */
955
* Not using syslog; check the log file...
958
if (!cupsdCheckLogFile(&AccessFile, AccessLog))
962
* Write a log of the request in "common log format"...
965
cupsFilePrintf(AccessFile,
966
"%s - %s %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n",
968
con->username[0] != '\0' ? con->username : "-",
969
cupsdGetDateTime(&(con->start), LogTimeFormat),
970
states[con->operation],
971
_httpEncodeURI(temp, con->uri, sizeof(temp)),
972
con->http.version / 100, con->http.version % 100,
973
code, CUPS_LLCAST con->bytes,
975
ippOpString(con->request->request.op.operation_id) : "-",
977
ippErrorString(con->response->request.status.status_code) :
980
cupsFileFlush(AccessFile);
987
* 'cupsdWriteErrorLog()' - Write a line to the ErrorLog.
990
int /* O - 1 on success, 0 on failure */
991
cupsdWriteErrorLog(int level, /* I - Log level */
992
const char *message) /* I - Message string */
994
static const char levels[] = /* Log levels... */
1011
* See if we are logging errors via syslog...
1014
if (!strcmp(ErrorLog, "syslog"))
1016
syslog(syslevels[level], "%s", message);
1019
#endif /* HAVE_VSYSLOG */
1022
* Not using syslog; check the log file...
1025
if (!cupsdCheckLogFile(&ErrorFile, ErrorLog))
1029
* Write the log message...
1032
cupsFilePrintf(ErrorFile, "%c %s %s\n", levels[level],
1033
cupsdGetDateTime(NULL, LogTimeFormat), message);
1034
cupsFileFlush(ErrorFile);
1041
* 'format_log_line()' - Format a line for a log file.
1043
* This function resizes a global string buffer as needed. Each call returns
1044
* a pointer to this buffer, so the contents are only good until the next call
1045
* to format_log_line()...
1048
static int /* O - -1 for fatal, 0 for retry, 1 for success */
1049
format_log_line(const char *message, /* I - Printf-style format string */
1050
va_list ap) /* I - Argument list */
1052
int len; /* Length of formatted line */
1056
* Allocate the line buffer as needed...
1061
log_linesize = 8192;
1062
log_line = malloc(log_linesize);
1069
* Format the log message...
1072
len = vsnprintf(log_line, log_linesize, message, ap);
1075
* Resize the buffer as needed...
1078
if (len >= log_linesize && log_linesize < 65536)
1080
char *temp; /* Temporary string pointer */
1087
else if (len > 65536)
1090
temp = realloc(log_line, len);
1106
* End of "$Id: log.c 10996 2013-05-29 11:51:34Z msweet $".