]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/plog.c
ipsec-146.2.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / plog.c
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>
58 #include <pthread.h>
59 #include <unistd.h>
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
69 # define VA_COPY(dst,src) memcpy(&(dst), (src), sizeof(va_list))
70 #endif
71
72 extern int print_pid;
73
74 char *pname = NULL;
75 u_int32_t loglevel = LLV_BASE;
76 int f_foreground = 0;
77
78 int print_location = 0;
79
80 static struct log *logp = NULL;
81 static pthread_mutex_t logp_mtx = {0};
82 static char *logfile = NULL;
83
84 static char *plog_common __P((int, const char *, const char *));
85
86 static 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
100 static char *
101 plog_common(pri, fmt, func)
102 int pri;
103 const char *fmt, *func;
104 {
105 static char buf[800]; /* XXX shoule be allocated every time ? */
106 char *p;
107 int reslen, len;
108
109 p = buf;
110 reslen = sizeof(buf);
111
112 if (logfile || f_foreground) {
113 time_t t;
114 struct tm *tm;
115
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 }
122
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 }
134
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
143
144 return buf;
145 }
146
147 void
148 plogmtxinit (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
157 void
158 plog_func(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...)
159 {
160 va_list ap;
161
162 va_start(ap, fmt);
163 plogv(pri, func, sa, fmt, &ap);
164 va_end(ap);
165 }
166
167 void
168 plogv(int pri, const char *func, struct sockaddr *sa,
169 const char *fmt, va_list *ap)
170 {
171 char *newfmt;
172 va_list ap_bak;
173
174 if (pri > loglevel)
175 return;
176
177 pthread_mutex_lock(&logp_mtx);
178
179 newfmt = plog_common(pri, fmt, func);
180
181 VA_COPY(ap_bak, ap);
182
183 if (f_foreground)
184 vprintf(newfmt, *ap);
185
186
187 if (logfile) {
188 log_vaprint(logp, newfmt, ap_bak);
189 } else {
190 if (pri < ARRAYLEN(ptab))
191 vsyslog(ptab[pri].priority, newfmt, ap_bak);
192 else
193 vsyslog(LOG_ALERT, newfmt, ap_bak);
194 }
195 pthread_mutex_unlock(&logp_mtx);
196 }
197
198 void
199 plogdump(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 }
235 plog_func(pri, LOCATION, NULL, "%s", buf);
236
237 racoon_free(buf);
238 }
239
240 void
241 ploginit()
242 {
243 pthread_mutex_lock(&logp_mtx);
244
245 if (logfile) {
246 logp = log_open(250, logfile);
247 if (logp == NULL)
248 errx(1, "ERROR: failed to open log file %s.", logfile);
249 pthread_mutex_unlock(&logp_mtx);
250 return;
251 }
252
253 openlog(pname, LOG_NDELAY, LOG_DAEMON);
254
255 pthread_mutex_unlock(&logp_mtx);
256 }
257
258 void
259 plogset(file)
260 char *file;
261 {
262 pthread_mutex_lock(&logp_mtx);
263 if (logfile != NULL)
264 racoon_free(logfile);
265 logfile = racoon_strdup(file);
266 STRDUP_FATAL(logfile);
267 pthread_mutex_unlock(&logp_mtx);
268 }
269
270 void
271 plogreset(file)
272 char *file;
273 {
274 pthread_mutex_lock(&logp_mtx);
275
276 /* if log paths equal - do nothing */
277 if (logfile == NULL && file == NULL) {
278 pthread_mutex_unlock(&logp_mtx);
279 return;
280 }
281 if (logfile != NULL && file != NULL)
282 if (!strcmp(logfile, file)) {
283 pthread_mutex_unlock(&logp_mtx);
284 return;
285 }
286
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();
299
300 pthread_mutex_unlock(&logp_mtx);
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 */
308 char*
309 binsanitize(binstr, n)
310 char *binstr;
311 size_t n;
312 {
313 int p,q;
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