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 72char *pname = NULL; 73u_int32_t loglevel = LLV_BASE; 74int f_foreground = 0; 75 76int print_location = 0; 77 78static struct log *logp = NULL; 79static char *logfile = NULL; 80 81static char *plog_common __P((int, const char *, const char *)); 82 83static 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 96static char * 97plog_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 140void 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 150void 151plogv(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 177void 178plogdump(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 219void 220ploginit() 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 232void 233plogset(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 */ 247char* 248binsanitize(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