1/* 2 * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * 25 *--------------------------------------------------------------------------- 26 * 27 * i4b daemon - logging routines 28 * ----------------------------- 29 * 30 * $Id: log.c,v 1.8 2011/08/31 16:24:59 plunky Exp $ 31 * 32 * $FreeBSD$ 33 * 34 * last edit-date: [Mon Jan 8 08:09:36 2001] 35 * 36 *---------------------------------------------------------------------------*/ 37 38#include "isdnd.h" 39 40#define LOGBUFLEN 256 41 42extern int do_monitor; 43extern int accepted; 44extern FILE *logfp; 45 46static void check_reg(char *logstring); 47 48struct logtab { 49 const char *text; 50 int pri; 51}; 52 53/*---------------------------------------------------------------------------* 54 * table for converting internal log levels into syslog levels 55 *---------------------------------------------------------------------------*/ 56static struct logtab logtab[] = { 57 {"ERR", LOG_ERR}, /* error conditions */ 58 {"WRN", LOG_WARNING}, /* warning conditions, nonfatal */ 59 {"DMN", LOG_NOTICE}, /* significant conditions of the daemon */ 60 {"CHD", LOG_INFO}, /* informational, call handling */ 61 {"DBG", LOG_DEBUG}, /* debug messages */ 62 {"MER", LOG_ERR}, /* monitor error conditions */ 63 {"PKT", LOG_INFO} /* packet logging */ 64}; 65 66/*---------------------------------------------------------------------------* 67 * initialize logging 68 *---------------------------------------------------------------------------*/ 69void 70init_log(void) 71{ 72 int i; 73 74 if (uselogfile) 75 { 76 if ((logfp = fopen(logfile, "a")) == NULL) 77 { 78 fprintf(stderr, "ERROR, cannot open logfile %s: %s\n", 79 logfile, strerror(errno)); 80 exit(1); 81 } 82 83 /* set unbuffered operation */ 84 85 setvbuf(logfp, NULL, _IONBF, 0); 86 } 87 else 88 { 89#if DEBUG 90 if (do_debug && do_fork == 0 && do_fullscreen == 0) 91 (void)openlog("isdnd", 92 LOG_PID|LOG_NDELAY|LOG_PERROR, 93 logfacility); 94 else 95#endif 96 (void)openlog("isdnd", LOG_PID|LOG_NDELAY, 97 logfacility); 98 } 99 100 /* initialize the regexp array */ 101 102 for (i = 0; i < MAX_RE; i++) 103 { 104 char *p; 105 char buf[64]; 106 107 snprintf(buf, sizeof(buf), "%s%d", REGPROG_DEF, i); 108 109 rarr[i].re_flg = 0; 110 111 if ((p = strdup(buf)) == NULL) 112 { 113 logit(LL_DBG, "init_log: malloc failed: %s", strerror(errno)); 114 do_exit(1); 115 } 116 117 rarr[i].re_prog = p; 118 } 119} 120 121/*---------------------------------------------------------------------------* 122 * finish logging 123 *---------------------------------------------------------------------------*/ 124void 125finish_log(void) 126{ 127 if (uselogfile) 128 { 129 fflush(logfp); 130 fclose(logfp); 131 } 132 else 133 { 134 (void)closelog(); 135 } 136} 137 138/*---------------------------------------------------------------------------* 139 * place entry into logfile 140 *---------------------------------------------------------------------------*/ 141void 142logit(int what, const char *fmt, ...) 143{ 144 char buffer[LOGBUFLEN]; 145 register char *dp; 146 va_list ap; 147 148 va_start(ap, fmt); 149 vsnprintf(buffer, LOGBUFLEN-1, fmt, ap); 150 va_end(ap); 151 152 dp = getlogdatetime(); /* get time string ptr */ 153 154 /* put some messages on stderr to, important if in early startup 155 phase and not yet daemonized */ 156 if (what == LL_ERR) 157 if (!do_fullscreen || !curses_ready) 158 fprintf(stderr, "isdnd: %s\n", buffer); 159 160#ifdef USE_CURSES 161 162 /* put log on screen ? */ 163 164 if ((do_fullscreen && curses_ready) && 165 ((!debug_noscreen) || (debug_noscreen && (what != LL_DBG)))) 166 { 167 wprintw(lower_w, "%s %s %-.*s\n", dp, logtab[what].text, 168 169/* 170 * FreeBSD-current integrated ncurses. Since then it is no longer possible 171 * to write to the last column in the logfilewindow without causing an 172 * automatic newline to occur resulting in a blank line in that window. 173 */ 174#ifdef __FreeBSD__ 175#include <osreldate.h> 176#endif 177#if defined(__FreeBSD_version) && __FreeBSD_version >= 400009 178#warning "FreeBSD ncurses is buggy: write to last column = auto newline!" 179 COLS-((strlen(dp))+(strlen(logtab[what].text))+3), buffer); 180#else 181 (int)(COLS-((strlen(dp))+(strlen(logtab[what].text))+2)), buffer); 182#endif 183 wrefresh(lower_w); 184 } 185#endif 186 187#ifdef I4B_EXTERNAL_MONITOR 188 if (what != LL_MER) /* don't send monitor errs, endless loop !!! */ 189 monitor_evnt_log(logtab[what].pri, logtab[what].text, buffer); 190#endif 191 192 if (uselogfile) 193 { 194 fprintf(logfp, "%s %s %s\n", dp, logtab[what].text, buffer); 195 } 196 else 197 { 198 register char *s = buffer; 199 200 /* strip leading spaces from syslog output */ 201 202 while(*s && (*s == ' ')) 203 s++; 204 205 syslog(logtab[what].pri, "%s %s", logtab[what].text, s); 206 } 207 208 209#if DEBUG 210 if (what != LL_DBG) /* don't check debug logs, endless loop !!! */ 211#endif 212 check_reg(buffer); 213} 214 215/*---------------------------------------------------------------------------* 216 * return ptr to static area containing date/time 217 *---------------------------------------------------------------------------*/ 218char * 219getlogdatetime() 220{ 221 static char logdatetime[41]; 222 time_t tim; 223 register struct tm *tp; 224 225 tim = time(NULL); 226 tp = localtime(&tim); 227 strftime(logdatetime,40,I4B_TIME_FORMAT,tp); 228 return(logdatetime); 229} 230 231/*---------------------------------------------------------------------------* 232 * check for a match in the regexp array 233 *---------------------------------------------------------------------------*/ 234static void 235check_reg(char *logstring) 236{ 237 register int i; 238 239 for (i = 0; i < MAX_RE; i++) 240 { 241 if (rarr[i].re_flg && (!regexec(&(rarr[i].re), logstring, (size_t) 0, NULL, 0))) 242 { 243 const char* argv[3]; 244 argv[0] = rarr[i].re_prog; 245 argv[1] = logstring; 246 argv[2] = NULL; 247 248 exec_prog(rarr[i].re_prog, argv); 249 break; 250 } 251 } 252} 253 254/* EOF */ 255