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