summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/command.c63
-rw-r--r--lib/command.h22
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 *,