diff options
Diffstat (limited to '')
-rw-r--r-- | lib/command.c | 63 | ||||
-rw-r--r-- | lib/command.h | 22 |
2 files changed, 85 insertions, 0 deletions
diff --git a/lib/command.c b/lib/command.c index 6aae4a074..97e60a592 100644 --- a/lib/command.c +++ b/lib/command.c @@ -44,6 +44,7 @@ #include "defaults.h" #include "libfrr.h" #include "jhash.h" +#include "hook.h" DEFINE_MTYPE(LIB, HOST, "Host config") DEFINE_MTYPE(LIB, COMPLETION, "Completion item") @@ -1140,6 +1141,68 @@ int cmd_execute_command_strict(vector vline, struct vty *vty, return cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd); } +/* + * Hook for preprocessing command string before executing. + * + * All subscribers are called with the raw command string that is to be + * executed. If any changes are to be made, a new string should be allocated + * with MTYPE_TMP and *cmd_out updated to point to this new string. The caller + * is then responsible for freeing this string. + * + * All processing functions must be mutually exclusive in their action, i.e. if + * one subscriber decides to modify the command, all others must not modify it + * when called. Feeding the output of one processing command into a subsequent + * one is not supported. + * + * This hook is intentionally internal to the command processing system. + * + * cmd_in + * The raw command string. + * + * cmd_out + * The result of any processing. + */ +DECLARE_HOOK(cmd_execute, + (struct vty * vty, const char *cmd_in, char **cmd_out), + (vty, cmd_in, cmd_out)); +DEFINE_HOOK(cmd_execute, (struct vty * vty, const char *cmd_in, char **cmd_out), + (vty, cmd_in, cmd_out)); + +/* Hook executed after a CLI command. */ +DECLARE_KOOH(cmd_execute_done, (struct vty * vty, const char *cmd_exec), + (vty, cmd_exec)); +DEFINE_KOOH(cmd_execute_done, (struct vty * vty, const char *cmd_exec), + (vty, cmd_exec)); + +int cmd_execute(struct vty *vty, const char *cmd, + const struct cmd_element **matched, int vtysh) +{ + int ret; + char *cmd_out = NULL; + const char *cmd_exec; + vector vline; + + hook_call(cmd_execute, vty, cmd, &cmd_out); + cmd_exec = cmd_out ? (const char *)cmd_out : cmd; + + vline = cmd_make_strvec(cmd_exec); + + if (vline) { + ret = cmd_execute_command(vline, vty, matched, vtysh); + cmd_free_strvec(vline); + } else { + ret = CMD_SUCCESS; + } + + hook_call(cmd_execute_done, vty, cmd_exec); + + if (cmd_out) + XFREE(MTYPE_TMP, cmd_out); + + return ret; +} + + /** * Parse one line of config, walking up the parse tree attempting to find a * match diff --git a/lib/command.h b/lib/command.h index 58cc58600..9bf482f41 100644 --- a/lib/command.h +++ b/lib/command.h @@ -416,6 +416,28 @@ extern int command_config_read_one_line(struct vty *vty, int use_config_node); extern int config_from_file(struct vty *, FILE *, unsigned int *line_num); extern enum node_type node_parent(enum node_type); +/* + * Execute command under the given vty context. + * + * vty + * The vty context to execute under. + * + * cmd + * The command string to execute. + * + * matched + * If non-null and a match was found, the address of the matched command is + * stored here. No action otherwise. + * + * vtysh + * Whether or not this is being called from vtysh. If this is nonzero, + * XXX: then what? + * + * Returns: + * XXX: what does it return + */ +extern int cmd_execute(struct vty *vty, const char *cmd, + const struct cmd_element **matched, int vtysh); extern int cmd_execute_command(vector, struct vty *, const struct cmd_element **, int); extern int cmd_execute_command_strict(vector, struct vty *, |