[PATCH v2] Client: add "show hostname" command, and add client prompt hostname display
Molly Miller
bird at m-squa.red
Fri Mar 5 18:25:05 CET 2021
Hi,
This is a small update to the patch I posted previously, as I ran into a
compilation error when building in a different environment due to passing a
non-const string as the first argument to printf(3) in birdcl.
Please see the updated patch below.
Thanks,
--mm.
On 11/02/2021 21:14, Molly Miller wrote:
> Hi all,
>
> The recent patch on the list from Vincent Bernat which added support for the
> draft BGP hostname capability [1] reminded me of a thread from last year, in
> which there was a feature request for the ability to display the system
> hostname in the Bird client prompt [2].
>
> This feature doesn't appear to have been implemented since then, and now
> that a hostname is tracked internally by Bird, I've written a
> proof-of-concept patch (appended inline) which displays the daemon hostname
> in the client prompt.
>
> This patch adds a "show hostname" command to the daemon for convenience, and
> modifies the client to automatically issue this command when starting in
> interactive mode. The client then intercepts the response (which will either
> contain the daemon hostname, or be a syntax error if the daemon does not
> understand the command), and then sets the received hostname in the prompt
> if the response is a success code.
>
> (The rationale for not simply calling uname(2) in the client is that the
> resulting nodename may not match the hostname configured in the daemon, in
> the case where the daemon configuration contains a hostname "<foo>"
> directive. It's also possible to connect to the daemon over a Unix socket
> forwarded over SSH, in which case the client would be running on a separate
> system with a different hostname regardless of the daemon configuration --
> thanks to Tim Stallard for pointing this out.)
>
> I don't know how willing the Bird maintainers would be to commit this patch,
> however I thought I'd post it to the list in case anyone else is interested.
>
> Cheers,
> --mm.
>
>
> [1]: https://bird.network.cz/pipermail/bird-users/2021-February/015187.html,
> merged as 71423871
> [2]: https://bird.network.cz/pipermail/bird-users/2020-July/014678.html
>
-- >8 --
Subject: [PATCH v2] Client: add "show hostname" command, and client prompt
hostname display.
This patch adds a "show hostname" command to the daemon, which returns the
server's currently configured hostname, and extends the command line client
to issue this command upon connecting to the daemon, in order to retrieve a
hostname to display in the client's prompt. A '-p' option has also been added
to suppress this behaviour.
molly on flywheel ~> birdc
BIRD v2.0.7 ready.
bird(flywheel)> show hostname
Hostname: flywheel
bird(flywheel)> exit
molly on flywheel ~> birdc -p
BIRD v2.0.7 ready.
bird> show hostname
Hostname: flywheel
bird> quit
Additionally, the error message generated by older versions of the daemon when
running the "show hostname" command is caught, in order to remain interoperable
with versions which do not have this patch.
The client program does not, however, have any means of detecting whether the
hostname changes as part of an online configuration update, so changes in the
daemon's hostname will not be propagated to a client which is persistent across
the configuration change.
---
client/birdc.c | 11 +++++++++--
client/birdcl.c | 8 +++++++-
client/client.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
client/client.h | 2 ++
doc/reply_codes | 1 +
nest/cmds.c | 7 +++++++
nest/cmds.h | 1 +
nest/config.Y | 3 +++
8 files changed, 72 insertions(+), 9 deletions(-)
diff --git a/client/birdc.c b/client/birdc.c
index f1aea2fe..b1b9b218 100644
--- a/client/birdc.c
+++ b/client/birdc.c
@@ -162,7 +162,7 @@ input_init(void)
rl_readline_name = "birdc";
rl_add_defun("bird-complete", input_complete, '\t');
rl_add_defun("bird-help", input_help, '?');
- rl_callback_handler_install("bird> ", input_got_line);
+ rl_callback_handler_install(prompt_string, input_got_line);
// rl_get_screen_size();
term_lns = LINES;
@@ -184,7 +184,7 @@ input_reveal(void)
tcdrain(STDOUT_FILENO);
rl_end = input_hidden_end;
- rl_expand_prompt("bird> ");
+ rl_expand_prompt(prompt_string);
rl_forced_update_display();
prompt_active = 1;
@@ -201,6 +201,13 @@ input_hide(void)
prompt_active = 0;
}
+void
+input_reload(void)
+{
+ input_hide();
+ input_reveal();
+}
+
void
input_notify(int prompt)
{
diff --git a/client/birdcl.c b/client/birdcl.c
index 4508185c..d8517acd 100644
--- a/client/birdcl.c
+++ b/client/birdcl.c
@@ -38,6 +38,12 @@ input_stop_list(void)
/* Empty in non-ncurses version. */
}
+void
+input_reload(void)
+{
+ /* Empty in non-ncurses version. */
+}
+
void
input_notify(int prompt)
{
@@ -45,7 +51,7 @@ input_notify(int prompt)
if (!prompt)
return;
- printf("bird> ");
+ fputs(prompt_string, stdout);
fflush(stdout);
}
diff --git a/client/client.c b/client/client.c
index 97cf6639..2f225442 100644
--- a/client/client.c
+++ b/client/client.c
@@ -37,8 +37,11 @@
#include "sysdep/unix/unix.h"
#define SERVER_READ_BUF_LEN 4096
+#define SERVER_PROMPT_LEN 64
+#define SERVER_PROMPT_DEFAULT "bird> "
+#define SERVER_HOSTNAME_PREFIX "Hostname: "
-static char *opt_list = "s:vrl";
+static char *opt_list = "s:vrlp";
static int verbose, restricted, once;
static char *init_cmd;
@@ -47,12 +50,15 @@ static int server_fd;
static byte server_read_buf[SERVER_READ_BUF_LEN];
static byte *server_read_pos = server_read_buf;
-int init = 1; /* During intial sequence */
-int busy = 1; /* Executing BIRD command */
-int interactive; /* Whether stdin is terminal */
+int init = 1; /* During intial sequence */
+int busy = 1; /* Executing BIRD command */
+int hostprompt = 1; /* Whether to show hostname in prompt */
+int interactive; /* Whether stdin is terminal */
+char prompt_string[SERVER_PROMPT_LEN]; /* Prompt string */
static int num_lines, skip_input;
int term_lns, term_cls;
+static int hostname_read = 0;
/*** Parsing of arguments ***/
@@ -60,7 +66,7 @@ int term_lns, term_cls;
static void
usage(char *name)
{
- fprintf(stderr, "Usage: %s [-s <control-socket>] [-v] [-r] [-l]\n", name);
+ fprintf(stderr, "Usage: %s [-s <control-socket>] [-v] [-r] [-l] [-p]\n", name);
exit(1);
}
@@ -87,6 +93,9 @@ parse_args(int argc, char **argv)
if (!server_changed)
server_path = xbasename(server_path);
break;
+ case 'p':
+ hostprompt = 0;
+ break;
default:
usage(argv[0]);
}
@@ -199,6 +208,12 @@ init_commands(void)
exit(0);
}
+ /* Set up local prompt, and attempt to retrieve daemon hostname */
+ memset(prompt_string, 0, sizeof(prompt_string));
+ strcpy(prompt_string, SERVER_PROMPT_DEFAULT);
+ if (hostprompt)
+ submit_server_command("show hostname");
+
input_init();
term_lns = (term_lns > 0) ? term_lns : 25;
@@ -239,6 +254,16 @@ more(void)
more_end();
}
+static void
+update_prompt(char *x)
+{
+ if (strncmp(x, SERVER_HOSTNAME_PREFIX, sizeof(SERVER_HOSTNAME_PREFIX)-1) != 0)
+ return;
+
+ memset(prompt_string, 0, sizeof(prompt_string));
+ snprintf(prompt_string, sizeof(prompt_string), "bird(%s)> ", x+sizeof(SERVER_HOSTNAME_PREFIX)-1);
+}
+
/*** Communication with server ***/
@@ -281,7 +306,18 @@ server_got_reply(char *x)
(x[4] == ' ' || x[4] == '-'))
{
if (code)
- PRINTF(len, "%s\n", verbose ? x : x+5);
+ {
+ if ((code == 1026 || code == 9001) && !hostname_read && hostprompt)
+ {
+ hostname_read = 1;
+ if (code == 1026) {
+ update_prompt(x+5);
+ input_reload();
+ }
+ }
+ else
+ PRINTF(len, "%s\n", verbose ? x : x+5);
+ }
if (x[4] == ' ')
{
diff --git a/client/client.h b/client/client.h
index f9693def..8de7b38c 100644
--- a/client/client.h
+++ b/client/client.h
@@ -9,6 +9,7 @@
extern int init, busy, interactive;
extern int term_lns, term_cls;
+extern char prompt_string[];
/* birdc.c / birdcl.c */
@@ -16,6 +17,7 @@ void input_start_list(void);
void input_stop_list(void);
void input_init(void);
+void input_reload(void);
void input_notify(int prompt);
void input_read(void);
diff --git a/doc/reply_codes b/doc/reply_codes
index 02f4e656..47f9d3e8 100644
--- a/doc/reply_codes
+++ b/doc/reply_codes
@@ -61,6 +61,7 @@ Reply codes of BIRD command-line interface
1023 Show Babel interfaces
1024 Show Babel neighbors
1025 Show Babel entries
+1026 Show hostname
8000 Reply too long
8001 Route not found
diff --git a/nest/cmds.c b/nest/cmds.c
index 18f39eb5..a412faf3 100644
--- a/nest/cmds.c
+++ b/nest/cmds.c
@@ -95,6 +95,13 @@ cmd_show_memory(void)
cli_msg(0, "");
}
+void
+cmd_show_hostname(void)
+{
+ cli_msg(-1026, "Hostname: %s", config->hostname);
+ cli_msg(0, "");
+}
+
void
cmd_eval(const struct f_line *expr)
{
diff --git a/nest/cmds.h b/nest/cmds.h
index 194a9d7f..14c7293d 100644
--- a/nest/cmds.h
+++ b/nest/cmds.h
@@ -16,6 +16,7 @@ struct f_inst;
void cmd_show_status(void);
void cmd_show_symbols(struct sym_show_data *sym);
void cmd_show_memory(void);
+void cmd_show_hostname(void);
struct f_line;
void cmd_eval(const struct f_line *expr);
diff --git a/nest/config.Y b/nest/config.Y
index 39bf6149..72ea0726 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -564,6 +564,9 @@ CF_CLI(SHOW STATUS,,, [[Show router status]])
CF_CLI(SHOW MEMORY,,, [[Show memory usage]])
{ cmd_show_memory(); } ;
+CF_CLI(SHOW HOSTNAME,,, [[Show current hostname]])
+{ cmd_show_hostname(); } ;
+
CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
{ proto_apply_cmd($3, proto_cmd_show, 0, 0); } ;
--
2.20.1
More information about the Bird-users
mailing list