log.c revision 1.4
1/* $OpenBSD: log.c,v 1.4 1998/12/21 01:02:26 niklas Exp $ */ 2/* $EOM: log.c,v 1.14 1998/12/01 10:19:44 niklas Exp $ */ 3 4/* 5 * Copyright (c) 1998 Niklas Hallqvist. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Ericsson Radio Systems. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33/* 34 * This code was written under funding by Ericsson Radio Systems. 35 */ 36 37#include <errno.h> 38#include <stdio.h> 39#include <string.h> 40#include <syslog.h> 41#ifdef __STDC__ 42#include <stdarg.h> 43#else 44#include <varargs.h> 45#endif 46 47#include "log.h" 48 49/* 50 * We cannot do the log strings dynamically sizeable as out of memory is one 51 * of the situations we need to report about. 52 */ 53#define LOG_SIZE 200 54 55static void _log_print (int, int, const char *, va_list); 56 57static FILE *log_output = stderr; 58static int log_level[LOG_ENDCLASS]; 59 60void 61log_to (FILE *f) 62{ 63 if (!log_output && f) 64 closelog (); 65 log_output = f; 66 if (!f) 67 openlog ("isakmpd", 0, LOG_DAEMON); 68} 69 70FILE * 71log_current (void) 72{ 73 return log_output; 74} 75 76static void 77_log_print (int error, int level, const char *fmt, va_list ap) 78{ 79 char buffer[LOG_SIZE]; 80 int len; 81 82 len = vsnprintf (buffer, LOG_SIZE, fmt, ap); 83 if (len < LOG_SIZE - 1 && error) 84 snprintf (buffer + len, LOG_SIZE - len, ": %s", strerror (errno)); 85 if (log_output) 86 { 87 fputs (buffer, log_output); 88 fputc ('\n', log_output); 89 } 90 else 91 syslog (level, buffer); 92} 93 94void 95#ifdef __STDC__ 96log_debug (int cls, int level, const char *fmt, ...) 97#else 98log_debug (cls, level, clfmt, va_alist) 99 int cls; 100 int level; 101 const char *fmt; 102 va_dcl 103#endif 104{ 105 va_list ap; 106 107 /* 108 * If we are not debugging this class, or the level is too low, just return. 109 */ 110 if (log_level[cls] == 0 || level > log_level[cls]) 111 return; 112#ifdef __STDC__ 113 va_start (ap, fmt); 114#else 115 va_start (ap); 116 fmt = va_arg (ap, const char *); 117#endif 118 _log_print (0, LOG_DEBUG, fmt, ap); 119 va_end (ap); 120} 121 122void 123log_debug_buf (int cls, int level, const char *header, const u_int8_t *buf, 124 size_t sz) 125{ 126 char s[73]; 127 int i, j; 128 129 /* 130 * If we are not debugging this class, or the level is too low, just return. 131 */ 132 if (log_level[cls] == 0 || level > log_level[cls]) 133 return; 134 135 log_debug (cls, level, "%s:", header); 136 for (i = j = 0; i < sz;) 137 { 138 sprintf (s + j, "%02x", buf[i++]); 139 j += 2; 140 if (i % 4 == 0) 141 { 142 if (i % 32 == 0) 143 { 144 s[j] = '\0'; 145 log_debug (cls, level, "%s", s); 146 j = 0; 147 } 148 else 149 s[j++] = ' '; 150 } 151 } 152 if (j) 153 { 154 s[j] = '\0'; 155 log_debug (cls, level, "%s", s); 156 } 157} 158 159void 160#ifdef __STDC__ 161log_print (const char *fmt, ...) 162#else 163log_print (fmt, va_alist) 164 const char *fmt; 165 va_dcl 166#endif 167{ 168 va_list ap; 169 170#ifdef __STDC__ 171 va_start (ap, fmt); 172#else 173 va_start (ap); 174 fmt = va_arg (ap, const char *); 175#endif 176 _log_print (0, LOG_NOTICE, fmt, ap); 177 va_end (ap); 178} 179 180void 181#ifdef __STDC__ 182log_error (const char *fmt, ...) 183#else 184log_error (fmt, va_alist) 185 const char *fmt; 186 va_dcl 187#endif 188{ 189 va_list ap; 190 191#ifdef __STDC__ 192 va_start (ap, fmt); 193#else 194 va_start (ap); 195 fmt = va_arg (ap, const char *); 196#endif 197 _log_print (1, LOG_ERR, fmt, ap); 198 va_end (ap); 199} 200 201void 202#ifdef __STDC__ 203log_fatal (const char *fmt, ...) 204#else 205log_fatal (fmt, va_alist) 206 const char *fmt; 207 va_dcl 208#endif 209{ 210 va_list ap; 211 212#ifdef __STDC__ 213 va_start (ap, fmt); 214#else 215 va_start (ap); 216 fmt = va_arg (ap, const char *); 217#endif 218 _log_print (1, LOG_CRIT, fmt, ap); 219 va_end (ap); 220 exit (1); 221} 222 223void 224log_debug_cmd (int cls, int level) 225{ 226 if (cls < 0 || cls >= LOG_ENDCLASS) 227 { 228 log_print ("log_debug_cmd: invalid debugging class %d", cls); 229 return; 230 } 231 232 if (level < 0) 233 { 234 log_print ("log_debug_cmd: invalid debugging level %d for class %d", 235 level, cls); 236 return; 237 } 238 239 if (level == log_level[cls]) 240 log_print ("log_debug_cmd: log level unchanged for class %d", cls); 241 else 242 { 243 log_print ("log_debug_cmd: log level changed from %d to %d for class %d", 244 log_level[cls], level, cls); 245 log_level[cls] = level; 246 } 247} 248