From 2f7dbe110ac6efab99709169b22f7fab860d2948 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 10 Mar 2023 10:20:40 +0100 Subject: [PATCH] src/mech: add some basic 'show' commands - Example of optional args (show log [FILE]) - Example of dynamic expansion - Example of how to re-enable signals for external commands - Example of hidden commands - Add basic 'help' command for the current level Signed-off-by: Joachim Wiberg --- src/mech/src/core/core-cli.c | 81 +++++++++++++++++++++++++++++++++- src/mech/src/core/core-cli.cli | 20 ++++++++- 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/src/mech/src/core/core-cli.c b/src/mech/src/core/core-cli.c index 0aff4d9f..c583b557 100644 --- a/src/mech/src/core/core-cli.c +++ b/src/mech/src/core/core-cli.c @@ -1,3 +1,4 @@ +#include #include #include @@ -5,9 +6,85 @@ #include #include -int cli_sysinfo(clicon_handle h, cvec *cvv, cvec *argv) +#define _PATH_LOG "/var/log/" + +/* Not exported in the common Clixon API, needed to run external commands */ +void cli_signal_block(clicon_handle h); +void cli_signal_unblock(clicon_handle h); + +static int exec(clicon_handle h, char *cmd) { - printf("System Information: Infix\n"); + int rc; + + cli_signal_unblock(h); + rc = system(cmd); + cli_signal_block(h); + + return rc; +} + +int cli_exec_shell(clicon_handle h, cvec *cvv, cvec *argv) +{ + return exec(h, "$SHELL -l"); +} + +int cli_exec_show(clicon_handle h, cvec *cvv, cvec *argv) +{ + char cmd[256]; + int pos = 0; + int i; + + for (i = 0; i < cvec_len(cvv); i++) + pos += snprintf(&cmd[pos], sizeof(cmd) - pos, "%s ", + cv_string_get(cvec_i(cvv, i))); + + return exec(h, cmd); +} + +int cli_exec_log(clicon_handle h, cvec *cvv, cvec *argv) +{ + char cmd[128], arg[32]; + cg_var *cv; + + /* cvv[0] is the whole command, e.g. 'show log btmp' */ + if (!strncmp("follow", cv_string_get(cvec_i(cvv, 0)), 6)) + snprintf(cmd, sizeof(cmd), "tail -F "); + else + snprintf(cmd, sizeof(cmd), "cat "); + + cv = cvec_find(cvv, "fn"); + if (cv) { + snprintf(arg, sizeof(arg), _PATH_LOG "%s", cv_string_get(cv)); + strcat(cmd, arg); + } else + strcat(cmd, _PATH_LOG "syslog"); + + return exec(h, cmd); +} + +int logfiles(cligen_handle h, char *fn_str, cvec *cvv, cg_var *argv, + cvec *commands, cvec *helptexts) +{ + glob_t gl; + size_t i; + int rc; + + rc = glob(_PATH_LOG "*", 0, NULL, &gl); + if (rc && rc != GLOB_NOMATCH) + return 0; + + for (i = 0; i < gl.gl_pathc; i++) { + char *fn; + + fn = rindex(gl.gl_pathv[i], '/'); + if (fn) + fn++; + else + fn = gl.gl_pathv[i]; + cvec_add_string(commands, NULL, fn); + } + globfree(&gl); + return 0; } diff --git a/src/mech/src/core/core-cli.cli b/src/mech/src/core/core-cli.cli index 110f54fe..28d65c46 100644 --- a/src/mech/src/core/core-cli.cli +++ b/src/mech/src/core/core-cli.cli @@ -32,8 +32,23 @@ copy("Copy and create a new object") { } } +follow("Continuously monitor a log file, default syslog"), cli_exec_log(); { + (""), cli_exec_log(); +} + +help("Show help"), cli_help(); + show("Show various system state and configuration") { - system-information("System information"), cli_sysinfo(); + system-information("System information"), cli_exec_show(); + fdb("Show forwarding database (unicast)"), cli_exec_show(); + mdb("Show multicast forwarding database (unicast)"), cli_exec_show(); + ports("Show ports available for bridging"), cli_exec_show(); + vlans("Show port groups in bridge"), cli_exec_show(); + ifaces("Show interfaces and their addresses"), cli_exec_show(); + log("Show latest syslog entries"), cli_exec_log(); { + (""), cli_exec_log(); + } + version("Show operating system version"), cli_exec_show(); auto("Show expand x") { xml @datamodelshow, cli_show_auto("candidate", "xml", true, false, "report-all"); @@ -72,3 +87,6 @@ show("Show various system state and configuration") { } } } + +# Hidden shell command, after 'show' command to avoid any possible completion problems +shell("Start domain shell"), hide, cli_exec_shell();