diff options
-rw-r--r-- | lib/command.c | 179 |
1 files changed, 157 insertions, 22 deletions
diff --git a/lib/command.c b/lib/command.c index 8cbecce1..8fd2b648 100644 --- a/lib/command.c +++ b/lib/command.c @@ -1411,9 +1411,21 @@ desc_unique_string (vector v, char *str) return 0; } +int +cmd_try_do_shortcut (enum node_type node, char* first_word) { + if ( first_word != NULL && + node != AUTH_NODE && + node != VIEW_NODE && + node != AUTH_ENABLE_NODE && + node != ENABLE_NODE && + 0 == strcmp( "do", first_word ) ) + return 1; + return 0; +} + /* '?' describe command support. */ vector -cmd_describe_command (vector vline, struct vty *vty, int *status) +cmd_describe_command_real (vector vline, struct vty *vty, int *status) { int i; vector cmd_vector; @@ -1536,6 +1548,40 @@ cmd_describe_command (vector vline, struct vty *vty, int *status) return matchvec; } +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) @@ -1571,7 +1617,7 @@ cmd_lcd (char **matched) /* Command line completion support. */ char ** -cmd_complete_command (vector vline, struct vty *vty, int *status) +cmd_complete_command_real (vector vline, struct vty *vty, int *status) { int i; vector cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node)); @@ -1717,9 +1763,59 @@ cmd_complete_command (vector vline, struct vty *vty, int *status) return match_str; } +char ** +cmd_complete_command (vector vline, struct vty *vty, int *status) +{ + char **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_complete_command_real (shifted_vline, vty, status); + + vector_free(shifted_vline); + vty->node = onode; + return ret; + } + + + return cmd_complete_command_real (vline, vty, status); +} + +/* return parent node */ +/* MUST eventually converge on CONFIG_NODE */ +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; + } + + return ret; +} + /* Execute command by argument vline vector. */ int -cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd) +cmd_execute_command_real (vector vline, struct vty *vty, struct cmd_element **cmd) { int i; int index; @@ -1842,6 +1938,59 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd) return (*matched_element->func) (matched_element, vty, argc, argv); } + +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; +} + /* Execute command by argument readline. */ int cmd_execute_command_strict (vector vline, struct vty *vty, @@ -1981,27 +2130,13 @@ config_from_file (struct vty *vty, FILE *fp) ret = cmd_execute_command_strict (vline, vty, NULL); /* Try again with setting node to CONFIG_NODE */ - if (ret != CMD_SUCCESS && ret != CMD_WARNING) + while (ret != CMD_SUCCESS && ret != CMD_WARNING + && vty->node != CONFIG_NODE) { - if (vty->node == KEYCHAIN_KEY_NODE) - { - vty->node = KEYCHAIN_NODE; - - ret = cmd_execute_command_strict (vline, vty, NULL); - - if (ret != CMD_SUCCESS && ret != CMD_WARNING) - { - vty->node = CONFIG_NODE; - ret = cmd_execute_command_strict (vline, vty, NULL); - } - } - else - { - vty->node = CONFIG_NODE; - ret = cmd_execute_command_strict (vline, vty, NULL); - } + vty->node = node_parent(vty->node); + ret = cmd_execute_command_strict (vline, vty, NULL); } - + cmd_free_strvec (vline); if (ret != CMD_SUCCESS && ret != CMD_WARNING) |