summaryrefslogtreecommitdiffstats
path: root/sysdep/unix
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>1999-12-06 14:45:56 +0100
committerMartin Mares <mj@ucw.cz>1999-12-06 14:45:56 +0100
commita0c37b45e59f024fc24b65ffbaf2c9e0f1996938 (patch)
treeb20a91de7de7349266e4eb708c839f8ceb9d7a77 /sysdep/unix
parent7c0cc76ed76100ef8492f13eeec1e061d52b9be0 (diff)
downloadbird-a0c37b45e59f024fc24b65ffbaf2c9e0f1996938.tar
bird-a0c37b45e59f024fc24b65ffbaf2c9e0f1996938.zip
Logging is now configurable. You can define multiple log outputs (to both
files and syslog) and assign lists of message categories to each of them.
Diffstat (limited to 'sysdep/unix')
-rw-r--r--sysdep/unix/Modules1
-rw-r--r--sysdep/unix/config.Y62
-rw-r--r--sysdep/unix/log.c120
-rw-r--r--sysdep/unix/main.c25
-rw-r--r--sysdep/unix/unix.h16
5 files changed, 168 insertions, 56 deletions
diff --git a/sysdep/unix/Modules b/sysdep/unix/Modules
index 7534a47..aca7931 100644
--- a/sysdep/unix/Modules
+++ b/sysdep/unix/Modules
@@ -4,6 +4,7 @@ timer.h
io.c
unix.h
endian.h
+config.Y
krt.c
krt.h
diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y
new file mode 100644
index 0000000..bd9c382
--- /dev/null
+++ b/sysdep/unix/config.Y
@@ -0,0 +1,62 @@
+/*
+ * BIRD -- UNIX Configuration
+ *
+ * (c) 1999 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+CF_HDR
+
+#include "lib/unix.h"
+
+CF_DECLS
+
+CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG)
+
+%type <i> log_mask log_mask_list log_cat
+
+CF_GRAMMAR
+
+CF_ADDTO(conf, log_config)
+
+log_config: LOG TEXT log_mask ';' {
+ struct log_config *c = cfg_allocz(sizeof(struct log_config));
+ FILE *f = rfopen(new_config->pool, $2, "a");
+ if (!f) cf_error("Unable to open log file `%s': %m", $2);
+ c->mask = $3;
+ c->fh = f;
+ add_tail(&new_config->logfiles, &c->n);
+ }
+ | LOG SYSLOG log_mask ';' {
+ struct log_config *c = cfg_allocz(sizeof(struct log_config));
+ c->mask = $3;
+ add_tail(&new_config->logfiles, &c->n);
+ }
+ ;
+
+log_mask:
+ ALL { $$ = ~0; }
+ | '{' log_mask_list '}' { $$ = $2; }
+ ;
+
+log_mask_list:
+ log_cat { $$ = 1 << $1; }
+ | log_mask_list ',' log_cat { $$ = $1 | (1 << $3); }
+ ;
+
+log_cat:
+ DEBUG { $$ = L_DEBUG[0]; }
+ | TRACE { $$ = L_TRACE[0]; }
+ | INFO { $$ = L_INFO[0]; }
+ | REMOTE { $$ = L_REMOTE[0]; }
+ | WARNING { $$ = L_WARN[0]; }
+ | ERROR { $$ = L_ERR[0]; }
+ | AUTH { $$ = L_AUTH[0]; }
+ | FATAL { $$ = L_FATAL[0]; }
+ | BUG { $$ = L_BUG[0]; }
+ ;
+
+CF_CODE
+
+CF_END
diff --git a/sysdep/unix/log.c b/sysdep/unix/log.c
index a6e1a56..afc30a9 100644
--- a/sysdep/unix/log.c
+++ b/sysdep/unix/log.c
@@ -14,21 +14,26 @@
#include "nest/bird.h"
#include "nest/cli.h"
#include "lib/string.h"
+#include "lib/lists.h"
+#include "lib/unix.h"
-static int log_inited;
-static FILE *logf = NULL;
static FILE *dbgf = NULL;
+static list *current_log_list;
+static list init_log_list;
#ifdef HAVE_SYSLOG
#include <sys/syslog.h>
static int syslog_priorities[] = {
- LOG_INFO,
+ LOG_DEBUG,
+ LOG_DEBUG,
LOG_DEBUG,
LOG_INFO,
+ LOG_ERR,
LOG_WARNING,
LOG_ERR,
- LOG_NOTICE,
+ LOG_ERR,
+ LOG_CRIT,
LOG_CRIT
};
#endif
@@ -36,50 +41,55 @@ static int syslog_priorities[] = {
static char *class_names[] = {
"???",
"DBG",
+ "TRACE",
"INFO",
+ "RMT",
"WARN",
"ERR",
"AUTH",
- "FATAL"
+ "FATAL",
+ "BUG"
};
static void
vlog(int class, char *msg, va_list args)
{
char buf[1024];
- char date[32];
+ struct log_config *l;
if (bvsnprintf(buf, sizeof(buf)-1, msg, args) < 0)
bsprintf(buf + sizeof(buf) - 100, " ... <too long>");
- if (logf)
+ WALK_LIST(l, *current_log_list)
{
- time_t now = time(NULL);
- struct tm *tm = localtime(&now);
-
- bsprintf(date, "%02d-%02d-%04d %02d:%02d:%02d <%s> ",
- tm->tm_mday,
- tm->tm_mon+1,
- tm->tm_year+1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec,
- class_names[class]);
- fputs(date, logf);
- fputs(buf, logf);
- fputc('\n', logf);
- fflush(logf);
- }
+ if (!(l->mask & (1 << class)))
+ continue;
+ if (l->fh)
+ {
+ time_t now = time(NULL);
+ struct tm *tm = localtime(&now);
+
+ if (l->terminal_flag)
+ fputs("bird: ", l->fh);
+ else
+ {
+ fprintf(l->fh, "%02d-%02d-%04d %02d:%02d:%02d <%s> ",
+ tm->tm_mday,
+ tm->tm_mon+1,
+ tm->tm_year+1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ class_names[class]);
+ }
+ fputs(buf, l->fh);
+ fputc('\n', l->fh);
+ fflush(l->fh);
+ }
#ifdef HAVE_SYSLOG
- else if (log_inited)
- syslog(syslog_priorities[class], "%s", buf);
+ else
+ syslog(syslog_priorities[class], "%s", buf);
#endif
- else
- {
- fputs("bird: ", stderr);
- fputs(buf, stderr);
- fputc('\n', stderr);
- fflush(stderr);
}
cli_echo(class, buf);
}
@@ -124,36 +134,40 @@ debug(char *msg, ...)
char buf[1024];
va_start(args, msg);
- if (bvsnprintf(buf, sizeof(buf), msg, args) < 0)
- bsprintf(buf + sizeof(buf) - 100, " ... <too long>\n");
if (dbgf)
- fputs(buf, dbgf);
+ {
+ if (bvsnprintf(buf, sizeof(buf), msg, args) < 0)
+ bsprintf(buf + sizeof(buf) - 100, " ... <too long>\n");
+ fputs(buf, dbgf);
+ }
va_end(args);
}
void
-log_init(char *f)
+log_init(int debug)
{
- FILE *new;
+ static struct log_config lc_stderr = { mask: ~0, terminal_flag: 1 };
+
+ init_list(&init_log_list);
+ current_log_list = &init_log_list;
- if (!f)
- new = stderr;
- else if (!*f)
- {
- new = NULL;
#ifdef HAVE_SYSLOG
- openlog("bird", LOG_CONS | LOG_NDELAY, LOG_DAEMON);
-#endif
- }
- else if (!(new = fopen(f, "a")))
+ if (!debug)
{
- log(L_ERR "Unable to open log file `%s': %m", f);
- return;
+ static struct log_config lc_syslog = { mask: ~0 };
+ openlog("bird", LOG_CONS | LOG_NDELAY, LOG_DAEMON);
+ add_tail(current_log_list, &lc_syslog.n);
}
- if (logf && logf != stderr)
- fclose(logf);
- logf = new;
- log_inited = 1;
+#endif
+
+ lc_stderr.fh = stderr;
+ add_tail(current_log_list, &lc_stderr.n);
+}
+
+void
+log_switch(list *l)
+{
+ current_log_list = l;
}
void
@@ -162,9 +176,9 @@ log_init_debug(char *f)
if (dbgf && dbgf != stderr)
fclose(dbgf);
if (!f)
- dbgf = stderr;
- else if (!*f)
dbgf = NULL;
+ else if (!*f)
+ dbgf = stderr;
else if (!(dbgf = fopen(f, "a")))
log(L_ERR "Error opening debug file `%s': %m", f);
}
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index d5ea10b..8e2678a 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -67,6 +67,18 @@ cf_read(byte *dest, unsigned int len)
return l;
}
+void
+sysdep_preconfig(struct config *c)
+{
+ init_list(&c->logfiles);
+}
+
+void
+sysdep_commit(struct config *c)
+{
+ log_switch(&c->logfiles);
+}
+
static void
read_config(void)
{
@@ -258,12 +270,13 @@ signal_init(void)
* Parsing of command-line arguments
*/
-static char *opt_list = "c:d:";
+static char *opt_list = "c:dD:";
+static int debug_flag = 1; /* FIXME: Turn off for production use */
static void
usage(void)
{
- fprintf(stderr, "Usage: bird [-c <config-file>] [-d <debug-file>]\n");
+ fprintf(stderr, "Usage: bird [-c <config-file>] [-d] [-D <debug-file>]\n");
exit(1);
}
@@ -279,7 +292,11 @@ parse_args(int argc, char **argv)
config_name = optarg;
break;
case 'd':
+ debug_flag |= 1;
+ break;
+ case 'D':
log_init_debug(optarg);
+ debug_flag |= 2;
break;
default:
usage();
@@ -300,10 +317,12 @@ main(int argc, char **argv)
dmalloc_debug(0x2f03d00);
#endif
- log_init_debug(NULL);
setvbuf(stdout, NULL, _IONBF, 0); /* FIXME: Kill some day. */
setvbuf(stderr, NULL, _IONBF, 0);
parse_args(argc, argv);
+ if (debug_flag == 1)
+ log_init_debug("");
+ log_init(debug_flag);
log(L_INFO "Launching BIRD " BIRD_VERSION "...");
diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h
index ab724d1..8dd7249 100644
--- a/sysdep/unix/unix.h
+++ b/sysdep/unix/unix.h
@@ -9,6 +9,8 @@
#ifndef _BIRD_UNIX_H_
#define _BIRD_UNIX_H_
+struct pool;
+
/* main.c */
void async_config(void);
@@ -38,9 +40,23 @@ void io_loop(void);
void fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port);
void get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port);
int sk_open_unix(struct birdsock *s, char *name);
+void *tracked_fopen(struct pool *, char *name, char *mode);
/* krt.c bits */
void krt_io_init(void);
+/* log.c */
+
+void log_init(int debug);
+void log_init_debug(char *); /* Initialize debug dump to given file (NULL=stderr, ""=off) */
+void log_switch(struct list *);
+
+struct log_config {
+ node n;
+ unsigned int mask; /* Classes to log */
+ void *fh; /* FILE to log to, NULL=syslog */
+ int terminal_flag;
+};
+
#endif