]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add "runnable" to see if a command is runnable.
authorAlan T. DeKok <aland@freeradius.org>
Thu, 28 Jun 2018 12:29:37 +0000 (08:29 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 28 Jun 2018 12:55:00 +0000 (08:55 -0400)
So we can allow the admin to enter partial commands, and
have them be part of a context

src/include/command.h
src/main/command.c

index 7d009cb3b5c5e61143aba8b5fa8540225133491d..179207e11c74a29f546edaec941e4b78454d4be4 100644 (file)
@@ -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
 }
index b30951bdcbe66685803a49e2addc6f1cbab1b283..fcb2d90e5ff21458cf99d282490929ecc1329dc1 100644 (file)
@@ -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.