Initial import from FreeBSD RELENG_4:
[dragonfly.git] / usr.sbin / i4b / isdnd / log.c
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.25 2000/10/09 12:53:29 hm Exp $ 
31  *
32  * $FreeBSD: src/usr.sbin/i4b/isdnd/log.c,v 1.6.2.2 2001/08/01 17:45:03 obrien Exp $
33  *
34  *      last edit-date: [Mon Dec 13 21:47:28 1999]
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
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_CONS|LOG_NDELAY|LOG_PERROR,
93                                 logfacility);
94                 else
95 #endif
96                 (void)openlog("isdnd", LOG_PID|LOG_CONS|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 = malloc(strlen(buf) + 1)) == NULL)
112                 {
113                         log(LL_DBG, "init_log: malloc failed: %s", strerror(errno));
114                         do_exit(1);
115                 }
116
117                 strcpy(p, buf);
118
119                 rarr[i].re_prog = p;
120         }
121 }
122
123 /*---------------------------------------------------------------------------*
124  *      finish logging
125  *---------------------------------------------------------------------------*/
126 void
127 finish_log(void)
128 {
129         if(uselogfile)
130         {
131                 fflush(logfp);
132                 fclose(logfp);
133         }
134         else
135         {
136                 (void)closelog();
137         }
138 }
139
140 /*---------------------------------------------------------------------------*
141  *      place entry into logfile
142  *---------------------------------------------------------------------------*/
143 void
144 log(int what, const char *fmt, ...)
145 {
146         char buffer[LOGBUFLEN];
147         register char *dp;
148         va_list ap;
149
150         va_start(ap, fmt);
151         vsnprintf(buffer, LOGBUFLEN-1, fmt, ap);
152         va_end(ap);
153         
154         dp = getlogdatetime();  /* get time string ptr */
155         
156 #ifdef USE_CURSES
157
158         /* put log on screen ? */
159
160         if((do_fullscreen && curses_ready) &&
161            ((!debug_noscreen) || (debug_noscreen && (what != LL_DBG))))
162         {
163                 wprintw(lower_w, "%s %s %-.*s\n", dp, logtab[what].text,
164
165 /*
166  * FreeBSD-current integrated ncurses. Since then it is no longer possible
167  * to write to the last column in the logfilewindow without causing an
168  * automatic newline to occur resulting in a blank line in that window.
169  */
170 #ifdef __FreeBSD__
171 #include <osreldate.h>
172 #endif
173 #if defined(__FreeBSD_version) && __FreeBSD_version >= 400009           
174 #warning "FreeBSD ncurses is buggy: write to last column = auto newline!"
175                      COLS-((strlen(dp))+(strlen(logtab[what].text))+3), buffer);
176 #else
177                      (int)(COLS-((strlen(dp))+(strlen(logtab[what].text))+2)), buffer);
178 #endif
179                 wrefresh(lower_w);
180         }
181 #endif
182
183 #ifdef I4B_EXTERNAL_MONITOR
184         if(what != LL_MER) /* don't send monitor errs, endless loop !!! */
185                 monitor_evnt_log(logtab[what].pri, logtab[what].text, buffer);
186 #endif
187
188         if(uselogfile)
189         {
190                 fprintf(logfp, "%s %s %s\n", dp, logtab[what].text, buffer);
191         }
192         else
193         {
194                 register char *s = buffer;
195                 
196                 /* strip leading spaces from syslog output */
197                 
198                 while(*s && (*s == ' '))
199                         s++;
200                         
201                 syslog(logtab[what].pri, "%s %s", logtab[what].text, s);
202         }
203
204
205 #if DEBUG
206         if(what != LL_DBG) /* don't check debug logs, endless loop !!! */
207 #endif
208                 check_reg(buffer);
209 }
210
211 /*---------------------------------------------------------------------------*
212  *      return ptr to static area containing date/time
213  *---------------------------------------------------------------------------*/
214 char *
215 getlogdatetime()
216 {
217         static char logdatetime[41];
218         time_t tim;
219         register struct tm *tp;
220         
221         tim = time(NULL);
222         tp = localtime(&tim);
223         strftime(logdatetime,40,I4B_TIME_FORMAT,tp);
224         return(logdatetime);
225 }
226
227 /*---------------------------------------------------------------------------*
228  *      check for a match in the regexp array
229  *---------------------------------------------------------------------------*/
230 static void
231 check_reg(char *logstring)
232 {
233         register int i;
234
235         for(i = 0; i < MAX_RE; i++)
236         {
237                 if(rarr[i].re_flg && (!regexec(&(rarr[i].re), logstring, (size_t) 0, NULL, 0)))
238                 {
239                         char* argv[3];
240                         argv[0] = rarr[i].re_prog;
241                         argv[1] = logstring;
242                         argv[2] = NULL;
243
244                         exec_prog(rarr[i].re_prog, argv);
245                         break;
246                 }
247         }
248 }
249
250 /* EOF */