Skip to content

Commit

Permalink
CLI: Add timeformat command
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wydrych authored and Ondrej Zajicek committed Nov 7, 2024
1 parent 9eca3e1 commit 82d57fb
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 6 deletions.
7 changes: 7 additions & 0 deletions doc/bird.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
1 change: 1 addition & 0 deletions doc/reply_codes
Original file line number Diff line number Diff line change
Expand Up @@ -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
30 changes: 30 additions & 0 deletions nest/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
3 changes: 3 additions & 0 deletions nest/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "lib/resource.h"
#include "lib/event.h"
#include "lib/timer.h"
#include "lib/tlists.h"
#include "conf/conf.h"

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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, ""); };
Expand Down
7 changes: 4 additions & 3 deletions nest/cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
10 changes: 10 additions & 0 deletions nest/config.Y
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
2 changes: 1 addition & 1 deletion nest/proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion nest/rt-show.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion proto/bfd/bfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down

0 comments on commit 82d57fb

Please sign in to comment.