From 57fb974856b9ae143ca5642e279d181a45bbdd10 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 28 Jul 2008 12:19:04 -0700 Subject: [vtysh] Make vtysh more useable for scripting Add environment variable (VTYSH_LOG) for logging. If a command fails, exit with non-zero exit code and don't continue multipart commands. --- vtysh/vtysh.c | 17 +++++++++-------- vtysh/vtysh.h | 4 ++-- vtysh/vtysh_main.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 53 insertions(+), 13 deletions(-) (limited to 'vtysh') diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 32b626c7..20f7df44 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -272,10 +272,10 @@ vtysh_pager_init (void) } /* Command execution over the vty interface. */ -static void +static int vtysh_execute_func (const char *line, int pager) { - int ret, cmd_stat; + int ret, cmd_stat = CMD_SUCCESS; u_int i; vector vline; struct cmd_element *cmd; @@ -288,7 +288,7 @@ vtysh_execute_func (const char *line, int pager) vline = cmd_make_strvec (line); if (vline == NULL) - return; + return CMD_SUCCESS; saved_ret = ret = cmd_execute_command (vline, vty, &cmd, 1); saved_node = vty->node; @@ -394,7 +394,7 @@ vtysh_execute_func (const char *line, int pager) } fp = NULL; } - return; + return CMD_SUCCESS; } ret = cmd_execute_command (vline, vty, &cmd, 1); @@ -435,18 +435,19 @@ vtysh_execute_func (const char *line, int pager) } fp = NULL; } + return cmd_stat; } -void +int vtysh_execute_no_pager (const char *line) { - vtysh_execute_func (line, 0); + return vtysh_execute_func (line, 0); } -void +int vtysh_execute (const char *line) { - vtysh_execute_func (line, 1); + return vtysh_execute_func (line, 1); } /* Configration make from file. */ diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 3ed0dd32..e711d593 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -42,8 +42,8 @@ extern int vtysh_connect_all (const char *optional_daemon_name); void vtysh_readline_init (void); void vtysh_user_init (void); -void vtysh_execute (const char *); -void vtysh_execute_no_pager (const char *); +int vtysh_execute (const char *); +int vtysh_execute_no_pager (const char *); char *vtysh_prompt (void); diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index d655e073..55a430d5 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -58,6 +58,9 @@ static char *line_read; /* Master of threads. */ struct thread_master *master; +/* Command logging */ +FILE *logfile; + /* SIGTSTP handler. This function care user's ^Z input. */ void sigtstp (int sig) @@ -191,6 +194,18 @@ vtysh_rl_gets () return (line_read); } +static void log_it(const char *line) +{ + time_t t = time(NULL); + struct tm *tmp = localtime(&t); + char *user = getenv("USER") ? : "boot"; + char tod[64]; + + strftime(tod, sizeof tod, "%Y%m%d-%H:%M.%S", tmp); + + fprintf(logfile, "%s:%s %s\n", tod, user, line); +} + /* VTY shell main routine. */ int main (int argc, char **argv, char **env) @@ -210,6 +225,10 @@ main (int argc, char **argv, char **env) /* Preserve name of myself. */ progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); + /* if logging open now */ + if ((p = getenv("VTYSH_LOG")) != NULL) + logfile = fopen(p, "a"); + /* Option handling. */ while (1) { @@ -299,19 +318,39 @@ main (int argc, char **argv, char **env) while (cmd != NULL) { + int ret; char *eol; while ((eol = strchr(cmd->line, '\n')) != NULL) { *eol = '\0'; + if (echo_command) - printf("%s%s\n", vtysh_prompt(), cmd->line); - vtysh_execute_no_pager(cmd->line); + printf("%s%s\n", vtysh_prompt(), cmd->line); + + if (logfile) + log_it(cmd->line); + + ret = vtysh_execute_no_pager(cmd->line); + if (ret != CMD_SUCCESS + && ret != CMD_SUCCESS_DAEMON + && ret != CMD_WARNING) + exit(1); + cmd->line = eol+1; } + if (echo_command) printf("%s%s\n", vtysh_prompt(), cmd->line); - vtysh_execute_no_pager (cmd->line); + + if (logfile) + log_it(cmd->line); + + ret = vtysh_execute_no_pager(cmd->line); + if (ret != CMD_SUCCESS + && ret != CMD_SUCCESS_DAEMON + && ret != CMD_WARNING) + exit(1); { struct cmd_rec *cr; -- cgit v1.2.1