]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/log.c
2 * "$Id: log.c 6027 2006-10-11 21:04:58Z mike $"
4 * Log file routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * cupsdGetDateTime() - Returns a pointer to a date/time string.
27 * cupsdLogMessage() - Log a message to the error log file.
28 * cupsdLogPage() - Log a page to the page log file.
29 * cupsdLogRequest() - Log an HTTP request in Common Log Format.
30 * check_log_file() - Open/rotate a log file if it needs it.
34 * Include necessary headers...
46 static int check_log_file(cups_file_t
**, const char *);
50 * 'cupsdGetDateTime()' - Returns a pointer to a date/time string.
53 char * /* O - Date/time string */
54 cupsdGetDateTime(time_t t
) /* I - Time value */
56 struct tm
*date
; /* Date/time value */
57 static time_t last_time
= -1; /* Last time value */
58 static char s
[1024]; /* Date/time string */
59 static const char * const months
[12] =/* Months */
81 * Get the date and time from the UNIX time value, and then format it
82 * into a string. Note that we *can't* use the strftime() function since
83 * it is localized and will seriously confuse automatic programs if the
84 * month names are in the wrong language!
86 * Also, we use the "timezone" variable that contains the current timezone
87 * offset from GMT in seconds so that we are reporting local time in the
88 * log files. If you want GMT, set the TZ environment variable accordingly
89 * before starting the scheduler.
91 * (*BSD and Darwin store the timezone offset in the tm structure)
96 snprintf(s
, sizeof(s
), "[%02d/%s/%04d:%02d:%02d:%02d %+03ld%02ld]",
97 date
->tm_mday
, months
[date
->tm_mon
], 1900 + date
->tm_year
,
98 date
->tm_hour
, date
->tm_min
, date
->tm_sec
,
100 date
->tm_gmtoff
/ 3600, (date
->tm_gmtoff
/ 60) % 60);
102 timezone
/ 3600, (timezone
/ 60) % 60);
103 #endif /* HAVE_TM_GMTOFF */
111 * 'cupsdLogMessage()' - Log a message to the error log file.
114 int /* O - 1 on success, 0 on error */
115 cupsdLogMessage(int level
, /* I - Log level */
116 const char *message
, /* I - printf-style message string */
117 ...) /* I - Additional args as needed */
119 int len
; /* Length of message */
120 va_list ap
; /* Argument pointer */
121 static const char levels
[] = /* Log levels... */
135 static const int syslevels
[] = /* SYSLOG levels... */
148 #endif /* HAVE_VSYSLOG */
149 static int linesize
= 0; /* Size of line for output file */
150 static char *line
= NULL
; /* Line for output file */
154 * See if we want to log this message...
157 if (level
> LogLevel
|| !ErrorLog
)
162 * See if we are logging errors via syslog...
165 if (!strcmp(ErrorLog
, "syslog"))
167 va_start(ap
, message
);
168 vsyslog(syslevels
[level
], message
, ap
);
173 #endif /* HAVE_VSYSLOG */
176 * Not using syslog; check the log file...
179 if (!check_log_file(&ErrorFile
, ErrorLog
))
183 * Print the log level and date/time...
186 cupsFilePrintf(ErrorFile
, "%c %s ", levels
[level
], cupsdGetDateTime(time(NULL
)));
189 * Allocate the line buffer as needed...
195 line
= malloc(linesize
);
199 cupsFilePrintf(ErrorFile
,
200 "ERROR: Unable to allocate memory for line - %s\n",
202 cupsFileFlush(ErrorFile
);
209 * Format the log message...
212 va_start(ap
, message
);
213 len
= vsnprintf(line
, linesize
, message
, ap
);
217 * Resize the buffer as needed...
226 else if (len
> 65536)
229 line
= realloc(line
, len
);
235 cupsFilePrintf(ErrorFile
,
236 "ERROR: Unable to allocate memory for line - %s\n",
238 cupsFileFlush(ErrorFile
);
243 va_start(ap
, message
);
244 len
= vsnprintf(line
, linesize
, message
, ap
);
252 * Then the log message...
255 cupsFilePuts(ErrorFile
, line
);
261 if (len
> 0 && line
[len
- 1] != '\n')
262 cupsFilePutChar(ErrorFile
, '\n');
265 * Flush the line to the file and return...
268 cupsFileFlush(ErrorFile
);
275 * 'cupsdLogPage()' - Log a page to the page log file.
278 int /* O - 1 on success, 0 on error */
279 cupsdLogPage(cupsd_job_t
*job
, /* I - Job being printed */
280 const char *page
) /* I - Page being printed */
282 ipp_attribute_t
*billing
, /* job-billing attribute */
283 *hostname
; /* job-originating-host-name attribute */
286 billing
= ippFindAttribute(job
->attrs
, "job-billing", IPP_TAG_ZERO
);
287 hostname
= ippFindAttribute(job
->attrs
, "job-originating-host-name",
292 * See if we are logging pages via syslog...
295 if (!strcmp(PageLog
, "syslog"))
297 syslog(LOG_INFO
, "PAGE %s %s %d %s %s %s", job
->printer
->name
,
298 job
->username
? job
->username
: "-",
299 job
->id
, page
, billing
? billing
->values
[0].string
.text
: "-",
300 hostname
->values
[0].string
.text
);
304 #endif /* HAVE_VSYSLOG */
307 * Not using syslog; check the log file...
310 if (!check_log_file(&PageFile
, PageLog
))
314 * Print a page log entry of the form:
316 * printer job-id user [DD/MON/YYYY:HH:MM:SS +TTTT] page num-copies \
320 cupsFilePrintf(PageFile
, "%s %s %d %s %s %s %s\n", job
->printer
->name
,
321 job
->username
? job
->username
: "-",
322 job
->id
, cupsdGetDateTime(time(NULL
)), page
,
323 billing
? billing
->values
[0].string
.text
: "-",
324 hostname
->values
[0].string
.text
);
325 cupsFileFlush(PageFile
);
332 * 'cupsdLogRequest()' - Log an HTTP request in Common Log Format.
335 int /* O - 1 on success, 0 on error */
336 cupsdLogRequest(cupsd_client_t
*con
, /* I - Request to log */
337 http_status_t code
) /* I - Response code */
339 static const char * const states
[] = /* HTTP client states... */
360 * See if we are logging accesses via syslog...
363 if (!strcmp(AccessLog
, "syslog"))
366 "REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT
" %s %s\n",
367 con
->http
.hostname
, con
->username
[0] != '\0' ? con
->username
: "-",
368 states
[con
->operation
], con
->uri
,
369 con
->http
.version
/ 100, con
->http
.version
% 100,
370 code
, CUPS_LLCAST con
->bytes
,
372 ippOpString(con
->request
->request
.op
.operation_id
) : "-",
374 ippErrorString(con
->response
->request
.status
.status_code
) : "-");
378 #endif /* HAVE_VSYSLOG */
381 * Not using syslog; check the log file...
384 if (!check_log_file(&AccessFile
, AccessLog
))
388 * Write a log of the request in "common log format"...
391 cupsFilePrintf(AccessFile
,
392 "%s - %s %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT
" %s %s\n",
393 con
->http
.hostname
, con
->username
[0] != '\0' ? con
->username
: "-",
394 cupsdGetDateTime(con
->start
), states
[con
->operation
], con
->uri
,
395 con
->http
.version
/ 100, con
->http
.version
% 100,
396 code
, CUPS_LLCAST con
->bytes
,
398 ippOpString(con
->request
->request
.op
.operation_id
) : "-",
400 ippErrorString(con
->response
->request
.status
.status_code
) :
403 cupsFileFlush(AccessFile
);
410 * 'check_log_file()' - Open/rotate a log file if it needs it.
413 static int /* O - 1 if log file open */
414 check_log_file(cups_file_t
**lf
, /* IO - Log file */
415 const char *logname
) /* I - Log filename */
417 char backname
[1024], /* Backup log filename */
418 filename
[1024], /* Formatted log filename */
419 *ptr
; /* Pointer into filename */
423 * See if we have a log file to check...
426 if (!lf
|| !logname
|| !logname
[0])
430 * Format the filename as needed...
434 (strncmp(logname
, "/dev/", 5) && cupsFileTell(*lf
) > MaxLogSize
&&
438 * Handle format strings...
441 filename
[sizeof(filename
) - 1] = '\0';
443 if (logname
[0] != '/')
445 strlcpy(filename
, ServerRoot
, sizeof(filename
));
446 strlcat(filename
, "/", sizeof(filename
));
451 for (ptr
= filename
+ strlen(filename
);
452 *logname
&& ptr
< (filename
+ sizeof(filename
) - 1);
464 * Insert the server name...
467 strlcpy(ptr
, ServerName
, sizeof(filename
) - (ptr
- filename
));
473 * Otherwise just insert the character...
486 * See if the log file is open...
492 * Nope, open the log file...
495 if ((*lf
= cupsFileOpen(filename
, "a")) == NULL
)
497 syslog(LOG_ERR
, "Unable to open log file \"%s\" - %s", filename
,
503 if (strncmp(filename
, "/dev/", 5))
506 * Change ownership and permissions of non-device logs...
509 fchown(cupsFileNumber(*lf
), RunUser
, Group
);
510 fchmod(cupsFileNumber(*lf
), LogFilePerm
);
515 * Do we need to rotate the log?
518 if (strncmp(logname
, "/dev/", 5) && cupsFileTell(*lf
) > MaxLogSize
&&
527 strcpy(backname
, filename
);
528 strlcat(backname
, ".O", sizeof(backname
));
531 rename(filename
, backname
);
533 if ((*lf
= cupsFileOpen(filename
, "a")) == NULL
)
535 syslog(LOG_ERR
, "Unable to open log file \"%s\" - %s", filename
,
542 * Change ownership and permissions of non-device logs...
545 fchown(cupsFileNumber(*lf
), RunUser
, Group
);
546 fchmod(cupsFileNumber(*lf
), LogFilePerm
);
554 * End of "$Id: log.c 6027 2006-10-11 21:04:58Z mike $".