1/* 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
30#ifdef FOX_RIP_DEBUG
31
32const char *zlog_proto_names[] =
33{
34  "NONE",
35  "DEFAULT",
36  "ZEBRA",
37  "RIP",
38  "BGP",
39  "OSPF",
40  "RIPNG",
41  "OSPF6",
42  "MASC",
43  NULL,
44};
45#endif /* FOX_RIP_DEBUG */
46
47const char *zlog_priority[] =
48{
49  "emergencies",
50  "alerts",
51  "critical",
52  "errors",
53  "warnings",
54  "notifications",
55  "informational",
56  "debugging",
57  NULL,
58};
59
60#ifdef FOX_RIP_DEBUG
61
62/* For time string format. */
63#define TIME_BUF 27
64
65/* Utility routine for current time printing. */
66static void
67time_print (FILE *fp)
68{
69  int ret;
70  char buf [TIME_BUF];
71  time_t clock;
72  struct tm *tm;
73
74  time (&clock);
75  tm = localtime (&clock);
76
77  ret = strftime (buf, TIME_BUF, "%Y/%m/%d %H:%M:%S", tm);
78  if (ret == 0) {
79    zlog_warn ("strftime error");
80  }
81
82  fprintf (fp, "%s ", buf);
83}
84
85/* va_list version of zlog. */
86void
87vzlog (struct zlog *zl, int priority, const char *format, va_list *args)
88{
89  /* If zlog is not specified, use default one. */
90  if (zl == NULL)
91    zl = zlog_default;
92
93  /* When zlog_default is also NULL, use stderr for logging. */
94  if (zl == NULL)
95    {
96      time_print (stderr);
97      fprintf (stderr, "%s: ", "unknown");
98      vfprintf (stderr, format, args[ZLOG_NOLOG_INDEX]);
99      fprintf (stderr, "\n");
100      fflush (stderr);
101
102      /* In this case we return at here. */
103      return;
104    }
105
106  /* only log this information if it has not been masked out */
107  if ( priority > zl->maskpri )
108    return ;
109
110  /* Syslog output */
111  if (zl->flags & ZLOG_SYSLOG)
112    vsyslog (priority, format, args[ZLOG_SYSLOG_INDEX]);
113
114  /* File output. */
115  if (zl->flags & ZLOG_FILE)
116    {
117      time_print (zl->fp);
118      if (zl->record_priority) fprintf (zl->fp, "%s: ", zlog_priority[priority]);
119      fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]);
120      vfprintf (zl->fp, format, args[ZLOG_FILE_INDEX]);
121      fprintf (zl->fp, "\n");
122      fflush (zl->fp);
123    }
124
125  /* stdout output. */
126  if (zl->flags & ZLOG_STDOUT)
127    {
128      time_print (stdout);
129      if (zl->record_priority) fprintf (stdout, "%s: ", zlog_priority[priority]);
130      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);
140      if (zl->record_priority) fprintf (stderr, "%s: ", zlog_priority[priority]);
141      fprintf (stderr, "%s: ", zlog_proto_names[zl->protocol]);
142      vfprintf (stderr, format, args[ZLOG_STDERR_INDEX]);
143      fprintf (stderr, "\n");
144      fflush (stderr);
145    }
146
147  /* Terminal monitor. */
148  vty_log (zlog_proto_names[zl->protocol], format, args[ZLOG_NOLOG_INDEX]);
149}
150
151void
152zlog (struct zlog *zl, int priority, const char *format, ...)
153{
154  va_list args[ZLOG_MAX_INDEX];
155  int index;
156
157  for (index = 0; index < ZLOG_MAX_INDEX; index++)
158    va_start(args[index], format);
159
160  vzlog (zl, priority, format, args);
161
162  for (index = 0; index < ZLOG_MAX_INDEX; index++)
163    va_end (args[index]);
164}
165
166void
167zlog_err (const char *format, ...)
168{
169  va_list args[ZLOG_MAX_INDEX];
170  int index;
171
172  for (index = 0; index < ZLOG_MAX_INDEX; index++)
173    va_start(args[index], format);
174
175  vzlog (NULL, LOG_ERR, format, args);
176
177  for (index = 0; index < ZLOG_MAX_INDEX; index++)
178    va_end (args[index]);
179}
180
181void
182zlog_warn (const char *format, ...)
183{
184  va_list args[ZLOG_MAX_INDEX];
185  int index;
186
187  for (index = 0; index < ZLOG_MAX_INDEX; index++)
188    va_start(args[index], format);
189
190  vzlog (NULL, LOG_WARNING, format, args);
191
192  for (index = 0; index < ZLOG_MAX_INDEX; index++)
193    va_end (args[index]);
194}
195
196void
197zlog_info (const char *format, ...)
198{
199  va_list args[ZLOG_MAX_INDEX];
200  int index;
201
202  for (index = 0; index < ZLOG_MAX_INDEX; index++)
203    va_start(args[index], format);
204
205  vzlog (NULL, LOG_INFO, format, args);
206
207  for (index = 0; index < ZLOG_MAX_INDEX; index++)
208    va_end (args[index]);
209}
210
211void
212zlog_notice (const char *format, ...)
213{
214  va_list args[ZLOG_MAX_INDEX];
215  int index;
216
217  for (index = 0; index < ZLOG_MAX_INDEX; index++)
218    va_start(args[index], format);
219
220  vzlog (NULL, LOG_NOTICE, format, args);
221
222  for (index = 0; index < ZLOG_MAX_INDEX; index++)
223    va_end (args[index]);
224}
225
226void
227zlog_debug (const char *format, ...)
228{
229  va_list args[ZLOG_MAX_INDEX];
230  int index;
231
232  for (index = 0; index < ZLOG_MAX_INDEX; index++)
233    va_start(args[index], format);
234
235  vzlog (NULL, LOG_DEBUG, format, args);
236
237  for (index = 0; index < ZLOG_MAX_INDEX; index++)
238    va_end (args[index]);
239}
240
241void
242plog_err (struct zlog *zl, const char *format, ...)
243{
244  va_list args[ZLOG_MAX_INDEX];
245  int index;
246
247  for (index = 0; index < ZLOG_MAX_INDEX; index++)
248    va_start(args[index], format);
249
250  vzlog (zl, LOG_ERR, format, args);
251
252  for (index = 0; index < ZLOG_MAX_INDEX; index++)
253    va_end (args[index]);
254}
255
256void
257plog_warn (struct zlog *zl, const char *format, ...)
258{
259  va_list args[ZLOG_MAX_INDEX];
260  int index;
261
262  for (index = 0; index < ZLOG_MAX_INDEX; index++)
263    va_start(args[index], format);
264
265  vzlog (zl, LOG_WARNING, format, args);
266
267  for (index = 0; index < ZLOG_MAX_INDEX; index++)
268    va_end (args[index]);
269}
270
271void
272plog_info (struct zlog *zl, const char *format, ...)
273{
274  va_list args[ZLOG_MAX_INDEX];
275  int index;
276
277  for (index = 0; index < ZLOG_MAX_INDEX; index++)
278    va_start(args[index], format);
279
280  vzlog (zl, LOG_INFO, format, args);
281
282  for (index = 0; index < ZLOG_MAX_INDEX; index++)
283    va_end (args[index]);
284}
285
286void
287plog_notice (struct zlog *zl, const char *format, ...)
288{
289  va_list args[ZLOG_MAX_INDEX];
290  int index;
291
292  for (index = 0; index < ZLOG_MAX_INDEX; index++)
293    va_start(args[index], format);
294
295  vzlog (zl, LOG_NOTICE, format, args);
296
297  for (index = 0; index < ZLOG_MAX_INDEX; index++)
298    va_end (args[index]);
299}
300
301void
302plog_debug (struct zlog *zl, const char *format, ...)
303{
304  va_list args[ZLOG_MAX_INDEX];
305  int index;
306
307  for (index = 0; index < ZLOG_MAX_INDEX; index++)
308    va_start(args[index], format);
309
310  vzlog (zl, LOG_DEBUG, format, args);
311
312  for (index = 0; index < ZLOG_MAX_INDEX; index++)
313    va_end (args[index]);
314}
315
316
317/* Open log stream */
318struct zlog *
319openzlog (const char *progname, int flags, zlog_proto_t protocol,
320	  int syslog_flags, int syslog_facility)
321{
322  struct zlog *zl;
323
324  zl = XMALLOC(MTYPE_ZLOG, sizeof (struct zlog));
325  memset (zl, 0, sizeof (struct zlog));
326
327  zl->ident = progname;
328  zl->flags = flags;
329  zl->protocol = protocol;
330  zl->facility = syslog_facility;
331  zl->maskpri = LOG_DEBUG;
332  zl->record_priority = 0;
333
334  openlog (progname, syslog_flags, zl->facility);
335
336  return zl;
337}
338
339void
340closezlog (struct zlog *zl)
341{
342  closelog();
343  fclose (zl->fp);
344
345  XFREE (MTYPE_ZLOG, zl);
346}
347
348/* Called from command.c. */
349void
350zlog_set_flag (struct zlog *zl, int flags)
351{
352  if (zl == NULL)
353    zl = zlog_default;
354
355  zl->flags |= flags;
356}
357
358void
359zlog_reset_flag (struct zlog *zl, int flags)
360{
361  if (zl == NULL)
362    zl = zlog_default;
363
364  zl->flags &= ~flags;
365}
366
367int
368zlog_set_file (struct zlog *zl, int flags, char *filename)
369{
370  FILE *fp;
371
372  /* There is opend file.  */
373  zlog_reset_file (zl);
374
375  /* Set default zl. */
376  if (zl == NULL)
377    zl = zlog_default;
378
379  /* Open file. */
380  fp = fopen (filename, "a");
381  if (fp == NULL)
382    return 0;
383
384  /* Set flags. */
385  zl->filename = strdup (filename);
386  zl->flags |= ZLOG_FILE;
387  zl->fp = fp;
388
389  return 1;
390}
391
392/* Reset opend file. */
393int
394zlog_reset_file (struct zlog *zl)
395{
396  if (zl == NULL)
397    zl = zlog_default;
398
399  zl->flags &= ~ZLOG_FILE;
400
401  if (zl->fp)
402    fclose (zl->fp);
403  zl->fp = NULL;
404
405  if (zl->filename)
406    free (zl->filename);
407  zl->filename = NULL;
408
409  return 1;
410}
411
412/* Reopen log file. */
413int
414zlog_rotate (struct zlog *zl)
415{
416  FILE *fp;
417
418  if (zl == NULL)
419    zl = zlog_default;
420
421  if (zl->fp)
422    fclose (zl->fp);
423  zl->fp = NULL;
424
425  if (zl->filename)
426    {
427      fp = fopen (zl->filename, "a");
428      if (fp == NULL)
429	return -1;
430      zl->fp = fp;
431    }
432
433  return 1;
434}
435
436static char *zlog_cwd = NULL;
437
438void
439zlog_save_cwd ()
440{
441  char *cwd;
442
443  cwd = getcwd (NULL, MAXPATHLEN);
444
445  zlog_cwd = XMALLOC (MTYPE_TMP, strlen (cwd) + 1);
446  strcpy (zlog_cwd, cwd);
447}
448
449char *
450zlog_get_cwd ()
451{
452  return zlog_cwd;
453}
454
455void
456zlog_free_cwd ()
457{
458  if (zlog_cwd)
459    XFREE (MTYPE_TMP, zlog_cwd);
460}
461#endif /* FOX_RIP_DEBUG */
462
463/* Message lookup function. */
464char *
465lookup (struct message *mes, int key)
466{
467  struct message *pnt;
468
469  for (pnt = mes; pnt->key != 0; pnt++)
470    if (pnt->key == key)
471      return pnt->str;
472
473  return "";
474}
475
476#ifdef FOX_RIP_DEBUG
477/* Very old hacky version of message lookup function.  Still partly
478   used in bgpd and ospfd. */
479char *
480mes_lookup (struct message *meslist, int max, int index)
481{
482  if (index < 0 || index >= max)
483    {
484      zlog_err ("message index out of bound: %d", max);
485      return NULL;
486    }
487  return meslist[index].str;
488}
489
490#endif /* FOX_RIP_DEBUG */
491