summaryrefslogtreecommitdiff
path: root/vtysh
diff options
context:
space:
mode:
authorAndrew J. Schorr <ajschorr@alumni.princeton.edu>2006-07-27 18:01:41 +0000
committerAndrew J. Schorr <ajschorr@alumni.princeton.edu>2006-07-27 18:01:41 +0000
commitf366ad31ae6bf7e2fb7271cf8eab6dee4af3baf9 (patch)
tree452f3071f7e1dc71d056bd476481bb008f6f435e /vtysh
parent171eee31edbddbd8906447dc8725e0513227d013 (diff)
[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.
Diffstat (limited to 'vtysh')
-rw-r--r--vtysh/ChangeLog26
-rw-r--r--vtysh/vtysh.c27
-rw-r--r--vtysh/vtysh.h2
-rw-r--r--vtysh/vtysh_main.c87
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");