lib: add hook for preprocessing commands

This patch adds a hook point intended to allow subscribers to modify the
raw text of a CLI command before it is passed to the rest of the CLI
pipeline. To give access to the raw text of the command, a new function
for executing CLI has been defined whose only difference from
`cmd_execute_command` is that it accepts the command to execute as a
string rather than as a string vector.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2018-05-12 20:09:08 -04:00
parent fe011935cd
commit 01e24c4a69
2 changed files with 85 additions and 0 deletions

View File

@ -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

View File

@ -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 *,