log.c revision 1.5
1/* $OpenBSD: log.c,v 1.5 1999/02/26 03:45:48 niklas Exp $ */ 2/* $EOM: log.c,v 1.15 1999/02/25 11:39:10 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 "sysdep.h" 48 49#include "log.h" 50 51/* 52 * We cannot do the log strings dynamically sizeable as out of memory is one 53 * of the situations we need to report about. 54 */ 55#define LOG_SIZE 200 56 57static void _log_print (int, int, const char *, va_list); 58 59static FILE *log_output = stderr; 60static int log_level[LOG_ENDCLASS]; 61 62void 63log_to (FILE *f) 64{ 65 if (!log_output && f) 66 closelog (); 67 log_output = f; 68 if (!f) 69 openlog ("isakmpd", 0, LOG_DAEMON); 70} 71 72FILE * 73log_current (void) 74{ 75 return log_output; 76} 77 78static void 79_log_print (int error, int level, const char *fmt, va_list ap) 80{ 81 char buffer[LOG_SIZE]; 82 int len; 83 84 len = vsnprintf (buffer, LOG_SIZE, fmt, ap); 85 if (len < LOG_SIZE - 1 && error) 86 snprintf (buffer + len, LOG_SIZE - len, ": %s", strerror (errno)); 87 if (log_output) 88 { 89 fputs (buffer, log_output); 90 fputc ('\n', log_output); 91 } 92 else 93 syslog (level, buffer); 94} 95 96void 97#ifdef __STDC__ 98log_debug (int cls, int level, const char *fmt, ...) 99#else 100log_debug (cls, level, clfmt, va_alist) 101 int cls; 102 int level; 103 const char *fmt; 104 va_dcl 105#endif 106{ 107 va_list ap; 108 109 /* 110 * If we are not debugging this class, or the level is too low, just return. 111 */ 112 if (log_level[cls] == 0 || level > log_level[cls]) 113 return; 114#ifdef __STDC__ 115 va_start (ap, fmt); 116#else 117 va_start (ap); 118 fmt = va_arg (ap, const char *); 119#endif 120 _log_print (0, LOG_DEBUG, fmt, ap); 121 va_end (ap); 122} 123 124void 125log_debug_buf (int cls, int level, const char *header, const u_int8_t *buf, 126 size_t sz) 127{ 128 char s[73]; 129 int i, j; 130 131 /* 132 * If we are not debugging this class, or the level is too low, just return. 133 */ 134 if (log_level[cls] == 0 || level > log_level[cls]) 135 return; 136 137 log_debug (cls, level, "%s:", header); 138 for (i = j = 0; i < sz;) 139 { 140 sprintf (s + j, "%02x", buf[i++]); 141 j += 2; 142 if (i % 4 == 0) 143 { 144 if (i % 32 == 0) 145 { 146 s[j] = '\0'; 147 log_debug (cls, level, "%s", s); 148 j = 0; 149 } 150 else 151 s[j++] = ' '; 152 } 153 } 154 if (j) 155 { 156 s[j] = '\0'; 157 log_debug (cls, level, "%s", s); 158 } 159} 160 161void 162#ifdef __STDC__ 163log_print (const char *fmt, ...) 164#else 165log_print (fmt, va_alist) 166 const char *fmt; 167 va_dcl 168#endif 169{ 170 va_list ap; 171 172#ifdef __STDC__ 173 va_start (ap, fmt); 174#else 175 va_start (ap); 176 fmt = va_arg (ap, const char *); 177#endif 178 _log_print (0, LOG_NOTICE, fmt, ap); 179 va_end (ap); 180} 181 182void 183#ifdef __STDC__ 184log_error (const char *fmt, ...) 185#else 186log_error (fmt, va_alist) 187 const char *fmt; 188 va_dcl 189#endif 190{ 191 va_list ap; 192 193#ifdef __STDC__ 194 va_start (ap, fmt); 195#else 196 va_start (ap); 197 fmt = va_arg (ap, const char *); 198#endif 199 _log_print (1, LOG_ERR, fmt, ap); 200 va_end (ap); 201} 202 203void 204#ifdef __STDC__ 205log_fatal (const char *fmt, ...) 206#else 207log_fatal (fmt, va_alist) 208 const char *fmt; 209 va_dcl 210#endif 211{ 212 va_list ap; 213 214#ifdef __STDC__ 215 va_start (ap, fmt); 216#else 217 va_start (ap); 218 fmt = va_arg (ap, const char *); 219#endif 220 _log_print (1, LOG_CRIT, fmt, ap); 221 va_end (ap); 222 exit (1); 223} 224 225void 226log_debug_cmd (int cls, int level) 227{ 228 if (cls < 0 || cls >= LOG_ENDCLASS) 229 { 230 log_print ("log_debug_cmd: invalid debugging class %d", cls); 231 return; 232 } 233 234 if (level < 0) 235 { 236 log_print ("log_debug_cmd: invalid debugging level %d for class %d", 237 level, cls); 238 return; 239 } 240 241 if (level == log_level[cls]) 242 log_print ("log_debug_cmd: log level unchanged for class %d", cls); 243 else 244 { 245 log_print ("log_debug_cmd: log level changed from %d to %d for class %d", 246 log_level[cls], level, cls); 247 log_level[cls] = level; 248 } 249} 250