]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/log.c
3beb7e4307a0ad8a44b65debea160fe8a47a4cea
2 * "$Id: log.c,v 1.19.2.9 2003/03/04 15:34:57 mike Exp $"
4 * Log file routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2003 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-3111 USA
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * GetDateTime() - Returns a pointer to a date/time string.
27 * LogMessage() - Log a message to the error log file.
28 * LogPage() - Log a page to the page log file.
29 * LogRequest() - 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...
42 #endif /* HAVE_VSYSLOG */
49 static int check_log_file(FILE **, const char *);
53 * 'GetDateTime()' - Returns a pointer to a date/time string.
56 char * /* O - Date/time string */
57 GetDateTime(time_t t
) /* I - Time value */
59 struct tm
*date
; /* Date/time value */
60 static char s
[1024]; /* Date/time string */
61 static const char * const months
[12] =
79 * Get the date and time from the UNIX time value, and then format it
80 * into a string. Note that we *can't* use the strftime() function since
81 * it is localized and will seriously confuse automatic programs if the
82 * month names are in the wrong language!
84 * Also, we use the "timezone" variable that contains the current timezone
85 * offset from GMT in seconds so that we are reporting local time in the
86 * log files. If you want GMT, set the TZ environment variable accordingly
87 * before starting the scheduler.
89 * (*BSD and Darwin store the timezone offset in the tm structure)
94 snprintf(s
, sizeof(s
), "[%02d/%s/%04d:%02d:%02d:%02d %+03ld%02ld]",
95 date
->tm_mday
, months
[date
->tm_mon
], 1900 + date
->tm_year
,
96 date
->tm_hour
, date
->tm_min
, date
->tm_sec
,
98 date
->tm_gmtoff
/ 3600, (date
->tm_gmtoff
/ 60) % 60);
100 timezone
/ 3600, (timezone
/ 60) % 60);
101 #endif /* HAVE_TM_GMTOFF */
108 * 'LogMessage()' - Log a message to the error log file.
111 int /* O - 1 on success, 0 on error */
112 LogMessage(int level
, /* I - Log level */
113 const char *message
, /* I - printf-style message string */
114 ...) /* I - Additional args as needed */
116 int len
; /* Length of message */
117 char line
[1024]; /* Line for output file */
118 va_list ap
; /* Argument pointer */
119 static const char levels
[] = /* Log levels... */
133 static const int syslevels
[] =/* SYSLOG levels... */
146 #endif /* HAVE_VSYSLOG */
150 * See if we want to log this message...
153 if (level
> LogLevel
)
158 * See if we are logging errors via syslog...
161 if (strcmp(ErrorLog
, "syslog") == 0)
163 va_start(ap
, message
);
164 vsyslog(syslevels
[level
], message
, ap
);
169 #endif /* HAVE_VSYSLOG */
172 * Not using syslog; check the log file...
175 if (!check_log_file(&ErrorFile
, ErrorLog
))
179 * Print the log level and date/time...
182 fprintf(ErrorFile
, "%c %s ", levels
[level
], GetDateTime(time(NULL
)));
185 * Then the log message...
188 va_start(ap
, message
);
189 len
= vsnprintf(line
, sizeof(line
), message
, ap
);
196 fputs(line
, ErrorFile
);
197 if (len
> 0 && line
[len
- 1] != '\n')
198 putc('\n', ErrorFile
);
207 * 'LogPage()' - Log a page to the page log file.
210 int /* O - 1 on success, 0 on error */
211 LogPage(job_t
*job
, /* I - Job being printed */
212 const char *page
) /* I - Page being printed */
214 ipp_attribute_t
*billing
, /* job-billing attribute */
215 *hostname
; /* job-originating-host-name attribute */
218 billing
= ippFindAttribute(job
->attrs
, "job-billing", IPP_TAG_ZERO
);
219 hostname
= ippFindAttribute(job
->attrs
, "job-originating-host-name",
224 * See if we are logging pages via syslog...
227 if (strcmp(PageLog
, "syslog") == 0)
229 syslog(LOG_INFO
, "PAGE %s %s %d %s %s %s", job
->printer
->name
,
230 job
->username
? job
->username
: "-",
231 job
->id
, page
, billing
? billing
->values
[0].string
.text
: "-",
232 hostname
->values
[0].string
.text
);
236 #endif /* HAVE_VSYSLOG */
239 * Not using syslog; check the log file...
242 if (!check_log_file(&PageFile
, PageLog
))
246 * Print a page log entry of the form:
248 * printer job-id user [DD/MON/YYYY:HH:MM:SS +TTTT] page num-copies \
252 fprintf(PageFile
, "%s %s %d %s %s %s %s\n", job
->printer
->name
,
253 job
->username
? job
->username
: "-",
254 job
->id
, GetDateTime(time(NULL
)), page
,
255 billing
? billing
->values
[0].string
.text
: "-",
256 hostname
->values
[0].string
.text
);
264 * 'LogRequest()' - Log an HTTP request in Common Log Format.
267 int /* O - 1 on success, 0 on error */
268 LogRequest(client_t
*con
, /* I - Request to log */
269 http_status_t code
) /* I - Response code */
271 static const char * const states
[] =
272 { /* HTTP client states... */
292 * See if we are logging accesses via syslog...
295 if (strcmp(AccessLog
, "syslog") == 0)
297 syslog(LOG_INFO
, "REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d %d\n",
298 con
->http
.hostname
, con
->username
[0] != '\0' ? con
->username
: "-",
299 states
[con
->operation
], con
->uri
,
300 con
->http
.version
/ 100, con
->http
.version
% 100,
305 #endif /* HAVE_VSYSLOG */
308 * Not using syslog; check the log file...
311 if (!check_log_file(&AccessFile
, AccessLog
))
315 * Write a log of the request in "common log format"...
318 fprintf(AccessFile
, "%s - %s %s \"%s %s HTTP/%d.%d\" %d %d\n",
319 con
->http
.hostname
, con
->username
[0] != '\0' ? con
->username
: "-",
320 GetDateTime(con
->start
), states
[con
->operation
], con
->uri
,
321 con
->http
.version
/ 100, con
->http
.version
% 100,
330 * 'check_log_file()' - Open/rotate a log file if it needs it.
333 static int /* O - 1 if log file open */
334 check_log_file(FILE **log
, /* IO - Log file */
335 const char *logname
) /* I - Log filename */
337 char backname
[1024], /* Backup log filename */
338 filename
[1024], /* Formatted log filename */
339 *ptr
; /* Pointer into filename */
343 * See if we have a log file to check...
346 if (log
== NULL
|| logname
== NULL
|| !logname
[0])
350 * Format the filename as needed...
354 (ftell(*log
) > MaxLogSize
&& MaxLogSize
> 0))
357 * Handle format strings...
360 filename
[sizeof(filename
) - 1] = '\0';
362 if (logname
[0] != '/')
364 strlcpy(filename
, ServerRoot
, sizeof(filename
));
365 strlcat(filename
, "/", sizeof(filename
));
370 for (ptr
= filename
+ strlen(filename
);
371 *logname
&& ptr
< (filename
+ sizeof(filename
) - 1);
383 * Insert the server name...
386 strlcpy(ptr
, ServerName
, sizeof(filename
) - (ptr
- filename
));
392 * Otherwise just insert the character...
405 * See if the log file is open...
411 * Nope, open the log file...
414 if ((*log
= fopen(filename
, "a")) == NULL
)
417 fchown(fileno(*log
), User
, Group
);
418 fchmod(fileno(*log
), LogFilePerm
);
422 * Do we need to rotate the log?
425 if (ftell(*log
) > MaxLogSize
&& MaxLogSize
> 0)
433 strcpy(backname
, filename
);
434 strlcat(backname
, ".O", sizeof(backname
));
437 rename(filename
, backname
);
439 if ((*log
= fopen(filename
, "a")) == NULL
)
442 fchown(fileno(*log
), User
, Group
);
443 fchmod(fileno(*log
), LogFilePerm
);
451 * End of "$Id: log.c,v 1.19.2.9 2003/03/04 15:34:57 mike Exp $".