Import of tac_plus.v8.tar.gz: 173206 bytes, md5:
[tac_plus.git] / report.c
1 /* 
2    Copyright (c) 1995-1998 by Cisco systems, Inc.
3
4    Permission to use, copy, modify, and distribute this software for
5    any purpose and without fee is hereby granted, provided that this
6    copyright and permission notice appear on all copies of the
7    software and supporting documentation, the name of Cisco Systems,
8    Inc. not be used in advertising or publicity pertaining to
9    distribution of the program without specific prior permission, and
10    notice be given in supporting documentation that modification,
11    copying and distribution is by permission of Cisco Systems, Inc.
12
13    Cisco Systems, Inc. makes no representations about the suitability
14    of this software for any purpose.  THIS SOFTWARE IS PROVIDED ``AS
15    IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
16    WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17    FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20 #include "tac_plus.h"
21 #include <stdio.h>
22
23 #ifdef AIX
24 #include <sys/types.h>
25 #else
26 #include <time.h>
27 #endif
28
29 #ifdef __STDC__
30 #include <stdarg.h>             /* ANSI C, variable length args */
31 #else
32 #include <varargs.h>            /* has 'vararg' definitions */
33 #endif
34
35 FILE *ostream = NULL;
36
37 char *logfile = LOGFILE_DEFAULT;
38
39 /* report:
40  *
41  * This routine reports errors and such via stderr and syslog() if
42  * appopriate.  It just helps avoid a lot of if-else in the code.
43  *
44  * LOG_DEBUG messages are ignored unless debugging is on.
45  * All other priorities are always logged to syslog.
46  */
47
48 #ifdef __STDC__
49 void
50 report(int priority, char *fmt,...)
51 #else
52 /* VARARGS2 */
53 void
54 report(priority, fmt, va_alist)
55 int priority;
56 char *fmt;
57 va_dcl                          /* no terminating semi-colon */
58 #endif
59 {
60     char msg[255];              /* temporary string */
61     char *fp, *bufp, *charp;
62     int len, m, i, n;
63     char digits[16];
64     va_list ap;
65
66 #ifdef __STDC__
67     va_start(ap, fmt);
68 #else
69     va_start(ap);
70 #endif
71
72     /* ensure that msg is never overwritten */
73     n = 255;
74     fp = fmt;
75     len = 0;
76     msg[n-1] = '\0';
77     bufp = msg;
78
79     while (*fp) {
80
81         if (*fp != '%') {
82             if ((len+1) >= n) {
83                 break;
84             }
85             *bufp++ = *fp++;
86             len++;
87             continue;
88         }
89
90         /* seen a '%' */
91         fp++;
92
93         switch (*fp) {
94
95         case 's':
96             fp++;
97             charp = va_arg(ap, char *);
98             m = strlen(charp);
99             break;
100
101         case 'u':
102             fp++;
103             i = va_arg(ap, uint);
104             sprintf(digits, "%u", i);
105             m = strlen(digits);
106             charp = digits;
107             break;
108         case 'x':
109             fp++;
110             i = va_arg(ap, uint);
111             sprintf(digits, "%x", i);
112             m = strlen(digits);
113             charp = digits;
114             break;
115         case 'd':
116             fp++;
117             i = va_arg(ap, int);
118             sprintf(digits, "%d", i);
119             m = strlen(digits);
120             charp = digits;
121             break;
122         }
123             
124         if ((len + m + 1) >= n) {
125             break;
126         }
127
128         memcpy(bufp, charp, m);
129         bufp += m;
130         len += m;
131         continue;
132     }
133
134     msg[len] = '\0';
135
136     /* check we never overwrote the end of the buffer */
137     if (msg[n-1]) {
138         abort();
139     }
140
141     va_end(ap);
142
143
144     if (console) {
145         extern int errno;
146         
147         if (!ostream)
148             ostream = fopen("/dev/console", "w");
149
150         if (ostream) {
151             if (priority == LOG_ERR)
152                 fprintf(ostream, "Error ");
153             fprintf(ostream, "%s\n", msg);
154         }
155         else 
156             syslog(LOG_ERR, "Cannot open /dev/console errno=%d", errno);
157     }
158
159     if (debug) {
160         int logfd;
161
162         logfd = open(logfile, O_CREAT | O_WRONLY | O_APPEND, 0640);
163         if (logfd >= 0) {
164             char buf[512];
165             time_t t = time(NULL);
166             char *ct = ctime(&t);
167
168             ct[24] = '\0';
169             tac_lockfd(logfile, logfd);
170             sprintf(buf, "%s [%d]: ", ct, getpid());
171             write(logfd, buf, strlen(buf));
172             if (priority == LOG_ERR)
173                 write(logfd, "Error ", 6);
174             write(logfd, msg, strlen(msg));
175             write(logfd, "\n", 1);
176             close(logfd);
177         }
178     }
179
180     if (single) {
181         fprintf(stderr, "%s\n", msg);
182     }
183
184     if (priority == LOG_DEBUG)
185         return;
186
187     if (priority == LOG_ERR)
188         syslog(priority, "Error %s", msg);
189     else
190         syslog(priority, "%s", msg);
191 }
192
193 /* format a hex dump for syslog */
194 void
195 report_hex(priority, p, len)
196 u_char *p;
197 int len;
198 {
199     char buf[256];
200     char digit[10];
201     int buflen;
202     int i;
203     
204     if (len <= 0)
205         return;
206
207     buf[0] = '\0';
208     buflen = 0;
209     for (i = 0; i < len && i < 255; i++, p++) {
210
211         sprintf(digit, "0x%x ", *p);
212         strcat(buf, digit);
213         buflen += strlen(digit);
214
215         if (buflen > 75) {
216             report(priority, "%s", buf);
217             buf[0] = '\0';
218             buflen = 0;
219         }
220     }
221
222     if (buf[0]) {
223         report(priority, "%s", buf);
224     }
225 }
226
227
228 /* format a non-null terminated string for syslog */
229 void
230 report_string(priority, p, len)
231 u_char *p;
232 int len;
233 {
234     char buf[256];
235     char *bufp = buf;
236     int i;
237
238     if (len <= 0)
239         return;
240
241     for (i = 0; i < len && i < 255; i++) {
242         if (32 <= *p && *p <= 126) {
243             *bufp++ = *p++;
244         } else {
245             sprintf(bufp, " 0x%x ", *p);
246             bufp += strlen(bufp);
247             p++;
248         }
249     }
250     *bufp = '\0';
251     report(priority, "%s", buf);
252 }
253
254 void
255 regerror(s)
256 char *s;
257 {
258     report(LOG_ERR, "in regular expression %s", s);
259 }
260