summaryrefslogtreecommitdiff
path: root/sysdep/unix
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>1999-12-06 13:45:56 +0000
committerMartin Mares <mj@ucw.cz>1999-12-06 13:45:56 +0000
commita0c37b45e59f024fc24b65ffbaf2c9e0f1996938 (patch)
treeb20a91de7de7349266e4eb708c839f8ceb9d7a77 /sysdep/unix
parent7c0cc76ed76100ef8492f13eeec1e061d52b9be0 (diff)
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 7534a47b..aca79319 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 00000000..bd9c3822
--- /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 a6e1a56f..afc30a92 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 d5ea10bd..8e2678a2 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 ab724d19..8dd72496 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