aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2019-06-12 14:47:48 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2019-06-14 17:44:16 +0200
commit7e1b03f763350fefa1a68e45764e2076063fdb15 (patch)
tree5783342be56399c9e033163e4f415bc774c5d6e5
parent14aadd5b6f12dddd055a7c82c19df4b5ec119843 (diff)
vty: command.c: Fix: multi-choice args are no longer passed incomplete to vty func
For instance, take command "multi0 (one|two|three)": If user executes "multi0 tw", VTY func will receive argv[0]="two" instead of argv[0]="tw". Fixes: OS#4045 Change-Id: I91b6621ac3d87fda5412a9b415e7bfb4736c8a9a
-rw-r--r--src/vty/command.c51
-rw-r--r--tests/tdef/tdef_vty_test_config_root.vty11
-rw-r--r--tests/vty/vty_transcript_test.vty12
3 files changed, 56 insertions, 18 deletions
diff --git a/src/vty/command.c b/src/vty/command.c
index 17d28fe6..3c91bfd3 100644
--- a/src/vty/command.c
+++ b/src/vty/command.c
@@ -2217,7 +2217,7 @@ static int
cmd_execute_command_real(vector vline, struct vty *vty,
struct cmd_element **cmd)
{
- unsigned int i;
+ unsigned int i, j;
unsigned int index;
vector cmd_vector;
struct cmd_element *cmd_element;
@@ -2228,6 +2228,10 @@ cmd_execute_command_real(vector vline, struct vty *vty,
enum match_type match = 0;
int varflag;
char *command;
+ int rc;
+ /* Used for temporary storage of cmd_deopt() allocated arguments during
+ argv[] generation */
+ void *cmd_deopt_ctx = NULL;
/* Make copy of command elements. */
cmd_vector = vector_copy(cmd_node_vector(cmdvec, vty->node));
@@ -2293,9 +2297,13 @@ cmd_execute_command_real(vector vline, struct vty *vty,
varflag = 0;
argc = 0;
+ cmd_deopt_ctx = talloc_named_const(tall_vty_cmd_ctx, 0, __func__);
+
for (i = 0; i < vector_active(vline); i++) {
- if (argc == CMD_ARGC_MAX)
- return CMD_ERR_EXEED_ARGC_MAX;
+ if (argc == CMD_ARGC_MAX) {
+ rc = CMD_ERR_EXEED_ARGC_MAX;
+ goto rc_free_deopt_ctx;
+ }
if (varflag) {
argv[argc++] = vector_slot(vline, i);
continue;
@@ -2313,7 +2321,32 @@ cmd_execute_command_real(vector vline, struct vty *vty,
|| CMD_OPTION(desc->cmd))
argv[argc++] = vector_slot(vline, i);
} else {
- argv[argc++] = vector_slot(vline, i);
+ /* multi choice argument. look up which choice
+ the user meant (can only be one after
+ filtering and checking for ambigous). For instance,
+ if user typed "th" for "(two|three)" arg, we
+ want to pass "three" in argv[]. */
+ for (j = 0; j < vector_active(descvec); j++) {
+ struct desc *desc = vector_slot(descvec, j);
+ const char *tmp_cmd;
+ if (!desc)
+ continue;
+ if (cmd_match(desc->cmd, vector_slot(vline, i), ANY_MATCH, true) == NO_MATCH)
+ continue;
+ if (CMD_OPTION(desc->cmd)) {
+ /* we need to first remove the [] chars, then check to see what's inside (var or token) */
+ tmp_cmd = cmd_deopt(cmd_deopt_ctx, desc->cmd);
+ } else {
+ tmp_cmd = desc->cmd;
+ }
+
+ if(CMD_VARIABLE(tmp_cmd)) {
+ argv[argc++] = vector_slot(vline, i);
+ } else {
+ argv[argc++] = tmp_cmd;
+ }
+ break;
+ }
}
}
@@ -2322,10 +2355,14 @@ cmd_execute_command_real(vector vline, struct vty *vty,
*cmd = matched_element;
if (matched_element->daemon)
- return CMD_SUCCESS_DAEMON;
+ rc = CMD_SUCCESS_DAEMON;
+ else /* Execute matched command. */
+ rc = (*matched_element->func) (matched_element, vty, argc, argv);
- /* Execute matched command. */
- return (*matched_element->func) (matched_element, vty, argc, argv);
+rc_free_deopt_ctx:
+ /* Now after we called the command func, we can free temporary strings */
+ talloc_free(cmd_deopt_ctx);
+ return rc;
}
int
diff --git a/tests/tdef/tdef_vty_test_config_root.vty b/tests/tdef/tdef_vty_test_config_root.vty
index 8613ff36..f3aba0f9 100644
--- a/tests/tdef/tdef_vty_test_config_root.vty
+++ b/tests/tdef/tdef_vty_test_config_root.vty
@@ -163,7 +163,6 @@ tdef_vty_test(config)# timer te T2
tdef_vty_test(config)# timer test T2 100
tdef_vty_test(config)# timer tes T2 100
-% Error: no timers found
tdef_vty_test(config)# timer te T2 100
% Ambiguous command.
@@ -219,7 +218,6 @@ tdef_vty_test(config)# timer softw T3
software: T3 = 480 m Fix bugs (default: 480 m)
tdef_vty_test(config)# timer softw T3 23
-% Error: no timers found
tdef_vty_test(config)# timer
tea: T1 = 50 s Water Boiling Timeout (default: 50 s)
@@ -234,7 +232,7 @@ test: T2147483647 = 4294967295 m Very large (default: 4294967295 m)
test: X23 = 239471 s Negative T number (default: 239471 s)
software: T1 = 13 m Write code (default: 30 m)
software: T2 = 0 ms Hit segfault (default: 20 ms)
-software: T3 = 480 m Fix bugs (default: 480 m)
+software: T3 = 23 m Fix bugs (default: 480 m)
tdef_vty_test(config)# do show timer
tea: T1 = 50 s Water Boiling Timeout (default: 50 s)
@@ -249,13 +247,14 @@ test: T2147483647 = 4294967295 m Very large (default: 4294967295 m)
test: X23 = 239471 s Negative T number (default: 239471 s)
software: T1 = 13 m Write code (default: 30 m)
software: T2 = 0 ms Hit segfault (default: 20 ms)
-software: T3 = 480 m Fix bugs (default: 480 m)
+software: T3 = 23 m Fix bugs (default: 480 m)
tdef_vty_test(config)# show running-config
... !timer
timer tea T3 32
timer software T1 13
timer software T2 0
+timer software T3 23
... !timer
tdef_vty_test(config)# timer tea T3 default
@@ -263,10 +262,12 @@ tdef_vty_test(config)# timer software T1 default
tdef_vty_test(config)# show running-config
... !timer
timer software T2 0
+timer software T3 23
... !timer
tdef_vty_test(config)# timer softw 2 default
-% Error: no timers found
tdef_vty_test(config)# timer software 2 default
tdef_vty_test(config)# show running-config
... !timer
+timer software T3 23
+... !timer
diff --git a/tests/vty/vty_transcript_test.vty b/tests/vty/vty_transcript_test.vty
index 15577446..f2dbacbf 100644
--- a/tests/vty/vty_transcript_test.vty
+++ b/tests/vty/vty_transcript_test.vty
@@ -16,13 +16,13 @@ vty_transcript_test> multi0 two
ok argc=1 two
vty_transcript_test> multi0 o
-ok argc=1 o
+ok argc=1 one
vty_transcript_test> multi0 t
% Ambiguous command.
vty_transcript_test> multi0 th
-ok argc=1 th
+ok argc=1 three
vty_transcript_test> multi0
% Command incomplete.
@@ -39,13 +39,13 @@ vty_transcript_test> multi1 two
ok argc=1 two
vty_transcript_test> multi1 o
-ok argc=1 o
+ok argc=1 one
vty_transcript_test> multi1 t
% Ambiguous command.
vty_transcript_test> multi1 th
-ok argc=1 th
+ok argc=1 three
vty_transcript_test> multi1
ok argc=0
@@ -68,10 +68,10 @@ vty_transcript_test> multi2
ok argc=0
vty_transcript_test> multi0 thr
-ok argc=1 thr
+ok argc=1 three
vty_transcript_test> multi1 on
-ok argc=1 on
+ok argc=1 one
vty_transcript_test> multi2 t
% Ambiguous command.