/* $OpenBSD: log.c,v 1.5 1999/02/26 03:45:48 niklas Exp $ */ /* $EOM: log.c,v 1.15 1999/02/25 11:39:10 niklas Exp $ */ /* * Copyright (c) 1998 Niklas Hallqvist. 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Ericsson Radio Systems. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ /* * This code was written under funding by Ericsson Radio Systems. */ #include <errno.h> #include <stdio.h> #include <string.h> #include <syslog.h> #ifdef __STDC__ #include <stdarg.h> #else #include <varargs.h> #endif #include "sysdep.h" #include "log.h" /* * We cannot do the log strings dynamically sizeable as out of memory is one * of the situations we need to report about. */ #define LOG_SIZE 200 static void _log_print (int, int, const char *, va_list); static FILE *log_output = stderr; static int log_level[LOG_ENDCLASS]; void log_to (FILE *f) { if (!log_output && f) closelog (); log_output = f; if (!f) openlog ("isakmpd", 0, LOG_DAEMON); } FILE * log_current (void) { return log_output; } static void _log_print (int error, int level, const char *fmt, va_list ap) { char buffer[LOG_SIZE]; int len; len = vsnprintf (buffer, LOG_SIZE, fmt, ap); if (len < LOG_SIZE - 1 && error) snprintf (buffer + len, LOG_SIZE - len, ": %s", strerror (errno)); if (log_output) { fputs (buffer, log_output); fputc ('\n', log_output); } else syslog (level, buffer); } void #ifdef __STDC__ log_debug (int cls, int level, const char *fmt, ...) #else log_debug (cls, level, clfmt, va_alist) int cls; int level; const char *fmt; va_dcl #endif { va_list ap; /* * If we are not debugging this class, or the level is too low, just return. */ if (log_level[cls] == 0 || level > log_level[cls]) return; #ifdef __STDC__ va_start (ap, fmt); #else va_start (ap); fmt = va_arg (ap, const char *); #endif _log_print (0, LOG_DEBUG, fmt, ap); va_end (ap); } void log_debug_buf (int cls, int level, const char *header, const u_int8_t *buf, size_t sz) { char s[73]; int i, j; /* * If we are not debugging this class, or the level is too low, just return. */ if (log_level[cls] == 0 || level > log_level[cls]) return; log_debug (cls, level, "%s:", header); for (i = j = 0; i < sz;) { sprintf (s + j, "%02x", buf[i++]); j += 2; if (i % 4 == 0) { if (i % 32 == 0) { s[j] = '\0'; log_debug (cls, level, "%s", s); j = 0; } else s[j++] = ' '; } } if (j) { s[j] = '\0'; log_debug (cls, level, "%s", s); } } void #ifdef __STDC__ log_print (const char *fmt, ...) #else log_print (fmt, va_alist) const char *fmt; va_dcl #endif { va_list ap; #ifdef __STDC__ va_start (ap, fmt); #else va_start (ap); fmt = va_arg (ap, const char *); #endif _log_print (0, LOG_NOTICE, fmt, ap); va_end (ap); } void #ifdef __STDC__ log_error (const char *fmt, ...) #else log_error (fmt, va_alist) const char *fmt; va_dcl #endif { va_list ap; #ifdef __STDC__ va_start (ap, fmt); #else va_start (ap); fmt = va_arg (ap, const char *); #endif _log_print (1, LOG_ERR, fmt, ap); va_end (ap); } void #ifdef __STDC__ log_fatal (const char *fmt, ...) #else log_fatal (fmt, va_alist) const char *fmt; va_dcl #endif { va_list ap; #ifdef __STDC__ va_start (ap, fmt); #else va_start (ap); fmt = va_arg (ap, const char *); #endif _log_print (1, LOG_CRIT, fmt, ap); va_end (ap); exit (1); } void log_debug_cmd (int cls, int level) { if (cls < 0 || cls >= LOG_ENDCLASS) { log_print ("log_debug_cmd: invalid debugging class %d", cls); return; } if (level < 0) { log_print ("log_debug_cmd: invalid debugging level %d for class %d", level, cls); return; } if (level == log_level[cls]) log_print ("log_debug_cmd: log level unchanged for class %d", cls); else { log_print ("log_debug_cmd: log level changed from %d to %d for class %d", log_level[cls], level, cls); log_level[cls] = level; } }