]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Timers: Parse and format functions for microsecond times
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 6 Jun 2017 14:47:30 +0000 (16:47 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Thu, 7 Dec 2017 12:49:27 +0000 (13:49 +0100)
Date/time output (e.g. in logs, show commands) can use %f to specify
subsecond time. By default, millisecond precision is used in output.

21 files changed:
conf/conf.c
conf/conf.h
conf/confbase.Y
doc/bird.sgml
lib/timer.c
lib/timer.h
nest/cmds.c
nest/config.Y
nest/password.c
nest/password.h
nest/proto.c
nest/protocol.h
nest/route.h
nest/rt-show.c
nest/rt-table.c
proto/bfd/bfd.c
proto/bfd/bfd.h
sysdep/unix/config.Y
sysdep/unix/io.c
sysdep/unix/log.c
sysdep/unix/timer.h

index c4933122d9b15ee1daf53bb9a39c9df32941b320..a570fad575bc855a0ac86ff162bda04945f6ea38 100644 (file)
@@ -102,9 +102,9 @@ config_alloc(const char *name)
   c->pool = p;
   c->mem = l;
   c->file_name = ndup;
-  c->load_time = now;
-  c->tf_route = c->tf_proto = (struct timeformat){"%T", "%F", 20*3600};
-  c->tf_base = c->tf_log = (struct timeformat){"%F %T", NULL, 0};
+  c->load_time = current_time();
+  c->tf_route = c->tf_proto = TM_ISO_SHORT_MS;
+  c->tf_base = c->tf_log = TM_ISO_LONG_MS;
   c->gr_wait = DEFAULT_GR_WAIT;
 
   return c;
index af92f056b8f7fe1d1d7c228326be1fd856737495..552d0120f0871e875f06c46493ad9912a982bfc4 100644 (file)
@@ -57,7 +57,7 @@ struct config {
   struct config *fallback;             /* Link to regular config for CLI parsing */
   int obstacle_count;                  /* Number of items blocking freeing of this config */
   int shutdown;                                /* This is a pseudo-config for daemon shutdown */
-  bird_clock_t load_time;              /* When we've got this configuration */
+  btime load_time;                     /* When we've got this configuration */
 };
 
 /* Please don't use these variables in protocols. Use proto_config->global instead. */
index 901ca2b2bff428173123ca49d3b9c4e2e516ef0d..390041c4ba9976184896315cc0c6aa2e4b77e677 100644 (file)
@@ -14,7 +14,7 @@ CF_HDR
 #include "conf/conf.h"
 #include "lib/resource.h"
 #include "lib/socket.h"
-#include "sysdep/unix/timer.h"
+#include "lib/timer.h"
 #include "lib/string.h"
 #include "nest/protocol.h"
 #include "nest/iface.h"
@@ -60,7 +60,7 @@ CF_DECLS
   struct lsadb_show_data *ld;
   struct iface *iface;
   void *g;
-  bird_clock_t time;
+  btime time;
   struct f_prefix px;
   struct proto_spec ps;
   struct channel_limit cl;
@@ -81,7 +81,7 @@ CF_DECLS
 
 %type <i> expr bool pxlen4
 %type <i32> expr_us
-%type <time> datetime
+%type <time> time
 %type <a> ipa
 %type <net> net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
 %type <net_ptr> net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_
@@ -308,11 +308,11 @@ label_stack:
   }
 ;
 
-datetime:
+time:
    TEXT {
-     $$ = tm_parse_datetime($1);
+     $$ = tm_parse_time($1);
      if (!$$)
-       cf_error("Invalid date and time");
+       cf_error("Invalid date/time");
    }
  ;
 
index 1b4b3d6743f58554ebee2e98450fbdb49b51b0f3..65efebb8aa060c03ec0dd9b7836687773afb3533 100644 (file)
@@ -456,24 +456,26 @@ protocol rip {
        used for other commands and <cf/log/ is used in a log file.
 
        "<m/format1/" is a format string using <it/strftime(3)/ notation (see
-       <it/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 few 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"/.
+       <it/man strftime/ for details). It is extended to support sub-second
+       time part with variable precision (up to microseconds) using "%f"
+       conversion code (e.g., "%T.%3f" is hh:mm:ss.sss time). <m/limit/ and
+       "<m/format2/" allow to specify the second format string for times in
+       past deeper than <m/limit/ seconds.
+
+       There are several 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"/. Similarly, <cf/iso long ms/ and <cf/iso long us/ are ISO 8601
+       date/time formats with millisecond or microsecond precision.
        <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"/.
+       format (YYYY-MM-DD) for far times. This is a shorthand for <cf/"%T"
+       72000 "%F"/. And there are also <cf/iso short ms/ and <cf/iso short us/
+       high-precision variants of that.
 
-       By default, BIRD uses the <cf/iso short/ format for <cf/route/ and
-       <cf/protocol/ times, and the <cf/iso long/ format for <cf/base/ and
+       By default, BIRD uses the <cf/iso short ms/ format for <cf/route/ and
+       <cf/protocol/ times, and the <cf/iso long ms/ format for <cf/base/ and
        <cf/log/ times.
 
-       In pre-1.4.0 versions, BIRD used 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 timeformats could be set by
-       <cf/old short/ and <cf/old long/ compatibility shorthands.
-
        <tag><label id="opt-table">table <m/name/ [sorted]</tag>
        Create a new routing table. The default routing table is created
        implicitly, other routing tables have to be added by this command.
index 2c08b353460f3584413da25534f8eda72b4dfd5b..3136a56b45e350e3c4e5e36dd5f561bbca5491fd 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 
+#include <stdio.h>
 #include <stdlib.h>
 
 #include "nest/bird.h"
@@ -222,3 +223,137 @@ timer_init(void)
   timers_init(&main_timeloop, &root_pool);
   timeloop_init_current();
 }
+
+
+/**
+ * tm_parse_time - parse a date and time
+ * @x: time string
+ *
+ * tm_parse_time() takes a textual representation of a date and time
+ * (yyyy-mm-dd[ hh:mm:ss[.sss]]) and converts it to the corresponding value of
+ * type &btime.
+ */
+btime
+tm_parse_time(char *x)
+{
+  struct tm tm;
+  int usec, n1, n2, n3, r;
+
+  r = sscanf(x, "%d-%d-%d%n %d:%d:%d%n.%d%n",
+            &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &n1,
+            &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &n2,
+            &usec, &n3);
+
+  if ((r == 3) && !x[n1])
+    tm.tm_hour = tm.tm_min = tm.tm_sec = usec = 0;
+  else if ((r == 6) && !x[n2])
+    usec = 0;
+  else if ((r == 7) && !x[n3])
+  {
+    /* Convert subsecond digits to proper precision */
+    int digits = n3 - n2 - 1;
+    if ((usec < 0) || (usec > 999999) || (digits < 1) || (digits > 6))
+      return 0;
+
+    while (digits++ < 6)
+      usec *= 10;
+  }
+  else
+    return 0;
+
+  tm.tm_mon--;
+  tm.tm_year -= 1900;
+  s64 ts = mktime(&tm);
+  if ((ts == (s64) (time_t) -1) || (ts < 0) || (ts > ((s64) 1 << 40)))
+    return 0;
+
+  return ts S + usec;
+}
+
+/**
+ * tm_format_time - convert date and time to textual representation
+ * @x: destination buffer of size %TM_DATETIME_BUFFER_SIZE
+ * @fmt: specification of resulting textual representation of the time
+ * @t: time
+ *
+ * This function formats the given relative time value @t to a textual
+ * date/time representation (dd-mm-yyyy hh:mm:ss) in real time.
+ */
+void
+tm_format_time(char *x, struct timeformat *fmt, btime t)
+{
+  btime dt = current_time() - t;
+  btime rt = current_real_time() - dt;
+  int v1 = !fmt->limit || (dt < fmt->limit);
+
+  tm_format_real_time(x, v1 ? fmt->fmt1 : fmt->fmt2, rt);
+}
+
+/* Replace %f in format string with usec scaled to requested precision */
+static int
+strfusec(char *buf, int size, const char *fmt, uint usec)
+{
+  char *str = buf;
+  int parity = 0;
+
+  while (*fmt)
+  {
+    if (!size)
+      return 0;
+
+    if ((fmt[0] == '%') && (!parity) &&
+       ((fmt[1] == 'f') || (fmt[1] >= '1') && (fmt[1] <= '6') && (fmt[2] == 'f')))
+    {
+      int digits = (fmt[1] == 'f') ? 6 : (fmt[1] - '0');
+      uint d = digits, u = usec;
+
+      /* Convert microseconds to requested precision */
+      while (d++ < 6)
+       u /= 10;
+
+      int num = bsnprintf(str, size, "%0*u", digits, u);
+      if (num < 0)
+       return 0;
+
+      fmt += (fmt[1] == 'f') ? 2 : 3;
+      ADVANCE(str, size, num);
+    }
+    else
+    {
+      /* Handle '%%' expression */
+      parity = (*fmt == '%') ? !parity : 0;
+      *str++ = *fmt++;
+      size--;
+    }
+  }
+
+  if (!size)
+    return 0;
+
+  *str = 0;
+  return str - buf;
+}
+
+void
+tm_format_real_time(char *x, const char *fmt, btime t)
+{
+  s64 t1 = t TO_S;
+  s64 t2 = t - t1 S;
+
+  time_t ts = t1;
+  struct tm tm;
+  if (!localtime_r(&ts, &tm))
+    goto err;
+
+  byte tbuf[TM_DATETIME_BUFFER_SIZE];
+  if (!strfusec(tbuf, TM_DATETIME_BUFFER_SIZE, fmt, t2))
+    goto err;
+
+  if (!strftime(x, TM_DATETIME_BUFFER_SIZE, tbuf, &tm))
+    goto err;
+
+  return;
+
+err:
+  strcpy(x, "<error>");
+}
index b70ac48d37edc4835a3808cd308bae6dd9161d21..61a2aa94b7575eea329f09d726482dc5eb48aef4 100644 (file)
@@ -105,4 +105,23 @@ void timers_fire(struct timeloop *loop);
 void timer_init(void);
 
 
+struct timeformat {
+  char *fmt1, *fmt2;
+  btime limit;
+};
+
+#define TM_ISO_SHORT_S (struct timeformat){"%T",     "%F", (s64) (20*3600) S_}
+#define TM_ISO_SHORT_MS        (struct timeformat){"%T.%3f", "%F", (s64) (20*3600) S_}
+#define TM_ISO_SHORT_US        (struct timeformat){"%T.%6f", "%F", (s64) (20*3600) S_}
+
+#define TM_ISO_LONG_S  (struct timeformat){"%F %T",     NULL, 0}
+#define TM_ISO_LONG_MS (struct timeformat){"%F %T.%3f", NULL, 0}
+#define TM_ISO_LONG_US (struct timeformat){"%F %T.%6f", NULL, 0}
+
+#define TM_DATETIME_BUFFER_SIZE 32     /* Buffer size required by tm_format_time() */
+
+btime tm_parse_time(char *x);
+void tm_format_time(char *x, struct timeformat *fmt, btime t);
+void tm_format_real_time(char *x, const char *fmt, btime t);
+
 #endif
index 371e8877b84e9aa1b4a33d8db67295cae0b7903f..ca601ef26744d3eac4edd5f38b9a22928b875cb9 100644 (file)
@@ -25,12 +25,12 @@ cmd_show_status(void)
   byte tim[TM_DATETIME_BUFFER_SIZE];
 
   cli_msg(-1000, "BIRD " BIRD_VERSION);
-  tm_format_datetime(tim, &config->tf_base, now);
+  tm_format_time(tim, &config->tf_base, current_time());
   cli_msg(-1011, "Router ID is %R", config->router_id);
   cli_msg(-1011, "Current server time is %s", tim);
-  tm_format_datetime(tim, &config->tf_base, boot_time TO_S);
+  tm_format_time(tim, &config->tf_base, boot_time);
   cli_msg(-1011, "Last reboot on %s", tim);
-  tm_format_datetime(tim, &config->tf_base, config->load_time);
+  tm_format_time(tim, &config->tf_base, config->load_time);
   cli_msg(-1011, "Last reconfiguration on %s", tim);
 
   graceful_restart_show_status();
index 220fa8b0f9861b9ca4cd4d4ab717ad97e3c4f363..ef29fb966d31deac65b9514d7f5e33bf2930e509 100644 (file)
@@ -73,6 +73,7 @@ CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512)
 CF_KEYWORDS(PRIMARY, STATS, COUNT, BY, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE)
 CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
 CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
+CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US)
 CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
 
 /* For r_args_channel */
@@ -295,6 +296,7 @@ limit_spec:
  | OFF { $$ = (struct channel_limit){}; }
  ;
 
+
 CF_ADDTO(conf, debug_default)
 
 debug_default:
@@ -304,6 +306,31 @@ debug_default:
 
 /* MRTDUMP PROTOCOLS is in systep/unix/config.Y */
 
+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, (s64) $3 S_}; }
+ | timeformat_which ISO SHORT    { *$1 = TM_ISO_SHORT_S; }
+ | timeformat_which ISO SHORT MS { *$1 = TM_ISO_SHORT_MS; }
+ | timeformat_which ISO SHORT US { *$1 = TM_ISO_SHORT_US; }
+ | timeformat_which ISO LONG    { *$1 = TM_ISO_LONG_S; }
+ | timeformat_which ISO LONG MS { *$1 = TM_ISO_LONG_MS; }
+ | timeformat_which ISO LONG US { *$1 = TM_ISO_LONG_US; }
+ ;
+
+timeformat_base:
+   TIMEFORMAT timeformat_spec ';'
+ ;
+
+
 /* Interface patterns */
 
 iface_patt_node_init:
@@ -462,12 +489,12 @@ password_item_begin:
 
 password_item_params:
    /* empty */ { }
- | GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
- | GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
- | ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
- | ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; }
- | FROM datetime ';' password_item_params { this_p_item->genfrom = this_p_item->accfrom = $2; }
- | TO datetime ';' password_item_params { this_p_item->gento = this_p_item->accto = $2; }
+ | GENERATE FROM time ';' password_item_params { this_p_item->genfrom = $3; }
+ | GENERATE TO time ';' password_item_params { this_p_item->gento = $3; }
+ | ACCEPT FROM time ';' password_item_params { this_p_item->accfrom = $3; }
+ | ACCEPT TO time ';' password_item_params { this_p_item->accto = $3; }
+ | FROM time ';' password_item_params { this_p_item->genfrom = this_p_item->accfrom = $2; }
+ | TO time ';' password_item_params { this_p_item->gento = this_p_item->accto = $2; }
  | ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); }
  | ALGORITHM password_algorithm ';' password_item_params { this_p_item->alg = $2; }
  ;
index e48137413f8e5d31e88f0158a4b99746b18910e3..72f23f5d7aa00c7fa4ea64d0605958849706b0f8 100644 (file)
@@ -19,12 +19,13 @@ password_find(list *l, int first_fit)
 {
   struct password_item *pi;
   struct password_item *pf = NULL;
+  btime now_ = current_real_time();
 
   if (l)
   {
     WALK_LIST(pi, *l)
     {
-      if ((pi->genfrom < now_real) && (pi->gento > now_real))
+      if ((pi->genfrom < now_) && (pi->gento > now_))
       {
        if (first_fit)
          return pi;
@@ -41,12 +42,13 @@ struct password_item *
 password_find_by_id(list *l, uint id)
 {
   struct password_item *pi;
+  btime now_ = current_real_time();
 
   if (!l)
     return NULL;
 
   WALK_LIST(pi, *l)
-    if ((pi->id == id) && (pi->accfrom <= now_real) && (now_real < pi->accto))
+    if ((pi->id == id) && (pi->accfrom <= now_) && (now_ < pi->accto))
       return pi;
 
   return NULL;
@@ -56,12 +58,13 @@ struct password_item *
 password_find_by_value(list *l, char *pass, uint size)
 {
   struct password_item *pi;
+  btime now_ = current_real_time();
 
   if (!l)
     return NULL;
 
   WALK_LIST(pi, *l)
-    if (password_verify(pi, pass, size) && (pi->accfrom <= now_real) && (now_real < pi->accto))
+    if (password_verify(pi, pass, size) && (pi->accfrom <= now_) && (now_ < pi->accto))
       return pi;
 
   return NULL;
index 78244985ab27e31c091289b55ef730501c729d4d..c40178482461460758b7caa28b5e88160abc23b2 100644 (file)
 #ifndef PASSWORD_H
 #define PASSWORD_H
 
-#include "sysdep/unix/timer.h"
-
 struct password_item {
   node n;
   char *password;                      /* Key data, null terminated */
   uint length;                         /* Key length, without null */
   uint id;                             /* Key ID */
   uint alg;                            /* MAC algorithm */
-  bird_clock_t accfrom, accto, genfrom, gento;
+  btime accfrom, accto, genfrom, gento;
 };
 
 extern struct password_item *last_password_item;
index 65375c35b54a2d9245e8cebaaeb927997de7de8a..3043b648d29eda3b20ab9449031acbacdf68f58b 100644 (file)
@@ -162,7 +162,7 @@ proto_add_channel(struct proto *p, struct channel_config *cf)
 
   c->channel_state = CS_DOWN;
   c->export_state = ES_DOWN;
-  c->last_state_change = now;
+  c->last_state_change = current_time();
   c->reloadable = 1;
 
   CALL(c->channel->init, c, cf);
@@ -341,7 +341,7 @@ channel_set_state(struct channel *c, uint state)
     return;
 
   c->channel_state = state;
-  c->last_state_change = now;
+  c->last_state_change = current_time();
 
   switch (state)
   {
@@ -672,7 +672,7 @@ proto_init(struct proto_config *c, node *n)
   struct proto *p = pr->init(c);
 
   p->proto_state = PS_DOWN;
-  p->last_state_change = now;
+  p->last_state_change = current_time();
   insert_node(&p->n, n);
 
   p->event = ev_new(proto_pool);
@@ -1500,7 +1500,7 @@ proto_notify_state(struct proto *p, uint state)
     return;
 
   p->proto_state = state;
-  p->last_state_change = now;
+  p->last_state_change = current_time();
 
   switch (state)
   {
@@ -1631,7 +1631,7 @@ proto_cmd_show(struct proto *p, uint verbose, int cnt)
   buf[0] = 0;
   if (p->proto->get_status)
     p->proto->get_status(p, buf);
-  tm_format_datetime(tbuf, &config->tf_proto, p->last_state_change);
+  tm_format_time(tbuf, &config->tf_proto, p->last_state_change);
   cli_msg(-1002, "%-8s %-8s %-8s %-5s  %-10s  %s",
          p->name,
          p->proto->name,
index eed0a29142347ac93c875c82dbabaa45cd0617b7..abd11affdc5ac4aded1e314a5938efa69e40be9e 100644 (file)
@@ -159,7 +159,7 @@ struct proto {
   byte down_sched;                     /* Shutdown is scheduled for later (PDS_*) */
   byte down_code;                      /* Reason for shutdown (PDC_* codes) */
   u32 hash_key;                                /* Random key used for hashing of neighbors */
-  bird_clock_t last_state_change;      /* Time of last state transition */
+  btime last_state_change;             /* Time of last state transition */
   char *last_state_name_announced;     /* Last state name we've announced to the user */
 
   /*
@@ -508,7 +508,7 @@ struct channel {
   u8 gr_lock;                          /* Graceful restart mechanism should wait for this channel */
   u8 gr_wait;                          /* Route export to channel is postponed until graceful restart */
 
-  bird_clock_t last_state_change;      /* Time of last state transition */
+  btime last_state_change;             /* Time of last state transition */
 };
 
 
index c1a60ccc62e990f9bbe79ae1ed9527ab5a6ef2b7..2aa2bcd886f1163d4784f465e92789cea7064459 100644 (file)
@@ -159,8 +159,8 @@ typedef struct rtable {
                                         * obstacle from this routing table.
                                         */
   struct event *rt_event;              /* Routing table event */
+  btime gc_time;                       /* Time of last GC */
   int gc_counter;                      /* Number of operations since last GC */
-  bird_clock_t gc_time;                        /* Time of last GC */
   byte prune_state;                    /* Table prune state, 1 -> scheduled, 2-> running */
   byte hcu_scheduled;                  /* Hostcache update is scheduled */
   byte nhu_state;                      /* Next Hop Update state */
@@ -213,7 +213,7 @@ typedef struct rte {
   byte flags;                          /* Flags (REF_...) */
   byte pflags;                         /* Protocol-specific flags */
   word pref;                           /* Route preference */
-  bird_clock_t lastmod;                        /* Last modified */
+  btime lastmod;                       /* Last modified */
   union {                              /* Protocol-dependent data (metrics etc.) */
 #ifdef CONFIG_RIP
     struct {
index afde2810f57b16dfb7a6f63936c5db4f819adc86..9989afa4929f5b8597ac174cc005c8ef5469ac08 100644 (file)
@@ -39,7 +39,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm
   void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs);
   struct nexthop *nh;
 
-  tm_format_datetime(tm, &config->tf_route, e->lastmod);
+  tm_format_time(tm, &config->tf_route, e->lastmod);
   if (ipa_nonzero(a->from) && !ipa_equal(a->from, a->nh.gw))
     bsprintf(from, " from %I", a->from);
   else
index 2bb78cf2d6a24e6fc61dece1af367efe90b833b8..c42d3a978d8ff54859a67869859bd7db0de29869 100644 (file)
@@ -1173,7 +1173,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
     }
 
   if (new)
-    new->lastmod = now;
+    new->lastmod = current_time();
 
   /* Log the route change */
   if (p->debug & D_ROUTES)
@@ -1201,7 +1201,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
 
   if (!net->routes &&
       (table->gc_counter++ >= table->config->gc_max_ops) &&
-      (table->gc_time + table->config->gc_min_time <= now))
+      (table->gc_time + table->config->gc_min_time <= current_time()))
     rt_schedule_prune(table);
 
   if (old_ok && p->rte_remove)
@@ -1497,7 +1497,7 @@ rte_dump(rte *e)
 {
   net *n = e->net;
   debug("%-1N ", n->n.addr);
-  debug("KF=%02x PF=%02x pref=%d lm=%d ", n->n.flags, e->pflags, e->pref, now-e->lastmod);
+  debug("KF=%02x PF=%02x pref=%d ", n->n.flags, e->pflags, e->pref);
   rta_dump(e->attrs);
   if (e->attrs->src->proto->proto->dump_attrs)
     e->attrs->src->proto->proto->dump_attrs(e);
@@ -1609,7 +1609,7 @@ rt_setup(pool *p, rtable *t, char *name, struct rtable_config *cf)
       t->rt_event = ev_new(p);
       t->rt_event->hook = rt_event;
       t->rt_event->data = t;
-      t->gc_time = now;
+      t->gc_time = current_time();
     }
 }
 
@@ -1708,7 +1708,7 @@ again:
 #endif
 
   tab->gc_counter = 0;
-  tab->gc_time = now;
+  tab->gc_time = current_time();
 
   /* state change 2->0, 3->1 */
   tab->prune_state &= 1;
index e2c6050bc367726cc0ed9a225a41459f6e34d02f..2374cfe8ca434540a6ac217c7fc22f3d90b6360f 100644 (file)
@@ -145,6 +145,7 @@ bfd_session_update_state(struct bfd_session *s, uint state, uint diag)
   bfd_lock_sessions(p);
   s->loc_state = state;
   s->loc_diag = diag;
+  s->last_state_change = current_time();
 
   notify = !NODE_VALID(&s->n);
   if (notify)
@@ -438,7 +439,7 @@ bfd_add_session(struct bfd_proto *p, ip_addr addr, ip_addr local, struct iface *
   bfd_session_control_tx_timer(s, 1);
 
   init_list(&s->request_list);
-  s->last_state_change = now;
+  s->last_state_change = current_time();
 
   TRACE(D_EVENTS, "Session to %I added", s->addr);
 
@@ -879,9 +880,6 @@ bfd_notify_hook(sock *sk, uint len UNUSED)
     diag = s->loc_diag;
     bfd_unlock_sessions(p);
 
-    /* FIXME: convert to btime and move to bfd_session_update_state() */
-    s->last_state_change = now;
-
     s->notify_running = 1;
     WALK_LIST_DELSAFE(n, nn, s->request_list)
       bfd_request_notify(SKIP_BACK(struct bfd_request, n, n), state, diag);
@@ -1105,7 +1103,7 @@ bfd_show_sessions(struct proto *P)
     timeout = (MAX(s->req_min_rx_int, s->rem_min_tx_int) TO_MS) * s->rem_detect_mult;
 
     state = (state < 4) ? state : 0;
-    tm_format_datetime(tbuf, &config->tf_proto, s->last_state_change);
+    tm_format_time(tbuf, &config->tf_proto, s->last_state_change);
 
     cli_msg(-1020, "%-25I %-10s %-10s %-10s  %3u.%03u  %3u.%03u",
            s->addr, ifname, bfd_state_names[state], tbuf,
index e2e757538aa2df6e4a2e555b29ab73641b1ac162..203da4372c17cc06bd2d06d1d5af2a623ae32686 100644 (file)
@@ -144,7 +144,7 @@ struct bfd_session
   timer2 *hold_timer;                  /* Timer for session down detection time */
 
   list request_list;                   /* List of client requests (struct bfd_request) */
-  bird_clock_t last_state_change;      /* Time of last state change */
+  btime last_state_change;             /* Time of last state change */
   u8 notify_running;                   /* 1 if notify hooks are running */
 
   u8 rx_csn_known;                     /* Received crypto sequence number is known */
index ebadd4546585b4798997bb0e1e076c920490a515..ccca4a6271a18ccf41d5d048e198ee780b103624 100644 (file)
@@ -14,8 +14,7 @@ CF_HDR
 CF_DECLS
 
 CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG, STDERR, SOFT)
-CF_KEYWORDS(TIMEFORMAT, ISO, OLD, SHORT, LONG, BASE, NAME, CONFIRM, UNDO, CHECK, TIMEOUT)
-CF_KEYWORDS(DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING, TIMEOUT)
+CF_KEYWORDS(NAME, CONFIRM, UNDO, CHECK, TIMEOUT, DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING)
 
 %type <i> log_mask log_mask_list log_cat cfg_timeout
 %type <g> log_file
@@ -85,29 +84,6 @@ 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_which OLD SHORT { *$1 = (struct timeformat){NULL, NULL, 0}; }
- | timeformat_which OLD LONG  { *$1 = (struct timeformat){"%d-%m-%Y %T", NULL, 0}; }
- ;
-
-timeformat_base:
-   TIMEFORMAT timeformat_spec ';'
- ;
-
-
 CF_ADDTO(conf, debug_unix)
 
 debug_unix:
index d3506d75c1583caf91748aec1618d4d972801fe9..99f52aa904724c53f646ab82a7bad7fab73c4a8f 100644 (file)
@@ -40,6 +40,7 @@
 #include "lib/timer.h"
 #include "lib/string.h"
 #include "nest/iface.h"
+#include "conf/conf.h"
 
 #include "sysdep/unix/unix.h"
 #include CONFIG_INCLUDE_SYSIO_H
@@ -385,102 +386,6 @@ tm_shot(void)
 }
 #endif
 
-/**
- * tm_parse_datetime - parse a date and time
- * @x: datetime string
- *
- * tm_parse_datetime() takes a textual representation of
- * a date and time (dd-mm-yyyy hh:mm:ss)
- * and converts it to the corresponding value of type &bird_clock_t.
- */
-bird_clock_t
-tm_parse_datetime(char *x)
-{
-  struct tm tm;
-  int n;
-  time_t t;
-
-  if (sscanf(x, "%d-%d-%d %d:%d:%d%n", &tm.tm_mday, &tm.tm_mon, &tm.tm_year, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &n) != 6 || x[n])
-    return tm_parse_date(x);
-  tm.tm_mon--;
-  tm.tm_year -= 1900;
-  t = mktime(&tm);
-  if (t == (time_t) -1)
-    return 0;
-  return t;
-}
-/**
- * tm_parse_date - parse a date
- * @x: date string
- *
- * tm_parse_date() takes a textual representation of a date (dd-mm-yyyy)
- * and converts it to the corresponding value of type &bird_clock_t.
- */
-bird_clock_t
-tm_parse_date(char *x)
-{
-  struct tm tm;
-  int n;
-  time_t t;
-
-  if (sscanf(x, "%d-%d-%d%n", &tm.tm_mday, &tm.tm_mon, &tm.tm_year, &n) != 3 || x[n])
-    return 0;
-  tm.tm_mon--;
-  tm.tm_year -= 1900;
-  tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
-  t = mktime(&tm);
-  if (t == (time_t) -1)
-    return 0;
-  return t;
-}
-
-static void
-tm_format_reltime(char *x, struct tm *tm, bird_clock_t delta)
-{
-  static char *month_names[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-                                  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
-  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
- * @fmt_spec: specification of resulting textual representation of the time
- * @t: time
- *
- * This function formats the given relative time value @t to a textual
- * date/time representation (dd-mm-yyyy hh:mm:ss) in real time.
- */
-void
-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 (fmt_spec->fmt1 == NULL)
-    return tm_format_reltime(x, tm, delta);
-
-  if ((fmt_spec->limit == 0) || (delta < fmt_spec->limit))
-    fmt_used = fmt_spec->fmt1;
-  else
-    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>");
-}
-
 
 /*
  *     Time clock
index 06d3b09ea236e3e7d63efa0ec8460178b2fd505f..e564f8f298eae8faedb0607ec24074b4da2b6be1 100644 (file)
@@ -120,7 +120,7 @@ log_commit(int class, buffer *buf)
          else
            {
              byte tbuf[TM_DATETIME_BUFFER_SIZE];
-             tm_format_datetime(tbuf, &config->tf_log, now);
+             tm_format_real_time(tbuf, config->tf_log.fmt1, current_real_time());
              fprintf(l->fh, "%s <%s> ", tbuf, class_names[class]);
            }
          fputs(buf->start, l->fh);
index 1c4f6e3b9615993cd918d26df9b3c23df6470c8f..495d10c71e68adb88ec748c31fd0d56d13fe09d8 100644 (file)
@@ -45,18 +45,6 @@ static inline timer * tm_new_set(pool *p, void (*hook)(timer *), void *data, uin
 { return tm2_new_init(p, hook, data, rec S_, rand S_); }
 
 
-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 */
-
-#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);
-
 #define TIME_INFINITY ((s64) 0x7fffffffffffffff)