]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #2221 from rodnymolina/vtysh_extension
authorQuentin Young <qlyoung@users.noreply.github.com>
Thu, 17 May 2018 17:03:11 +0000 (13:03 -0400)
committerGitHub <noreply@github.com>
Thu, 17 May 2018 17:03:11 +0000 (13:03 -0400)
vtysh: Extending vtysh to allow question-mark cmds

vtysh/vtysh.c
vtysh/vtysh.h
vtysh/vtysh_main.c

index 4974e538ea0789ec4a859cdd9323a3d0bd3bcb32..30de9d7711b2b51e07f9ed9b64b4430f3321e8bc 100644 (file)
@@ -846,27 +846,29 @@ int vtysh_config_from_file(struct vty *vty, FILE *fp)
        return (retcode);
 }
 
-/* We don't care about the point of the cursor when '?' is typed. */
-static int vtysh_rl_describe(void)
+/*
+ * Function processes cli commands terminated with '?' character when entered
+ * through either 'vtysh' or 'vtysh -c' interfaces.
+ */
+static int vtysh_process_questionmark(const char *input, int input_len)
 {
-       int ret;
+       int ret, width = 0;
        unsigned int i;
-       vector vline;
-       vector describe;
-       int width;
+       vector vline, describe;
        struct cmd_token *token;
 
-       vline = cmd_make_strvec(rl_line_buffer);
+       if (!input)
+               return 1;
+
+       vline = cmd_make_strvec(input);
 
        /* In case of '> ?'. */
        if (vline == NULL) {
                vline = vector_init(1);
                vector_set(vline, NULL);
-       } else if (rl_end && isspace((int)rl_line_buffer[rl_end - 1]))
+       } else if (input_len && isspace((int)input[input_len - 1]))
                vector_set(vline, NULL);
 
-       fprintf(stdout, "\n");
-
        describe = cmd_describe_command(vline, vty, &ret);
 
        /* Ambiguous and no match error. */
@@ -875,7 +877,6 @@ static int vtysh_rl_describe(void)
                cmd_free_strvec(vline);
                vector_free(describe);
                fprintf(stdout, "%% Ambiguous command.\n");
-               rl_on_new_line();
                return 0;
                break;
        case CMD_ERR_NO_MATCH:
@@ -883,7 +884,6 @@ static int vtysh_rl_describe(void)
                if (describe)
                        vector_free(describe);
                fprintf(stdout, "%% There is no matched command.\n");
-               rl_on_new_line();
                return 0;
                break;
        }
@@ -933,9 +933,61 @@ static int vtysh_rl_describe(void)
        cmd_free_strvec(vline);
        vector_free(describe);
 
+       return 0;
+}
+
+/*
+ * Entry point for user commands terminated with '?' character and typed through
+ * the usual vtysh's stdin interface. This is the function being registered with
+ * readline() api's.
+ */
+static int vtysh_rl_describe(void)
+{
+       int ret;
+
+       fprintf(stdout, "\n");
+
+       ret = vtysh_process_questionmark(rl_line_buffer, rl_end);
        rl_on_new_line();
 
-       return 0;
+       return ret;
+}
+
+/*
+ * Function in charged of processing vtysh instructions terminating with '?'
+ * character and received through the 'vtysh -c' interface. If user's
+ * instruction is well-formatted, we will call the same processing routine
+ * utilized by the traditional vtysh's stdin interface.
+ */
+int vtysh_execute_command_questionmark(char *input)
+{
+       int input_len, qmark_count = 0;
+       const char *str;
+
+       if (!(input && *input))
+               return 1;
+
+       /* Finding out question_mark count and strlen */
+       for (str = input; *str; ++str) {
+               if (*str == '?')
+                       qmark_count++;
+       }
+       input_len = str - input;
+
+       /*
+        * Verify that user's input terminates in '?' and that patterns such as
+        * 'cmd ? subcmd ?' are prevented.
+        */
+       if (qmark_count != 1 || input[input_len - 1] != '?')
+               return 1;
+
+       /*
+        * Questionmark-processing function is not expecting to receive '?'
+        * character in input string.
+        */
+       input[input_len - 1] = '\0';
+
+       return vtysh_process_questionmark(input, input_len - 1);
 }
 
 /* Result of cmd_complete_command() call will be stored here
index f3e58f309e8d85516864d05dc30b6678c1141dbf..ccfdd6557b425da2fda33c42419c026330030e05 100644 (file)
@@ -71,6 +71,7 @@ void vtysh_user_init(void);
 
 int vtysh_execute(const char *);
 int vtysh_execute_no_pager(const char *);
+int vtysh_execute_command_questionmark(char *input);
 
 char *vtysh_prompt(void);
 
index cd59d8094b95c35541f17cea470ba93a2c68397f..3dd70983bc27a8847a11670ce840f6d4594b3453 100644 (file)
@@ -611,7 +611,16 @@ int main(int argc, char **argv, char **env)
                        if (logfile)
                                log_it(cmd->line);
 
-                       ret = vtysh_execute_no_pager(cmd->line);
+                       /*
+                        * Parsing logic for regular commands will be different than
+                        * for those commands requiring further processing, such as
+                        * cli instructions terminating with question-mark character.
+                        */
+                       if (!vtysh_execute_command_questionmark(cmd->line))
+                               ret = CMD_SUCCESS;
+                       else
+                               ret = vtysh_execute_no_pager(cmd->line);
+
                        if (!no_error
                            && !(ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON
                                 || ret == CMD_WARNING))