blob: b24dacd89f802db5679ea181961b2ec98e889c1c [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Logging of zebra
2 * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "log.h"
25#include "memory.h"
26#include "command.h"
27
28struct zlog *zlog_default = NULL;
29
30const char *zlog_proto_names[] =
31{
32 "NONE",
33 "DEFAULT",
34 "ZEBRA",
35 "RIP",
36 "BGP",
37 "OSPF",
38 "RIPNG",
39 "OSPF6",
jardin9e867fe2003-12-23 08:56:18 +000040 "ISIS",
paul718e3742002-12-13 20:15:29 +000041 "MASC",
42 NULL,
43};
44
45const char *zlog_priority[] =
46{
47 "emergencies",
48 "alerts",
49 "critical",
50 "errors",
51 "warnings",
52 "notifications",
53 "informational",
54 "debugging",
55 NULL,
56};
57
58
59
60/* For time string format. */
61#define TIME_BUF 27
62
63/* Utility routine for current time printing. */
64static void
65time_print (FILE *fp)
66{
67 int ret;
68 char buf [TIME_BUF];
69 time_t clock;
70 struct tm *tm;
71
72 time (&clock);
73 tm = localtime (&clock);
74
75 ret = strftime (buf, TIME_BUF, "%Y/%m/%d %H:%M:%S", tm);
76 if (ret == 0) {
77 zlog_warn ("strftime error");
78 }
79
80 fprintf (fp, "%s ", buf);
81}
82
83/* va_list version of zlog. */
84void
85vzlog (struct zlog *zl, int priority, const char *format, va_list *args)
86{
87 /* If zlog is not specified, use default one. */
88 if (zl == NULL)
89 zl = zlog_default;
90
91 /* When zlog_default is also NULL, use stderr for logging. */
92 if (zl == NULL)
93 {
94 time_print (stderr);
95 fprintf (stderr, "%s: ", "unknown");
96 vfprintf (stderr, format, args[ZLOG_NOLOG_INDEX]);
97 fprintf (stderr, "\n");
98 fflush (stderr);
99
100 /* In this case we return at here. */
101 return;
102 }
103
104 /* only log this information if it has not been masked out */
105 if ( priority > zl->maskpri )
106 return ;
107
108 /* Syslog output */
109 if (zl->flags & ZLOG_SYSLOG)
paul828eb7f2003-07-26 06:05:18 +0000110 vsyslog (priority|zlog_default->facility, format, args[ZLOG_SYSLOG_INDEX]);
paul718e3742002-12-13 20:15:29 +0000111
112 /* File output. */
113 if (zl->flags & ZLOG_FILE)
114 {
115 time_print (zl->fp);
hassob04c6992004-10-04 19:10:31 +0000116 if (zl->record_priority)
117 fprintf (zl->fp, "%s: ", zlog_priority[priority]);
paul718e3742002-12-13 20:15:29 +0000118 fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]);
119 vfprintf (zl->fp, format, args[ZLOG_FILE_INDEX]);
120 fprintf (zl->fp, "\n");
121 fflush (zl->fp);
122 }
123
124 /* stdout output. */
125 if (zl->flags & ZLOG_STDOUT)
126 {
127 time_print (stdout);
hassob04c6992004-10-04 19:10:31 +0000128 if (zl->record_priority)
129 fprintf (stdout, "%s: ", zlog_priority[priority]);
paul718e3742002-12-13 20:15:29 +0000130 fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]);
131 vfprintf (stdout, format, args[ZLOG_STDOUT_INDEX]);
132 fprintf (stdout, "\n");
133 fflush (stdout);
134 }
135
136 /* stderr output. */
137 if (zl->flags & ZLOG_STDERR)
138 {
139 time_print (stderr);
hassob04c6992004-10-04 19:10:31 +0000140 if (zl->record_priority)
141 fprintf (stderr, "%s: ", zlog_priority[priority]);
paul718e3742002-12-13 20:15:29 +0000142 fprintf (stderr, "%s: ", zlog_proto_names[zl->protocol]);
143 vfprintf (stderr, format, args[ZLOG_STDERR_INDEX]);
144 fprintf (stderr, "\n");
145 fflush (stderr);
146 }
147
148 /* Terminal monitor. */
149 vty_log (zlog_proto_names[zl->protocol], format, args[ZLOG_NOLOG_INDEX]);
150}
151
152void
153zlog (struct zlog *zl, int priority, const char *format, ...)
154{
155 va_list args[ZLOG_MAX_INDEX];
156 int index;
157
158 for (index = 0; index < ZLOG_MAX_INDEX; index++)
159 va_start(args[index], format);
160
161 vzlog (zl, priority, format, args);
162
163 for (index = 0; index < ZLOG_MAX_INDEX; index++)
164 va_end (args[index]);
165}
166
167void
168zlog_err (const char *format, ...)
169{
170 va_list args[ZLOG_MAX_INDEX];
171 int index;
172
173 for (index = 0; index < ZLOG_MAX_INDEX; index++)
174 va_start(args[index], format);
175
176 vzlog (NULL, LOG_ERR, format, args);
177
178 for (index = 0; index < ZLOG_MAX_INDEX; index++)
179 va_end (args[index]);
180}
181
182void
183zlog_warn (const char *format, ...)
184{
185 va_list args[ZLOG_MAX_INDEX];
186 int index;
187
188 for (index = 0; index < ZLOG_MAX_INDEX; index++)
189 va_start(args[index], format);
190
191 vzlog (NULL, LOG_WARNING, format, args);
192
193 for (index = 0; index < ZLOG_MAX_INDEX; index++)
194 va_end (args[index]);
195}
196
197void
198zlog_info (const char *format, ...)
199{
200 va_list args[ZLOG_MAX_INDEX];
201 int index;
202
203 for (index = 0; index < ZLOG_MAX_INDEX; index++)
204 va_start(args[index], format);
205
206 vzlog (NULL, LOG_INFO, format, args);
207
208 for (index = 0; index < ZLOG_MAX_INDEX; index++)
209 va_end (args[index]);
210}
211
212void
213zlog_notice (const char *format, ...)
214{
215 va_list args[ZLOG_MAX_INDEX];
216 int index;
217
218 for (index = 0; index < ZLOG_MAX_INDEX; index++)
219 va_start(args[index], format);
220
221 vzlog (NULL, LOG_NOTICE, format, args);
222
223 for (index = 0; index < ZLOG_MAX_INDEX; index++)
224 va_end (args[index]);
225}
226
227void
228zlog_debug (const char *format, ...)
229{
230 va_list args[ZLOG_MAX_INDEX];
231 int index;
232
233 for (index = 0; index < ZLOG_MAX_INDEX; index++)
234 va_start(args[index], format);
235
236 vzlog (NULL, LOG_DEBUG, format, args);
237
238 for (index = 0; index < ZLOG_MAX_INDEX; index++)
239 va_end (args[index]);
240}
241
242void
243plog_err (struct zlog *zl, const char *format, ...)
244{
245 va_list args[ZLOG_MAX_INDEX];
246 int index;
247
248 for (index = 0; index < ZLOG_MAX_INDEX; index++)
249 va_start(args[index], format);
250
251 vzlog (zl, LOG_ERR, format, args);
252
253 for (index = 0; index < ZLOG_MAX_INDEX; index++)
254 va_end (args[index]);
255}
256
257void
258plog_warn (struct zlog *zl, const char *format, ...)
259{
260 va_list args[ZLOG_MAX_INDEX];
261 int index;
262
263 for (index = 0; index < ZLOG_MAX_INDEX; index++)
264 va_start(args[index], format);
265
266 vzlog (zl, LOG_WARNING, format, args);
267
268 for (index = 0; index < ZLOG_MAX_INDEX; index++)
269 va_end (args[index]);
270}
271
272void
273plog_info (struct zlog *zl, const char *format, ...)
274{
275 va_list args[ZLOG_MAX_INDEX];
276 int index;
277
278 for (index = 0; index < ZLOG_MAX_INDEX; index++)
279 va_start(args[index], format);
280
281 vzlog (zl, LOG_INFO, format, args);
282
283 for (index = 0; index < ZLOG_MAX_INDEX; index++)
284 va_end (args[index]);
285}
286
287void
288plog_notice (struct zlog *zl, const char *format, ...)
289{
290 va_list args[ZLOG_MAX_INDEX];
291 int index;
292
293 for (index = 0; index < ZLOG_MAX_INDEX; index++)
294 va_start(args[index], format);
295
296 vzlog (zl, LOG_NOTICE, format, args);
297
298 for (index = 0; index < ZLOG_MAX_INDEX; index++)
299 va_end (args[index]);
300}
301
302void
303plog_debug (struct zlog *zl, const char *format, ...)
304{
305 va_list args[ZLOG_MAX_INDEX];
306 int index;
307
308 for (index = 0; index < ZLOG_MAX_INDEX; index++)
309 va_start(args[index], format);
310
311 vzlog (zl, LOG_DEBUG, format, args);
312
313 for (index = 0; index < ZLOG_MAX_INDEX; index++)
314 va_end (args[index]);
315}
316
317
318/* Open log stream */
319struct zlog *
320openzlog (const char *progname, int flags, zlog_proto_t protocol,
321 int syslog_flags, int syslog_facility)
322{
323 struct zlog *zl;
324
325 zl = XMALLOC(MTYPE_ZLOG, sizeof (struct zlog));
326 memset (zl, 0, sizeof (struct zlog));
327
328 zl->ident = progname;
329 zl->flags = flags;
330 zl->protocol = protocol;
331 zl->facility = syslog_facility;
332 zl->maskpri = LOG_DEBUG;
333 zl->record_priority = 0;
334
335 openlog (progname, syslog_flags, zl->facility);
336
337 return zl;
338}
339
340void
341closezlog (struct zlog *zl)
342{
343 closelog();
344 fclose (zl->fp);
345
346 XFREE (MTYPE_ZLOG, zl);
347}
348
349/* Called from command.c. */
350void
351zlog_set_flag (struct zlog *zl, int flags)
352{
353 if (zl == NULL)
354 zl = zlog_default;
355
356 zl->flags |= flags;
357}
358
359void
360zlog_reset_flag (struct zlog *zl, int flags)
361{
362 if (zl == NULL)
363 zl = zlog_default;
364
365 zl->flags &= ~flags;
366}
367
368int
paul9035efa2004-10-10 11:56:56 +0000369zlog_set_file (struct zlog *zl, int flags, const char *filename)
paul718e3742002-12-13 20:15:29 +0000370{
371 FILE *fp;
gdtaa593d52003-12-22 20:15:53 +0000372 mode_t oldumask;
paul718e3742002-12-13 20:15:29 +0000373
374 /* There is opend file. */
375 zlog_reset_file (zl);
376
377 /* Set default zl. */
378 if (zl == NULL)
379 zl = zlog_default;
380
381 /* Open file. */
gdtaa593d52003-12-22 20:15:53 +0000382 oldumask = umask (0777 & ~LOGFILE_MASK);
paul718e3742002-12-13 20:15:29 +0000383 fp = fopen (filename, "a");
384 if (fp == NULL)
gdtaa593d52003-12-22 20:15:53 +0000385 {
386 umask(oldumask);
387 return 0;
388 }
389 umask(oldumask);
paul718e3742002-12-13 20:15:29 +0000390
391 /* Set flags. */
392 zl->filename = strdup (filename);
393 zl->flags |= ZLOG_FILE;
394 zl->fp = fp;
395
396 return 1;
397}
398
399/* Reset opend file. */
400int
401zlog_reset_file (struct zlog *zl)
402{
403 if (zl == NULL)
404 zl = zlog_default;
405
406 zl->flags &= ~ZLOG_FILE;
407
408 if (zl->fp)
409 fclose (zl->fp);
410 zl->fp = NULL;
411
412 if (zl->filename)
413 free (zl->filename);
414 zl->filename = NULL;
415
416 return 1;
417}
418
419/* Reopen log file. */
420int
421zlog_rotate (struct zlog *zl)
422{
423 FILE *fp;
424
425 if (zl == NULL)
426 zl = zlog_default;
427
428 if (zl->fp)
429 fclose (zl->fp);
430 zl->fp = NULL;
431
432 if (zl->filename)
433 {
gdtaa593d52003-12-22 20:15:53 +0000434 mode_t oldumask;
435
436 oldumask = umask (0777 & ~LOGFILE_MASK);
paul718e3742002-12-13 20:15:29 +0000437 fp = fopen (zl->filename, "a");
438 if (fp == NULL)
gdtaa593d52003-12-22 20:15:53 +0000439 {
440 umask(oldumask);
441 return -1;
442 }
443 umask(oldumask);
paul718e3742002-12-13 20:15:29 +0000444 zl->fp = fp;
445 }
446
447 return 1;
448}
449
450static char *zlog_cwd = NULL;
451
452void
453zlog_save_cwd ()
454{
455 char *cwd;
456
457 cwd = getcwd (NULL, MAXPATHLEN);
458
459 zlog_cwd = XMALLOC (MTYPE_TMP, strlen (cwd) + 1);
460 strcpy (zlog_cwd, cwd);
461}
462
463char *
464zlog_get_cwd ()
465{
466 return zlog_cwd;
467}
468
469void
470zlog_free_cwd ()
471{
472 if (zlog_cwd)
473 XFREE (MTYPE_TMP, zlog_cwd);
474}
475
476/* Message lookup function. */
hasso8c328f12004-10-05 21:01:23 +0000477const char *
paul718e3742002-12-13 20:15:29 +0000478lookup (struct message *mes, int key)
479{
480 struct message *pnt;
481
482 for (pnt = mes; pnt->key != 0; pnt++)
483 if (pnt->key == key)
484 return pnt->str;
485
486 return "";
487}
488
489/* Very old hacky version of message lookup function. Still partly
hassob04c6992004-10-04 19:10:31 +0000490 used in bgpd and ospfd. FIXME Seems that it's not used any more. */
hasso8c328f12004-10-05 21:01:23 +0000491const char *
paul718e3742002-12-13 20:15:29 +0000492mes_lookup (struct message *meslist, int max, int index)
493{
494 if (index < 0 || index >= max)
495 {
496 zlog_err ("message index out of bound: %d", max);
497 return NULL;
498 }
499 return meslist[index].str;
500}
ajsca359762004-11-19 23:40:16 +0000501
502/* Wrapper around strerror to handle case where it returns NULL. */
503const char *
504safe_strerror(int errnum)
505{
506 const char *s = strerror(errnum);
507 return (s != NULL) ? s : "Unknown error";
508}