diff options
Diffstat (limited to 'vtysh')
| -rw-r--r-- | vtysh/ChangeLog | 26 | ||||
| -rw-r--r-- | vtysh/vtysh.c | 27 | ||||
| -rw-r--r-- | vtysh/vtysh.h | 2 | ||||
| -rw-r--r-- | vtysh/vtysh_main.c | 87 | 
4 files changed, 119 insertions, 23 deletions
| diff --git a/vtysh/ChangeLog b/vtysh/ChangeLog index ac038e1c..b9b78f5e 100644 --- a/vtysh/ChangeLog +++ b/vtysh/ChangeLog @@ -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. diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 110c361a..9b7d300f 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -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;      } diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index d619c294..dd2bcbd0 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -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); diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index 7f8e0592..134bcf73 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -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"); | 
