summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf/conf.h1
-rw-r--r--doc/bird.sgml5
-rw-r--r--sysdep/unix/config.Y10
-rw-r--r--sysdep/unix/log.c49
-rw-r--r--sysdep/unix/main.c23
-rw-r--r--sysdep/unix/unix.h4
6 files changed, 66 insertions, 26 deletions
diff --git a/conf/conf.h b/conf/conf.h
index 5823cdb..6c784d7 100644
--- a/conf/conf.h
+++ b/conf/conf.h
@@ -21,6 +21,7 @@ struct config {
list tables; /* Configured routing tables (struct rtable_config) */
list logfiles; /* Configured log fils (sysdep) */
int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */
+ char *syslog_name; /* Name used for syslog (NULL -> no syslog) */
struct rtable_config *master_rtc; /* Configuration of master routing table */
u32 router_id; /* Our Router ID */
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 6e696e3..64185e9 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -219,9 +219,10 @@ protocol rip {
<sect>Global options
<p><descrip>
- <tag>log "<m/filename/"|syslog|stderr all|{ <m/list of classes/ }</tag>
+ <tag>log "<m/filename/"|syslog [name <m/name/]|stderr all|{ <m/list of classes/ }</tag>
Set logging of messages having the given class (either <cf/all/ or <cf/{
- error, trace }/ etc.) into selected destination. Classes are:
+ error, trace }/ etc.) into selected destination (a file specified as a filename string,
+ syslog with optional name argument, or the stderr output). Classes are:
<cf/info/, <cf/warning/, <cf/error/ and <cf/fatal/ for messages about local problems,
<cf/debug/ for debugging messages,
<cf/trace/ when you want to know what happens in the network,
diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y
index ac5be7e..844f53d 100644
--- a/sysdep/unix/config.Y
+++ b/sysdep/unix/config.Y
@@ -14,12 +14,13 @@ CF_HDR
CF_DECLS
CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG, STDERR, SOFT)
-CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, BASE)
+CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, BASE, NAME)
%type <i> log_mask log_mask_list log_cat
%type <g> log_file
%type <t> cfg_name
%type <tf> timeformat_which
+%type <t> syslog_name
CF_GRAMMAR
@@ -33,13 +34,18 @@ log_config: LOG log_file log_mask ';' {
}
;
+syslog_name:
+ NAME TEXT { $$ = $2; }
+ | { $$ = bird_name; }
+ ;
+
log_file:
TEXT {
FILE *f = tracked_fopen(new_config->pool, $1, "a");
if (!f) cf_error("Unable to open log file `%s': %m", $1);
$$ = f;
}
- | SYSLOG { $$ = NULL; }
+ | SYSLOG syslog_name { $$ = NULL; new_config->syslog_name = $2; }
| STDERR { $$ = stderr; }
;
diff --git a/sysdep/unix/log.c b/sysdep/unix/log.c
index 3d3b433..d4c3648 100644
--- a/sysdep/unix/log.c
+++ b/sysdep/unix/log.c
@@ -28,9 +28,9 @@
#include "lib/lists.h"
#include "lib/unix.h"
-static FILE *dbgf = NULL;
+static FILE *dbgf;
static list *current_log_list;
-static list init_log_list;
+static char *current_syslog_name; /* NULL -> syslog closed */
bird_clock_t rate_limit_time = 5;
int rate_limit_count = 5;
@@ -209,38 +209,55 @@ debug(char *msg, ...)
va_end(args);
}
-void
-log_init(int debug, int init)
+static list *
+default_log_list(int debug, int init, char **syslog_name)
{
- static struct log_config lc_stderr = { mask: ~0, terminal_flag: 1 };
-
+ static list init_log_list;
init_list(&init_log_list);
- current_log_list = &init_log_list;
+ *syslog_name = NULL;
#ifdef HAVE_SYSLOG
if (!debug)
{
static struct log_config lc_syslog = { mask: ~0 };
- openlog("bird", LOG_CONS | LOG_NDELAY, LOG_DAEMON);
- add_tail(current_log_list, &lc_syslog.n);
+ add_tail(&init_log_list, &lc_syslog.n);
+ *syslog_name = bird_name;
if (!init)
- return;
+ return &init_log_list;
}
#endif
+ static struct log_config lc_stderr = { mask: ~0, terminal_flag: 1 };
lc_stderr.fh = stderr;
- add_tail(current_log_list, &lc_stderr.n);
+ add_tail(&init_log_list, &lc_stderr.n);
+ return &init_log_list;
}
void
-log_switch(int debug, list *l)
+log_switch(int debug, list *l, char *new_syslog_name)
{
- if (EMPTY_LIST(*l))
- log_init(debug, 0);
- else
- current_log_list = l;
+ if (!l || EMPTY_LIST(*l))
+ l = default_log_list(debug, !l, &new_syslog_name);
+
+ current_log_list = l;
+
+#ifdef HAVE_SYSLOG
+ if (current_syslog_name && new_syslog_name &&
+ !strcmp(current_syslog_name, new_syslog_name))
+ return;
+
+ if (current_syslog_name)
+ closelog();
+
+ if (new_syslog_name)
+ openlog(new_syslog_name, LOG_CONS | LOG_NDELAY, LOG_DAEMON);
+
+ current_syslog_name = new_syslog_name;
+#endif
}
+
+
void
log_init_debug(char *f)
{
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index e0e0d63..732c916 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -83,7 +83,7 @@ sysdep_preconfig(struct config *c)
int
sysdep_commit(struct config *new, struct config *old UNUSED)
{
- log_switch(debug_flag, &new->logfiles);
+ log_switch(debug_flag, &new->logfiles, new->syslog_name);
return 0;
}
@@ -378,21 +378,36 @@ signal_init(void)
*/
static char *opt_list = "c:dD:ps:";
+static int parse_and_exit;
+char *bird_name;
static void
usage(void)
{
- fprintf(stderr, "Usage: bird [-c <config-file>] [-d] [-D <debug-file>] [-p] [-s <control-socket>]\n");
+ fprintf(stderr, "Usage: %s [-c <config-file>] [-d] [-D <debug-file>] [-p] [-s <control-socket>]\n", bird_name);
exit(1);
}
-int parse_and_exit;
+static inline char *
+get_bird_name(char *s, char *def)
+{
+ char *t;
+ if (!s)
+ return def;
+ t = strrchr(s, '/');
+ if (!t)
+ return s;
+ if (!t[1])
+ return def;
+ return t+1;
+}
static void
parse_args(int argc, char **argv)
{
int c;
+ bird_name = get_bird_name(argv[0], "bird");
if (argc == 2)
{
if (!strcmp(argv[1], "--version"))
@@ -444,7 +459,7 @@ main(int argc, char **argv)
parse_args(argc, argv);
if (debug_flag == 1)
log_init_debug("");
- log_init(debug_flag, 1);
+ log_switch(debug_flag, NULL, NULL);
if (!parse_and_exit)
test_old_bird(path_control_socket);
diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h
index 4de74f2..76825aa 100644
--- a/sysdep/unix/unix.h
+++ b/sysdep/unix/unix.h
@@ -15,6 +15,7 @@ struct pool;
/* main.c */
+extern char *bird_name;
void async_config(void);
void async_dump(void);
void async_shutdown(void);
@@ -60,9 +61,8 @@ void krt_io_init(void);
/* log.c */
-void log_init(int debug, int init);
void log_init_debug(char *); /* Initialize debug dump to given file (NULL=stderr, ""=off) */
-void log_switch(int debug, struct list *);
+void log_switch(int debug, list *l, char *); /* Use l=NULL for initial switch */
struct log_config {
node n;