summaryrefslogtreecommitdiff
path: root/lib/command.c
diff options
context:
space:
mode:
authorpaul <paul>2003-01-18 01:16:20 +0000
committerpaul <paul>2003-01-18 01:16:20 +0000
commit9ab6812d1dd27813f3ae01624312edc21c1a0bb6 (patch)
tree0e74ebe8d75aa0217233de3045240579933395eb /lib/command.c
parenteda031f6f3558239da5ceb196312ff71aa74fef1 (diff)
This patch adds Yon's CLI 'walk back up tree' patch. Following are email
describing original patch and a shorter email describing changes to an updated patch, the one which is applied: From havanna_moon@gmx.net Sat Jan 18 00:37:13 2003 Date: Mon, 9 Dec 2002 05:32:58 +0100 (CET) From: Yon Uriarte <havanna_moon@gmx.net> To: "the list(tm) Zebra" <zebra@zebra.org> Subject: [zebra 16671] [PATCH] CLI extensions. Hi, this patch adds 2 improvements to the CLI (lib/command.c): #1) When in subconfig mode (router XXX, interface XXX, ...) commands that fail for that node are tried on the main CONFIG_NODE. This is great for configuring interfaces or changing the sub-config mode quickly, without the need to type 'exit' between commands: ospfd(config)# int eth1 ospfd(config-if)# ip ospf cost 9 ospfd(config-if)# ip ospf prio 101 ospfd(config-if)# router ospf ospfd(config-router)# network 1.1.1.0/24 area 51 ospfd(config-router)# int eth2 ospfd(config-if)# ip ospf authentication message-digest ospfd(config-if)# ^Z ospfd# Is this IOS-like or does IOS try to walk up the tree of config sub-modes instead of directly trying the command on CONFIG_NODE? CAVEATS: "?" and "TAB" don't work. IIRC IOS doesnt show that help neither. NON-CAVEATS: This wont break much, as config_from_file() already does try a failed command on the parent node of the actual vty->node. If changing the code to walk the node tree instead of directly trying the command on the ENABLE_NODE the same semantics would be in use and no future bugs could creep in. #2) When in config or subconfig mode use the "do " prefix to execute commans of the ENABLE_NODE. "?" and "TAB" work. The space after the "do" is needed: ospfd(config-router)# do<?> % There is no matched command. ospfd(config-router)# do <?> clear Reset functions configure Configuration from vty interface copy Copy configuration debug Debugging functions (see also 'undebug') disable Turn off privileged mode command end End current mode and change to enable mode. exit Exit current mode and down to previous mode help Description of the interactive help system list Print command list no Negate a command or set its defaults quit Exit current mode and down to previous mode show Show running system information terminal Set terminal line parameters who Display who is on vty write Write running configuration to memory, network, or terminal ospfd(config-router)# do sho<TAB> ospfd(config-router)# do show me<TAB> ospfd(config-router)# do show memory r<TAB> ospfd(config-router)# do show memory rip RIP structure : 0 RIP route info : 0 RIP interface : 0 RIP peer : 0 RIP offset list : 0 RIP distance : 0 ospfd(config-router)# ^Z ospfd# CAVEATS: I don't have access to an IOS with this feature, so I implemented it from the comments on this mailing list (in fact my personal motivation was to implement feature #1, which I missed on zebra. But #2 sounded like a nice one to have, and xemacs was already parked on command.c ...). Is this IOS-like or are there differences? I will happily change this patch to mimick IOS or the mailing-list consensus on CLI-usability. regards, yon From havanna_moon@gmx.net Sat Jan 18 01:13:11 2003 Date: Sat, 11 Jan 2003 23:36:51 +0100 (CET) From: Yon Uriarte <havanna_moon@gmx.net> To: zebra@zebra.org Subject: [zebra 17218] Re: [PATCH] CLI extensions. Hi, [redacted] > I prefer the IOS way for the node "up walking". This patch should walk the tree upwards: bgpd(config)# router bgp 1 bgpd(config-router)# address-family ipv4 multicast bgpd(config-router-af)# access-list 1 remark hola que tal bgpd(config)# I cant test all combinations, so I cant rule out some bugs. I'd love to get (long and explicit) bug reports. [redacted]
Diffstat (limited to 'lib/command.c')
-rw-r--r--lib/command.c153
1 files changed, 41 insertions, 112 deletions
diff --git a/lib/command.c b/lib/command.c
index f0ddb6d7..f57cf5ca 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA. */
#include "memory.h"
#include "log.h"
#include "version.h"
+#include "thread.h"
/* Command vector which includes some level of command lists. Normally
each daemon maintains each own cmdvec. */
@@ -1582,40 +1583,6 @@ cmd_describe_command (vector vline, struct vty *vty, int *status)
}
-vector
-cmd_describe_command (vector vline, struct vty *vty, int *status)
-{
- vector ret;
-
- if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
- {
- enum node_type onode;
- vector shifted_vline;
- int index;
-
- onode = vty->node;
- vty->node = ENABLE_NODE;
- /* We can try it on enable node, cos' the vty is authenticated */
-
- shifted_vline = vector_init (vector_count(vline));
- /* use memcpy? */
- for (index = 1; index < vector_max (vline); index++)
- {
- vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
- }
-
- ret = cmd_describe_command_real (shifted_vline, vty, status);
-
- vector_free(shifted_vline);
- vty->node = onode;
- return ret;
- }
-
-
- return cmd_describe_command_real (vline, vty, status);
-}
-
-
/* Check LCD of matched command. */
int
cmd_lcd (char **matched)
@@ -1798,7 +1765,7 @@ cmd_complete_command_real (vector vline, struct vty *vty, int *status)
}
char **
-cmd_complete_command_real (vector vline, struct vty *vty, int *status)
+cmd_complete_command (vector vline, struct vty *vty, int *status)
{
char **ret;
@@ -1836,12 +1803,21 @@ enum node_type node_parent ( enum node_type node )
{
enum node_type ret;
- switch ( node ) {
- case KEYCHAIN_KEY_NODE:
- ret = KEYCHAIN_NODE;
- break;
- default:
- ret = CONFIG_NODE;
+ assert (node > CONFIG_NODE);
+
+ switch (node)
+ {
+ case BGP_VPNV4_NODE:
+ case BGP_IPV4_NODE:
+ case BGP_IPV4M_NODE:
+ case BGP_IPV6_NODE:
+ ret = BGP_NODE;
+ break;
+ case KEYCHAIN_KEY_NODE:
+ ret = KEYCHAIN_NODE;
+ break;
+ default:
+ ret = CONFIG_NODE;
}
return ret;
@@ -1975,61 +1951,10 @@ cmd_execute_command_real (vector vline, struct vty *vty, struct cmd_element **cm
int
cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd) {
- int ret;
- enum node_type onode = vty->node;
-
- if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
- {
- vector shifted_vline;
- int index;
-
- vty->node = ENABLE_NODE;
- /* We can try it on enable node, cos' the vty is authenticated */
-
- shifted_vline = vector_init (vector_count(vline));
- /* use memcpy? */
- for (index = 1; index < vector_max (vline); index++)
- {
- vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
- }
-
- ret = cmd_execute_command_real (shifted_vline, vty, cmd);
-
- vector_free(shifted_vline);
- vty->node = onode;
- return ret;
- }
-
-
- ret = cmd_execute_command_real (vline, vty, cmd);
-
- /* This assumes all nodes above CONFIG_NODE are childs of CONFIG_NODE */
- if ( ret != CMD_SUCCESS && ret != CMD_WARNING
- && vty->node > CONFIG_NODE )
- {
- /* XXX try node_parent(vty->node)? */
- vty->node = CONFIG_NODE;
- ret = cmd_execute_command_real (vline, vty, cmd);
- if (ret != CMD_SUCCESS && ret != CMD_WARNING)
- {
- /* if the command changed the node dont reset it */
- if( vty->node == CONFIG_NODE )
- vty->node = onode;
- return ret;
- }
- else
- if( vty->node == CONFIG_NODE )
- vty->node = onode;
- /* if the command changed the node dont reset it */
- }
- return ret;
-}
-
+ int ret, saved_ret, tried = 0;
+ enum node_type onode, try_node;
-int
-cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd) {
- int ret;
- enum node_type onode = vty->node;
+ onode = try_node = vty->node;
if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
{
@@ -2054,28 +1979,27 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd) {
}
- ret = cmd_execute_command_real (vline, vty, cmd);
+ saved_ret = ret = cmd_execute_command_real (vline, vty, cmd);
/* This assumes all nodes above CONFIG_NODE are childs of CONFIG_NODE */
- if ( ret != CMD_SUCCESS && ret != CMD_WARNING
+ while ( ret != CMD_SUCCESS && ret != CMD_WARNING
&& vty->node > CONFIG_NODE )
{
- /* XXX try node_parent(vty->node)? */
- vty->node = CONFIG_NODE;
+ try_node = node_parent(try_node);
+ vty->node = try_node;
ret = cmd_execute_command_real (vline, vty, cmd);
- if (ret != CMD_SUCCESS && ret != CMD_WARNING)
+ tried = 1;
+ if (ret == CMD_SUCCESS || ret == CMD_WARNING)
{
- /* if the command changed the node dont reset it */
- if( vty->node == CONFIG_NODE )
- vty->node = onode;
+ /* succesfull command, leave the node as is */
return ret;
}
- else
- if( vty->node == CONFIG_NODE )
- vty->node = onode;
- /* if the command changed the node dont reset it */
}
- return ret;
+ /* no command succeeded, reset the vty to the original node and
+ return the error for this node */
+ if ( tried )
+ vty->node = onode;
+ return saved_ret;
}
/* Execute command by argument readline. */
@@ -2219,11 +2143,11 @@ config_from_file (struct vty *vty, FILE *fp)
/* Try again with setting node to CONFIG_NODE */
while (ret != CMD_SUCCESS && ret != CMD_WARNING
&& vty->node != CONFIG_NODE)
- {
+ {
vty->node = node_parent(vty->node);
- ret = cmd_execute_command_strict (vline, vty, NULL);
- }
-
+ ret = cmd_execute_command_strict (vline, vty, NULL);
+ }
+
cmd_free_strvec (vline);
if (ret != CMD_SUCCESS && ret != CMD_WARNING)
@@ -3199,5 +3123,10 @@ cmd_init (int terminal)
install_element (CONFIG_NODE, &no_service_terminal_length_cmd);
}
+ if (terminal)
+ {
+ install_element(VIEW_NODE, &show_thread_cpu_cmd);
+ install_element(ENABLE_NODE, &show_thread_cpu_cmd);
+ }
srand(time(NULL));
}