/* $NetBSD: plog.c,v 1.4.6.2 2009/04/20 13:35:36 tteras Exp $ */ /* Id: plog.c,v 1.11 2006/06/20 09:57:31 vanhu Exp */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "config.h" #include <sys/types.h> #include <sys/param.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #ifdef HAVE_STDARG_H #include <stdarg.h> #else #include <varargs.h> #endif #if TIME_WITH_SYS_TIME # include <sys/time.h> # include <time.h> #else # if HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif #endif #include <ctype.h> #include <err.h> #include "var.h" #include "misc.h" #include "plog.h" #include "logger.h" #include "debug.h" #include "gcmalloc.h" #ifndef VA_COPY # define VA_COPY(dst,src) memcpy(&(dst), &(src), sizeof(va_list)) #endif char *pname = NULL; u_int32_t loglevel = LLV_BASE; int f_foreground = 0; int print_location = 0; static struct log *logp = NULL; static char *logfile = NULL; static char *plog_common __P((int, const char *, const char *)); static struct plogtags { char *name; int priority; } ptab[] = { { "(not defined)", 0, }, { "ERROR", LOG_INFO, }, { "WARNING", LOG_INFO, }, { "NOTIFY", LOG_INFO, }, { "INFO", LOG_INFO, }, { "DEBUG", LOG_DEBUG, }, { "DEBUG2", LOG_DEBUG, }, }; static char * plog_common(pri, fmt, func) int pri; const char *fmt, *func; { static char buf[800]; /* XXX shoule be allocated every time ? */ char *p; int reslen, len; p = buf; reslen = sizeof(buf); if (logfile || f_foreground) { time_t t; struct tm *tm; t = time(0); tm = localtime(&t); len = strftime(p, reslen, "%Y-%m-%d %T: ", tm); p += len; reslen -= len; } if (pri < ARRAYLEN(ptab)) { len = snprintf(p, reslen, "%s: ", ptab[pri].name); if (len >= 0 && len < reslen) { p += len; reslen -= len; } else *p = '\0'; } if (print_location) snprintf(p, reslen, "%s: %s", func, fmt); else snprintf(p, reslen, "%s", fmt); #ifdef BROKEN_PRINTF while ((p = strstr(buf,"%z")) != NULL) p[1] = 'l'; #endif return buf; } void _plog(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...) { va_list ap; va_start(ap, fmt); plogv(pri, func, sa, fmt, ap); va_end(ap); } void plogv(int pri, const char *func, struct sockaddr *sa, const char *fmt, va_list ap) { char *newfmt; va_list ap_bak; if (pri > loglevel) return; newfmt = plog_common(pri, fmt, func); VA_COPY(ap_bak, ap); if (f_foreground) vprintf(newfmt, ap); if (logfile) log_vaprint(logp, newfmt, ap_bak); else { if (pri < ARRAYLEN(ptab)) vsyslog(ptab[pri].priority, newfmt, ap_bak); else vsyslog(LOG_ALERT, newfmt, ap_bak); } } void plogdump(pri, data, len) int pri; void *data; size_t len; { caddr_t buf; size_t buflen; int i, j; if (pri > loglevel) return; /* * 2 words a bytes + 1 space 4 bytes + 1 newline 32 bytes * + 2 newline + '\0' */ buflen = (len * 2) + (len / 4) + (len / 32) + 3; buf = racoon_malloc(buflen); i = 0; j = 0; while (j < len) { if (j % 32 == 0) buf[i++] = '\n'; else if (j % 4 == 0) buf[i++] = ' '; snprintf(&buf[i], buflen - i, "%02x", ((unsigned char *)data)[j] & 0xff); i += 2; j++; } if (buflen - i >= 2) { buf[i++] = '\n'; buf[i] = '\0'; } plog(pri, LOCATION, NULL, "%s", buf); racoon_free(buf); } void ploginit() { if (logfile) { logp = log_open(250, logfile); if (logp == NULL) errx(1, "ERROR: failed to open log file %s.", logfile); return; } openlog(pname, LOG_NDELAY, LOG_DAEMON); } void plogset(file) char *file; { if (logfile != NULL) racoon_free(logfile); logfile = racoon_strdup(file); STRDUP_FATAL(logfile); } /* Returns a printable string from (possibly) binary data ; concatenates all unprintable chars to one space. XXX Maybe the printable chars range is too large... */ char* binsanitize(binstr, n) char *binstr; size_t n; { int p,q; char* d; d = racoon_malloc(n + 1); for (p = 0, q = 0; p < n; p++) { if (isgraph((int)binstr[p])) { d[q++] = binstr[p]; } else { if (q && d[q - 1] != ' ') d[q++] = ' '; } } d[q++] = '\0'; return d; }