1: /* $NetBSD: plog.c,v 1.7 2011/01/28 12:51:40 tteras Exp $ */
2:
3: /* Id: plog.c,v 1.11 2006/06/20 09:57:31 vanhu Exp */
4:
5: /*
6: * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. Neither the name of the project nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #include "config.h"
35:
36: #include <sys/types.h>
37: #include <sys/param.h>
38:
39: #include <arpa/inet.h>
40: #include <stdlib.h>
41: #include <stdio.h>
42: #include <string.h>
43: #include <errno.h>
44: #ifdef HAVE_STDARG_H
45: #include <stdarg.h>
46: #else
47: #include <varargs.h>
48: #endif
49: #if TIME_WITH_SYS_TIME
50: # include <sys/time.h>
51: # include <time.h>
52: #else
53: # if HAVE_SYS_TIME_H
54: # include <sys/time.h>
55: # else
56: # include <time.h>
57: # endif
58: #endif
59: #include <ctype.h>
60: #include <err.h>
61:
62: #include "var.h"
63: #include "misc.h"
64: #include "plog.h"
65: #include "logger.h"
66: #include "debug.h"
67: #include "gcmalloc.h"
68:
69: #ifndef VA_COPY
70: # define VA_COPY(dst,src) memcpy(&(dst), &(src), sizeof(va_list))
71: #endif
72:
73: char *pname = NULL;
74: u_int32_t loglevel = LLV_BASE;
75: int f_foreground = 0;
76:
77: int print_location = 0;
78:
79: static struct log *logp = NULL;
80: static char *logfile = NULL;
81:
82: static char *plog_common __P((int, const char *, const char *, struct sockaddr *));
83:
84: static struct plogtags {
85: char *name;
86: int priority;
87: } ptab[] = {
88: { "(not defined)", 0, },
89: { "ERROR", LOG_INFO, },
90: { "WARNING", LOG_INFO, },
91: { "NOTIFY", LOG_INFO, },
92: { "INFO", LOG_INFO, },
93: { "DEBUG", LOG_DEBUG, },
94: { "DEBUG2", LOG_DEBUG, },
95: };
96:
97: static char *
98: plog_common(pri, fmt, func, sa)
99: int pri;
100: const char *fmt, *func;
101: struct sockaddr *sa;
102: {
103: static char buf[800]; /* XXX shoule be allocated every time ? */
104: void *addr;
105: char *p;
106: int reslen, len;
107:
108: p = buf;
109: reslen = sizeof(buf);
110:
111: if (logfile || f_foreground) {
112: time_t t;
113: struct tm *tm;
114:
115: t = time(0);
116: tm = localtime(&t);
117: len = strftime(p, reslen, "%Y-%m-%d %T: ", tm);
118: p += len;
119: reslen -= len;
120: }
121:
122: if (sa && reslen > 3) {
123: addr = NULL;
124: switch (sa->sa_family) {
125: case AF_INET:
126: addr = &((struct sockaddr_in*)sa)->sin_addr;
127: break;
128: case AF_INET6:
129: addr = &((struct sockaddr_in6*)sa)->sin6_addr;
130: break;
131: }
132: if (inet_ntop(sa->sa_family, addr, p + 1, reslen - 3) != NULL) {
133: *p++ = '[';
134: len = strlen(p);
135: p += len;
136: *p++ = ']';
137: *p++ = ' ';
138: reslen -= len + 3;
139: }
140: }
141:
142: if (pri < ARRAYLEN(ptab)) {
143: len = snprintf(p, reslen, "%s: ", ptab[pri].name);
144: p += len;
145: reslen -= len;
146: }
147:
148: if (print_location)
149: len = snprintf(p, reslen, "%s: %s", func, fmt);
150: else
151: len = snprintf(p, reslen, "%s", fmt);
152: p += len;
153: reslen -= len;
154:
155: /* Force nul termination */
156: if (reslen == 0)
157: p[-1] = 0;
158:
159: #ifdef BROKEN_PRINTF
160: while ((p = strstr(buf,"%z")) != NULL)
161: p[1] = 'l';
162: #endif
163:
164: return buf;
165: }
166:
167: void
168: _plog(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...)
169: {
170: va_list ap;
171:
172: va_start(ap, fmt);
173: plogv(pri, func, sa, fmt, ap);
174: va_end(ap);
175: }
176:
177: void
178: plogv(int pri, const char *func, struct sockaddr *sa,
179: const char *fmt, va_list ap)
180: {
181: char *newfmt;
182: va_list ap_bak;
183:
184: if (pri > loglevel)
185: return;
186:
187: newfmt = plog_common(pri, fmt, func, sa);
188:
189: VA_COPY(ap_bak, ap);
190:
191: if (f_foreground)
192: vprintf(newfmt, ap);
193:
194: if (logfile)
195: log_vaprint(logp, newfmt, ap_bak);
196: else {
197: if (pri < ARRAYLEN(ptab))
198: vsyslog(ptab[pri].priority, newfmt, ap_bak);
199: else
200: vsyslog(LOG_ALERT, newfmt, ap_bak);
201: }
202: }
203:
204: void
205: plogdump(pri, data, len)
206: int pri;
207: void *data;
208: size_t len;
209: {
210: caddr_t buf;
211: size_t buflen;
212: int i, j;
213:
214: if (pri > loglevel)
215: return;
216:
217: /*
218: * 2 words a bytes + 1 space 4 bytes + 1 newline 32 bytes
219: * + 2 newline + '\0'
220: */
221: buflen = (len * 2) + (len / 4) + (len / 32) + 3;
222: buf = racoon_malloc(buflen);
223:
224: i = 0;
225: j = 0;
226: while (j < len) {
227: if (j % 32 == 0)
228: buf[i++] = '\n';
229: else
230: if (j % 4 == 0)
231: buf[i++] = ' ';
232: snprintf(&buf[i], buflen - i, "%02x",
233: ((unsigned char *)data)[j] & 0xff);
234: i += 2;
235: j++;
236: }
237: if (buflen - i >= 2) {
238: buf[i++] = '\n';
239: buf[i] = '\0';
240: }
241: plog(pri, LOCATION, NULL, "%s", buf);
242:
243: racoon_free(buf);
244: }
245:
246: void
247: ploginit()
248: {
249: if (logfile) {
250: logp = log_open(250, logfile);
251: if (logp == NULL)
252: errx(1, "ERROR: failed to open log file %s.", logfile);
253: return;
254: }
255:
256: openlog(pname, LOG_NDELAY, LOG_DAEMON);
257: }
258:
259: void
260: plogset(file)
261: char *file;
262: {
263: if (logfile != NULL)
264: racoon_free(logfile);
265: logfile = racoon_strdup(file);
266: STRDUP_FATAL(logfile);
267: }
268:
269: /*
270: Returns a printable string from (possibly) binary data ;
271: concatenates all unprintable chars to one space.
272: XXX Maybe the printable chars range is too large...
273: */
274: char*
275: binsanitize(binstr, n)
276: char *binstr;
277: size_t n;
278: {
279: int p,q;
280: char* d;
281:
282: d = racoon_malloc(n + 1);
283: for (p = 0, q = 0; p < n; p++) {
284: if (isgraph((int)binstr[p])) {
285: d[q++] = binstr[p];
286: } else {
287: if (q && d[q - 1] != ' ')
288: d[q++] = ' ';
289: }
290: }
291: d[q++] = '\0';
292:
293: return d;
294: }
295:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>