]> git.proxmox.com Git - mirror_frr.git/commitdiff
[vtysh] Never skip authentication, and add support for multiple -c commands
authorAndrew J. Schorr <ajschorr@alumni.princeton.edu>
Thu, 27 Jul 2006 18:01:41 +0000 (18:01 +0000)
committerAndrew J. Schorr <ajschorr@alumni.princeton.edu>
Thu, 27 Jul 2006 18:01:41 +0000 (18:01 +0000)
2006-07-27 Andrew J. Schorr <ajschorr@alumni.princeton.edu>

* vtysh.1: Document new options -d and -E, and note that now multiple
  -c options may be supplied, with embedded linefeed now supported.
  In BUGS section, remove warning about vtysh causing a daemon
  to freeze, since this has been fixed.
* vtysh_main.c: (usage) Add new -d and -E options.  And note that
  -c can be used multiple times, possibly with embedded linefeeds.
  (longopts) Add new -d and -E options.
  (main) Add new -d and -E options, and create a linked list to
  support multiple -c options.  Do not call vtysh_connect_all until
  after vtysh_read_config(config_default) and vtysh_auth have
  succeeded.  This prevents the vtysh.conf file from configuring
  any daemons, and it ensures that authentication has been passed
  before we send any commands to any daemons.  Call vtysh_connect_all
  with any daemon name supplied with -d.  If it is unable to connect
  to any daemons, issue an error message and exit immediately.
  When used in -c mode, call vtysh_execute("enable") before
  executing the commands in order to match interactive behavior.
  And detect embedded linefeed chars in -c commands and break them up
  appropriately.
* vtysh.h: (vtysh_connect_all) Fix proto to reflect new
  daemon_name argument, and that it now returns an integer -- the
  number of daemons to which we were able to connect.
* vtysh.c: (vtysh_connect_all) Add a new daemon_name argument.
  If supplied, connect only to that daemon.  And return
  the number of daemons to which we were able to connect.
  (vtysh_prompt): Performance enhancement -- make struct utsname
  static so we call uname to get the hostname only once.

doc/ChangeLog
doc/vtysh.1
vtysh/ChangeLog
vtysh/vtysh.c
vtysh/vtysh.h
vtysh/vtysh_main.c

index c811cb3198c43aca3483ff4ee15b826c132b37ac..a0c39953014fd2e8a955c347c1d3245110e26d0e 100644 (file)
@@ -1,3 +1,10 @@
+2006-07-27 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
+       * vtysh.1: Document new options -d and -E, and note that now multiple
+         -c options may be supplied, with embedded linefeed now supported.
+         In BUGS section, remove warning about vtysh causing a daemon
+         to freeze, since this has been fixed.
+
 2006-07-04 Paul Jakma <paul.jakma@sun.com>
 
        * quagga.info: remove auto-generated file. It will still be
index e5fccb119397c40f753d593432de50b2ba5f8621..eb960cdc0056059a44509670e8f022b2053be275 100644 (file)
@@ -1,4 +1,4 @@
-.TH VTYSH 1 "3 October 2004" "Quagga VTY shell" "Version 0.96.5"
+.TH VTYSH 1 "27 July 2006" "Quagga VTY shell" "Version 0.96.5"
 .SH NAME
 vtysh \- a integrated shell for Quagga routing software
 .SH SYNOPSIS
@@ -9,6 +9,12 @@ vtysh \- a integrated shell for Quagga routing software
 .br
 .B vtysh
 [
+.B \-E
+] [
+.B \-d
+.I daemon
+]
+] [
 .B \-c
 .I command
 ]
@@ -29,13 +35,32 @@ info.
 Specify command to be executed under batch mode. It behaves like -c option in
 any other shell -
 .I command
-is executed and vtysh exits.
+is executed and
+.B vtysh
+exits.
 
-It's useful for gathering info from Quagga routing software from shell scripts
-etc.
+It's useful for gathering info from Quagga routing software or reconfiguring
+daemons from inside shell scripts, etc.
+Note that multiple commands may be executed by using more than one
+-c option and/or embedding linefeed characters inside the
+.I command
+string.
+.IP "\fB\-d, \-\-daemon \fIdaemon_name\fP"
+Specify which daemon to connect to.  By default,
+.B vtysh
+attempts to connect to all Quagga daemons running on the system.  With this
+flag, one can specify a single daemon to connect to instead.  For example,
+specifying '-d ospfd' will connect only to ospfd.  This can be particularly
+useful inside scripts with -c where the command is targeted for a single daemon.
 .IP "\fB\-e, \-\-execute \fIcommand\fP"
 Alias for -c. It's here only for compatibility with Zebra routing software and
 older Quagga versions. This will be removed in future.
+.IP "\fB\-E, \-\-echo\fP"
+When the -c option is being used, this flag will cause the standard
+.B vtysh
+prompt and command to be echoed prior to displaying the results.
+This is particularly useful to separate the results
+when executing multiple commands.
 .IP "\fB\-h, \-\-help\fP"
 Display a usage message on standard output and exit.
 .SH ENVIRONMENT VARIABLES
@@ -63,10 +88,6 @@ options. The definitive document is the Info file \fBQuagga\fR.
 .BR isisd (8),
 .BR zebra (8)
 .SH BUGS
-Running the command which outputs large amount of data through pager ("show ip
-ospf database", "show ip bgp" etc. in big networks) will cause daemon to be
-unresponsive until vtysh returns back to the prompt.
-
 .B vtysh
 eats bugs for breakfast. If you have food for the maintainers try 
 .BI http://bugzilla.quagga.net
index ac038e1c116b454985aa6da37fc5068b200966df..b9b78f5ed158ab75ac1edf2bb38b04052f941a93 100644 (file)
@@ -1,3 +1,29 @@
+2006-07-27 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
+       * vtysh_main.c: (usage) Add new -d and -E options.  And note that
+         -c can be used multiple times, possibly with embedded linefeeds.
+         (longopts) Add new -d and -E options.
+         (main) Add new -d and -E options, and create a linked list to
+         support multiple -c options.  Do not call vtysh_connect_all until
+         after vtysh_read_config(config_default) and vtysh_auth have
+         succeeded.  This prevents the vtysh.conf file from configuring
+         any daemons, and it ensures that authentication has been passed
+         before we send any commands to any daemons.  Call vtysh_connect_all
+         with any daemon name supplied with -d.  If it is unable to connect
+         to any daemons, issue an error message and exit immediately.
+         When used in -c mode, call vtysh_execute("enable") before
+         executing the commands in order to match interactive behavior. 
+         And detect embedded linefeed chars in -c commands and break them up
+         appropriately.
+       * vtysh.h: (vtysh_connect_all) Fix proto to reflect new
+         daemon_name argument, and that it now returns an integer -- the
+         number of daemons to which we were able to connect.
+       * vtysh.c: (vtysh_connect_all) Add a new daemon_name argument.
+         If supplied, connect only to that daemon.  And return
+         the number of daemons to which we were able to connect.
+         (vtysh_prompt): Performance enhancement -- make struct utsname
+         static so we call uname to get the hostname only once.
+
 2006-05-24 Paul Jakma <paul.jakma@sun.com>
 
        * vtysh.c: (general) Add 'show memory' command.
index 110c361a987ab86eac61687ecea0f8aa8efa03d5..9b7d300fee93dcb90e75287f185c020bc4a6d197 100644 (file)
@@ -2119,18 +2119,28 @@ vtysh_connect (struct vtysh_client *vclient)
   return 0;
 }
 
-void
-vtysh_connect_all(void)
+int
+vtysh_connect_all(const char *daemon_name)
 {
   u_int i;
+  int rc = 0;
+  int matches = 0;
 
   for (i = 0; i < VTYSH_INDEX_MAX; i++)
     {
-      vtysh_connect(&vtysh_client[i]);
-      /* We need direct access to ripd in vtysh_exit_ripd_only. */
-      if (vtysh_client[i].flag == VTYSH_RIPD)
-        ripd_client = &vtysh_client[i];
+      if (!daemon_name || !strcmp(daemon_name, vtysh_client[i].name))
+       {
+         matches++;
+         if (vtysh_connect(&vtysh_client[i]) == 0)
+           rc++;
+         /* We need direct access to ripd in vtysh_exit_ripd_only. */
+         if (vtysh_client[i].flag == VTYSH_RIPD)
+           ripd_client = &vtysh_client[i];
+       }
     }
+  if (!matches)
+    fprintf(stderr, "Error: no daemons match name %s!\n", daemon_name);
+  return rc;
 }
 
 /* To disable readline's filename completion. */
@@ -2155,7 +2165,7 @@ vtysh_readline_init (void)
 char *
 vtysh_prompt (void)
 {
-  struct utsname names;
+  static struct utsname names;
   static char buf[100];
   const char*hostname;
   extern struct host host;
@@ -2164,7 +2174,8 @@ vtysh_prompt (void)
 
   if (!hostname)
     {
-      uname (&names);
+      if (!names.nodename[0])
+       uname (&names);
       hostname = names.nodename;
     }
 
index d619c294e5ed013e9c294e4d2fea37dcdc0b07eb..dd2bcbd0a03f281ac0e8d9c08748443751204934 100644 (file)
@@ -38,7 +38,7 @@
 
 void vtysh_init_vty (void);
 void vtysh_init_cmd (void);
-void vtysh_connect_all (void);
+extern int vtysh_connect_all (const char *optional_daemon_name);
 void vtysh_readline_init (void);
 void vtysh_user_init (void);
 
index 7f8e05929e152c16b0141938a67861f2e3d5a9ed..134bcf73ca4df451b5a6abd53f67270dd199302a 100644 (file)
@@ -32,6 +32,7 @@
 #include <lib/version.h>
 #include "getopt.h"
 #include "command.h"
+#include "memory.h"
 
 #include "vtysh/vtysh.h"
 #include "vtysh/vtysh_user.h"
@@ -132,10 +133,15 @@ usage (int status)
     fprintf (stderr, "Try `%s --help' for more information.\n", progname);
   else
     printf ("Usage : %s [OPTION...]\n\n" \
-           "Integrated shell for Quagga routing software suite. \n\n"\
+           "Integrated shell for Quagga routing software suite. \n\n" \
            "-b, --boot               Execute boot startup configuration\n" \
-           "-c, --command            Execute argument as command\n "\
+           "-c, --command            Execute argument as command\n" \
+           "-d, --daemon             Connect only to the specified daemon\n" \
+           "-E, --echo               Echo prompt and command in -c mode\n" \
            "-h, --help               Display this help and exit\n\n" \
+           "Note that multiple commands may be executed from the command\n" \
+           "line by passing multiple -c args, or by embedding linefeed\n" \
+           "characters in one or more of the commands.\n\n" \
            "Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
 
   exit (status);
@@ -148,6 +154,8 @@ struct option longopts[] =
   /* For compatibility with older zebra/quagga versions */
   { "eval",                 required_argument,       NULL, 'e'},
   { "command",              required_argument,       NULL, 'c'},
+  { "daemon",               required_argument,       NULL, 'd'},
+  { "echo",                 no_argument,             NULL, 'E'},
   { "help",                 no_argument,             NULL, 'h'},
   { 0 }
 };
@@ -187,9 +195,14 @@ main (int argc, char **argv, char **env)
 {
   char *p;
   int opt;
-  int eval_flag = 0;
   int boot_flag = 0;
-  char *eval_line = NULL;
+  const char *daemon_name = NULL;
+  struct cmd_rec {
+    const char *line;
+    struct cmd_rec *next;
+  } *cmd = NULL;
+  struct cmd_rec *tail = NULL;
+  int echo_command = 0;
 
   /* Preserve name of myself. */
   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
@@ -197,7 +210,7 @@ main (int argc, char **argv, char **env)
   /* Option handling. */
   while (1) 
     {
-      opt = getopt_long (argc, argv, "be:c:h", longopts, 0);
+      opt = getopt_long (argc, argv, "be:c:d:Eh", longopts, 0);
     
       if (opt == EOF)
        break;
@@ -211,8 +224,23 @@ main (int argc, char **argv, char **env)
          break;
        case 'e':
        case 'c':
-         eval_flag = 1;
-         eval_line = optarg;
+         {
+           struct cmd_rec *cr;
+           cr = XMALLOC(0, sizeof(*cr));
+           cr->line = optarg;
+           cr->next = NULL;
+           if (tail)
+             tail->next = cr;
+           else
+             cmd = cr;
+           tail = cr;
+         }
+         break;
+       case 'd':
+         daemon_name = optarg;
+         break;
+       case 'E':
+         echo_command = 1;
          break;
        case 'h':
          usage (0);
@@ -239,15 +267,48 @@ main (int argc, char **argv, char **env)
 
   sort_node ();
 
-  vtysh_connect_all ();
-
-  /* Read vtysh configuration file. */
+  /* Read vtysh configuration file before connecting to daemons. */
   vtysh_read_config (config_default);
 
+  /* Make sure we pass authentication before proceeding. */
+  vtysh_auth ();
+
+  /* Do not connect until we have passed authentication. */
+  if (vtysh_connect_all (daemon_name) <= 0)
+    {
+      fprintf(stderr, "Exiting: failed to connect to any daemons.\n");
+      exit(1);
+    }
+
   /* If eval mode. */
-  if (eval_flag)
+  if (cmd)
     {
-      vtysh_execute_no_pager (eval_line);
+      /* Enter into enable node. */
+      vtysh_execute ("enable");
+
+      while (cmd != NULL)
+        {
+         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);
+             cmd->line = eol+1;
+           }
+         if (echo_command)
+           printf("%s%s\n", vtysh_prompt(), cmd->line);
+         vtysh_execute_no_pager (cmd->line);
+
+         {
+           struct cmd_rec *cr;
+           cr = cmd;
+           cmd = cmd->next;
+           XFREE(0, cr);
+         }
+        }
       exit (0);
     }
   
@@ -270,8 +331,6 @@ main (int argc, char **argv, char **env)
 
   vty_hello (vty);
 
-  vtysh_auth ();
-
   /* Enter into enable node. */
   vtysh_execute ("enable");