pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/14436
Change subject: vty: command.c: Fix: multi-choice args are no longer passed incomplete to vty func ...................................................................... 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 --- M src/vty/command.c M tests/tdef/tdef_vty_test_config_root.vty M tests/vty/vty_transcript_test.vty 3 files changed, 83 insertions(+), 25 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/36/14436/1 diff --git a/src/vty/command.c b/src/vty/command.c index b4afd35..6e8bc5b 100644 --- a/src/vty/command.c +++ b/src/vty/command.c @@ -2217,7 +2217,7 @@ 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 @@ 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,11 +2297,15 @@ 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 (varflag) { argv[argc++] = vector_slot(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; + } continue; } @@ -2313,11 +2321,38 @@ || 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; + } } - 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; + } } /* For vtysh execution. */ @@ -2325,10 +2360,14 @@ *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 8613ff3..3ff3f37 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 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 @@ 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: 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,24 +247,45 @@ 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 + +Current configuration: +! +! +line vty + no login +! timer tea T3 32 timer software T1 13 timer software T2 0 -... !timer +timer software T3 23 +end tdef_vty_test(config)# timer tea T3 default tdef_vty_test(config)# timer software T1 default tdef_vty_test(config)# show running-config -... !timer + +Current configuration: +! +! +line vty + no login +! timer software T2 0 -... !timer +timer software T3 23 +end 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 + +Current configuration: +! +! +line vty + no login +! +timer software T3 23 +end diff --git a/tests/vty/vty_transcript_test.vty b/tests/vty/vty_transcript_test.vty index 1557744..f2dbacb 100644 --- a/tests/vty/vty_transcript_test.vty +++ b/tests/vty/vty_transcript_test.vty @@ -16,13 +16,13 @@ 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 @@ 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 @@ 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. -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/14436 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I91b6621ac3d87fda5412a9b415e7bfb4736c8a9a Gerrit-Change-Number: 14436 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pes...@sysmocom.de> Gerrit-MessageType: newchange