]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Makes date/time formats configurable.
authorOndrej Zajicek <santiago@crfreenet.org>
Tue, 2 Feb 2010 23:19:24 +0000 (00:19 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 2 Feb 2010 23:19:24 +0000 (00:19 +0100)
conf/conf.c
conf/conf.h
conf/confbase.Y
doc/bird.sgml
nest/cmds.c
nest/proto.c
nest/rt-table.c
sysdep/unix/config.Y
sysdep/unix/io.c
sysdep/unix/log.c
sysdep/unix/timer.h

index 7ffe8d1314e96645a0f4f975f196ad744cae6cc1..bc0715aec6ba8b01e5fadca6fbc983de0f563f1e 100644 (file)
@@ -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;
index f8ab71312c6be68125e5def6b3e527b378f2bbd3..5823cdbef4e90b7ea9d2e1258301d10a7f80e1d1 100644 (file)
@@ -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 */
index 91bfb1d588e9928dff737144c29937c8ff7f6813..b65d608768db1db91dd9fd2f4dc5fa6c8b7cc823 100644 (file)
@@ -42,6 +42,7 @@ CF_DECLS
   void *g;
   bird_clock_t time;
   struct prefix px;
+  struct timeformat *tf;
 }
 
 %token END CLI_MARKER INVALID_TOKEN
index 343d016bcc4aa6c155db8849d9022f2ef26f8d43..799972cc1bc64b4b3a2db6985a695035f1ac7844 100644 (file)
@@ -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.
index faed870c782e38b617efb89c68e4fd4d3378b3cf..16fbba612a1fa06c10795a6de5d5125923526d5d 100644 (file)
@@ -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");
index 9f0311f6dbf13b47491307adac3f1de1b84d62f9..297c05eb8d615de864acb60a47a6862977d15e9a 100644 (file)
@@ -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
index df2834a615d54667e46ef51f200056fb42917860..ed7ecd57f7af521f7983f686bb0d8332b0c61b92 100644 (file)
@@ -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
index 46c5862b6e8da8564bbd01bd134ac236d771fa74..8c2b690343179d8ab77f86fd1345b4c8af453b53 100644 (file)
@@ -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 */
 
index 39f29c5803f3b646a810c921670e90ef31ccf093..296b6b3ae64606a14371fd6bec57b4ae3af82901 100644 (file)
@@ -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>");
 }
 
 /**
index dad0c5db4403e00a981669b32ee1f99ecd4145ba..f227549c03cb15d34f5023ded7cc3acc6c586fab 100644 (file)
@@ -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);
index 761cb42b0c158321982057334b889058c80a977b..3ed6ff16a04ffa8dfe3f16317a6e4e642d5881ba 100644 (file)
@@ -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