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.6 2003/10/06 09:43:27 itojun 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
42 extern int do_monitor;
43 extern int accepted;
44 extern FILE *logfp;
45
46 static void check_reg(char *logstring);
47
48 struct logtab {
49 char *text;
50 int pri;
51 };
52
53 /*---------------------------------------------------------------------------*
54 * table for converting internal log levels into syslog levels
55 *---------------------------------------------------------------------------*/
56 static 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 *---------------------------------------------------------------------------*/
69 void
init_log(void)70 init_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, (char *)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 *---------------------------------------------------------------------------*/
124 void
finish_log(void)125 finish_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 *---------------------------------------------------------------------------*/
141 void
logit(int what,const char * fmt,...)142 logit(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 *---------------------------------------------------------------------------*/
218 char *
getlogdatetime()219 getlogdatetime()
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 *---------------------------------------------------------------------------*/
234 static void
check_reg(char * logstring)235 check_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 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