#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include "log.h"
#include "misc.h"
static int log_mask = ~0;
static char *log_ident;
static Log_type log_type;
static char strfmt_buf[256];
static int log_stderr_setmask(int mask)
{
int old = log_mask;
if (mask)
log_mask = mask;
return old;
}
static void log_stderr(int prio, const char *fmt, ...)
{
if (!(LOG_MASK(prio) & log_mask))
return;
char *loglevel;
/* Can't use an array because LOG_ values aren't guaranteed to be
* sequential or even small by POSIX */
switch (prio)
{
case LOG_ALERT:
loglevel = "ALERT";
break;
case LOG_CRIT:
loglevel = "CRIT";
break;
case LOG_DEBUG:
loglevel = "DEBUG";
break;
case LOG_EMERG:
loglevel = "EMERG";
break;
case LOG_ERR:
loglevel = "ERR";
break;
case LOG_INFO:
loglevel = "INFO";
break;
case LOG_NOTICE:
loglevel = "NOTICE";
break;
case LOG_WARNING:
loglevel = "WARNING";
break;
default:
loglevel = "UNKNOWN";
}
va_list args;
va_start(args, fmt);
time_t now = time(NULL);
/* Syslog-like output: "time (priority) ident: msg" */
strftime(strfmt_buf, sizeof(strfmt_buf) - 1, "%b %d %T", localtime(&now));
fprintf(stderr, "%s (%s) %s: ", strfmt_buf, loglevel, log_ident);
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
va_end(args);
}
void log_init(Log_type type, const char *ident)
{
log_type = type;
switch (type)
{
case LOG_TYPE_SYSLOG:
openlog(ident, 0, LOG_USER);
log_append = syslog;
log_setmask = setlogmask;
break;
case LOG_TYPE_STDERR:
setvbuf(stderr, NULL, _IOLBF, 0);
log_ident = xstrdup(ident);
log_append = log_stderr;
log_setmask = log_stderr_setmask;
}
}
void log_free(void)
{
if (log_type == LOG_TYPE_SYSLOG)
closelog();
if (log_type == LOG_TYPE_STDERR)
free(log_ident);
}