From 718e3744195351130f4ce7dbe0613f4b3e23df93 Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 13 Dec 2002 20:15:29 +0000 Subject: Initial revision --- lib/log.c | 483 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 483 insertions(+) create mode 100644 lib/log.c (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c new file mode 100644 index 00000000..9c676428 --- /dev/null +++ b/lib/log.c @@ -0,0 +1,483 @@ +/* Logging of zebra + * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include + +#include "log.h" +#include "memory.h" +#include "command.h" + +struct zlog *zlog_default = NULL; + +const char *zlog_proto_names[] = +{ + "NONE", + "DEFAULT", + "ZEBRA", + "RIP", + "BGP", + "OSPF", + "RIPNG", + "OSPF6", + "MASC", + NULL, +}; + +const char *zlog_priority[] = +{ + "emergencies", + "alerts", + "critical", + "errors", + "warnings", + "notifications", + "informational", + "debugging", + NULL, +}; + + + +/* For time string format. */ +#define TIME_BUF 27 + +/* Utility routine for current time printing. */ +static void +time_print (FILE *fp) +{ + int ret; + char buf [TIME_BUF]; + time_t clock; + struct tm *tm; + + time (&clock); + tm = localtime (&clock); + + ret = strftime (buf, TIME_BUF, "%Y/%m/%d %H:%M:%S", tm); + if (ret == 0) { + zlog_warn ("strftime error"); + } + + fprintf (fp, "%s ", buf); +} + +/* va_list version of zlog. */ +void +vzlog (struct zlog *zl, int priority, const char *format, va_list *args) +{ + /* If zlog is not specified, use default one. */ + if (zl == NULL) + zl = zlog_default; + + /* When zlog_default is also NULL, use stderr for logging. */ + if (zl == NULL) + { + time_print (stderr); + fprintf (stderr, "%s: ", "unknown"); + vfprintf (stderr, format, args[ZLOG_NOLOG_INDEX]); + fprintf (stderr, "\n"); + fflush (stderr); + + /* In this case we return at here. */ + return; + } + + /* only log this information if it has not been masked out */ + if ( priority > zl->maskpri ) + return ; + + /* Syslog output */ + if (zl->flags & ZLOG_SYSLOG) + vsyslog (priority, format, args[ZLOG_SYSLOG_INDEX]); + + /* File output. */ + if (zl->flags & ZLOG_FILE) + { + time_print (zl->fp); + if (zl->record_priority) fprintf (zl->fp, "%s: ", zlog_priority[priority]); + fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]); + vfprintf (zl->fp, format, args[ZLOG_FILE_INDEX]); + fprintf (zl->fp, "\n"); + fflush (zl->fp); + } + + /* stdout output. */ + if (zl->flags & ZLOG_STDOUT) + { + time_print (stdout); + if (zl->record_priority) fprintf (stdout, "%s: ", zlog_priority[priority]); + fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]); + vfprintf (stdout, format, args[ZLOG_STDOUT_INDEX]); + fprintf (stdout, "\n"); + fflush (stdout); + } + + /* stderr output. */ + if (zl->flags & ZLOG_STDERR) + { + time_print (stderr); + if (zl->record_priority) fprintf (stderr, "%s: ", zlog_priority[priority]); + fprintf (stderr, "%s: ", zlog_proto_names[zl->protocol]); + vfprintf (stderr, format, args[ZLOG_STDERR_INDEX]); + fprintf (stderr, "\n"); + fflush (stderr); + } + + /* Terminal monitor. */ + vty_log (zlog_proto_names[zl->protocol], format, args[ZLOG_NOLOG_INDEX]); +} + +void +zlog (struct zlog *zl, int priority, const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (zl, priority, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + +void +zlog_err (const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (NULL, LOG_ERR, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + +void +zlog_warn (const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (NULL, LOG_WARNING, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + +void +zlog_info (const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (NULL, LOG_INFO, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + +void +zlog_notice (const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (NULL, LOG_NOTICE, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + +void +zlog_debug (const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (NULL, LOG_DEBUG, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + +void +plog_err (struct zlog *zl, const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (zl, LOG_ERR, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + +void +plog_warn (struct zlog *zl, const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (zl, LOG_WARNING, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + +void +plog_info (struct zlog *zl, const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (zl, LOG_INFO, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + +void +plog_notice (struct zlog *zl, const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (zl, LOG_NOTICE, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + +void +plog_debug (struct zlog *zl, const char *format, ...) +{ + va_list args[ZLOG_MAX_INDEX]; + int index; + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_start(args[index], format); + + vzlog (zl, LOG_DEBUG, format, args); + + for (index = 0; index < ZLOG_MAX_INDEX; index++) + va_end (args[index]); +} + + +/* Open log stream */ +struct zlog * +openzlog (const char *progname, int flags, zlog_proto_t protocol, + int syslog_flags, int syslog_facility) +{ + struct zlog *zl; + + zl = XMALLOC(MTYPE_ZLOG, sizeof (struct zlog)); + memset (zl, 0, sizeof (struct zlog)); + + zl->ident = progname; + zl->flags = flags; + zl->protocol = protocol; + zl->facility = syslog_facility; + zl->maskpri = LOG_DEBUG; + zl->record_priority = 0; + + openlog (progname, syslog_flags, zl->facility); + + return zl; +} + +void +closezlog (struct zlog *zl) +{ + closelog(); + fclose (zl->fp); + + XFREE (MTYPE_ZLOG, zl); +} + +/* Called from command.c. */ +void +zlog_set_flag (struct zlog *zl, int flags) +{ + if (zl == NULL) + zl = zlog_default; + + zl->flags |= flags; +} + +void +zlog_reset_flag (struct zlog *zl, int flags) +{ + if (zl == NULL) + zl = zlog_default; + + zl->flags &= ~flags; +} + +int +zlog_set_file (struct zlog *zl, int flags, char *filename) +{ + FILE *fp; + + /* There is opend file. */ + zlog_reset_file (zl); + + /* Set default zl. */ + if (zl == NULL) + zl = zlog_default; + + /* Open file. */ + fp = fopen (filename, "a"); + if (fp == NULL) + return 0; + + /* Set flags. */ + zl->filename = strdup (filename); + zl->flags |= ZLOG_FILE; + zl->fp = fp; + + return 1; +} + +/* Reset opend file. */ +int +zlog_reset_file (struct zlog *zl) +{ + if (zl == NULL) + zl = zlog_default; + + zl->flags &= ~ZLOG_FILE; + + if (zl->fp) + fclose (zl->fp); + zl->fp = NULL; + + if (zl->filename) + free (zl->filename); + zl->filename = NULL; + + return 1; +} + +/* Reopen log file. */ +int +zlog_rotate (struct zlog *zl) +{ + FILE *fp; + + if (zl == NULL) + zl = zlog_default; + + if (zl->fp) + fclose (zl->fp); + zl->fp = NULL; + + if (zl->filename) + { + fp = fopen (zl->filename, "a"); + if (fp == NULL) + return -1; + zl->fp = fp; + } + + return 1; +} + +static char *zlog_cwd = NULL; + +void +zlog_save_cwd () +{ + char *cwd; + + cwd = getcwd (NULL, MAXPATHLEN); + + zlog_cwd = XMALLOC (MTYPE_TMP, strlen (cwd) + 1); + strcpy (zlog_cwd, cwd); +} + +char * +zlog_get_cwd () +{ + return zlog_cwd; +} + +void +zlog_free_cwd () +{ + if (zlog_cwd) + XFREE (MTYPE_TMP, zlog_cwd); +} + +/* Message lookup function. */ +char * +lookup (struct message *mes, int key) +{ + struct message *pnt; + + for (pnt = mes; pnt->key != 0; pnt++) + if (pnt->key == key) + return pnt->str; + + return ""; +} + +/* Very old hacky version of message lookup function. Still partly + used in bgpd and ospfd. */ +char * +mes_lookup (struct message *meslist, int max, int index) +{ + if (index < 0 || index >= max) + { + zlog_err ("message index out of bound: %d", max); + return NULL; + } + return meslist[index].str; +} -- cgit v1.2.3 From 828eb7fb46a61ab7bc5fdf393dc8c5b65fd1ec24 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 26 Jul 2003 06:05:18 +0000 Subject: 2003-07-26 Paul Jakma * lib/command.c: Add config_log_syslog_facility_cmd, to set syslog facility. This was a commit to zebra.org on May 20, merge in to zebra-pj. --- lib/log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 9c676428..88e1dbf0 100644 --- a/lib/log.c +++ b/lib/log.c @@ -106,7 +106,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list *args) /* Syslog output */ if (zl->flags & ZLOG_SYSLOG) - vsyslog (priority, format, args[ZLOG_SYSLOG_INDEX]); + vsyslog (priority|zlog_default->facility, format, args[ZLOG_SYSLOG_INDEX]); /* File output. */ if (zl->flags & ZLOG_FILE) -- cgit v1.2.3 From aa593d5e2638566ead1e69381e60639550991ff2 Mon Sep 17 00:00:00 2001 From: gdt Date: Mon, 22 Dec 2003 20:15:53 +0000 Subject: 2003-12-22 Christian Hammers * configure.ac (and everywhere a regular file is opened for writing): use file permissions from configure rather than compiled-in umask. --- lib/log.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 88e1dbf0..aedab3c6 100644 --- a/lib/log.c +++ b/lib/log.c @@ -365,6 +365,7 @@ int zlog_set_file (struct zlog *zl, int flags, char *filename) { FILE *fp; + mode_t oldumask; /* There is opend file. */ zlog_reset_file (zl); @@ -374,9 +375,14 @@ zlog_set_file (struct zlog *zl, int flags, char *filename) zl = zlog_default; /* Open file. */ + oldumask = umask (0777 & ~LOGFILE_MASK); fp = fopen (filename, "a"); if (fp == NULL) - return 0; + { + umask(oldumask); + return 0; + } + umask(oldumask); /* Set flags. */ zl->filename = strdup (filename); @@ -421,9 +427,16 @@ zlog_rotate (struct zlog *zl) if (zl->filename) { + mode_t oldumask; + + oldumask = umask (0777 & ~LOGFILE_MASK); fp = fopen (zl->filename, "a"); if (fp == NULL) - return -1; + { + umask(oldumask); + return -1; + } + umask(oldumask); zl->fp = fp; } -- cgit v1.2.3 From 9e867fe663c4eb43c36f35067c0dd092e8c83c14 Mon Sep 17 00:00:00 2001 From: jardin Date: Tue, 23 Dec 2003 08:56:18 +0000 Subject: Merge isisd into the Quagga's framework: - add privs support - use misc quagga's definitions - make it compile"able" - fix segfault cases related to hostname() - add debug isis xxx command This patch has been approved by Paul Jakma. --- lib/log.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index aedab3c6..5f6b32f5 100644 --- a/lib/log.c +++ b/lib/log.c @@ -37,6 +37,7 @@ const char *zlog_proto_names[] = "OSPF", "RIPNG", "OSPF6", + "ISIS", "MASC", NULL, }; -- cgit v1.2.3 From b04c699ecfb4704a67f4583e4ea929a6a3e49856 Mon Sep 17 00:00:00 2001 From: hasso Date: Mon, 4 Oct 2004 19:10:31 +0000 Subject: First small part of lib cleanup. Mainly "constification" of arguments and adding FIXME's. --- lib/log.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 5f6b32f5..2090b91e 100644 --- a/lib/log.c +++ b/lib/log.c @@ -113,7 +113,8 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list *args) if (zl->flags & ZLOG_FILE) { time_print (zl->fp); - if (zl->record_priority) fprintf (zl->fp, "%s: ", zlog_priority[priority]); + if (zl->record_priority) + fprintf (zl->fp, "%s: ", zlog_priority[priority]); fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]); vfprintf (zl->fp, format, args[ZLOG_FILE_INDEX]); fprintf (zl->fp, "\n"); @@ -124,7 +125,8 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list *args) if (zl->flags & ZLOG_STDOUT) { time_print (stdout); - if (zl->record_priority) fprintf (stdout, "%s: ", zlog_priority[priority]); + if (zl->record_priority) + fprintf (stdout, "%s: ", zlog_priority[priority]); fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]); vfprintf (stdout, format, args[ZLOG_STDOUT_INDEX]); fprintf (stdout, "\n"); @@ -135,7 +137,8 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list *args) if (zl->flags & ZLOG_STDERR) { time_print (stderr); - if (zl->record_priority) fprintf (stderr, "%s: ", zlog_priority[priority]); + if (zl->record_priority) + fprintf (stderr, "%s: ", zlog_priority[priority]); fprintf (stderr, "%s: ", zlog_proto_names[zl->protocol]); vfprintf (stderr, format, args[ZLOG_STDERR_INDEX]); fprintf (stderr, "\n"); @@ -484,7 +487,7 @@ lookup (struct message *mes, int key) } /* Very old hacky version of message lookup function. Still partly - used in bgpd and ospfd. */ + used in bgpd and ospfd. FIXME Seems that it's not used any more. */ char * mes_lookup (struct message *meslist, int max, int index) { -- cgit v1.2.3 From 8c328f1106cf0498333c2d8a96940e7b4581e316 Mon Sep 17 00:00:00 2001 From: hasso Date: Tue, 5 Oct 2004 21:01:23 +0000 Subject: Number of warnings is down to 3 again in lib directory. A lot of const's added to strings and a lot of int -> unsigned int changes. --- lib/log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 2090b91e..bbe6e996 100644 --- a/lib/log.c +++ b/lib/log.c @@ -474,7 +474,7 @@ zlog_free_cwd () } /* Message lookup function. */ -char * +const char * lookup (struct message *mes, int key) { struct message *pnt; @@ -488,7 +488,7 @@ lookup (struct message *mes, int key) /* Very old hacky version of message lookup function. Still partly used in bgpd and ospfd. FIXME Seems that it's not used any more. */ -char * +const char * mes_lookup (struct message *meslist, int max, int index) { if (index < 0 || index >= max) -- cgit v1.2.3 From 9035efaa924c69f4f4fcb1049c7dc4f43b9da980 Mon Sep 17 00:00:00 2001 From: paul Date: Sun, 10 Oct 2004 11:56:56 +0000 Subject: 2004-10-10 Paul Jakma * version.h.in: (pid_output*) add const qualifier. * command.h: Change DEFUN func to take const char *[] rather than char **, to begin process of fixing compile warnings in lib/. Nearly all other changes in this commit follow from this change. * buffer.{c,h}: (buffer_write) pointer-arithmetic is gccism, take const void * and cast an automatic const char *p to it. (buffer_putstr) add const * command.c: (zencrypt) const qualifier (cmd_execute_command_real) ditto (cmd_execute_command_strict) ditto (config_log_file) ditto. Fix leak of getcwd() returned string. * memory.{c,h}: Add MTYPE_DISTRIBUTE_IFNAME for struct dist ifname. * distribute.{c,h}: Update with const qualifier. (distribute_free) use MTYPE_DISTRIBUTE_IFNAME (distribute_lookup) Cast to char *, note that it's ok. (distribute_hash_alloc) use MTYPE_DISTRIBUTE_IFNAME. (distribute_get) Cast to char *, note that it's ok. * filter.c: Update with const qualifier. * if.{c,h}: ditto. * if_rmap.{c,h}: ditto. (if_rmap_lookup) Cast to char *, note that it's ok. (if_rmap_get) ditto. * log.{c,h}: Update with const qualifier. * plist.{c,h}: ditto. * routemap.{c,h}: ditto. * smux.{c,h}: ditto. Fix some signed/unsigned comparisons. * sockopt.c: (getsockopt_cmsg_data) add return for error case. * vty.c: Update with const qualifier. --- lib/log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index bbe6e996..375730f2 100644 --- a/lib/log.c +++ b/lib/log.c @@ -366,7 +366,7 @@ zlog_reset_flag (struct zlog *zl, int flags) } int -zlog_set_file (struct zlog *zl, int flags, char *filename) +zlog_set_file (struct zlog *zl, int flags, const char *filename) { FILE *fp; mode_t oldumask; -- cgit v1.2.3 From ca35976927190883368ef3bd32bbf9f174575bd6 Mon Sep 17 00:00:00 2001 From: ajs Date: Fri, 19 Nov 2004 23:40:16 +0000 Subject: 2004-11-19 David Young * log.c: (safe_strerror) New function: safe wrapper for strerror. --- lib/log.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 375730f2..b24dacd8 100644 --- a/lib/log.c +++ b/lib/log.c @@ -498,3 +498,11 @@ mes_lookup (struct message *meslist, int max, int index) } return meslist[index].str; } + +/* Wrapper around strerror to handle case where it returns NULL. */ +const char * +safe_strerror(int errnum) +{ + const char *s = strerror(errnum); + return (s != NULL) ? s : "Unknown error"; +} -- cgit v1.2.3 From d246bd965898f0ba6781f2b2048af9a5eba079d3 Mon Sep 17 00:00:00 2001 From: ajs Date: Tue, 23 Nov 2004 17:35:08 +0000 Subject: 2004-11-23 Andrew J. Schorr * log.c: (vzlog) Take a single va_list argument and use va_copy as necessary for multiple traversals. (zlog) Pass only one va_list to vzlog. (zlog_*,plog_*) Use a macro for boilerplate code; pass only one va_list to vzlog. (zlog_set_file) Remove unused 2nd argument (flags). (zlog_save_cwd,zlog_get_cwd,zlog_free_cwd) Remove unused functions. * log.h: Remove ZLOG_*_INDEX defines (no longer used). Remove unused 2nd argument from zlog_set_file prototype. Fix prototype for zlog_rotate. * command.c: (config_log_file) Remove unused 2nd arg to zlog_set_file. * vty.c: (vty_out) Fix stdarg usage to perform multiple traversals properly. (vty_log) Must use va_copy for multiple traversals of va_list arg. --- lib/log.c | 231 +++++++++++++++----------------------------------------------- 1 file changed, 54 insertions(+), 177 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index b24dacd8..205b7c0d 100644 --- a/lib/log.c +++ b/lib/log.c @@ -81,8 +81,8 @@ time_print (FILE *fp) } /* va_list version of zlog. */ -void -vzlog (struct zlog *zl, int priority, const char *format, va_list *args) +static void +vzlog (struct zlog *zl, int priority, const char *format, va_list args) { /* If zlog is not specified, use default one. */ if (zl == NULL) @@ -93,7 +93,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list *args) { time_print (stderr); fprintf (stderr, "%s: ", "unknown"); - vfprintf (stderr, format, args[ZLOG_NOLOG_INDEX]); + vfprintf (stderr, format, args); fprintf (stderr, "\n"); fflush (stderr); @@ -107,16 +107,24 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list *args) /* Syslog output */ if (zl->flags & ZLOG_SYSLOG) - vsyslog (priority|zlog_default->facility, format, args[ZLOG_SYSLOG_INDEX]); + { + va_list ac; + va_copy(ac, args); + vsyslog (priority|zlog_default->facility, format, ac); + va_end(ac); + } /* File output. */ if (zl->flags & ZLOG_FILE) { + va_list ac; time_print (zl->fp); if (zl->record_priority) fprintf (zl->fp, "%s: ", zlog_priority[priority]); fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]); - vfprintf (zl->fp, format, args[ZLOG_FILE_INDEX]); + va_copy(ac, args); + vfprintf (zl->fp, format, ac); + va_end(ac); fprintf (zl->fp, "\n"); fflush (zl->fp); } @@ -124,11 +132,14 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list *args) /* stdout output. */ if (zl->flags & ZLOG_STDOUT) { + va_list ac; time_print (stdout); if (zl->record_priority) fprintf (stdout, "%s: ", zlog_priority[priority]); fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]); - vfprintf (stdout, format, args[ZLOG_STDOUT_INDEX]); + va_copy(ac, args); + vfprintf (stdout, format, ac); + va_end(ac); fprintf (stdout, "\n"); fflush (stdout); } @@ -136,183 +147,75 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list *args) /* stderr output. */ if (zl->flags & ZLOG_STDERR) { + va_list ac; time_print (stderr); if (zl->record_priority) fprintf (stderr, "%s: ", zlog_priority[priority]); fprintf (stderr, "%s: ", zlog_proto_names[zl->protocol]); - vfprintf (stderr, format, args[ZLOG_STDERR_INDEX]); + va_copy(ac, args); + vfprintf (stderr, format, ac); + va_end(ac); fprintf (stderr, "\n"); fflush (stderr); } /* Terminal monitor. */ - vty_log (zlog_proto_names[zl->protocol], format, args[ZLOG_NOLOG_INDEX]); + vty_log (zlog_proto_names[zl->protocol], format, args); } void zlog (struct zlog *zl, int priority, const char *format, ...) { - va_list args[ZLOG_MAX_INDEX]; - int index; - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); + va_list args; + va_start(args, format); vzlog (zl, priority, format, args); - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); -} - -void -zlog_err (const char *format, ...) -{ - va_list args[ZLOG_MAX_INDEX]; - int index; - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); - - vzlog (NULL, LOG_ERR, format, args); - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); -} - -void -zlog_warn (const char *format, ...) -{ - va_list args[ZLOG_MAX_INDEX]; - int index; - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); - - vzlog (NULL, LOG_WARNING, format, args); - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); -} - -void -zlog_info (const char *format, ...) -{ - va_list args[ZLOG_MAX_INDEX]; - int index; - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); - - vzlog (NULL, LOG_INFO, format, args); - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); -} - -void -zlog_notice (const char *format, ...) -{ - va_list args[ZLOG_MAX_INDEX]; - int index; - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); - - vzlog (NULL, LOG_NOTICE, format, args); - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); -} - -void -zlog_debug (const char *format, ...) -{ - va_list args[ZLOG_MAX_INDEX]; - int index; - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); - - vzlog (NULL, LOG_DEBUG, format, args); - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); + va_end (args); } -void -plog_err (struct zlog *zl, const char *format, ...) -{ - va_list args[ZLOG_MAX_INDEX]; - int index; - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); - - vzlog (zl, LOG_ERR, format, args); - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); +#define ZLOG_FUNC(FUNCNAME,PRIORITY) \ +void \ +FUNCNAME(const char *format, ...) \ +{ \ + va_list args; \ + va_start(args, format); \ + vzlog (NULL, PRIORITY, format, args); \ + va_end(args); \ } -void -plog_warn (struct zlog *zl, const char *format, ...) -{ - va_list args[ZLOG_MAX_INDEX]; - int index; - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); +ZLOG_FUNC(zlog_err, LOG_ERR) - vzlog (zl, LOG_WARNING, format, args); +ZLOG_FUNC(zlog_warn, LOG_WARNING) - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); -} +ZLOG_FUNC(zlog_info, LOG_INFO) -void -plog_info (struct zlog *zl, const char *format, ...) -{ - va_list args[ZLOG_MAX_INDEX]; - int index; +ZLOG_FUNC(zlog_notice, LOG_NOTICE) - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); +ZLOG_FUNC(zlog_debug, LOG_DEBUG) - vzlog (zl, LOG_INFO, format, args); +#undef ZLOG_FUNC - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); +#define PLOG_FUNC(FUNCNAME,PRIORITY) \ +void \ +FUNCNAME(struct zlog *zl, const char *format, ...) \ +{ \ + va_list args; \ + va_start(args, format); \ + vzlog (zl, PRIORITY, format, args); \ + va_end(args); \ } -void -plog_notice (struct zlog *zl, const char *format, ...) -{ - va_list args[ZLOG_MAX_INDEX]; - int index; +PLOG_FUNC(plog_err, LOG_ERR) - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); +PLOG_FUNC(plog_warn, LOG_WARNING) - vzlog (zl, LOG_NOTICE, format, args); +PLOG_FUNC(plog_info, LOG_INFO) - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); -} +PLOG_FUNC(plog_notice, LOG_NOTICE) -void -plog_debug (struct zlog *zl, const char *format, ...) -{ - va_list args[ZLOG_MAX_INDEX]; - int index; - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_start(args[index], format); +PLOG_FUNC(plog_debug, LOG_DEBUG) - vzlog (zl, LOG_DEBUG, format, args); - - for (index = 0; index < ZLOG_MAX_INDEX; index++) - va_end (args[index]); -} +#undef PLOG_FUNC /* Open log stream */ @@ -366,7 +269,7 @@ zlog_reset_flag (struct zlog *zl, int flags) } int -zlog_set_file (struct zlog *zl, int flags, const char *filename) +zlog_set_file (struct zlog *zl, const char *filename) { FILE *fp; mode_t oldumask; @@ -447,32 +350,6 @@ zlog_rotate (struct zlog *zl) return 1; } -static char *zlog_cwd = NULL; - -void -zlog_save_cwd () -{ - char *cwd; - - cwd = getcwd (NULL, MAXPATHLEN); - - zlog_cwd = XMALLOC (MTYPE_TMP, strlen (cwd) + 1); - strcpy (zlog_cwd, cwd); -} - -char * -zlog_get_cwd () -{ - return zlog_cwd; -} - -void -zlog_free_cwd () -{ - if (zlog_cwd) - XFREE (MTYPE_TMP, zlog_cwd); -} - /* Message lookup function. */ const char * lookup (struct message *mes, int key) -- cgit v1.2.3 From 59a06a915da9129a4e756c2b4d42449aa71a0ee4 Mon Sep 17 00:00:00 2001 From: ajs Date: Tue, 23 Nov 2004 18:19:14 +0000 Subject: 2004-11-23 Andrew J. Schorr * sigevent.c: (signal_init) Set up some default signal handlers so that processes will issue an error message before terminating or dumping core. (trap_default_signals) New function to set up signal handlers for various signals that may kill the process. (exit_handler) Call zlog_signal, then _exit. (core_handler) Call zlog_signal, then abort. * log.h: Declare new function zlog_signal. * log.c: (zlog_signal) New function to log information about a received signal before the process dies. Try to log a backtrace also. (quagga_signal_handler,signal_set) Should be static. --- lib/log.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 205b7c0d..c55bfcb1 100644 --- a/lib/log.c +++ b/lib/log.c @@ -163,6 +163,104 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) vty_log (zlog_proto_names[zl->protocol], format, args); } +static char * +str_append(char *dst, int len, const char *src) +{ + while ((len-- > 0) && *src) + *dst++ = *src++; + return dst; +} + +static char * +num_append(char *s, int len, u_long x) +{ + char buf[30]; + char *t = &buf[29]; + + *t = '\0'; + while (x && (t > buf)) + { + *--t = '0'+(x % 10); + x /= 10; + } + return str_append(s,len,t); +} + +/* Note: the goal here is to use only async-signal-safe functions. */ +void +zlog_signal(int signo, const char *action) +{ + time_t now; + char buf[sizeof("DEFAULT: Received signal S at T; aborting...")+60]; + char *s = buf; + +#define LOC s,buf+sizeof(buf)-s + + time(&now); + if (zlog_default) + { + s = str_append(LOC,zlog_proto_names[zlog_default->protocol]); + *s++ = ':'; + *s++ = ' '; + } + s = str_append(LOC,"Received signal "); + s = num_append(LOC,signo); + s = str_append(LOC," at "); + s = num_append(LOC,now); + s = str_append(LOC,"; "); + s = str_append(LOC,action); + *s++ = '\n'; + +#define DUMP(FP) write(fileno(FP),buf,s-buf); + if (!zlog_default) + DUMP(stderr) + else + { + if ((zlog_default->flags & ZLOG_FILE) && zlog_default->fp) + DUMP(zlog_default->fp) + if (zlog_default->flags & ZLOG_STDOUT) + DUMP(stdout) + if (zlog_default->flags & ZLOG_STDERR) + DUMP(stderr) + /* Is there a signal-safe way to send a syslog message? */ + } +#undef DUMP + + /* Now try for a backtrace. */ +#ifdef HAVE_GLIBC_BACKTRACE + { + void *array[20]; + size_t size; + + size = backtrace(array,sizeof(array)/sizeof(array[0])); + s = buf; + s = str_append(LOC,"Backtrace for "); + s = num_append(LOC,size); + s = str_append(LOC," stack frames:\n"); + +#define DUMP(FP) { \ + write(fileno(FP),buf,s-buf); \ + backtrace_symbols_fd(array, size, fileno(FP)); \ +} + + if (!zlog_default) + DUMP(stderr) + else + { + if ((zlog_default->flags & ZLOG_FILE) && zlog_default->fp) + DUMP(zlog_default->fp) + if (zlog_default->flags & ZLOG_STDOUT) + DUMP(stdout) + if (zlog_default->flags & ZLOG_STDERR) + DUMP(stderr) + /* Is there a signal-safe way to send a syslog message? */ + } +#undef DUMP + } +#endif /* HAVE_GLIBC_BACKTRACE */ +#undef LOC +} + void zlog (struct zlog *zl, int priority, const char *format, ...) { -- cgit v1.2.3 From cee3df1e4b1b8103bf81e5281a46aab7881f93df Mon Sep 17 00:00:00 2001 From: ajs Date: Wed, 24 Nov 2004 17:14:49 +0000 Subject: 2004-11-24 Andrew J. Schorr * zassert.h: New header file to declare a quagga-specific assert macro. * log.c: (_zlog_assert_failed) New function called when assert fails to log the error and abort. * zebra.h: Include "zassert.h" instead of . * regex.c: Include "zassert.h" instead of . * dict.c: Include "zassert.h" instead of . --- lib/log.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index c55bfcb1..38f8ecea 100644 --- a/lib/log.c +++ b/lib/log.c @@ -315,6 +315,15 @@ PLOG_FUNC(plog_debug, LOG_DEBUG) #undef PLOG_FUNC +void +_zlog_assert_failed (const char *assertion, const char *file, + unsigned int line, const char *function) +{ + zlog_err("Assertion `%s' failed in file %s, line %u, function %s", + assertion,file,line,(function ? function : "?")); + abort(); +} + /* Open log stream */ struct zlog * -- cgit v1.2.3 From 101ec7099a0c725f8836f51e2f9ad2138eb43502 Mon Sep 17 00:00:00 2001 From: ajs Date: Wed, 24 Nov 2004 18:05:15 +0000 Subject: In zlog_signal, change type of size since backtrace actually returns an int. --- lib/log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 38f8ecea..86b54ebb 100644 --- a/lib/log.c +++ b/lib/log.c @@ -230,7 +230,7 @@ zlog_signal(int signo, const char *action) #ifdef HAVE_GLIBC_BACKTRACE { void *array[20]; - size_t size; + int size; size = backtrace(array,sizeof(array)/sizeof(array[0])); s = buf; -- cgit v1.2.3 From ad4d974d06ba3344e2e0df3277f7e0c42f018a4e Mon Sep 17 00:00:00 2001 From: ajs Date: Wed, 24 Nov 2004 18:20:30 +0000 Subject: In zlog_signal, should probably check the return code from backtrace, just to be safe. --- lib/log.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 86b54ebb..9d566806 100644 --- a/lib/log.c +++ b/lib/log.c @@ -232,7 +232,8 @@ zlog_signal(int signo, const char *action) void *array[20]; int size; - size = backtrace(array,sizeof(array)/sizeof(array[0])); + if ((size = backtrace(array,sizeof(array)/sizeof(array[0]))) <= 0) + return; s = buf; s = str_append(LOC,"Backtrace for "); s = num_append(LOC,size); -- cgit v1.2.3 From 063ee52af64472474af2fa4b3cb2ba9ced746b9f Mon Sep 17 00:00:00 2001 From: ajs Date: Fri, 26 Nov 2004 18:11:14 +0000 Subject: 2004-11-26 Andrew J. Schorr * log.c: (zlog_backtrace) New function to log a backtrace. (zlog_backtrace_safe) Log a backtrace in an async-signal-safe way. Unfortunately, this function does not support syslog logging yet. (zlog_signal) Move backtrace code into separate function zlog_backtrace_safe. (_zlog_assert_failed) Call zlog_backtrace before aborting. * log.h: Declare new functions zlog_backtrace and zlog_backtrace_safe. * memory.c: (zerror) Call zlog_backtrace before aborting. --- lib/log.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 17 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 9d566806..6623b5c9 100644 --- a/lib/log.c +++ b/lib/log.c @@ -186,14 +186,14 @@ num_append(char *s, int len, u_long x) return str_append(s,len,t); } -/* Note: the goal here is to use only async-signal-safe functions. */ +/* Note: the goal here is to use only async-signal-safe functions. + Needs to be enhanced to support syslog logging. */ void zlog_signal(int signo, const char *action) { time_t now; char buf[sizeof("DEFAULT: Received signal S at T; aborting...")+60]; char *s = buf; - #define LOC s,buf+sizeof(buf)-s time(&now); @@ -226,18 +226,33 @@ zlog_signal(int signo, const char *action) } #undef DUMP - /* Now try for a backtrace. */ + zlog_backtrace_safe(LOG_ERR); +#undef LOC +} + +/* Log a backtrace using only async-signal-safe functions. + Needs to be enhanced to support syslog logging. */ +void +zlog_backtrace_safe(int priority) +{ #ifdef HAVE_GLIBC_BACKTRACE - { - void *array[20]; - int size; + void *array[20]; + int size; + char buf[100]; + char *s; +#define LOC s,buf+sizeof(buf)-s - if ((size = backtrace(array,sizeof(array)/sizeof(array[0]))) <= 0) - return; - s = buf; - s = str_append(LOC,"Backtrace for "); - s = num_append(LOC,size); - s = str_append(LOC," stack frames:\n"); + /* only log this information if it has not been masked out */ + if (zlog_default && (priority > zlog_default->maskpri)) + return; + + if (((size = backtrace(array,sizeof(array)/sizeof(array[0]))) <= 0) || + ((size_t)size > sizeof(array)/sizeof(array[0]))) + return; + s = buf; + s = str_append(LOC,"Backtrace for "); + s = num_append(LOC,size); + s = str_append(LOC," stack frames:\n"); #define DUMP(FP) { \ write(fileno(FP),buf,s-buf); \ @@ -249,17 +264,50 @@ zlog_signal(int signo, const char *action) else { if ((zlog_default->flags & ZLOG_FILE) && zlog_default->fp) - DUMP(zlog_default->fp) + DUMP(zlog_default->fp) if (zlog_default->flags & ZLOG_STDOUT) - DUMP(stdout) + DUMP(stdout) if (zlog_default->flags & ZLOG_STDERR) - DUMP(stderr) + DUMP(stderr) /* Is there a signal-safe way to send a syslog message? */ } #undef DUMP - } -#endif /* HAVE_GLIBC_BACKTRACE */ #undef LOC +#endif /* HAVE_GLIBC_BACKTRACE */ +} + +void +zlog_backtrace(int priority) +{ +#ifndef HAVE_GLIBC_BACKTRACE + zlog(NULL, priority, "No backtrace available on this platform."); +#else + void *array[20]; + int size, i; + char **strings; + + if (((size = backtrace(array,sizeof(array)/sizeof(array[0]))) <= 0) || + ((size_t)size > sizeof(array)/sizeof(array[0]))) + { + zlog_err("Cannot get backtrace, returned invalid # of frames %d " + "(valid range is between 1 and %u)", + size, sizeof(array)/sizeof(array[0])); + return; + } + zlog(NULL, priority, "Backtrace for %d stack frames:", size); + if (!(strings = backtrace_symbols(array, size))) + { + zlog_err("Cannot get backtrace symbols (out of memory?)"); + for (i = 0; i < size; i++) + zlog(NULL, priority, "[bt %d] %p",i,array[i]); + } + else + { + for (i = 0; i < size; i++) + zlog(NULL, priority, "[bt %d] %s",i,strings[i]); + free(strings); + } +#endif /* HAVE_GLIBC_BACKTRACE */ } void @@ -322,6 +370,7 @@ _zlog_assert_failed (const char *assertion, const char *file, { zlog_err("Assertion `%s' failed in file %s, line %u, function %s", assertion,file,line,(function ? function : "?")); + zlog_backtrace(LOG_ERR); abort(); } -- cgit v1.2.3 From 48d6c69b345096425644b7796a7bc6b36bf0e974 Mon Sep 17 00:00:00 2001 From: ajs Date: Fri, 26 Nov 2004 20:52:59 +0000 Subject: 2004-11-26 Andrew J. Schorr * log.c, log.h, memory.c: Change function name from zlog_backtrace_safe to the more self-explanatory zlog_backtrace_sigsafe. --- lib/log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 6623b5c9..86e38339 100644 --- a/lib/log.c +++ b/lib/log.c @@ -226,14 +226,14 @@ zlog_signal(int signo, const char *action) } #undef DUMP - zlog_backtrace_safe(LOG_ERR); + zlog_backtrace_sigsafe(LOG_ERR); #undef LOC } /* Log a backtrace using only async-signal-safe functions. Needs to be enhanced to support syslog logging. */ void -zlog_backtrace_safe(int priority) +zlog_backtrace_sigsafe(int priority) { #ifdef HAVE_GLIBC_BACKTRACE void *array[20]; -- cgit v1.2.3 From 7d149b8e48ef72021aefddf44f400bccaf391870 Mon Sep 17 00:00:00 2001 From: ajs Date: Sun, 28 Nov 2004 23:00:01 +0000 Subject: 2004-11-28 Andrew J. Schorr * log.h: Remove several unused fields from struct zlog. Add comments for other fields, and add one new field syslog_options that is used in the new syslog_sigsafe implementation. * log.c: (syslog_sigsafe) New function to send syslog messages in an async-signal safe way that can be used inside a signal handler. (syslog_connect) New function to connect to syslog daemon inside a signal handler. This function supports only systems where /dev/log is a unix datagram socket (e.g. not Solaris). (zlog_signal) Call syslog_sigsafe if syslog logging is enabled. (zlog_backtrace_sigsafe) Call syslog_sigsafe if syslog logging is enabled. (openzlog) Save syslog_options for use in syslog_sigsafe. (num_append) Fix bug: handle 0 properly. (hex_append) New function to print a u_long in hex format. --- lib/log.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 114 insertions(+), 7 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 86e38339..d3106cb4 100644 --- a/lib/log.c +++ b/lib/log.c @@ -24,6 +24,9 @@ #include "log.h" #include "memory.h" #include "command.h" +#ifndef SUNOS_5 +#include +#endif struct zlog *zlog_default = NULL; @@ -175,9 +178,11 @@ static char * num_append(char *s, int len, u_long x) { char buf[30]; - char *t = &buf[29]; + char *t; - *t = '\0'; + if (!x) + return str_append(s,len,"0"); + *(t = &buf[sizeof(buf)-1]) = '\0'; while (x && (t > buf)) { *--t = '0'+(x % 10); @@ -186,14 +191,93 @@ num_append(char *s, int len, u_long x) return str_append(s,len,t); } -/* Note: the goal here is to use only async-signal-safe functions. - Needs to be enhanced to support syslog logging. */ +static char * +hex_append(char *s, int len, u_long x) +{ + char buf[30]; + char *t; + + if (!x) + return str_append(s,len,"0"); + *(t = &buf[sizeof(buf)-1]) = '\0'; + while (x && (t > buf)) + { + u_int cc = (x % 16); + *--t = ((cc < 10) ? ('0'+cc) : ('a'+cc-10)); + x /= 16; + } + return str_append(s,len,t); +} + +static int syslog_fd = -1; + +/* Needs to be enhanced to support Solaris. */ +static int +syslog_connect(void) +{ +#ifdef SUNOS_5 + return -1; +#else + int fd; + char *s; + struct sockaddr_un addr; + + if ((fd = socket(AF_UNIX,SOCK_DGRAM,0)) < 0) + return -1; + addr.sun_family = AF_UNIX; +#ifdef _PATH_LOG +#define SYSLOG_SOCKET_PATH _PATH_LOG +#else +#define SYSLOG_SOCKET_PATH "/dev/log" +#endif + s = str_append(addr.sun_path,sizeof(addr.sun_path),SYSLOG_SOCKET_PATH); +#undef SYSLOG_SOCKET_PATH + *s = '\0'; + if (connect(fd,(struct sockaddr *)&addr,sizeof(addr)) < 0) + { + close(fd); + return -1; + } + return fd; +#endif +} + +static void +syslog_sigsafe(int priority, const char *msg, size_t msglen) +{ + char buf[sizeof("<1234567890>ripngd[1234567890]: ")+msglen+50]; + char *s; + + if ((syslog_fd < 0) && ((syslog_fd = syslog_connect()) < 0)) + return; + +#define LOC s,buf+sizeof(buf)-s + s = buf; + s = str_append(LOC,"<"); + s = num_append(LOC,priority); + s = str_append(LOC,">"); + /* forget about the timestamp, too difficult in a signal handler */ + s = str_append(LOC,zlog_default->ident); + if (zlog_default->syslog_options & LOG_PID) + { + s = str_append(LOC,"["); + s = num_append(LOC,getpid()); + s = str_append(LOC,"]"); + } + s = str_append(LOC,": "); + s = str_append(LOC,msg); + write(syslog_fd,buf,s-buf); +#undef LOC +} + +/* Note: the goal here is to use only async-signal-safe functions. */ void zlog_signal(int signo, const char *action) { time_t now; char buf[sizeof("DEFAULT: Received signal S at T; aborting...")+60]; char *s = buf; + char *msgstart = buf; #define LOC s,buf+sizeof(buf)-s time(&now); @@ -202,6 +286,7 @@ zlog_signal(int signo, const char *action) s = str_append(LOC,zlog_proto_names[zlog_default->protocol]); *s++ = ':'; *s++ = ' '; + msgstart = s; } s = str_append(LOC,"Received signal "); s = num_append(LOC,signo); @@ -209,7 +294,8 @@ zlog_signal(int signo, const char *action) s = num_append(LOC,now); s = str_append(LOC,"; "); s = str_append(LOC,action); - *s++ = '\n'; + if (s < buf+sizeof(buf)) + *s++ = '\n'; #define DUMP(FP) write(fileno(FP),buf,s-buf); if (!zlog_default) @@ -222,7 +308,11 @@ zlog_signal(int signo, const char *action) DUMP(stdout) if (zlog_default->flags & ZLOG_STDERR) DUMP(stderr) - /* Is there a signal-safe way to send a syslog message? */ + if (zlog_default->flags & ZLOG_SYSLOG) + { + *--s = '\0'; + syslog_sigsafe(LOG_ERR|zlog_default->facility,msgstart,s-msgstart); + } } #undef DUMP @@ -269,7 +359,23 @@ zlog_backtrace_sigsafe(int priority) DUMP(stdout) if (zlog_default->flags & ZLOG_STDERR) DUMP(stderr) - /* Is there a signal-safe way to send a syslog message? */ + if (zlog_default->flags & ZLOG_SYSLOG) + { + int i; + *--s = '\0'; + syslog_sigsafe(priority|zlog_default->facility,buf,s-buf); + /* Just print the function addresses. */ + for (i = 0; i < size; i++) + { + s = buf; + s = str_append(LOC,"[bt "); + s = num_append(LOC,i); + s = str_append(LOC,"] 0x"); + s = hex_append(LOC,(u_long)(array[i])); + *s = '\0'; + syslog_sigsafe(priority|zlog_default->facility,buf,s-buf); + } + } } #undef DUMP #undef LOC @@ -391,6 +497,7 @@ openzlog (const char *progname, int flags, zlog_proto_t protocol, zl->facility = syslog_facility; zl->maskpri = LOG_DEBUG; zl->record_priority = 0; + zl->syslog_options = syslog_flags; openlog (progname, syslog_flags, zl->facility); -- cgit v1.2.3 From 274a4a4447b13f89f8237156a887d05a24a73cc6 Mon Sep 17 00:00:00 2001 From: ajs Date: Tue, 7 Dec 2004 15:39:31 +0000 Subject: 2004-12-07 Andrew J. Schorr * bgp_main.c: (main) The 2nd argument to openzlog has been removed. * isis_main.c: (main) The 2nd argument to openzlog has been removed. * ospf6_main.c: (main) The 2nd argument to openzlog has been removed. Note that stdout logging will no longer be enabled by default when not running as a daemon. * ospf_main.c: (main) The 2nd argument to openzlog has been removed. * rip_main.c: (main) The 2nd argument to openzlog has been removed. * ripng_main.c: (main) The 2nd argument to openzlog has been removed. * main.c: (main) The 2nd argument to openzlog has been removed. So stdout logging will no longer be enabled by default. * irdp_main.c: (irdp_finish) Reduce severity of shutdown message from LOG_WARNING to LOG_INFO. * vtysh.c: Make several functions static instead of global. Added several commands to support destination-specific logging levels. (vtysh_completion) This function is unused, so comment it out. * basic.texi: Document new logging features. Separate basic config commands from basic VTY commands. * log.h: Replace struct zlog flags and maskpri fields with maxlvl array to support individual logging levels for each destination. Remove the 2nd argument to openzlog since the default logging config should be standardized inside the library. Replaced the zlog_set_flag and zlog_reset_flag functions with zlog_set_level. And zlog_set_file now requires an additional log_level argument. Declare zlog_proto_names for use inside command.c in the "show logging" command. Added defines useful for command construction. * log.c: (vzlog) Decide where to send the message based on the individual logging levels configured for each destination. Remove support for ZLOG_STDERR since it was never actually used. Support record-priority for terminal monitors. (zlog_signal,zlog_backtrace_sigsafe) Support destination-specific logging levels. Remove stderr support (was never used). Added support for terminal monitor logging. (_zlog_assert_failed) Increase message severity to LOG_EMERG. (openzlog) Remove 2nd argument since default config should be standardized in library. By default, terminal monitoring is set to debug, and all other logging is disabled. (zlog_set_flag,zlog_reset_flag) Removed. (zlog_set_level) New function to replace zlog_set_flag and zlog_reset_flag. Supports destination-specific logging levels. (zlog_set_file,zlog_reset_file) Support file-specific logging level. (zlog_rotate) Log an error message if fopen fails, and support new file-specific logging level. * command.h: Change DEFUN_CMD_FUNC_DECL and DEFUN_CMD_FUNC_TEXT so that command functions will be static instead of global. Remove declarations for config_exit and config_help. Define new macros DEFUNSH_ATTR, DEFUNSH_HIDDEN, and DEFUNSH_DEPRECATED so we can have deprecated commands in vtysh. Similarly, for completeness, define macros ALIAS_SH, ALIAS_SH_HIDDEN, and ALIAS_SH_DEPRECATED. Also, fix bug in ALIAS_ATTR macro (didn't matter because it was never used). * command.c: Make many functions static instead of global. (facility_name,facility_match,level_match) New functions to support enhanced destination-specific logging levels. (config_write_host) Support new destination-specific logging levels. (config_logmsg) Added new "logmsg" command to help test logging system. (show_logging) Added "show logging" command to show the current configuration of the logging system. (config_log_stdout_level) Support explicit stdout logging level. (no_config_log_stdout) Now takes optional LEVEL arg. (config_log_monitor,config_log_monitor_level,no_config_log_monitor) New commands creating new "log monitor" commands to set terminal monitoring log level. (config_log_file_level) Support explicit file logging level. (config_log_syslog_level) Support explicit syslog logging level. (config_log_facility,no_config_log_facility) Implement new "log facility" command. (cmd_init) Add hooks for new commands: "show logging", "logmsg", "log stdout ", "log monitor", "log monitor ", "no log monitor", "log file ", "no log file ", "log syslog ", "log facility", and "no log facility". * vty.h: Added a "level" argument to vty_log so it can support "log record-priority". Declare new function vty_log_fixed for use in signal handlers. * vty.c: (vty_log,vty_log_out) Added a "level" argument to support "log record-priority" for vty terminal monitors. (vty_down_level) Use config_exit_cmd.func instead of calling config_exit directly (since command functions will now be static instead of global). (vty_log_fixed) New function to send terminal monitor messages from inside a signal handler. --- lib/log.c | 167 ++++++++++++++++++++++++++++---------------------------------- 1 file changed, 76 insertions(+), 91 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index d3106cb4..b68896ca 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,4 +1,7 @@ -/* Logging of zebra +/* + * $Id: log.c,v 1.17 2004/12/07 15:39:32 ajs Exp $ + * + * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro * * This file is part of GNU Zebra. @@ -104,12 +107,8 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) return; } - /* only log this information if it has not been masked out */ - if ( priority > zl->maskpri ) - return ; - /* Syslog output */ - if (zl->flags & ZLOG_SYSLOG) + if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG]) { va_list ac; va_copy(ac, args); @@ -118,7 +117,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) } /* File output. */ - if (zl->flags & ZLOG_FILE) + if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp) { va_list ac; time_print (zl->fp); @@ -133,7 +132,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) } /* stdout output. */ - if (zl->flags & ZLOG_STDOUT) + if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT]) { va_list ac; time_print (stdout); @@ -147,23 +146,10 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) fflush (stdout); } - /* stderr output. */ - if (zl->flags & ZLOG_STDERR) - { - va_list ac; - time_print (stderr); - if (zl->record_priority) - fprintf (stderr, "%s: ", zlog_priority[priority]); - fprintf (stderr, "%s: ", zlog_proto_names[zl->protocol]); - va_copy(ac, args); - vfprintf (stderr, format, ac); - va_end(ac); - fprintf (stderr, "\n"); - fflush (stderr); - } - /* Terminal monitor. */ - vty_log (zlog_proto_names[zl->protocol], format, args); + if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR]) + vty_log ((zl->record_priority ? zlog_priority[priority] : NULL), + zlog_proto_names[zl->protocol], format, args); } static char * @@ -297,26 +283,29 @@ zlog_signal(int signo, const char *action) if (s < buf+sizeof(buf)) *s++ = '\n'; + /* N.B. implicit priority is most severe */ +#define PRI LOG_EMERG + #define DUMP(FP) write(fileno(FP),buf,s-buf); if (!zlog_default) DUMP(stderr) else { - if ((zlog_default->flags & ZLOG_FILE) && zlog_default->fp) + if ((PRI <= zlog_default->maxlvl[ZLOG_DEST_FILE]) && zlog_default->fp) DUMP(zlog_default->fp) - if (zlog_default->flags & ZLOG_STDOUT) + if (PRI <= zlog_default->maxlvl[ZLOG_DEST_STDOUT]) DUMP(stdout) - if (zlog_default->flags & ZLOG_STDERR) - DUMP(stderr) - if (zlog_default->flags & ZLOG_SYSLOG) - { - *--s = '\0'; - syslog_sigsafe(LOG_ERR|zlog_default->facility,msgstart,s-msgstart); - } + /* Remove trailing '\n' for monitor and syslog */ + *--s = '\0'; + if (PRI <= zlog_default->maxlvl[ZLOG_DEST_MONITOR]) + vty_log_fixed(buf,s-buf); + if (PRI <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG]) + syslog_sigsafe(PRI|zlog_default->facility,msgstart,s-msgstart); } #undef DUMP - zlog_backtrace_sigsafe(LOG_ERR); + zlog_backtrace_sigsafe(PRI); +#undef PRI #undef LOC } @@ -332,10 +321,6 @@ zlog_backtrace_sigsafe(int priority) char *s; #define LOC s,buf+sizeof(buf)-s - /* only log this information if it has not been masked out */ - if (zlog_default && (priority > zlog_default->maskpri)) - return; - if (((size = backtrace(array,sizeof(array)/sizeof(array[0]))) <= 0) || ((size_t)size > sizeof(array)/sizeof(array[0]))) return; @@ -353,29 +338,34 @@ zlog_backtrace_sigsafe(int priority) DUMP(stderr) else { - if ((zlog_default->flags & ZLOG_FILE) && zlog_default->fp) + if ((priority <= zlog_default->maxlvl[ZLOG_DEST_FILE]) && + zlog_default->fp) DUMP(zlog_default->fp) - if (zlog_default->flags & ZLOG_STDOUT) + if (priority <= zlog_default->maxlvl[ZLOG_DEST_STDOUT]) DUMP(stdout) - if (zlog_default->flags & ZLOG_STDERR) - DUMP(stderr) - if (zlog_default->flags & ZLOG_SYSLOG) - { - int i; - *--s = '\0'; - syslog_sigsafe(priority|zlog_default->facility,buf,s-buf); - /* Just print the function addresses. */ - for (i = 0; i < size; i++) - { - s = buf; - s = str_append(LOC,"[bt "); - s = num_append(LOC,i); - s = str_append(LOC,"] 0x"); - s = hex_append(LOC,(u_long)(array[i])); - *s = '\0'; + /* Remove trailing '\n' for monitor and syslog */ + *--s = '\0'; + if (priority <= zlog_default->maxlvl[ZLOG_DEST_MONITOR]) + vty_log_fixed(buf,s-buf); + if (priority <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG]) + syslog_sigsafe(priority|zlog_default->facility,buf,s-buf); + { + int i; + /* Just print the function addresses. */ + for (i = 0; i < size; i++) + { + s = buf; + s = str_append(LOC,"[bt "); + s = num_append(LOC,i); + s = str_append(LOC,"] 0x"); + s = hex_append(LOC,(u_long)(array[i])); + *s = '\0'; + if (priority <= zlog_default->maxlvl[ZLOG_DEST_MONITOR]) + vty_log_fixed(buf,s-buf); + if (priority <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG]) syslog_sigsafe(priority|zlog_default->facility,buf,s-buf); - } - } + } + } } #undef DUMP #undef LOC @@ -476,29 +466,32 @@ _zlog_assert_failed (const char *assertion, const char *file, { zlog_err("Assertion `%s' failed in file %s, line %u, function %s", assertion,file,line,(function ? function : "?")); - zlog_backtrace(LOG_ERR); + zlog_backtrace(LOG_EMERG); abort(); } /* Open log stream */ struct zlog * -openzlog (const char *progname, int flags, zlog_proto_t protocol, +openzlog (const char *progname, zlog_proto_t protocol, int syslog_flags, int syslog_facility) { struct zlog *zl; + u_int i; - zl = XMALLOC(MTYPE_ZLOG, sizeof (struct zlog)); - memset (zl, 0, sizeof (struct zlog)); + zl = XCALLOC(MTYPE_ZLOG, sizeof (struct zlog)); zl->ident = progname; - zl->flags = flags; zl->protocol = protocol; zl->facility = syslog_facility; - zl->maskpri = LOG_DEBUG; - zl->record_priority = 0; zl->syslog_options = syslog_flags; + /* Set default logging levels. */ + for (i = 0; i < sizeof(zl->maxlvl)/sizeof(zl->maxlvl[0]); i++) + zl->maxlvl[i] = ZLOG_DISABLED; + zl->maxlvl[ZLOG_DEST_MONITOR] = LOG_DEBUG; + zl->default_lvl = LOG_DEBUG; + openlog (progname, syslog_flags, zl->facility); return zl; @@ -515,25 +508,16 @@ closezlog (struct zlog *zl) /* Called from command.c. */ void -zlog_set_flag (struct zlog *zl, int flags) +zlog_set_level (struct zlog *zl, zlog_dest_t dest, int log_level) { if (zl == NULL) zl = zlog_default; - zl->flags |= flags; -} - -void -zlog_reset_flag (struct zlog *zl, int flags) -{ - if (zl == NULL) - zl = zlog_default; - - zl->flags &= ~flags; + zl->maxlvl[dest] = log_level; } int -zlog_set_file (struct zlog *zl, const char *filename) +zlog_set_file (struct zlog *zl, const char *filename, int log_level) { FILE *fp; mode_t oldumask; @@ -548,16 +532,13 @@ zlog_set_file (struct zlog *zl, const char *filename) /* Open file. */ oldumask = umask (0777 & ~LOGFILE_MASK); fp = fopen (filename, "a"); - if (fp == NULL) - { - umask(oldumask); - return 0; - } umask(oldumask); + if (fp == NULL) + return 0; /* Set flags. */ zl->filename = strdup (filename); - zl->flags |= ZLOG_FILE; + zl->maxlvl[ZLOG_DEST_FILE] = log_level; zl->fp = fp; return 1; @@ -570,11 +551,10 @@ zlog_reset_file (struct zlog *zl) if (zl == NULL) zl = zlog_default; - zl->flags &= ~ZLOG_FILE; - if (zl->fp) fclose (zl->fp); zl->fp = NULL; + zl->maxlvl[ZLOG_DEST_FILE] = ZLOG_DISABLED; if (zl->filename) free (zl->filename); @@ -587,7 +567,7 @@ zlog_reset_file (struct zlog *zl) int zlog_rotate (struct zlog *zl) { - FILE *fp; + int level; if (zl == NULL) zl = zlog_default; @@ -595,20 +575,25 @@ zlog_rotate (struct zlog *zl) if (zl->fp) fclose (zl->fp); zl->fp = NULL; + level = zl->maxlvl[ZLOG_DEST_FILE]; + zl->maxlvl[ZLOG_DEST_FILE] = ZLOG_DISABLED; if (zl->filename) { mode_t oldumask; + int save_errno; oldumask = umask (0777 & ~LOGFILE_MASK); - fp = fopen (zl->filename, "a"); - if (fp == NULL) + zl->fp = fopen (zl->filename, "a"); + save_errno = errno; + umask(oldumask); + if (zl->fp == NULL) { - umask(oldumask); + zlog_err("Log rotate failed: cannot open file %s for append: %s", + zl->filename, safe_strerror(save_errno)); return -1; } - umask(oldumask); - zl->fp = fp; + zl->maxlvl[ZLOG_DEST_FILE] = level; } return 1; -- cgit v1.2.3 From ad572396fc8306cee92af37d1099e317856a99d0 Mon Sep 17 00:00:00 2001 From: gdt Date: Thu, 9 Dec 2004 14:53:32 +0000 Subject: add XXX comment about hex_append being unused. (only used if HAVE_GLIBC_BACKTRACE, so perhaps ifdef it?) --- lib/log.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index b68896ca..64d576a2 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.17 2004/12/07 15:39:32 ajs Exp $ + * $Id: log.c,v 1.18 2004/12/09 14:53:32 gdt Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -177,6 +177,10 @@ num_append(char *s, int len, u_long x) return str_append(s,len,t); } +/* + * XXX warning: `hex_append' defined but not used + * Apparently this is used only if HAVE_GLIBC_BACKTRACE is defined. + */ static char * hex_append(char *s, int len, u_long x) { -- cgit v1.2.3 From c3324c63b5f6b39c5f63329a679628b80b63e1bc Mon Sep 17 00:00:00 2001 From: ajs Date: Thu, 9 Dec 2004 17:26:31 +0000 Subject: 2004-12-09 Andrew J. Schorr * log.c: (hex_append) No need to include this function if HAVE_GLIBC_BACKTRACE is not defined. --- lib/log.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 64d576a2..ec958645 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.18 2004/12/09 14:53:32 gdt Exp $ + * $Id: log.c,v 1.19 2004/12/09 17:26:31 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -177,10 +177,10 @@ num_append(char *s, int len, u_long x) return str_append(s,len,t); } -/* - * XXX warning: `hex_append' defined but not used - * Apparently this is used only if HAVE_GLIBC_BACKTRACE is defined. - */ +#ifdef HAVE_GLIBC_BACKTRACE + +/* This function is used only in zlog_backtrace_sigsafe when glibc + backtraces are available. */ static char * hex_append(char *s, int len, u_long x) { @@ -199,6 +199,8 @@ hex_append(char *s, int len, u_long x) return str_append(s,len,t); } +#endif /* HAVE_GLIBC_BACKTRACE */ + static int syslog_fd = -1; /* Needs to be enhanced to support Solaris. */ -- cgit v1.2.3 From 3378d2099440cb3a14dc7531a3221d4140e186e2 Mon Sep 17 00:00:00 2001 From: ajs Date: Fri, 10 Dec 2004 22:43:17 +0000 Subject: 2004-12-10 Andrew J. Schorr * log.c: (zlog_signal,_zlog_assert_failed) Change logging level back to LOG_ERR instead of LOG_EMERG. --- lib/log.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index ec958645..1be1c0b0 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.19 2004/12/09 17:26:31 ajs Exp $ + * $Id: log.c,v 1.20 2004/12/10 22:43:17 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -290,7 +290,7 @@ zlog_signal(int signo, const char *action) *s++ = '\n'; /* N.B. implicit priority is most severe */ -#define PRI LOG_EMERG +#define PRI LOG_ERR #define DUMP(FP) write(fileno(FP),buf,s-buf); if (!zlog_default) @@ -472,7 +472,7 @@ _zlog_assert_failed (const char *assertion, const char *file, { zlog_err("Assertion `%s' failed in file %s, line %u, function %s", assertion,file,line,(function ? function : "?")); - zlog_backtrace(LOG_EMERG); + zlog_backtrace(LOG_ERR); abort(); } -- cgit v1.2.3 From 40abf2392ba9f14935dab556f43e674cb5c47cf3 Mon Sep 17 00:00:00 2001 From: ajs Date: Wed, 12 Jan 2005 17:27:27 +0000 Subject: 2005-01-12 Andrew J. Schorr * configure.ac: Test for header file (for use in signal processing). * sigevent.c: (trap_default_signals) Use the SA_SIGINFO flag to pass additional siginfo_t and ucontext_t arguments to core_handler and exit_handler. (core_handler,exit_handler) Now invoked with 3 arguments (using SA_SIGINFO). Pass additional info to zlog_signal. (program_counter) New function to find program counter in ucontext_t, needs to be enhanced to support more platforms (currently works only on Linux/x86). * log.h: Change the zlog_signal prototype to add new arguments siginfo_t * and program_counter. * log.c: (zlog_signal) Add new arguments siginfo and program_counter. Include si_addr and program counter (if non-NULL) in message. And remove #ifdef HAVE_GLIBC_BACKTRACE around hex_append, since that is now used to render the si_addr and PC pointers. --- lib/log.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 1be1c0b0..fcf7c5d5 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.20 2004/12/10 22:43:17 ajs Exp $ + * $Id: log.c,v 1.21 2005/01/12 17:27:27 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -177,10 +177,6 @@ num_append(char *s, int len, u_long x) return str_append(s,len,t); } -#ifdef HAVE_GLIBC_BACKTRACE - -/* This function is used only in zlog_backtrace_sigsafe when glibc - backtraces are available. */ static char * hex_append(char *s, int len, u_long x) { @@ -199,8 +195,6 @@ hex_append(char *s, int len, u_long x) return str_append(s,len,t); } -#endif /* HAVE_GLIBC_BACKTRACE */ - static int syslog_fd = -1; /* Needs to be enhanced to support Solaris. */ @@ -264,10 +258,11 @@ syslog_sigsafe(int priority, const char *msg, size_t msglen) /* Note: the goal here is to use only async-signal-safe functions. */ void -zlog_signal(int signo, const char *action) +zlog_signal(int signo, const char *action, siginfo_t *siginfo, + void *program_counter) { time_t now; - char buf[sizeof("DEFAULT: Received signal S at T; aborting...")+60]; + char buf[sizeof("DEFAULT: Received signal S at T (si_addr 0xP, PC 0xP); aborting...")+100]; char *s = buf; char *msgstart = buf; #define LOC s,buf+sizeof(buf)-s @@ -284,7 +279,14 @@ zlog_signal(int signo, const char *action) s = num_append(LOC,signo); s = str_append(LOC," at "); s = num_append(LOC,now); - s = str_append(LOC,"; "); + s = str_append(LOC," (si_addr 0x"); + s = hex_append(LOC,(u_long)(siginfo->si_addr)); + if (program_counter) + { + s = str_append(LOC,", PC 0x"); + s = hex_append(LOC,(u_long)program_counter); + } + s = str_append(LOC,"); "); s = str_append(LOC,action); if (s < buf+sizeof(buf)) *s++ = '\n'; -- cgit v1.2.3 From 239c26fdeae4dbccb43da359f9ea034041440831 Mon Sep 17 00:00:00 2001 From: ajs Date: Mon, 17 Jan 2005 15:22:28 +0000 Subject: 2005-01-17 Andrew J. Schorr * log.h: Change prototype for zlog_backtrace_sigsafe to take additional program_counter argument. * log.c: (zlog_backtrace_sigsafe) Add additional program_counter argument. If it is non-NULL, use backtrace_symbols_fd to resolve the address. (zlog_signal) Call zlog_backtrace_sigsafe with additional program_counter argument. [pullup candidate] --- lib/log.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index fcf7c5d5..a639745d 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.21 2005/01/12 17:27:27 ajs Exp $ + * $Id: log.c,v 1.22 2005/01/17 15:22:28 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -312,7 +312,7 @@ zlog_signal(int signo, const char *action, siginfo_t *siginfo, } #undef DUMP - zlog_backtrace_sigsafe(PRI); + zlog_backtrace_sigsafe(PRI, program_counter); #undef PRI #undef LOC } @@ -320,9 +320,10 @@ zlog_signal(int signo, const char *action, siginfo_t *siginfo, /* Log a backtrace using only async-signal-safe functions. Needs to be enhanced to support syslog logging. */ void -zlog_backtrace_sigsafe(int priority) +zlog_backtrace_sigsafe(int priority, void *program_counter) { #ifdef HAVE_GLIBC_BACKTRACE + static const char pclabel[] = "Program counter: "; void *array[20]; int size; char buf[100]; @@ -338,6 +339,11 @@ zlog_backtrace_sigsafe(int priority) s = str_append(LOC," stack frames:\n"); #define DUMP(FP) { \ + if (program_counter) \ + { \ + write(fileno(FP),pclabel,sizeof(pclabel)-1); \ + backtrace_symbols_fd(&program_counter, 1, fileno(FP)); \ + } \ write(fileno(FP),buf,s-buf); \ backtrace_symbols_fd(array, size, fileno(FP)); \ } -- cgit v1.2.3 From 31364274ddd1da6b77dd99e1d5d164b5c643732b Mon Sep 17 00:00:00 2001 From: ajs Date: Tue, 18 Jan 2005 22:18:59 +0000 Subject: 2005-01-18 Andrew J. Schorr * log.h: Test for SA_SIGINFO to see whether zlog_signal takes final two args (siginfo and program_counter). * log.c: (hex_append) Include this function only if SA_SIGINFO or HAVE_GLIBC_BACKTRACE is defined. (zlog_signal) Final two args (siginfo and program_counter) now depend on whether SA_SIGINFO is defined on this platform. * sigevent.c: (program_counter) Do not include this function if SA_SIGINFO is not defined on this platform. (exit_handler,core_handler) Test for SA_SIGINFO to decide whether 2nd & 3rd arguments are present and to decide how to invoke zlog_signal. (trap_default_signals) Test for SA_SIGINFO and invoke sigaction appropriately. --- lib/log.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index a639745d..2efc30f6 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.22 2005/01/17 15:22:28 ajs Exp $ + * $Id: log.c,v 1.23 2005/01/18 22:18:59 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -177,6 +177,7 @@ num_append(char *s, int len, u_long x) return str_append(s,len,t); } +#if defined(SA_SIGINFO) || defined(HAVE_GLIBC_BACKTRACE) static char * hex_append(char *s, int len, u_long x) { @@ -194,6 +195,7 @@ hex_append(char *s, int len, u_long x) } return str_append(s,len,t); } +#endif static int syslog_fd = -1; @@ -258,8 +260,11 @@ syslog_sigsafe(int priority, const char *msg, size_t msglen) /* Note: the goal here is to use only async-signal-safe functions. */ void -zlog_signal(int signo, const char *action, siginfo_t *siginfo, - void *program_counter) +zlog_signal(int signo, const char *action +#ifdef SA_SIGINFO + , siginfo_t *siginfo, void *program_counter +#endif + ) { time_t now; char buf[sizeof("DEFAULT: Received signal S at T (si_addr 0xP, PC 0xP); aborting...")+100]; @@ -279,6 +284,7 @@ zlog_signal(int signo, const char *action, siginfo_t *siginfo, s = num_append(LOC,signo); s = str_append(LOC," at "); s = num_append(LOC,now); +#ifdef SA_SIGINFO s = str_append(LOC," (si_addr 0x"); s = hex_append(LOC,(u_long)(siginfo->si_addr)); if (program_counter) @@ -287,6 +293,9 @@ zlog_signal(int signo, const char *action, siginfo_t *siginfo, s = hex_append(LOC,(u_long)program_counter); } s = str_append(LOC,"); "); +#else /* SA_SIGINFO */ + s = str_append(LOC,"; "); +#endif /* SA_SIGINFO */ s = str_append(LOC,action); if (s < buf+sizeof(buf)) *s++ = '\n'; @@ -312,7 +321,13 @@ zlog_signal(int signo, const char *action, siginfo_t *siginfo, } #undef DUMP - zlog_backtrace_sigsafe(PRI, program_counter); + zlog_backtrace_sigsafe(PRI, +#ifdef SA_SIGINFO + program_counter +#else + NULL +#endif + ); #undef PRI #undef LOC } -- cgit v1.2.3 From 1e2213541bbda26c49667b699a333d87bcc0f2e6 Mon Sep 17 00:00:00 2001 From: ajs Date: Thu, 3 Feb 2005 16:42:40 +0000 Subject: 2005-02-03 Andrew J. Schorr * log.c: (syslog_sigsafe) Reduce scope of syslog_fd: it is accessed inside this function only. (open_crashlog) New function to open /var/tmp/quagga..crashlog with flags O_WRONLY|O_CREAT|O_EXCL to save some crash info. (zlog_signal,_zlog_assert_failed) Increase logging priority from LOG_ERR to LOG_CRIT. If no file logging is configured, try to use open_crashlog to create a crash logfile. (zlog_backtrace_sigsafe) If a crashlog file descriptor is open, dump a backtrace to that file. --- lib/log.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 19 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 2efc30f6..dbd378fd 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.23 2005/01/18 22:18:59 ajs Exp $ + * $Id: log.c,v 1.24 2005/02/03 16:42:40 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -31,6 +31,9 @@ #include #endif +static int crashlog_fd = -1; /* Used for last-resort crash logfile when a + signal is caught. */ + struct zlog *zlog_default = NULL; const char *zlog_proto_names[] = @@ -197,8 +200,6 @@ hex_append(char *s, int len, u_long x) } #endif -static int syslog_fd = -1; - /* Needs to be enhanced to support Solaris. */ static int syslog_connect(void) @@ -233,6 +234,7 @@ syslog_connect(void) static void syslog_sigsafe(int priority, const char *msg, size_t msglen) { + static int syslog_fd = -1; char buf[sizeof("<1234567890>ripngd[1234567890]: ")+msglen+50]; char *s; @@ -258,6 +260,38 @@ syslog_sigsafe(int priority, const char *msg, size_t msglen) #undef LOC } +static int +open_crashlog(void) +{ +#define CRASHLOG_PREFIX "/var/tmp/quagga." +#define CRASHLOG_SUFFIX "crashlog" + if (zlog_default && zlog_default->ident) + { + /* Avoid strlen since it is not async-signal-safe. */ + const char *p; + size_t ilen; + + for (p = zlog_default->ident, ilen = 0; *p; p++) + ilen++; + { + char buf[sizeof(CRASHLOG_PREFIX)+ilen+sizeof(CRASHLOG_SUFFIX)+3]; + char *s = buf; +#define LOC s,buf+sizeof(buf)-s + s = str_append(LOC, CRASHLOG_PREFIX); + s = str_append(LOC, zlog_default->ident); + s = str_append(LOC, "."); + s = str_append(LOC, CRASHLOG_SUFFIX); +#undef LOC + *s = '\0'; + return open(buf, O_WRONLY|O_CREAT|O_EXCL, LOGFILE_MASK); + } + } + return open(CRASHLOG_PREFIX CRASHLOG_SUFFIX, O_WRONLY|O_CREAT|O_EXCL, + LOGFILE_MASK); +#undef CRASHLOG_SUFFIX +#undef CRASHLOG_PREFIX +} + /* Note: the goal here is to use only async-signal-safe functions. */ void zlog_signal(int signo, const char *action @@ -301,17 +335,21 @@ zlog_signal(int signo, const char *action *s++ = '\n'; /* N.B. implicit priority is most severe */ -#define PRI LOG_ERR +#define PRI LOG_CRIT -#define DUMP(FP) write(fileno(FP),buf,s-buf); +#define DUMP(FD) write(FD, buf, s-buf); + /* If no file logging configured, try to write to fallback log file. */ + if ((!zlog_default || !zlog_default->fp) && + ((crashlog_fd = open_crashlog()) >= 0)) + DUMP(crashlog_fd) if (!zlog_default) - DUMP(stderr) + DUMP(fileno(stderr)) else { if ((PRI <= zlog_default->maxlvl[ZLOG_DEST_FILE]) && zlog_default->fp) - DUMP(zlog_default->fp) + DUMP(fileno(zlog_default->fp)) if (PRI <= zlog_default->maxlvl[ZLOG_DEST_STDOUT]) - DUMP(stdout) + DUMP(fileno(stdout)) /* Remove trailing '\n' for monitor and syslog */ *--s = '\0'; if (PRI <= zlog_default->maxlvl[ZLOG_DEST_MONITOR]) @@ -353,25 +391,27 @@ zlog_backtrace_sigsafe(int priority, void *program_counter) s = num_append(LOC,size); s = str_append(LOC," stack frames:\n"); -#define DUMP(FP) { \ +#define DUMP(FD) { \ if (program_counter) \ { \ - write(fileno(FP),pclabel,sizeof(pclabel)-1); \ - backtrace_symbols_fd(&program_counter, 1, fileno(FP)); \ + write(FD, pclabel, sizeof(pclabel)-1); \ + backtrace_symbols_fd(&program_counter, 1, FD); \ } \ - write(fileno(FP),buf,s-buf); \ - backtrace_symbols_fd(array, size, fileno(FP)); \ + write(FD, buf, s-buf); \ + backtrace_symbols_fd(array, size, FD); \ } + if (crashlog_fd >= 0) + DUMP(crashlog_fd) if (!zlog_default) - DUMP(stderr) + DUMP(fileno(stderr)) else { if ((priority <= zlog_default->maxlvl[ZLOG_DEST_FILE]) && zlog_default->fp) - DUMP(zlog_default->fp) + DUMP(fileno(zlog_default->fp)) if (priority <= zlog_default->maxlvl[ZLOG_DEST_STDOUT]) - DUMP(stdout) + DUMP(fileno(stdout)) /* Remove trailing '\n' for monitor and syslog */ *--s = '\0'; if (priority <= zlog_default->maxlvl[ZLOG_DEST_MONITOR]) @@ -493,9 +533,21 @@ void _zlog_assert_failed (const char *assertion, const char *file, unsigned int line, const char *function) { - zlog_err("Assertion `%s' failed in file %s, line %u, function %s", - assertion,file,line,(function ? function : "?")); - zlog_backtrace(LOG_ERR); + if (zlog_default && !zlog_default->fp) + { + /* Force fallback file logging. */ + int fd; + FILE *fp; + + if (((fd = open_crashlog()) >= 0) && ((fp = fdopen(fd, "w")) != NULL)) + { + zlog_default->fp = fp; + zlog_default->maxlvl[ZLOG_DEST_FILE] = LOG_ERR; + } + } + zlog(NULL, LOG_CRIT, "Assertion `%s' failed in file %s, line %u, function %s", + assertion,file,line,(function ? function : "?")); + zlog_backtrace(LOG_CRIT); abort(); } -- cgit v1.2.3 From c4c7d0c48b1219d7ed9ed1377cea1be239c45d5d Mon Sep 17 00:00:00 2001 From: ajs Date: Thu, 3 Feb 2005 19:22:05 +0000 Subject: 2005-02-03 Andrew J. Schorr * log.c: (zlog_signal,zlog_backtrace_sigsafe) Eliminate use of fileno() since it is not async-signal-safe. (_zlog_assert_failed) Rewrite crashlog logic more compactly. (zlog_set_file,zlog_reset_file,zlog_rotate) Update logfile_fd for use in signal handler. --- lib/log.c | 48 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index dbd378fd..2c4b399a 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.24 2005/02/03 16:42:40 ajs Exp $ + * $Id: log.c,v 1.25 2005/02/03 19:22:05 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -31,8 +31,7 @@ #include #endif -static int crashlog_fd = -1; /* Used for last-resort crash logfile when a - signal is caught. */ +static int logfile_fd = -1; /* Used in signal handler. */ struct zlog *zlog_default = NULL; @@ -339,17 +338,14 @@ zlog_signal(int signo, const char *action #define DUMP(FD) write(FD, buf, s-buf); /* If no file logging configured, try to write to fallback log file. */ - if ((!zlog_default || !zlog_default->fp) && - ((crashlog_fd = open_crashlog()) >= 0)) - DUMP(crashlog_fd) + if ((logfile_fd >= 0) || ((logfile_fd = open_crashlog()) >= 0)) + DUMP(logfile_fd) if (!zlog_default) - DUMP(fileno(stderr)) + DUMP(STDERR_FILENO) else { - if ((PRI <= zlog_default->maxlvl[ZLOG_DEST_FILE]) && zlog_default->fp) - DUMP(fileno(zlog_default->fp)) if (PRI <= zlog_default->maxlvl[ZLOG_DEST_STDOUT]) - DUMP(fileno(stdout)) + DUMP(STDOUT_FILENO) /* Remove trailing '\n' for monitor and syslog */ *--s = '\0'; if (PRI <= zlog_default->maxlvl[ZLOG_DEST_MONITOR]) @@ -401,17 +397,14 @@ zlog_backtrace_sigsafe(int priority, void *program_counter) backtrace_symbols_fd(array, size, FD); \ } - if (crashlog_fd >= 0) - DUMP(crashlog_fd) + if ((logfile_fd >= 0) || ((logfile_fd = open_crashlog()) >= 0)) + DUMP(logfile_fd) if (!zlog_default) - DUMP(fileno(stderr)) + DUMP(STDERR_FILENO) else { - if ((priority <= zlog_default->maxlvl[ZLOG_DEST_FILE]) && - zlog_default->fp) - DUMP(fileno(zlog_default->fp)) if (priority <= zlog_default->maxlvl[ZLOG_DEST_STDOUT]) - DUMP(fileno(stdout)) + DUMP(STDOUT_FILENO) /* Remove trailing '\n' for monitor and syslog */ *--s = '\0'; if (priority <= zlog_default->maxlvl[ZLOG_DEST_MONITOR]) @@ -533,18 +526,11 @@ void _zlog_assert_failed (const char *assertion, const char *file, unsigned int line, const char *function) { - if (zlog_default && !zlog_default->fp) - { - /* Force fallback file logging. */ - int fd; - FILE *fp; - - if (((fd = open_crashlog()) >= 0) && ((fp = fdopen(fd, "w")) != NULL)) - { - zlog_default->fp = fp; - zlog_default->maxlvl[ZLOG_DEST_FILE] = LOG_ERR; - } - } + /* Force fallback file logging? */ + if (zlog_default && !zlog_default->fp && + ((logfile_fd = open_crashlog()) >= 0) && + ((zlog_default->fp = fdopen(logfile_fd, "w")) != NULL)) + zlog_default->maxlvl[ZLOG_DEST_FILE] = LOG_ERR; zlog(NULL, LOG_CRIT, "Assertion `%s' failed in file %s, line %u, function %s", assertion,file,line,(function ? function : "?")); zlog_backtrace(LOG_CRIT); @@ -621,6 +607,7 @@ zlog_set_file (struct zlog *zl, const char *filename, int log_level) zl->filename = strdup (filename); zl->maxlvl[ZLOG_DEST_FILE] = log_level; zl->fp = fp; + logfile_fd = fileno(fp); return 1; } @@ -635,6 +622,7 @@ zlog_reset_file (struct zlog *zl) if (zl->fp) fclose (zl->fp); zl->fp = NULL; + logfile_fd = -1; zl->maxlvl[ZLOG_DEST_FILE] = ZLOG_DISABLED; if (zl->filename) @@ -656,6 +644,7 @@ zlog_rotate (struct zlog *zl) if (zl->fp) fclose (zl->fp); zl->fp = NULL; + logfile_fd = -1; level = zl->maxlvl[ZLOG_DEST_FILE]; zl->maxlvl[ZLOG_DEST_FILE] = ZLOG_DISABLED; @@ -674,6 +663,7 @@ zlog_rotate (struct zlog *zl) zl->filename, safe_strerror(save_errno)); return -1; } + logfile_fd = fileno(zl->fp); zl->maxlvl[ZLOG_DEST_FILE] = level; } -- cgit v1.2.3 From f52d13cb2e8e7197934d5f241f88647f9b9d78b8 Mon Sep 17 00:00:00 2001 From: ajs Date: Sat, 1 Oct 2005 17:38:06 +0000 Subject: 2005-10-01 Andrew J. Schorr * zebra.h: Declare new functions zebra_route_string() and zebra_route_char(). * log.c: (zroute_lookup,zebra_route_string,zebra_route_char) New functions to map zebra route numbers to strings. * zebra_vty.c: (route_type_str) Remove obsolete function: use new library function zebra_route_string() instead. Note that there are a few differences: for IPv6 routes, we now get "ripng" and "ospf6" instead of the old behavior ("rip" and "ospf"). (route_type_char) Remove obsolete function: ues new library function zebra_route_char() instead. Note that there is one difference: the old function returned 'S' for a ZEBRA_ROUTE_SYSTEM route, whereas the new one returns 'X'. (vty_show_ip_route_detail,vty_show_ipv6_route_detail) Replace route_type_str() with zebra_route_string(). (vty_show_ip_route,vty_show_ipv6_route) Replace route_type_char() with zebra_route_char(). * bgp_vty.c: (bgp_config_write_redistribute) Use new library function zebra_route_string instead of a local hard-coded table. * ospf6_asbr.c: Remove local hard-coded tables zroute_name and zroute_abname. Change the ZROUTE_NAME macro to use new library function zebra_route_string(). Remove the ZROUTE_ABNAME macro. (ospf6_asbr_external_route_show): Replace ZROUTE_ABNAME() with a call to zebra_route_char(), and be sure to fix the format string, since we now have a char instead of a char *. * ospf6_zebra.c: Remove local hard-coded tables zebra_route_name and zebra_route_abname. Note that the zebra_route_name[] table contained mixed-case strings, whereas the zebra_route_string() function returns lower-case strings. (ospf6_zebra_read_ipv6): Change debug message to use new library function zebra_route_string() instead of zebra_route_name[]. (show_zebra): Use new library function zebra_route_string() instead of zebra_route_name[]. * ospf_dump.c: Remove local hard-coded table ospf_redistributed_proto. (ospf_redist_string) New function implemented using new library function zebra_route_string(). Note that there are a few differences in the output that will result: the new function returns strings that are lower-case, whereas the old table was mixed case. Also, the old table mapped ZEBRA_ROUTE_OSPF6 to "OSPFv3", whereas the new function returns "ospf6". * ospfd.h: Remove extern struct message ospf_redistributed_proto[], and add extern const char *ospf_redist_string(u_int route_type) instead. * ospf_asbr.c: (ospf_external_info_add) In two messages, use ospf_redist_string instead of LOOKUP(ospf_redistributed_proto). * ospf_vty.c: Remove local hard-coded table distribute_str. (config_write_ospf_redistribute,config_write_ospf_distribute): Use new library function zebra_route_string() instead of distribute_str[]. * ospf_zebra.c: (ospf_redistribute_set,ospf_redistribute_unset, ospf_redistribute_default_set,ospf_redistribute_check) In debug messages, use ospf_redist_string() instead of LOOKUP(ospf_redistributed_proto). * rip_zebra.c: (config_write_rip_redistribute): Remove local hard-coded table str[]. Replace str[] with calls to new library function zebra_route_string(). * ripd.c: Remove local hard-coded table route_info[]. (show_ip_rip) Replace uses of str[] with calls to new library functions zebra_route_char and zebra_route_string. * ripng_zebra.c: (ripng_redistribute_write) Remove local hard-coded table str[]. Replace str[i] with new library function zebra_route_string(i). * ripngd.c: Remove local hard-coded table route_info[]. (show_ipv6_ripng) Use new library function zebra_route_char() instead of table route_info[]. --- lib/log.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 2c4b399a..6748dbc0 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.25 2005/02/03 19:22:05 ajs Exp $ + * $Id: log.c,v 1.26 2005/10/01 17:38:07 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -703,3 +703,60 @@ safe_strerror(int errnum) const char *s = strerror(errnum); return (s != NULL) ? s : "Unknown error"; } + +/* Note: this table must match the ordering in lib/zebra.h */ +static const struct zebra_route_desc { + u_int zroute; + const char *string; + char chr; +} route_types[] = { + { ZEBRA_ROUTE_SYSTEM, "system", 'X' }, + { ZEBRA_ROUTE_KERNEL, "kernel", 'K' }, + { ZEBRA_ROUTE_CONNECT, "connected", 'C' }, + { ZEBRA_ROUTE_STATIC, "static", 'S' }, + { ZEBRA_ROUTE_RIP, "rip", 'R' }, + { ZEBRA_ROUTE_RIPNG, "ripng", 'R' }, + { ZEBRA_ROUTE_OSPF, "ospf", 'O' }, + { ZEBRA_ROUTE_OSPF6, "ospf6", 'O' }, + { ZEBRA_ROUTE_ISIS, "isis", 'I' }, + { ZEBRA_ROUTE_BGP, "bgp", 'B' }, + { ZEBRA_ROUTE_HSLS, "hsls", 'H' }, +}; + +static const struct zebra_route_desc * +zroute_lookup(u_int zroute) +{ + static const struct zebra_route_desc unknown = { 0, "unknown", '?' }; + u_int i; + + if (zroute >= sizeof(route_types)/sizeof(route_types[0])) + { + zlog_err("unknown zebra route type: %u", zroute); + return &unknown; + } + if (zroute == route_types[zroute].zroute) + return &route_types[zroute]; + for (i = 0; i < sizeof(route_types)/sizeof(route_types[0]); i++) + { + if (zroute == route_types[i].zroute) + { + zlog_warn("internal error: route type table out of order " + "while searching for %u, please notify developers", zroute); + return &route_types[i]; + } + } + zlog_err("internal error: cannot find route type %u in table!", zroute); + return &unknown; +} + +const char * +zebra_route_string(u_int zroute) +{ + return zroute_lookup(zroute)->string; +} + +char +zebra_route_char(u_int zroute) +{ + return zroute_lookup(zroute)->chr; +} -- cgit v1.2.3 From 75ec6dd3085bd68f7a098ff77ff06663e3ed8f96 Mon Sep 17 00:00:00 2001 From: paul Date: Mon, 15 May 2006 16:56:51 +0000 Subject: [lib] Add string mapping table for Zserv commands 2006-05-15 Paul Jakma * log.c: (general) Generalise struct zebra_route_desc into struct zebra_desc_table and, similar to route_types, add a command_types table to describe Zserv protocol commands. (route_types[]) use a macro to use designated initialisers while avoiding tedious duplication. (zserv_command_string) lookup string from zebra_desc_table, similar to zebra_route_string * zebra.h: Add declaration for zserv_command_string, adjust the comments to reflect zebra_desc_table. --- lib/log.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 20 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 6748dbc0..d55ffb7f 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.26 2005/10/01 17:38:07 ajs Exp $ + * $Id: log.c,v 1.27 2006/05/15 16:56:51 paul Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -704,29 +704,61 @@ safe_strerror(int errnum) return (s != NULL) ? s : "Unknown error"; } -/* Note: this table must match the ordering in lib/zebra.h */ -static const struct zebra_route_desc { - u_int zroute; +struct zebra_desc_table +{ + unsigned int type; const char *string; char chr; -} route_types[] = { - { ZEBRA_ROUTE_SYSTEM, "system", 'X' }, - { ZEBRA_ROUTE_KERNEL, "kernel", 'K' }, - { ZEBRA_ROUTE_CONNECT, "connected", 'C' }, - { ZEBRA_ROUTE_STATIC, "static", 'S' }, - { ZEBRA_ROUTE_RIP, "rip", 'R' }, - { ZEBRA_ROUTE_RIPNG, "ripng", 'R' }, - { ZEBRA_ROUTE_OSPF, "ospf", 'O' }, - { ZEBRA_ROUTE_OSPF6, "ospf6", 'O' }, - { ZEBRA_ROUTE_ISIS, "isis", 'I' }, - { ZEBRA_ROUTE_BGP, "bgp", 'B' }, - { ZEBRA_ROUTE_HSLS, "hsls", 'H' }, }; -static const struct zebra_route_desc * +#define DESC_ENTRY(T,S,C) [(T)] = { (T), (S), (C) } +static const struct zebra_desc_table route_types[] = { + DESC_ENTRY (ZEBRA_ROUTE_SYSTEM, "system", 'X' ), + DESC_ENTRY (ZEBRA_ROUTE_KERNEL, "kernel", 'K' ), + DESC_ENTRY (ZEBRA_ROUTE_CONNECT, "connected", 'C' ), + DESC_ENTRY (ZEBRA_ROUTE_STATIC, "static", 'S' ), + DESC_ENTRY (ZEBRA_ROUTE_RIP, "rip", 'R' ), + DESC_ENTRY (ZEBRA_ROUTE_RIPNG, "ripng", 'R' ), + DESC_ENTRY (ZEBRA_ROUTE_OSPF, "ospf", 'O' ), + DESC_ENTRY (ZEBRA_ROUTE_OSPF6, "ospf6", 'O' ), + DESC_ENTRY (ZEBRA_ROUTE_ISIS, "isis", 'I' ), + DESC_ENTRY (ZEBRA_ROUTE_BGP, "bgp", 'B' ), + DESC_ENTRY (ZEBRA_ROUTE_HSLS, "hsls", 'H' ), +}; +#undef DESC_ENTRY + +#define DESC_ENTRY(T) [(T)] = { (T), (#T), '\0' } +static const struct zebra_desc_table command_types[] = { + DESC_ENTRY (ZEBRA_INTERFACE_ADD), + DESC_ENTRY (ZEBRA_INTERFACE_DELETE), + DESC_ENTRY (ZEBRA_INTERFACE_ADDRESS_ADD), + DESC_ENTRY (ZEBRA_INTERFACE_ADDRESS_DELETE), + DESC_ENTRY (ZEBRA_INTERFACE_UP), + DESC_ENTRY (ZEBRA_INTERFACE_DOWN), + DESC_ENTRY (ZEBRA_IPV4_ROUTE_ADD), + DESC_ENTRY (ZEBRA_IPV4_ROUTE_DELETE), + DESC_ENTRY (ZEBRA_IPV6_ROUTE_ADD), + DESC_ENTRY (ZEBRA_IPV6_ROUTE_DELETE), + DESC_ENTRY (ZEBRA_REDISTRIBUTE_ADD), + DESC_ENTRY (ZEBRA_REDISTRIBUTE_DELETE), + DESC_ENTRY (ZEBRA_REDISTRIBUTE_DEFAULT_ADD), + DESC_ENTRY (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE), + DESC_ENTRY (ZEBRA_IPV4_NEXTHOP_LOOKUP), + DESC_ENTRY (ZEBRA_IPV6_NEXTHOP_LOOKUP), + DESC_ENTRY (ZEBRA_IPV4_IMPORT_LOOKUP), + DESC_ENTRY (ZEBRA_IPV6_IMPORT_LOOKUP), + DESC_ENTRY (ZEBRA_INTERFACE_RENAME), + DESC_ENTRY (ZEBRA_ROUTER_ID_ADD), + DESC_ENTRY (ZEBRA_ROUTER_ID_DELETE), + DESC_ENTRY (ZEBRA_ROUTER_ID_UPDATE), +}; +#undef DESC_ENTRY + +static const struct zebra_desc_table unknown = { 0, "unknown", '?' }; + +static const struct zebra_desc_table * zroute_lookup(u_int zroute) { - static const struct zebra_route_desc unknown = { 0, "unknown", '?' }; u_int i; if (zroute >= sizeof(route_types)/sizeof(route_types[0])) @@ -734,11 +766,11 @@ zroute_lookup(u_int zroute) zlog_err("unknown zebra route type: %u", zroute); return &unknown; } - if (zroute == route_types[zroute].zroute) + if (zroute == route_types[zroute].type) return &route_types[zroute]; for (i = 0; i < sizeof(route_types)/sizeof(route_types[0]); i++) { - if (zroute == route_types[i].zroute) + if (zroute == route_types[i].type) { zlog_warn("internal error: route type table out of order " "while searching for %u, please notify developers", zroute); @@ -760,3 +792,14 @@ zebra_route_char(u_int zroute) { return zroute_lookup(zroute)->chr; } + +const char * +zserv_command_string (unsigned int command) +{ + if (command >= sizeof(command_types)/sizeof(command_types[0])) + { + zlog_err ("unknown zserv command type: %u", command); + return unknown.string; + } + return command_types[command].string; +} -- cgit v1.2.3 From 9bd92b63be67a5eaf60043faa4640bfe3cd69e8f Mon Sep 17 00:00:00 2001 From: paul Date: Sun, 28 May 2006 08:26:15 +0000 Subject: [lib] Add support for Sun libc printstack to zlog_backtrace_sigsafe 2006-05-28 Paul Jakma * configure.ac: Check for Sun libc printstack(), add a general HAVE_STACK_TRACE define for lib/log.c, if any supported stack symbol dumping function is found (glibc backtrace/sun libc printstack). * log.c: (general) Add support for Sun libc printstack(). (hex_append) make the cpp conditional on general HAVE_STACK_TRACE define. (zlog_backtrace_sigsafe) Ditto. Add printstack() version of the the DUMP macro in this function. --- lib/log.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index d55ffb7f..dba2a857 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.27 2006/05/15 16:56:51 paul Exp $ + * $Id: log.c,v 1.28 2006/05/28 08:26:15 paul Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -179,7 +179,7 @@ num_append(char *s, int len, u_long x) return str_append(s,len,t); } -#if defined(SA_SIGINFO) || defined(HAVE_GLIBC_BACKTRACE) +#if defined(SA_SIGINFO) || defined(HAVE_STACK_TRACE) static char * hex_append(char *s, int len, u_long x) { @@ -371,7 +371,7 @@ zlog_signal(int signo, const char *action void zlog_backtrace_sigsafe(int priority, void *program_counter) { -#ifdef HAVE_GLIBC_BACKTRACE +#ifdef HAVE_STACK_TRACE static const char pclabel[] = "Program counter: "; void *array[20]; int size; @@ -379,13 +379,10 @@ zlog_backtrace_sigsafe(int priority, void *program_counter) char *s; #define LOC s,buf+sizeof(buf)-s +#ifdef HAVE_GLIBC_BACKTRACE if (((size = backtrace(array,sizeof(array)/sizeof(array[0]))) <= 0) || ((size_t)size > sizeof(array)/sizeof(array[0]))) return; - s = buf; - s = str_append(LOC,"Backtrace for "); - s = num_append(LOC,size); - s = str_append(LOC," stack frames:\n"); #define DUMP(FD) { \ if (program_counter) \ @@ -396,6 +393,19 @@ zlog_backtrace_sigsafe(int priority, void *program_counter) write(FD, buf, s-buf); \ backtrace_symbols_fd(array, size, FD); \ } +#elif defined(HAVE_PRINTSTACK) +#define DUMP(FD) { \ + if (program_counter) \ + write((FD), pclabel, sizeof(pclabel)-1); \ + write((FD), buf, s-buf); \ + printstack((FD)); \ +} +#endif /* HAVE_GLIBC_BACKTRACE, HAVE_PRINTSTACK */ + + s = buf; + s = str_append(LOC,"Backtrace for "); + s = num_append(LOC,size); + s = str_append(LOC," stack frames:\n"); if ((logfile_fd >= 0) || ((logfile_fd = open_crashlog()) >= 0)) DUMP(logfile_fd) @@ -431,7 +441,7 @@ zlog_backtrace_sigsafe(int priority, void *program_counter) } #undef DUMP #undef LOC -#endif /* HAVE_GLIBC_BACKTRACE */ +#endif /* HAVE_STRACK_TRACE */ } void -- cgit v1.2.3 From 2afa1544a80c883d534701626c467c446353cf3b Mon Sep 17 00:00:00 2001 From: ajs Date: Tue, 20 Mar 2007 20:48:27 +0000 Subject: [lib] Make message lookup function more robust. 2007-03-20 Andrew J. Schorr * log.c: (mes_lookup) Make the function more robust: check for cases where the index does not match the key value at that position. If so, give a warning and fall back to a linear search. And improve the error message in cases where even that fails. --- lib/log.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index dba2a857..e1cd24d8 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.28 2006/05/28 08:26:15 paul Exp $ + * $Id: log.c,v 1.29 2007/03/20 20:48:27 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -693,17 +693,32 @@ lookup (struct message *mes, int key) return ""; } -/* Very old hacky version of message lookup function. Still partly - used in bgpd and ospfd. FIXME Seems that it's not used any more. */ +/* Older/faster version of message lookup function, but requires caller to pass + in the array size (instead of relying on a 0 key to terminate the search). */ const char * mes_lookup (struct message *meslist, int max, int index) { - if (index < 0 || index >= max) - { - zlog_err ("message index out of bound: %d", max); - return NULL; - } - return meslist[index].str; + /* first check for best case: index is in range and matches the key + value in that slot */ + if ((index >= 0) && (index < max) && (meslist[index].key == index)) + return meslist[index].str; + + /* fall back to linear search */ + { + int i; + + for (i = 0; i < max; i++, meslist++) + { + if (meslist->key == index) + { + zlog_warn("message index %d [%s] found in position %d (max is %d)", + index, meslist->str, i, max); + return meslist->str; + } + } + } + zlog_err("message index %d not found (max is %d)", index, max); + return NULL; } /* Wrapper around strerror to handle case where it returns NULL. */ -- cgit v1.2.3 From 870a1b5e5b7a25411fdb9c66d3a90ff463d8535e Mon Sep 17 00:00:00 2001 From: ajs Date: Sat, 28 Apr 2007 22:14:10 +0000 Subject: [logging] Add new "log timestamp precision" command for subsecond timestamps 2007-04-28 Andrew J. Schorr * command.c: (config_write_host) Save "log timestamp precision" if not default value. (show_logging) Show configured timestamp precision. (config_log_timestamp_precision) Enable configuration of timestamp precision. (no_config_log_timestamp_precision) Restore default timestamp precision. (cmd_init) Install new timestamp precision commands. * log.h: (struct zlog) New timestamp_precision field. (quagga_timestamp) New function to generate a timestamp with the desired precision. (struct timestamp_control) Declare a structure for use in avoiding repeated duplicate calls to quagga_timestamp. * log.c: (quagga_timestamp) New function to generate a timestamp of the desired precision. (time_print) Call quagga_timestamp if the time hasn't already been calculated. (vzlog) Initialize a timestamp_control structure and pass it to time_print and vty_log. (zlog_backtrace) Fix 64-bit problem: cannot print size_t with %u. * vty.h: Must now include "log.h". (vty_log) Takes an additional struct timestamp_control argument. * vty.c: (vty_log_out) Use new struct timestamp_control and new quagga_timestamp function to print timestamps of the desired precision. (vty_time_print) Use new quagga_timestamp function. (vty_log) Accept new struct timestamp_control argument and pass it down to vty_log_out. --- lib/log.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 23 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index e1cd24d8..b6d2ba64 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.29 2007/03/20 20:48:27 ajs Exp $ + * $Id: log.c,v 1.30 2007/04/28 22:14:10 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -66,32 +66,81 @@ const char *zlog_priority[] = /* For time string format. */ -#define TIME_BUF 27 -/* Utility routine for current time printing. */ -static void -time_print (FILE *fp) +size_t +quagga_timestamp(int timestamp_precision, char *buf, size_t buflen) { - int ret; - char buf [TIME_BUF]; - time_t clock; - struct tm *tm; - - time (&clock); - tm = localtime (&clock); + static struct { + time_t last; + size_t len; + char buf[28]; + } cache; + struct timeval clock; + + /* would it be sufficient to use global 'recent_time' here? I fear not... */ + gettimeofday(&clock, NULL); + + /* first, we update the cache if the time has changed */ + if (cache.last != clock.tv_sec) + { + struct tm *tm; + cache.last = clock.tv_sec; + tm = localtime(&cache.last); + cache.len = strftime(cache.buf, sizeof(cache.buf), + "%Y/%m/%d %H:%M:%S", tm); + } + /* note: it's not worth caching the subsecond part, because + chances are that back-to-back calls are not sufficiently close together + for the clock not to have ticked forward */ - ret = strftime (buf, TIME_BUF, "%Y/%m/%d %H:%M:%S", tm); - if (ret == 0) { - zlog_warn ("strftime error"); - } + if (buflen > cache.len) + { + memcpy(buf, cache.buf, cache.len); + if ((timestamp_precision > 0) && + (buflen > cache.len+1+timestamp_precision)) + { + /* should we worry about locale issues? */ + long divisor = 100000; + char *p = buf+cache.len; + *p++ = '.'; + do + { + *p++ = '0'+(clock.tv_usec/divisor); + clock.tv_usec %= divisor; + divisor /= 10; + } + while (--timestamp_precision > 0); + *p = '\0'; + return p-buf; + } + buf[cache.len] = '\0'; + return cache.len; + } + if (buflen > 0) + buf[0] = '\0'; + return 0; +} - fprintf (fp, "%s ", buf); +/* Utility routine for current time printing. */ +static void +time_print(FILE *fp, struct timestamp_control *ctl) +{ + if (!ctl->already_rendered) + { + ctl->len = quagga_timestamp(ctl->precision, ctl->buf, sizeof(ctl->buf)); + ctl->already_rendered = 1; + } + fprintf(fp, "%s ", ctl->buf); } + /* va_list version of zlog. */ static void vzlog (struct zlog *zl, int priority, const char *format, va_list args) { + struct timestamp_control tsctl; + tsctl.already_rendered = 0; + /* If zlog is not specified, use default one. */ if (zl == NULL) zl = zlog_default; @@ -99,7 +148,8 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) /* When zlog_default is also NULL, use stderr for logging. */ if (zl == NULL) { - time_print (stderr); + tsctl.precision = 0; + time_print(stderr, &tsctl); fprintf (stderr, "%s: ", "unknown"); vfprintf (stderr, format, args); fprintf (stderr, "\n"); @@ -108,6 +158,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) /* In this case we return at here. */ return; } + tsctl.precision = zl->timestamp_precision; /* Syslog output */ if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG]) @@ -122,7 +173,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp) { va_list ac; - time_print (zl->fp); + time_print (zl->fp, &tsctl); if (zl->record_priority) fprintf (zl->fp, "%s: ", zlog_priority[priority]); fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]); @@ -137,7 +188,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT]) { va_list ac; - time_print (stdout); + time_print (stdout, &tsctl); if (zl->record_priority) fprintf (stdout, "%s: ", zlog_priority[priority]); fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]); @@ -151,7 +202,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) /* Terminal monitor. */ if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR]) vty_log ((zl->record_priority ? zlog_priority[priority] : NULL), - zlog_proto_names[zl->protocol], format, args); + zlog_proto_names[zl->protocol], format, &tsctl, args); } static char * @@ -458,8 +509,8 @@ zlog_backtrace(int priority) ((size_t)size > sizeof(array)/sizeof(array[0]))) { zlog_err("Cannot get backtrace, returned invalid # of frames %d " - "(valid range is between 1 and %u)", - size, sizeof(array)/sizeof(array[0])); + "(valid range is between 1 and %lu)", + size, (unsigned long)(sizeof(array)/sizeof(array[0]))); return; } zlog(NULL, priority, "Backtrace for %d stack frames:", size); -- cgit v1.2.3 From d108165de1b0ab760d996e1c297d888e08618d99 Mon Sep 17 00:00:00 2001 From: ajs Date: Sun, 29 Apr 2007 15:48:22 +0000 Subject: [logging] Minor performance tweak 2007-04-29 Andrew J. Schorr * log.c: (quagga_timestamp) Optimize the subsecond timestamp generation. --- lib/log.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index b6d2ba64..84a8bf2e 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.30 2007/04/28 22:14:10 ajs Exp $ + * $Id: log.c,v 1.31 2007/04/29 15:48:22 ajs Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -100,18 +100,25 @@ quagga_timestamp(int timestamp_precision, char *buf, size_t buflen) (buflen > cache.len+1+timestamp_precision)) { /* should we worry about locale issues? */ - long divisor = 100000; - char *p = buf+cache.len; - *p++ = '.'; + static const int divisor[] = {0, 100000, 10000, 1000, 100, 10, 1}; + int prec; + char *p = buf+cache.len+1+(prec = timestamp_precision); + *p-- = '\0'; + while (prec > 6) + /* this is unlikely to happen, but protect anyway */ + { + *p-- = '0'; + prec--; + } + clock.tv_usec /= divisor[prec]; do { - *p++ = '0'+(clock.tv_usec/divisor); - clock.tv_usec %= divisor; - divisor /= 10; + *p-- = '0'+(clock.tv_usec % 10); + clock.tv_usec /= 10; } - while (--timestamp_precision > 0); - *p = '\0'; - return p-buf; + while (--prec > 0); + *p = '.'; + return cache.len+1+timestamp_precision; } buf[cache.len] = '\0'; return cache.len; -- cgit v1.2.3 From fb6ce7ca5dfee02536e32ec5c76be7ae8737cb4e Mon Sep 17 00:00:00 2001 From: paul Date: Wed, 2 May 2007 16:05:35 +0000 Subject: [zebra] Routemap support on received routes, with 'set src' command (linux) 2007-05-01 David L Stevens * (general) These changes collectively add route-map and prefix-list support to zebra and fix a bug in "show route-map" (with no argument). * doc/main.texi: added route-map, prefix-list, ip protocol and set src documentation * lib/command.h: added PROTOCOL_NODE type * lib/log.c: (proto_name2num) new function, protocol name to number translation. * lib/routemap.c: (vty_show_route_map) fixed "show route-map" without route-map name * lib/routemap.h: added RMAP_ZEBRA type * lib/zebra.h: added proto_name2num() prototype * vtysh/extract.pl.in: added VTYSH_ZEBRA flag for route-map and plist * vtysh/Makefile.am: added zebra_routemap.c * vtysh/vtysh.h: added VTYSH_ZEBRA flag to VTYSH_RMAP * zebra/connected.c: (connected_up_ipv4) added src preference argument to rib_add_ipv4() * zebra/kernel_socket.c: (rtm_read) ditto * zebra/main.c: added prefix list initialization * zebra/Makefile.am: added zebra_routemap.c source file * zebra/rib.h: added generic address union "g_addr" and use in existing places that had an explicit union. Added "src" to struct nexthop. Added preferred src arg to nexthop_ipv4_add and rib_add_ipv4. * zebra/rt_netlink.c: (netlink_routing_table) set preferred source on netlink messages. (netlink_route_change) ditto (netlink_route_multipath) ditto. * zebra/rtread_getmsg.c: (handle_route_entry) added (NULL) src to rib_add_ipv4() call. * zebra/rtread_proc.c: (proc_route_read) ditto * zebra/zebra_rib.c: (nexthop_ipv4_add) add src argument. (nexthop_ipv4_ifindex_add) ditto (rib_add_ipv4) ditto (nexthop_active_check) Add route-map processing. * zebra/zebra_routemap.c: new file for zebra route-map commands. * zebra/zebra_vty.c: (ip_protocol_cmd) Apply route-map to protocol (vty_show_ip_route_detail) added "src" printing (vty_show_ip_route) ditto (show_ip_protocol_cmd) new command, list routemaps. (config_write_protocol) write out routemap protocl config. (zebra_vty_init) Install the new routemap protocol commands. * zebra/zserv.c: (zread_ipv4_add) added (NULL) src arg (zebra_init) init zebra route-maps. * zebra/zserv.h: add zebra_route_map_init --- lib/log.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 84a8bf2e..af6cedc3 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.31 2007/04/29 15:48:22 ajs Exp $ + * $Id: log.c,v 1.32 2007/05/02 16:05:35 paul Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -886,3 +886,17 @@ zserv_command_string (unsigned int command) } return command_types[command].string; } + +#define RTSIZE (sizeof(route_types)/sizeof(route_types[0])) + +int +proto_name2num(const char *s) +{ + unsigned i; + + for (i=0; i Date: Mon, 6 Aug 2007 15:21:45 +0000 Subject: [bgpd] cleanup, compact and consolidate capability parsing code 2007-07-26 Paul Jakma * (general) Clean up and compact capability parsing slightly. Consolidate validation of length and logging of generic TLV, and memcpy of capability data, thus removing such from cap specifc code (not always present or correct). * bgp_open.h: Add structures for the generic capability TLV header and for the data formats of the various specific capabilities we support. Hence remove the badly named, or else misdefined, struct capability. * bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data. Do the length checks *before* memcpy()'ing based on that length (stored capability - should have been validated anyway on input, but..). (bgp_afi_safi_valid_indices) new function to validate (afi,safi) which is about to be used as index into arrays, consolidates several instances of same, at least one of which appeared to be incomplete.. (bgp_capability_mp) Much condensed. (bgp_capability_orf_entry) New, process one ORF entry (bgp_capability_orf) Condensed. Fixed to process all ORF entries. (bgp_capability_restart) Condensed, and fixed to use a cap-specific type, rather than abusing capability_mp. (struct message capcode_str) added to aid generic logging. (size_t cap_minsizes[]) added to aid generic validation of capability length field. (bgp_capability_parse) Generic logging and validation of TLV consolidated here. Code compacted as much as possible. * bgp_packet.c: (bgp_open_receive) Capability parsers now use streams, so no more need here to manually fudge the input stream getp. (bgp_capability_msg_parse) use struct capability_mp_data. Validate lengths /before/ memcpy. Use bgp_afi_safi_valid_indices. (bgp_capability_receive) Exported for use by test harness. * bgp_vty.c: (bgp_show_summary) fix conversion warning (bgp_show_peer) ditto * bgp_debug.h: Fix storage 'extern' after type 'const'. * lib/log.c: (mes_lookup) warning about code not being in same-number array slot should be debug, not warning. E.g. BGP has several discontigious number spaces, allocating from different parts of a space is not uncommon (e.g. IANA assigned versus vendor-assigned code points in some number space). --- lib/log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index af6cedc3..c19459c4 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.32 2007/05/02 16:05:35 paul Exp $ + * $Id: log.c,v 1.33 2007/08/06 15:21:45 paul Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -769,7 +769,7 @@ mes_lookup (struct message *meslist, int max, int index) { if (meslist->key == index) { - zlog_warn("message index %d [%s] found in position %d (max is %d)", + zlog_debug ("message index %d [%s] found in position %d (max is %d)", index, meslist->str, i, max); return meslist->str; } -- cgit v1.2.3 From 8bd8d860740dc0eefdc79d8ce26bb38cc780bc5c Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 28 Feb 2008 23:26:02 +0000 Subject: [lib] Fix the struct message LOOKUP function to be more robust 2008-02-28 Paul Jakma * log.c: (mes_lookup) Sowmini Varadhan diagnosed a problem where this function can cause a NULL dereference, on lookups for unknown indices, or messages with NULL strings. Can occur, e.g., debug logging code when processing received messages. Fixed to accept a pointer to a default string to be used if there is no match. * log.h: LOOKUP adjusted to match --- lib/log.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index c19459c4..df630099 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,5 +1,5 @@ /* - * $Id: log.c,v 1.33 2007/08/06 15:21:45 paul Exp $ + * $Id: log.c,v 1.34 2008/02/28 23:26:02 paul Exp $ * * Logging of zebra * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro @@ -752,14 +752,24 @@ lookup (struct message *mes, int key) } /* Older/faster version of message lookup function, but requires caller to pass - in the array size (instead of relying on a 0 key to terminate the search). */ + * in the array size (instead of relying on a 0 key to terminate the search). + * + * The return value is the message string if found, or the 'none' pointer + * provided otherwise. + */ const char * -mes_lookup (struct message *meslist, int max, int index) +mes_lookup (struct message *meslist, int max, int index, const char *none) { + int pos = index - meslist[0].key; + /* first check for best case: index is in range and matches the key - value in that slot */ - if ((index >= 0) && (index < max) && (meslist[index].key == index)) - return meslist[index].str; + * value in that slot. + * NB: key numbering might be offset from 0. E.g. protocol constants + * often start at 1. + */ + if ((pos >= 0) && (pos < max) + && (meslist[pos].key == index)) + return meslist[pos].str; /* fall back to linear search */ { @@ -769,14 +779,17 @@ mes_lookup (struct message *meslist, int max, int index) { if (meslist->key == index) { + const char *str = (meslist->str ? meslist->str : none); + zlog_debug ("message index %d [%s] found in position %d (max is %d)", - index, meslist->str, i, max); - return meslist->str; + index, str, i, max); + return str; } } } zlog_err("message index %d not found (max is %d)", index, max); - return NULL; + assert (none); + return none; } /* Wrapper around strerror to handle case where it returns NULL. */ -- cgit v1.2.3