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