[vtysh] Never skip authentication, and add support for multiple -c commands

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.
This commit is contained in:
Andrew J. Schorr 2006-07-27 18:01:41 +00:00
parent 171eee31ed
commit f366ad31ae
6 changed files with 156 additions and 32 deletions

View 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

View 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

View 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.

View 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;
}

View 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);

View 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);
/* If eval mode. */
if (eval_flag)
/* Make sure we pass authentication before proceeding. */
vtysh_auth ();
/* Do not connect until we have passed authentication. */
if (vtysh_connect_all (daemon_name) <= 0)
{
vtysh_execute_no_pager (eval_line);
fprintf(stderr, "Exiting: failed to connect to any daemons.\n");
exit(1);
}
/* If eval mode. */
if (cmd)
{
/* 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");