]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
CLI: Add timeformat command
authorPiotr Wydrych <pwydrych@akamai.com>
Tue, 5 Nov 2024 17:53:22 +0000 (18:53 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 7 Nov 2024 14:08:51 +0000 (15:08 +0100)
Adds ability to override time format of show commands for current CLI session
so that it does not depend on configuration and may ease parsing when CLI is
called from tools.

Minor changes by committer.

doc/bird.sgml
doc/reply_codes
nest/cli.c
nest/cli.h
nest/cmds.c
nest/config.Y
nest/proto.c
nest/rt-show.c
proto/bfd/bfd.c

index 3faa9f3cf5e9304d6c37940ac4138d904c62d0bf..0d1e6f490426bf3d576d40cec6bca58d253def85 100644 (file)
@@ -1437,6 +1437,13 @@ This argument can be omitted if there exists only a single instance.
        pipe protocol, both directions are always reloaded together (<cf/in/ or
        <cf/out/ options are ignored in that case).
 
+       <tag><label id="cli-timeformat">timeformat "<m/format1/" [<m/limit/ "<m/format2/"]</tag>
+       Override format of date/time used by BIRD in this CLI session.
+
+       Meaning of "<m/format1/", <m/limit/, and "<m/format2/" is the same as in the
+       <ref id="opt-timeformat" name="timeformat"> configuration option. Also, the
+       same <cf/iso .../ shorthands may be used.
+
        <tag><label id="cli-down">down</tag>
        Shut BIRD down.
 
index 71cdf341da72a9a211d2561d223ef7b261fea862..6e7e588746c6440a329b392e3de07899af6ddc47 100644 (file)
@@ -76,3 +76,4 @@ Reply codes of BIRD command-line interface
 9000   Command too long
 9001   Parse error
 9002   Invalid symbol type
+9003   Argument too long
index 4601f86334fefcc9236efc416eb6453351ced53b..9573f7700688efa293313cd7fd8c4723807a2b04 100644 (file)
@@ -406,6 +406,36 @@ cli_echo(uint class, byte *msg)
     }
 }
 
+/* Set time format override for the current session */
+void
+cli_set_timeformat(cli *c, const struct timeformat tf)
+{
+  size_t len1 = strlen(tf.fmt1) + 1;
+  size_t len2 = tf.fmt2 ? strlen(tf.fmt2) + 1 : 0;
+
+  if (len1 > TM_DATETIME_BUFFER_SIZE || len2 > TM_DATETIME_BUFFER_SIZE)
+  {
+    cli_msg(9003, "Format string too long");
+    return;
+  }
+
+  struct timeformat *old_tf = c->tf;
+  struct timeformat *new_tf = mb_allocz(c->pool, sizeof(struct timeformat));
+  new_tf->fmt1 = memcpy(mb_alloc(c->pool, len1), tf.fmt1, len1);
+  new_tf->fmt2 = tf.fmt2 ? memcpy(mb_alloc(c->pool, len2), tf.fmt2, len2) : NULL;
+  new_tf->limit = tf.limit;
+  c->tf = new_tf;
+
+  if (old_tf)
+  {
+    mb_free((void *) old_tf->fmt1);
+    mb_free((void *) old_tf->fmt2);
+    mb_free(old_tf);
+  }
+
+  cli_msg(0, "");
+}
+
 /* Hack for scheduled undo notification */
 extern cli *cmd_reconfig_stored_cli;
 
index afcb6d552242efaf365359daea38068f07aecd91..e48216c2efeb9bb9e7a9430f3c0e5a84e81ba97e 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "lib/resource.h"
 #include "lib/event.h"
+#include "lib/timer.h"
 #include "lib/tlists.h"
 #include "conf/conf.h"
 
@@ -39,6 +40,7 @@ typedef struct cli {
   void *rover;                         /* Private to continuation routine */
   int last_reply;
   int restricted;                      /* CLI is restricted to read-only commands */
+  struct timeformat *tf;               /* Time format override */
   struct linpool *parser_pool;         /* Pool used during parsing */
   struct linpool *show_pool;           /* Pool used during route show */
   byte *ring_buf;                      /* Ring buffer for asynchronous messages */
@@ -76,6 +78,7 @@ extern struct cli *this_cli;          /* Used during parsing */
 void cli_printf(cli *, int, char *, ...);
 #define cli_msg(x...) cli_printf(this_cli, x)
 void cli_set_log_echo(cli *, uint mask, uint size);
+void cli_set_timeformat(cli *c, const struct timeformat tf);
 
 static inline void cli_separator(cli *c)
 { if (c->last_reply) cli_printf(c, -c->last_reply, ""); };
index d49bbc53c32384454d7f38f8537142943adbe365..09996c46c6762952f7a5897296ea390e89575eae 100644 (file)
@@ -22,16 +22,17 @@ extern int configuring;
 void
 cmd_show_status(void)
 {
+  struct timeformat *tf_base = this_cli->tf ?: &config->tf_base;
   byte tim[TM_DATETIME_BUFFER_SIZE];
 
   cli_msg(-1000, "BIRD " BIRD_VERSION);
-  tm_format_time(tim, &config->tf_base, current_time());
+  tm_format_time(tim, tf_base, current_time());
   cli_msg(-1011, "Router ID is %R", config->router_id);
   cli_msg(-1011, "Hostname is %s", config->hostname);
   cli_msg(-1011, "Current server time is %s", tim);
-  tm_format_time(tim, &config->tf_base, boot_time);
+  tm_format_time(tim, tf_base, boot_time);
   cli_msg(-1011, "Last reboot on %s", tim);
-  tm_format_time(tim, &config->tf_base, config->load_time);
+  tm_format_time(tim, tf_base, config->load_time);
   cli_msg(-1011, "Last reconfiguration on %s", tim);
 
   graceful_restart_show_status();
index f2a4f84baed9f3c9e935f2e8b31d433e61c4a1c4..3fcf3068e50586f733b7d0f4d0c918a617dea3b1 100644 (file)
@@ -945,6 +945,16 @@ CF_CLI(MRTDUMP, proto_patt mrtdump_mask, (<protocol> | \"<pattern>\" | all) (all
 CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]])
 { this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ;
 
+CF_CLI_HELP(TIMEFORMAT, ..., [[Set time format for this CLI session]])
+CF_CLI(TIMEFORMAT, timeformat_spec, \"<format1>\" [limit \"format2\"] | iso (short | long) [ ms | us ], [[Set time format for this CLI session]])
+{ cli_set_timeformat(this_cli, $2); } ;
+
+CF_CLI_OPT(TIMEFORMAT ISO)
+CF_CLI_OPT(TIMEFORMAT SHORT)
+CF_CLI_OPT(TIMEFORMAT LONG)
+CF_CLI_OPT(TIMEFORMAT MS)
+CF_CLI_OPT(TIMEFORMAT US)
+
 proto_patt:
    CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$.ptr = $1; $$.patt = 0; }
  | ALL  { $$.ptr = NULL; $$.patt = 1; }
index 88f4813ef572de5ca5a92cd360e4ca3dbf062815..a6c5a0c1187831a4f252182f7839c23286b595a3 100644 (file)
@@ -2135,7 +2135,7 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
   buf[0] = 0;
   if (p->proto->get_status)
     p->proto->get_status(p, buf);
-  tm_format_time(tbuf, &config->tf_proto, p->last_state_change);
+  tm_format_time(tbuf, (this_cli->tf ?: &config->tf_proto), p->last_state_change);
   cli_msg(-1002, "%-10s %-10s %-10s %-6s %-12s  %s",
          p->name,
          p->proto->name,
index fb71fba85bbaef622f5db28339d8a0fb90872b84..0ecc8637b1ca1ae963707e1e216af018221a4116 100644 (file)
@@ -47,7 +47,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary
   void (*get_route_info)(struct rte *, byte *buf);
   struct nexthop *nh;
 
-  tm_format_time(tm, &config->tf_route, e->lastmod);
+  tm_format_time(tm, (c->tf ?: &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 d08c413d4ddf6ec8973e20ed0a9a49246f5c42ca..cde7f11b516ed0a79f615da18752d3d3910e49da 100644 (file)
@@ -1205,7 +1205,7 @@ bfd_show_session(struct bfd_session *s, int details)
 
   byte dbuf[BFD_DIAG_BUFFER_SIZE];
   byte tbuf[TM_DATETIME_BUFFER_SIZE];
-  tm_format_time(tbuf, &config->tf_proto, s->last_state_change);
+  tm_format_time(tbuf, (this_cli->tf ?: &config->tf_proto), s->last_state_change);
 
   if (!details)
   {