]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/plog.c
ipsec-146.3.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / plog.c
CommitLineData
52b7d2ce
A
1/* $Id: plog.c,v 1.6.10.1 2005/12/07 10:19:51 vanhu Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * 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. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include "config.h"
33
34#include <sys/types.h>
35#include <sys/param.h>
36
37#include <stdlib.h>
38#include <stdio.h>
39#include <string.h>
40#include <errno.h>
41#ifdef HAVE_STDARG_H
42#include <stdarg.h>
43#else
44#include <varargs.h>
45#endif
46#if TIME_WITH_SYS_TIME
47# include <sys/time.h>
48# include <time.h>
49#else
50# if HAVE_SYS_TIME_H
51# include <sys/time.h>
52# else
53# include <time.h>
54# endif
55#endif
56#include <ctype.h>
57#include <err.h>
e8d9021d
A
58#include <pthread.h>
59#include <unistd.h>
52b7d2ce
A
60
61#include "var.h"
62#include "misc.h"
63#include "plog.h"
64#include "logger.h"
65#include "debug.h"
66#include "gcmalloc.h"
67
68#ifndef VA_COPY
d1e348cf 69# define VA_COPY(dst,src) memcpy(&(dst), (src), sizeof(va_list))
52b7d2ce
A
70#endif
71
72extern int print_pid;
73
74char *pname = NULL;
75u_int32_t loglevel = LLV_BASE;
76int f_foreground = 0;
77
78int print_location = 0;
79
80static struct log *logp = NULL;
e8d9021d 81static pthread_mutex_t logp_mtx = {0};
52b7d2ce
A
82static char *logfile = NULL;
83
84static char *plog_common __P((int, const char *, const char *));
85
86static struct plogtags {
87 char *name;
88 int priority;
89} ptab[] = {
90 { "(not defined)", 0, },
91 { "INFO", LOG_INFO, },
92 { "NOTIFY", LOG_INFO, },
93 { "WARNING", LOG_INFO, },
94 { "ERROR", LOG_INFO, },
95 { "ERROR", LOG_ERR, },
96 { "DEBUG", LOG_DEBUG, },
97 { "DEBUG2", LOG_DEBUG, },
98};
99
100static char *
101plog_common(pri, fmt, func)
e8d9021d
A
102int pri;
103const char *fmt, *func;
52b7d2ce
A
104{
105 static char buf[800]; /* XXX shoule be allocated every time ? */
106 char *p;
107 int reslen, len;
e8d9021d 108
52b7d2ce
A
109 p = buf;
110 reslen = sizeof(buf);
e8d9021d 111
52b7d2ce
A
112 if (logfile || f_foreground) {
113 time_t t;
114 struct tm *tm;
e8d9021d 115
52b7d2ce
A
116 t = time(0);
117 tm = localtime(&t);
118 len = strftime(p, reslen, "%Y-%m-%d %T: ", tm);
119 p += len;
120 reslen -= len;
121 }
e8d9021d 122
52b7d2ce
A
123 if (pri < ARRAYLEN(ptab)) {
124 if (print_pid)
125 len = snprintf(p, reslen, "[%d] %s: ", getpid(), ptab[pri].name);
126 else
127 len = snprintf(p, reslen, "%s: ", ptab[pri].name);
128 if (len >= 0 && len < reslen) {
129 p += len;
130 reslen -= len;
131 } else
132 *p = '\0';
133 }
e8d9021d 134
52b7d2ce
A
135 if (print_location)
136 snprintf(p, reslen, "%s: %s", func, fmt);
137 else
138 snprintf(p, reslen, "%s", fmt);
139#ifdef BROKEN_PRINTF
140 while ((p = strstr(buf,"%z")) != NULL)
141 p[1] = 'l';
142#endif
e8d9021d 143
52b7d2ce
A
144 return buf;
145}
146
147void
e8d9021d
A
148plogmtxinit (void)
149{
150 pthread_mutexattr_t attrs;
151 pthread_mutexattr_init(&attrs);
152 pthread_mutexattr_settype(&attrs, PTHREAD_MUTEX_RECURSIVE);
153 pthread_mutex_init(&logp_mtx, &attrs);
154 pthread_mutexattr_destroy(&attrs);
155}
156
157void
158plog_func(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...)
52b7d2ce
A
159{
160 va_list ap;
161
162 va_start(ap, fmt);
d1e348cf 163 plogv(pri, func, sa, fmt, &ap);
52b7d2ce
A
164 va_end(ap);
165}
166
167void
168plogv(int pri, const char *func, struct sockaddr *sa,
e8d9021d 169 const char *fmt, va_list *ap)
52b7d2ce
A
170{
171 char *newfmt;
172 va_list ap_bak;
e8d9021d 173
52b7d2ce
A
174 if (pri > loglevel)
175 return;
176
e8d9021d 177 pthread_mutex_lock(&logp_mtx);
52b7d2ce 178
e8d9021d
A
179 newfmt = plog_common(pri, fmt, func);
180
52b7d2ce
A
181 VA_COPY(ap_bak, ap);
182
183 if (f_foreground)
d1e348cf 184 vprintf(newfmt, *ap);
e8d9021d
A
185
186
187 if (logfile) {
52b7d2ce 188 log_vaprint(logp, newfmt, ap_bak);
e8d9021d 189 } else {
52b7d2ce
A
190 if (pri < ARRAYLEN(ptab))
191 vsyslog(ptab[pri].priority, newfmt, ap_bak);
192 else
193 vsyslog(LOG_ALERT, newfmt, ap_bak);
194 }
e8d9021d 195 pthread_mutex_unlock(&logp_mtx);
52b7d2ce
A
196}
197
198void
199plogdump(pri, data, len)
200 int pri;
201 void *data;
202 size_t len;
203{
204 caddr_t buf;
205 size_t buflen;
206 int i, j;
207
208 if (pri > loglevel)
209 return;
210
211 /*
212 * 2 words a bytes + 1 space 4 bytes + 1 newline 32 bytes
213 * + 2 newline + '\0'
214 */
215 buflen = (len * 2) + (len / 4) + (len / 32) + 3;
216 buf = racoon_malloc(buflen);
217
218 i = 0;
219 j = 0;
220 while (j < len) {
221 if (j % 32 == 0)
222 buf[i++] = '\n';
223 else
224 if (j % 4 == 0)
225 buf[i++] = ' ';
226 snprintf(&buf[i], buflen - i, "%02x",
227 ((unsigned char *)data)[j] & 0xff);
228 i += 2;
229 j++;
230 }
231 if (buflen - i >= 2) {
232 buf[i++] = '\n';
233 buf[i] = '\0';
234 }
e8d9021d 235 plog_func(pri, LOCATION, NULL, "%s", buf);
52b7d2ce
A
236
237 racoon_free(buf);
238}
239
240void
241ploginit()
242{
e8d9021d
A
243 pthread_mutex_lock(&logp_mtx);
244
52b7d2ce
A
245 if (logfile) {
246 logp = log_open(250, logfile);
247 if (logp == NULL)
248 errx(1, "ERROR: failed to open log file %s.", logfile);
e8d9021d 249 pthread_mutex_unlock(&logp_mtx);
52b7d2ce
A
250 return;
251 }
252
253 openlog(pname, LOG_NDELAY, LOG_DAEMON);
e8d9021d
A
254
255 pthread_mutex_unlock(&logp_mtx);
52b7d2ce
A
256}
257
258void
259plogset(file)
260 char *file;
261{
e8d9021d 262 pthread_mutex_lock(&logp_mtx);
52b7d2ce
A
263 if (logfile != NULL)
264 racoon_free(logfile);
d1e348cf
A
265 logfile = racoon_strdup(file);
266 STRDUP_FATAL(logfile);
e8d9021d 267 pthread_mutex_unlock(&logp_mtx);
52b7d2ce
A
268}
269
270void
271plogreset(file)
272 char *file;
273{
e8d9021d
A
274 pthread_mutex_lock(&logp_mtx);
275
52b7d2ce 276 /* if log paths equal - do nothing */
e8d9021d
A
277 if (logfile == NULL && file == NULL) {
278 pthread_mutex_unlock(&logp_mtx);
52b7d2ce 279 return;
e8d9021d 280 }
52b7d2ce 281 if (logfile != NULL && file != NULL)
e8d9021d
A
282 if (!strcmp(logfile, file)) {
283 pthread_mutex_unlock(&logp_mtx);
52b7d2ce 284 return;
e8d9021d
A
285 }
286
52b7d2ce
A
287 if (logfile == NULL) /* no logfile was specified - daemon was used */
288 closelog(); /* close it */
289 else {
290 log_close(logp);
291 logp = NULL;
292 racoon_free(logfile);
293 logfile = NULL;
294 }
295
296 if (file)
297 plogset(file);
298 ploginit();
e8d9021d
A
299
300 pthread_mutex_unlock(&logp_mtx);
d1e348cf
A
301}
302
303/*
304 Returns a printable string from (possibly) binary data ;
305 concatenates all unprintable chars to one space.
306 XXX Maybe the printable chars range is too large...
307 */
308char*
309binsanitize(binstr, n)
310 char *binstr;
311 size_t n;
312{
313 int p,q;
d1e348cf
A
314 for (p = 0, q = 0; p < n; p++) {
315 if (isgraph((int)binstr[p])) {
316 binstr[q++] = binstr[p];
317 } else {
318 if (q && binstr[q - 1] != ' ')
319 binstr[q++] = ' ';
320 }
321 }
322 binstr[q++] = '\0';
323 return binstr;
324}
325