Home | History | Annotate | Download | only in racoon
      1 /*	$NetBSD: plog.c,v 1.4.6.2 2009/04/20 13:35:36 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 <stdlib.h>
     40 #include <stdio.h>
     41 #include <string.h>
     42 #include <errno.h>
     43 #ifdef HAVE_STDARG_H
     44 #include <stdarg.h>
     45 #else
     46 #include <varargs.h>
     47 #endif
     48 #if TIME_WITH_SYS_TIME
     49 # include <sys/time.h>
     50 # include <time.h>
     51 #else
     52 # if HAVE_SYS_TIME_H
     53 #  include <sys/time.h>
     54 # else
     55 #  include <time.h>
     56 # endif
     57 #endif
     58 #include <ctype.h>
     59 #include <err.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 char *pname = NULL;
     73 u_int32_t loglevel = LLV_BASE;
     74 int f_foreground = 0;
     75 
     76 int print_location = 0;
     77 
     78 static struct log *logp = NULL;
     79 static char *logfile = NULL;
     80 
     81 static char *plog_common __P((int, const char *, const char *));
     82 
     83 static struct plogtags {
     84 	char *name;
     85 	int priority;
     86 } ptab[] = {
     87 	{ "(not defined)",	0, },
     88 	{ "ERROR",		LOG_INFO, },
     89 	{ "WARNING",		LOG_INFO, },
     90 	{ "NOTIFY",		LOG_INFO, },
     91 	{ "INFO",		LOG_INFO, },
     92 	{ "DEBUG",		LOG_DEBUG, },
     93 	{ "DEBUG2",		LOG_DEBUG, },
     94 };
     95 
     96 static char *
     97 plog_common(pri, fmt, func)
     98 	int pri;
     99 	const char *fmt, *func;
    100 {
    101 	static char buf[800];	/* XXX shoule be allocated every time ? */
    102 	char *p;
    103 	int reslen, len;
    104 
    105 	p = buf;
    106 	reslen = sizeof(buf);
    107 
    108 	if (logfile || f_foreground) {
    109 		time_t t;
    110 		struct tm *tm;
    111 
    112 		t = time(0);
    113 		tm = localtime(&t);
    114 		len = strftime(p, reslen, "%Y-%m-%d %T: ", tm);
    115 		p += len;
    116 		reslen -= len;
    117 	}
    118 
    119 	if (pri < ARRAYLEN(ptab)) {
    120 		len = snprintf(p, reslen, "%s: ", ptab[pri].name);
    121 		if (len >= 0 && len < reslen) {
    122 			p += len;
    123 			reslen -= len;
    124 		} else
    125 			*p = '\0';
    126 	}
    127 
    128 	if (print_location)
    129 		snprintf(p, reslen, "%s: %s", func, fmt);
    130 	else
    131 		snprintf(p, reslen, "%s", fmt);
    132 #ifdef BROKEN_PRINTF
    133 	while ((p = strstr(buf,"%z")) != NULL)
    134 		p[1] = 'l';
    135 #endif
    136 
    137 	return buf;
    138 }
    139 
    140 void
    141 _plog(int pri, const char *func, struct sockaddr *sa, const char *fmt, ...)
    142 {
    143 	va_list ap;
    144 
    145 	va_start(ap, fmt);
    146 	plogv(pri, func, sa, fmt, ap);
    147 	va_end(ap);
    148 }
    149 
    150 void
    151 plogv(int pri, const char *func, struct sockaddr *sa,
    152 	const char *fmt, va_list ap)
    153 {
    154 	char *newfmt;
    155 	va_list ap_bak;
    156 
    157 	if (pri > loglevel)
    158 		return;
    159 
    160 	newfmt = plog_common(pri, fmt, func);
    161 
    162 	VA_COPY(ap_bak, ap);
    163 
    164 	if (f_foreground)
    165 		vprintf(newfmt, ap);
    166 
    167 	if (logfile)
    168 		log_vaprint(logp, newfmt, ap_bak);
    169 	else {
    170 		if (pri < ARRAYLEN(ptab))
    171 			vsyslog(ptab[pri].priority, newfmt, ap_bak);
    172 		else
    173 			vsyslog(LOG_ALERT, newfmt, ap_bak);
    174 	}
    175 }
    176 
    177 void
    178 plogdump(pri, data, len)
    179 	int pri;
    180 	void *data;
    181 	size_t len;
    182 {
    183 	caddr_t buf;
    184 	size_t buflen;
    185 	int i, j;
    186 
    187 	if (pri > loglevel)
    188 		return;
    189 
    190 	/*
    191 	 * 2 words a bytes + 1 space 4 bytes + 1 newline 32 bytes
    192 	 * + 2 newline + '\0'
    193 	 */
    194 	buflen = (len * 2) + (len / 4) + (len / 32) + 3;
    195 	buf = racoon_malloc(buflen);
    196 
    197 	i = 0;
    198 	j = 0;
    199 	while (j < len) {
    200 		if (j % 32 == 0)
    201 			buf[i++] = '\n';
    202 		else
    203 		if (j % 4 == 0)
    204 			buf[i++] = ' ';
    205 		snprintf(&buf[i], buflen - i, "%02x",
    206 			((unsigned char *)data)[j] & 0xff);
    207 		i += 2;
    208 		j++;
    209 	}
    210 	if (buflen - i >= 2) {
    211 		buf[i++] = '\n';
    212 		buf[i] = '\0';
    213 	}
    214 	plog(pri, LOCATION, NULL, "%s", buf);
    215 
    216 	racoon_free(buf);
    217 }
    218 
    219 void
    220 ploginit()
    221 {
    222 	if (logfile) {
    223 		logp = log_open(250, logfile);
    224 		if (logp == NULL)
    225 			errx(1, "ERROR: failed to open log file %s.", logfile);
    226 		return;
    227 	}
    228 
    229         openlog(pname, LOG_NDELAY, LOG_DAEMON);
    230 }
    231 
    232 void
    233 plogset(file)
    234 	char *file;
    235 {
    236 	if (logfile != NULL)
    237 		racoon_free(logfile);
    238 	logfile = racoon_strdup(file);
    239 	STRDUP_FATAL(logfile);
    240 }
    241 
    242 /*
    243    Returns a printable string from (possibly) binary data ;
    244    concatenates all unprintable chars to one space.
    245    XXX Maybe the printable chars range is too large...
    246  */
    247 char*
    248 binsanitize(binstr, n)
    249 	char *binstr;
    250 	size_t n;
    251 {
    252 	int p,q;
    253 	char* d;
    254 
    255 	d = racoon_malloc(n + 1);
    256 	for (p = 0, q = 0; p < n; p++) {
    257 		if (isgraph((int)binstr[p])) {
    258 			d[q++] = binstr[p];
    259 		} else {
    260 			if (q && d[q - 1] != ' ')
    261 				d[q++] = ' ';
    262 		}
    263 	}
    264 	d[q++] = '\0';
    265 
    266 	return d;
    267 }
    268 
    269