From: Alan T. DeKok Date: Thu, 28 Jun 2018 12:29:37 +0000 (-0400) Subject: add "runnable" to see if a command is runnable. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a768f72e287b561b302f7746e39390ece402dc2d;p=thirdparty%2Ffreeradius-server.git add "runnable" to see if a command is runnable. So we can allow the admin to enter partial commands, and have them be part of a context --- diff --git a/src/include/command.h b/src/include/command.h index 7d009cb3b5c..179207e11c7 100644 --- a/src/include/command.h +++ b/src/include/command.h @@ -68,6 +68,7 @@ int fr_command_tab_expand(TALLOC_CTX *ctx, fr_cmd_t *head, int argc, char const char const *fr_command_help(fr_cmd_t *head, int argc, char const *argv[]); int fr_command_run(FILE *fp, fr_cmd_t *head, int argc, char const *argv[]); void fr_command_debug(FILE *fp, fr_cmd_t *head); +int fr_command_runnable(fr_cmd_t *head, int argc, char const *argv[]); #ifdef __cplusplus } diff --git a/src/main/command.c b/src/main/command.c index b30951bdcbe..fcb2d90e5ff 100644 --- a/src/main/command.c +++ b/src/main/command.c @@ -901,7 +901,7 @@ int fr_command_run(FILE *fp, fr_cmd_t *head, int argc, char const *argv[]) * @todo - allow varargs * @todo - return which argument was broken? */ - if ((i + cmd->syntax_argc) != argc) { + if (argc != (i + cmd->syntax_argc)) { fr_strerror_printf("Input has too many or too few parameters for command"); return -1; } @@ -942,6 +942,81 @@ int fr_command_run(FILE *fp, fr_cmd_t *head, int argc, char const *argv[]) return 0; } + +/** See if a particular command is runnable + * + * @param head the head of the command hierarchy. + * @param argc the number of arguments in the argv array + * @param argv the commands leading up to this one. + * @return + * - <0 on error, command doesn't exist + * - 0 the command is NOT runnable, it's a partial command + * - 1 the command IS runnable, and is a full command + */ +int fr_command_runnable(fr_cmd_t *head, int argc, char const *argv[]) +{ + int i; + fr_cmd_t *cmd, *start; + + start = head; + + /* + * Asked to do nothing, do nothing. + */ + if (argc == 0) return 0; + + for (i = 0; i < argc; i++) { + cmd = fr_command_find(&start, argv[i], NULL); + if (!cmd) { + if (argc == 1) { + fr_strerror_printf("No such command '%s'", argv[i]); + } else { + fr_strerror_printf("No such command '... %s'", argv[i]); + } + return -1; + } + + if (!cmd->syntax) { + if (cmd->func) { + rad_assert(cmd->func != NULL); + return 1; + } + + rad_assert(cmd->child != NULL); + start = cmd->child; + continue; + } + + /* + * Too many commands. That's an error. + * + * @todo - allow varargs + */ + if (argc > (i + cmd->syntax_argc)) { + fr_strerror_printf("Input has too many or too few parameters for command"); + return -1; + } + + /* + * Too few commands, it's OK, but not runnable. + */ + if (argc < (i + cmd->syntax_argc)) { + return 0; + } + + /* + * The right number of commands, it's runnable. + */ + return 1; + } + + /* + * Whatever it is, it's not runnable. + */ + return 0; +} + + /** Get help text for a particular command. * * @param head the head of the hierarchy.