]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
print out only one layer of help at a time
authorAlan T. DeKok <aland@freeradius.org>
Sun, 8 Jul 2018 13:23:28 +0000 (09:23 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 8 Jul 2018 13:23:28 +0000 (09:23 -0400)
src/include/command.h
src/main/command.c
src/main/radmin.c

index c5eb39875c3b8880621aefc876eeb9b3277a3939..92fab6dc530d262dc46dfc0ebe6ecd18f5e71dd7 100644 (file)
@@ -39,6 +39,7 @@ typedef struct fr_cmd_info_t {
        bool            runnable;                       //!< is the command runnable?
        char            **argv;                         //!< text version of commands
        fr_value_box_t  **box;                          //!< value_box version of commands.
+       fr_cmd_t        **cmd;                          //!< cached commands at each offset
 } fr_cmd_info_t;
 
 typedef int (*fr_cmd_func_t)(FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info);
@@ -73,7 +74,7 @@ int fr_command_tab_expand(TALLOC_CTX *ctx, fr_cmd_t *head, fr_cmd_info_t *info,
 char const *fr_command_help(fr_cmd_t *head, int argc, char *argv[]);
 int fr_command_run(FILE *fp, FILE *fp_err, fr_cmd_t *head, fr_cmd_info_t *info);
 void fr_command_debug(FILE *fp, fr_cmd_t *head);
-void fr_command_list(FILE *fp, fr_cmd_t *head);
+void fr_command_list(FILE *fp, int max_depth, fr_cmd_t *head, bool is_head);
 int fr_command_str_to_argv(fr_cmd_t *head, fr_cmd_info_t *info, char *str);
 
 #ifdef __cplusplus
index d440473f891526be2e94eb2bce0815ee6c014368..1a6c7d8cc4db19ff6f7463b43b25a3f8de1438c9 100644 (file)
@@ -1482,25 +1482,33 @@ static void fr_command_list_node(FILE *fp, fr_cmd_t *cmd, int depth, char const
        }
 }
 
-static void fr_command_list_internal(FILE *fp, fr_cmd_t *head, int depth, char const **argv)
+static void fr_command_list_internal(FILE *fp, fr_cmd_t *head, int depth, int max_depth, char const **argv)
 {
        fr_cmd_t *cmd;
 
        for (cmd = head; cmd != NULL; cmd = cmd->next) {
-               if (cmd->child) {
+               if (cmd->child && ((depth + 1) < max_depth)) {
                        argv[depth] = cmd->name;
-                       fr_command_list_internal(fp, cmd->child, depth + 1, argv);
+                       fr_command_list_internal(fp, cmd->child, depth + 1, max_depth, argv);
                } else {
                        fr_command_list_node(fp, cmd, depth, argv);
                }
        }
 }
 
-void fr_command_list(FILE *fp, fr_cmd_t *head)
+void fr_command_list(FILE *fp, int max_depth, fr_cmd_t *head, bool is_head)
 {
        char const *argv[CMD_MAX_ARGV];
 
-       fr_command_list_internal(fp, head, 0, argv);
+       if ((max_depth <= 0) || !head) return;
+       if (max_depth > CMD_MAX_ARGV) max_depth = CMD_MAX_ARGV;
+
+       if (!is_head) {
+               if (!head->child) return;
+               head = head->child;
+       }
+
+       fr_command_list_internal(fp, head, 0, max_depth, argv);
 }
 
 
@@ -1709,7 +1717,7 @@ int fr_command_str_to_argv(fr_cmd_t *head, fr_cmd_info_t *info, char *str)
        fr_cmd_t *cmd, *start;
        fr_cmd_argv_t *argv;
 
-       if ((info->argc < 0) || (info->max_argc <= 0) || !str) {
+       if ((info->argc < 0) || (info->max_argc <= 0) || !str || !head) {
                fr_strerror_printf("Invalid arguments passed to parse routine.");
                return -1;
        }
@@ -1761,6 +1769,11 @@ int fr_command_str_to_argv(fr_cmd_t *head, fr_cmd_info_t *info, char *str)
                        return -1;
                }
 
+               /*
+                *      Cache the command for later consumption.
+                */
+               if (info->cmd) info->cmd[i] = cmd;
+
                /*
                 *      There's a child.  Go match it.
                 */
index 2f10d0e59c48fcebe7382b1ee0d18d1bc81740c3..bcf8ff67b679e1be4fb2cc9f55e3ea72eb0ba876 100644 (file)
@@ -54,7 +54,7 @@ RCSID("$Id$")
 
 static pthread_t pthread_id;
 static bool stop = false;
-static int context = 0;
+static int context;
 static fr_cmd_info_t radmin_info;
 
 #ifndef USE_READLINE
@@ -133,6 +133,7 @@ static fr_cmd_t *radmin_cmd = NULL;
 #define CMD_MAX_ARGV (32)
 
 static int cmd_help(FILE *fp, FILE *fp_err, UNUSED void *ctx, fr_cmd_info_t const *info);
+static int cmd_exit(FILE *fp, FILE *fp_err, UNUSED void *ctx, fr_cmd_info_t const *info);
 
 static void *fr_radmin(UNUSED void *input_ctx)
 {
@@ -192,6 +193,15 @@ static void *fr_radmin(UNUSED void *input_ctx)
                                goto next;
                        }
 
+                       /*
+                        *      Special-case "quit", which works everywhere.
+                        *      It closes the CLI immediately.
+                        */
+                       if (strcmp(line, "quit") == 0) {
+                               cmd_exit(stdout, stderr, NULL, info);
+                               goto next;
+                       }
+
                        /*
                         *      Allow exiting from the current context.
                         */
@@ -326,18 +336,33 @@ static int cmd_exit(UNUSED FILE *fp, UNUSED FILE *fp_err, UNUSED void *ctx, UNUS
 
 static int cmd_help(FILE *fp, UNUSED FILE *fp_err, UNUSED void *ctx, fr_cmd_info_t const *info)
 {
-       char const *help;
+//     char const *help;
 
        if (info->argc == 0) {
-               fr_command_list(fp, radmin_cmd);
-               return 0;
+               /*
+                *      List only the top-level commands
+                */
+               if (radmin_info.argc == 1) {
+                       fr_command_list(fp, 1, radmin_cmd, true);
+                       return 0;
+               }
+
        }
 
+       /*
+        *      List the current command, but it's children instead of
+        *      itself.
+        */
+       fr_command_list(fp, 1, radmin_info.cmd[radmin_info.argc - 1], false);
+
+#if 0
+       // @todo - print out actual help from the above commands
        help = fr_command_help(radmin_cmd, info->argc, info->argv);
        if (help) {
                fprintf(fp, "%s\n", help);
                return 0;
        }
+#endif
 
        return 0;
 }
@@ -420,7 +445,14 @@ static fr_cmd_table_t cmd_table[] = {
        {
                .syntax = "exit",
                .func = cmd_exit,
-               .help = "Tell the server to exit immediately.",
+               .help = "Exit from the current context.",
+               .read_only = false
+       },
+
+       {
+               .syntax = "quit",
+               .func = cmd_exit,
+               .help = "Quit and close the command line immediately.",
                .read_only = false
        },