diff options
-rw-r--r-- | conf/conf.c | 2 | ||||
-rw-r--r-- | conf/conf.h | 5 | ||||
-rw-r--r-- | conf/confbase.Y | 1 | ||||
-rw-r--r-- | doc/bird.sgml | 25 | ||||
-rw-r--r-- | nest/cmds.c | 6 | ||||
-rw-r--r-- | nest/proto.c | 10 | ||||
-rw-r--r-- | nest/rt-table.c | 4 | ||||
-rw-r--r-- | sysdep/unix/config.Y | 19 | ||||
-rw-r--r-- | sysdep/unix/io.c | 61 | ||||
-rw-r--r-- | sysdep/unix/log.c | 14 | ||||
-rw-r--r-- | sysdep/unix/timer.h | 15 |
11 files changed, 97 insertions, 65 deletions
diff --git a/conf/conf.c b/conf/conf.c index 7ffe8d1..bc0715a 100644 --- a/conf/conf.c +++ b/conf/conf.c @@ -80,6 +80,8 @@ config_alloc(byte *name) cfg_mem = c->mem = l; c->file_name = cfg_strdup(name); c->load_time = now; + c->tf_base.fmt1 = c->tf_log.fmt1 = "%d-%m-%Y %T"; + if (!boot_time) boot_time = now; return c; diff --git a/conf/conf.h b/conf/conf.h index f8ab713..5823cdb 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -29,6 +29,11 @@ struct config { u32 listen_bgp_flags; /* Listening BGP socket should use these flags */ unsigned proto_default_debug; /* Default protocol debug mask */ unsigned proto_default_mrtdump; /* Default protocol mrtdump mask */ + struct timeformat tf_route; /* Time format for 'show route' */ + struct timeformat tf_proto; /* Time format for 'show protocol' */ + struct timeformat tf_log; /* Time format for the logfile */ + struct timeformat tf_base; /* Time format for other purposes */ + int cli_debug; /* Tracing of CLI connections and commands */ char *err_msg; /* Parser error message */ int err_lino; /* Line containing error */ diff --git a/conf/confbase.Y b/conf/confbase.Y index 91bfb1d..b65d608 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -42,6 +42,7 @@ CF_DECLS void *g; bird_clock_t time; struct prefix px; + struct timeformat *tf; } %token END CLI_MARKER INVALID_TOKEN diff --git a/doc/bird.sgml b/doc/bird.sgml index 343d016..799972c 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -271,6 +271,31 @@ protocol rip { listen to IPv6 connections only. This is needed if you want to run both bird and bird6 on the same port. + <tag>timeformat route|protocol|base|log "<m/format1/" [<m/limit> "<m/format2/"]</tag> + This option allows to specify a format of date/time used by + BIRD. The first argument specifies for which purpose such + format is used. <cf/route/ is a format used in 'show route' + command output, <cf/protocol/ is used in 'show protocols' + command output, <cf/base/ is used for other commands and + <cf/log/ is used in a log file. + + "<m/format1/" is a format string using <i/strftime(3)/ + notation (see <i/man strftime/ for details). <m/limit> and + "<m/format2/" allow to specify the second format string for + times in past deeper than <m/limit/ seconds. There are two + shorthands: <cf/iso long/ is a ISO 8601 date/time format + (YYYY-MM-DD hh:mm:ss) that can be also specified using <cf/"%F + %T"/. <cf/iso short/ is a variant of ISO 8601 that uses just + the time format (hh:mm:ss) for near times (up to 20 hours in + the past) and the date format (YYYY-MM-DD) for far times. This + is a shorthand for <cf/"%T" 72000 "%F"/. + + By default, BIRD uses an short, ad-hoc format for <cf/route/ + and <cf/protocol/ times, and a <cf/iso long/ similar format + (DD-MM-YYYY hh:mm:ss) for <cf/base/ and <cf/log/. These + defaults are here for a compatibility with older versions + and might change in the future. + <tag>table <m/name/</tag> Create a new routing table. The default routing table is created implicitly, other routing tables have to be added by this command. diff --git a/nest/cmds.c b/nest/cmds.c index faed870..16fbba6 100644 --- a/nest/cmds.c +++ b/nest/cmds.c @@ -18,12 +18,12 @@ cmd_show_status(void) byte tim[TM_DATETIME_BUFFER_SIZE]; cli_msg(-1000, "BIRD " BIRD_VERSION); - tm_format_datetime(tim, now); + tm_format_datetime(tim, &config->tf_base, now); cli_msg(-1011, "Router ID is %R", config->router_id); cli_msg(-1011, "Current server time is %s", tim); - tm_format_datetime(tim, boot_time); + tm_format_datetime(tim, &config->tf_base, boot_time); cli_msg(-1011, "Last reboot on %s", tim); - tm_format_datetime(tim, config->load_time); + tm_format_datetime(tim, &config->tf_base, config->load_time); cli_msg(-1011, "Last reconfiguration on %s", tim); if (shutting_down) cli_msg(13, "Shutdown in progress"); diff --git a/nest/proto.c b/nest/proto.c index 9f0311f..297c05e 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -730,18 +730,18 @@ proto_state_name(struct proto *p) static void proto_do_show(struct proto *p, int verbose) { - byte buf[256], reltime[TM_RELTIME_BUFFER_SIZE]; + byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE]; buf[0] = 0; if (p->proto->get_status) p->proto->get_status(p, buf); - tm_format_reltime(reltime, p->last_state_change); - cli_msg(-1002, "%-8s %-8s %-8s %-5s %-5s %s", + tm_format_datetime(tbuf, &config->tf_proto, p->last_state_change); + cli_msg(-1002, "%-8s %-8s %-8s %-5s %-10s %s", p->name, p->proto->name, p->table->name, proto_state_name(p), - reltime, + tbuf, buf); if (verbose) { @@ -782,7 +782,7 @@ proto_show(struct symbol *s, int verbose) cli_msg(9002, "%s is not a protocol", s->name); return; } - cli_msg(-2002, "name proto table state since info"); + cli_msg(-2002, "name proto table state since info"); if (s) proto_do_show(((struct proto_config *)s->def)->proto, verbose); else diff --git a/nest/rt-table.c b/nest/rt-table.c index df2834a..ed7ecd5 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1114,11 +1114,11 @@ static void rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tmpa) { byte via[STD_ADDRESS_P_LENGTH+32], from[STD_ADDRESS_P_LENGTH+6]; - byte tm[TM_RELTIME_BUFFER_SIZE], info[256]; + byte tm[TM_DATETIME_BUFFER_SIZE], info[256]; rta *a = e->attrs; rt_format_via(e, via); - tm_format_reltime(tm, e->lastmod); + tm_format_datetime(tm, &config->tf_route, e->lastmod); if (ipa_nonzero(a->from) && !ipa_equal(a->from, a->gw)) bsprintf(from, " from %I", a->from); else diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y index 46c5862..8c2b690 100644 --- a/sysdep/unix/config.Y +++ b/sysdep/unix/config.Y @@ -14,10 +14,12 @@ 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) %type <i> log_mask log_mask_list log_cat %type <g> log_file %type <t> cfg_name +%type <tf> timeformat_which CF_GRAMMAR @@ -75,7 +77,24 @@ mrtdump_base: } ; +CF_ADDTO(conf, timeformat_base) +timeformat_which: + ROUTE { $$ = &new_config->tf_route; } + | PROTOCOL { $$ = &new_config->tf_proto; } + | BASE { $$ = &new_config->tf_base; } + | LOG { $$ = &new_config->tf_log; } + +timeformat_spec: + timeformat_which TEXT { *$1 = (struct timeformat){$2, NULL, 0}; } + | timeformat_which TEXT expr TEXT { *$1 = (struct timeformat){$2, $4, $3}; } + | timeformat_which ISO SHORT { *$1 = (struct timeformat){"%T", "%F", 20*3600}; } + | timeformat_which ISO LONG { *$1 = (struct timeformat){"%F %T", NULL, 0}; } + ; + +timeformat_base: + TIMEFORMAT timeformat_spec ';' + ; /* Unix specific commands */ diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 39f29c5..296b6b3 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -410,23 +410,22 @@ tm_parse_date(char *x) return t; } -/** - * tm_format_date - convert date to textual representation - * @x: destination buffer of size %TM_DATE_BUFFER_SIZE - * @t: time - * - * This function formats the given relative time value @t to a textual - * date representation (dd-mm-yyyy) in real time.. - */ -void -tm_format_date(char *x, bird_clock_t t) +static void +tm_format_reltime(char *x, struct tm *tm, bird_clock_t delta) { - struct tm *tm; + static char *month_names[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - tm = localtime(&t); - bsprintf(x, "%02d-%02d-%04d", tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900); + if (delta < 20*3600) + bsprintf(x, "%02d:%02d", tm->tm_hour, tm->tm_min); + else if (delta < 360*86400) + bsprintf(x, "%s%02d", month_names[tm->tm_mon], tm->tm_mday); + else + bsprintf(x, "%d", tm->tm_year+1900); } +#include "conf/conf.h" + /** * tm_format_datetime - convert date and time to textual representation * @x: destination buffer of size %TM_DATETIME_BUFFER_SIZE @@ -436,39 +435,25 @@ tm_format_date(char *x, bird_clock_t t) * date/time representation (dd-mm-yyyy hh:mm:ss) in real time. */ void -tm_format_datetime(char *x, bird_clock_t t) +tm_format_datetime(char *x, struct timeformat *fmt_spec, bird_clock_t t) { + const char *fmt_used; struct tm *tm; bird_clock_t delta = now - t; t = now_real - delta; tm = localtime(&t); - if (strftime(x, TM_DATETIME_BUFFER_SIZE, "%d-%m-%Y %H:%M:%S", tm) == TM_DATETIME_BUFFER_SIZE) - strcpy(x, "<too-long>"); -} -/** - * tm_format_reltime - convert date and time to relative textual representation - * @x: destination buffer of size %TM_RELTIME_BUFFER_SIZE - * @t: time - * - * This function formats the given relative time value @t to a short - * textual representation in real time, relative to the current time. - */ -void -tm_format_reltime(char *x, bird_clock_t t) -{ - struct tm *tm; - static char *month_names[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + if (fmt_spec->fmt1 == NULL) + return tm_format_reltime(x, tm, delta); - bird_clock_t delta = now - t; - t = now_real - delta; - tm = localtime(&t); - if (delta < 20*3600) - bsprintf(x, "%02d:%02d", tm->tm_hour, tm->tm_min); - else if (delta < 360*86400) - bsprintf(x, "%s%02d", month_names[tm->tm_mon], tm->tm_mday); + if ((fmt_spec->limit == 0) || (delta < fmt_spec->limit)) + fmt_used = fmt_spec->fmt1; else - bsprintf(x, "%d", tm->tm_year+1900); + fmt_used = fmt_spec->fmt2; + + int rv = strftime(x, TM_DATETIME_BUFFER_SIZE, fmt_used, tm); + if (((rv == 0) && fmt_used[0]) || (rv == TM_DATETIME_BUFFER_SIZE)) + strcpy(x, "<too-long>"); } /** diff --git a/sysdep/unix/log.c b/sysdep/unix/log.c index dad0c5d..f227549 100644 --- a/sysdep/unix/log.c +++ b/sysdep/unix/log.c @@ -79,21 +79,13 @@ vlog(int class, char *msg, va_list args) 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]); + byte tbuf[TM_DATETIME_BUFFER_SIZE]; + tm_format_datetime(tbuf, &config->tf_log, now); + fprintf(l->fh, "%s <%s> ", tbuf, class_names[class]); } fputs(buf, l->fh); fputc('\n', l->fh); diff --git a/sysdep/unix/timer.h b/sysdep/unix/timer.h index 761cb42..3ed6ff1 100644 --- a/sysdep/unix/timer.h +++ b/sysdep/unix/timer.h @@ -33,14 +33,17 @@ void tm_dump_all(void); extern bird_clock_t now; /* Relative, monotonic time in seconds */ extern bird_clock_t now_real; /* Time in seconds since fixed known epoch */ +struct timeformat { + char *fmt1, *fmt2; + bird_clock_t limit; +}; + bird_clock_t tm_parse_date(char *); /* Convert date to bird_clock_t */ bird_clock_t tm_parse_datetime(char *); /* Convert date to bird_clock_t */ -void tm_format_date(char *, bird_clock_t); /* Convert bird_clock_t to date */ -#define TM_DATE_BUFFER_SIZE 12 /* Buffer size required by tm_format_date */ -void tm_format_datetime(char *, bird_clock_t); /* Convert bird_clock_t to date + time */ -#define TM_DATETIME_BUFFER_SIZE 64 /* Buffer size required by tm_format_datetime */ -void tm_format_reltime(char *, bird_clock_t); /* Convert bird_clock_t to relative datetime string */ -#define TM_RELTIME_BUFFER_SIZE 12 /* Buffer size required by tm_format_reltime */ + +#define TM_DATETIME_BUFFER_SIZE 32 /* Buffer size required by tm_format_datetime */ +void +tm_format_datetime(char *x, struct timeformat *fmt_spec, bird_clock_t t); #ifdef TIME_T_IS_64BIT #define TIME_INFINITY 0x7fffffffffffffff |