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