/*
* logging.c:
* Logging for tpop3d.
*
* Copyright (c) 2001 Chris Lightfoot. All rights reserved.
* Email: chris@ex-parrot.com; WWW: http://www.ex-parrot.com/~chris/
*
*/
static const char rcsid[] = "$Id: logging.c,v 1.6 2003/07/14 23:31:20 chris Exp $";
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "config.h"
#include "util.h"
extern int log_stderr; /* in main.c */
/* facil:
* Log facility names and constants, used to allow configurable logging at
* run time. Not all those defined in openlog(3) make sense, so only a few
* are listed here. */
static struct logfac {
char *name;
int fac;
} facil[] = {
{"mail", LOG_MAIL},
#ifdef LOG_AUTHPRIV
{"authpriv", LOG_AUTHPRIV},
#endif
#ifdef LOG_AUTH
{"auth", LOG_AUTH},
#endif
{"daemon", LOG_DAEMON},
{"user", LOG_USER},
{"local0", LOG_LOCAL0},
{"local1", LOG_LOCAL1},
{"local2", LOG_LOCAL2},
{"local3", LOG_LOCAL3},
{"local4", LOG_LOCAL4},
{"local5", LOG_LOCAL5},
{"local6", LOG_LOCAL6},
{"local7", LOG_LOCAL7},
};
#define NFACIL (sizeof(facil) / sizeof(struct logfac))
static int log_fac;
/* log_init:
* Start up logging. */
void log_init(void) {
int fac = LOG_MAIL, warn = 0;
char *s;
if ((s = config_get_string("log-facility"))) {
struct logfac *l;
warn = 1;
for (l = facil; l < facil + NFACIL; ++l)
if (strcasecmp(l->name, s) == 0) {
warn = 0;
fac = l->fac;
break;
}
}
openlog("tpop3d", LOG_PID | LOG_NDELAY, fac);
if (warn == 1)
log_print(LOG_ERR, _("log_init: log-facility `%s' unknown, using `mail'"), s);
log_fac = fac;
}
/* verrprintf:
* Returns a static string with the appropriate arguments printed into it.
* (Replaced the dynamically allocating one with a static-buffer based
* alternative, since it isn't possible to call vsnprintf(..., ap) in a loop,
* as the arg list can't be reset. D'oh.) */
static char *verrprintf(const char *fmt, va_list ap) {
char *e = strerror(errno);
const char *p, *q;
char fmtbuf[1024];
static char errbuf[1024];
*fmtbuf = 0;
/* First, we need to substitute errors into the string. This would not be
* safe in the presence of very long format strings in the rest of the
* code, but we can guarantee that won't happen.... */
for (p = fmt, q = strstr(p, "%m"); q; p = q, q = strstr(p, "%m")) {
strncat(fmtbuf, p, q - p);
strcat(fmtbuf, e);
q += 2;
}
strcat(fmtbuf, p);
vsnprintf(errbuf, sizeof(errbuf), fmtbuf, ap);
return errbuf;
}
/* log_print:
* Print a line to the log. */
void log_print(int priority, const char *fmt, ...) {
char *s;
va_list ap;
va_start(ap, fmt);
s = verrprintf(fmt, ap);
va_end(ap);
syslog(priority | log_fac, "%s", s);
if (log_stderr) fprintf(stderr, "%s\n", s);
}
syntax highlighted by Code2HTML, v. 0.9.1