#include "cupsd.h"
#include <stdarg.h>
#ifdef HAVE_VSYSLOG
# include <syslog.h>
#endif
static int check_log_file(FILE **, const char *);
char *
GetDateTime(time_t t)
{
struct tm *date;
static char s[1024];
static const char *months[12] =
{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
date = localtime(&t);
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
return (s);
}
int
LogMessage(int level,
const char *message,
...)
{
int len;
char line[1024];
va_list ap;
static char levels[] =
{
' ',
'X',
'A',
'C',
'E',
'W',
'N',
'I',
'D',
'd'
};
#ifdef HAVE_VSYSLOG
static int syslevels[] =
{
0,
LOG_EMERG,
LOG_ALERT,
LOG_CRIT,
LOG_ERR,
LOG_WARNING,
LOG_NOTICE,
LOG_INFO,
LOG_DEBUG,
LOG_DEBUG
};
#endif
if (level > LogLevel)
return (1);
#ifdef HAVE_VSYSLOG
if (strcmp(ErrorLog, "syslog") == 0)
{
va_start(ap, message);
vsyslog(syslevels[level], message, ap);
va_end(ap);
return (1);
}
#endif
if (!check_log_file(&ErrorFile, ErrorLog))
return (0);
fprintf(ErrorFile, "%c %s ", levels[level], GetDateTime(time(NULL)));
va_start(ap, message);
len = vsnprintf(line, sizeof(line), message, ap);
va_end(ap);
fputs(line, ErrorFile);
if (len > 0 && line[len - 1] != '\n')
putc('\n', ErrorFile);
fflush(ErrorFile);
return (1);
}
int
LogPage(job_t *job,
const char *page)
{
ipp_attribute_t *billing;
billing = ippFindAttribute(job->attrs, "job-billing", IPP_TAG_ZERO);
#ifdef HAVE_VSYSLOG
if (strcmp(PageLog, "syslog") == 0)
{
syslog(LOG_INFO, "PAGE %s %s %d %s %s", job->printer->name, job->username,
job->id, page, billing ? billing->values[0].string.text : "");
return (1);
}
#endif
if (!check_log_file(&PageFile, PageLog))
return (0);
fprintf(PageFile, "%s %s %d %s %s %s\n", job->printer->name, job->username,
job->id, GetDateTime(time(NULL)), page,
billing ? billing->values[0].string.text : "");
fflush(PageFile);
return (1);
}
int
LogRequest(client_t *con,
http_status_t code)
{
static const char *states[] =
{
"WAITING",
"OPTIONS",
"GET",
"GET",
"HEAD",
"POST",
"POST",
"POST",
"PUT",
"PUT",
"DELETE",
"TRACE",
"CLOSE",
"STATUS"
};
#ifdef HAVE_VSYSLOG
if (strcmp(AccessLog, "syslog") == 0)
{
syslog(LOG_INFO, "REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d %d\n",
con->http.hostname, con->username[0] != '\0' ? con->username : "-",
states[con->operation], con->uri,
con->http.version / 100, con->http.version % 100,
code, con->bytes);
return (1);
}
#endif
if (!check_log_file(&AccessFile, AccessLog))
return (0);
fprintf(AccessFile, "%s - %s %s \"%s %s HTTP/%d.%d\" %d %d\n",
con->http.hostname, con->username[0] != '\0' ? con->username : "-",
GetDateTime(con->start), states[con->operation], con->uri,
con->http.version / 100, con->http.version % 100,
code, con->bytes);
fflush(AccessFile);
return (1);
}
static int
check_log_file(FILE **log,
const char *logname)
{
char backname[1024],
filename[1024],
*ptr;
if (log == NULL || logname == NULL || !logname[0])
return (1);
if (*log == NULL ||
(ftell(*log) > MaxLogSize && MaxLogSize > 0))
{
filename[sizeof(filename) - 1] = '\0';
if (logname[0] != '/')
{
strlcpy(filename, ServerRoot, sizeof(filename));
strlcat(filename, "/", sizeof(filename));
}
else
filename[0] = '\0';
for (ptr = filename + strlen(filename);
*logname && ptr < (filename + sizeof(filename) - 1);
logname ++)
if (*logname == '%')
{
logname ++;
if (*logname == 's')
{
strlcpy(ptr, ServerName, sizeof(filename) - (ptr - filename));
ptr += strlen(ptr);
}
else
{
*ptr++ = *logname;
}
}
else
*ptr++ = *logname;
*ptr = '\0';
}
if (*log == NULL)
{
if ((*log = fopen(filename, "a")) == NULL)
return (0);
fchown(fileno(*log), User, Group);
fchmod(fileno(*log), LogFilePerm);
}
if (ftell(*log) > MaxLogSize && MaxLogSize > 0)
{
fclose(*log);
strcpy(backname, filename);
strlcat(backname, ".O", sizeof(backname));
unlink(backname);
rename(filename, backname);
if ((*log = fopen(filename, "a")) == NULL)
return (0);
fchown(fileno(*log), User, Group);
fchmod(fileno(*log), LogFilePerm);
}
return (1);
}