diff options
author | Guillaume Nault <g.nault@alphalink.fr> | 2013-02-08 14:27:11 +0100 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2013-02-12 00:05:19 +0400 |
commit | 5f78642b1899c43249f3eec34bc4b60aa1b64afd (patch) | |
tree | 404c976cb5b2576873c1f366f7a5dcdbb348466d /accel-pppd/cli | |
parent | cce2110e7ac9343372a65d82ec0791130a7580bf (diff) | |
download | accel-ppp-5f78642b1899c43249f3eec34bc4b60aa1b64afd.tar.gz accel-ppp-5f78642b1899c43249f3eec34bc4b60aa1b64afd.zip |
cli: Pass complete command line to regexp handlers
Split regexp and simple command handling from the generic command
processing function and handle regexp commands before simple ones.
This avoids splitting the original command line before processing
regexp command handlers, so that these handlers get the full command
line instead of only the first word.
The regexp command handlers are now only called when the command
matches the regexp (regexp handlers were called unconditionaly
before this patch). The rest of the processing properties should
remain unchanged.
Command processing summary:
-If the command starts with the "help" keyword, then all help
commands are called, starting with regexp help commands.
-Otherwise, regexp command handlers whose regexp matches the
command line are called. Then, simple command handlers whose
header matches the command line are called.
Any command handler that returns a value different from
CLI_CMD_OK stops the process, thus preventing the following
handlers from being called.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Diffstat (limited to 'accel-pppd/cli')
-rw-r--r-- | accel-pppd/cli/cli.c | 133 |
1 files changed, 80 insertions, 53 deletions
diff --git a/accel-pppd/cli/cli.c b/accel-pppd/cli/cli.c index 0a7ca3a..f6ab22d 100644 --- a/accel-pppd/cli/cli.c +++ b/accel-pppd/cli/cli.c @@ -167,68 +167,95 @@ static int cli_process_help_cmd(struct cli_client_t *cln) return 1; } +static int cli_process_regexp_cmd(struct cli_client_t *cln, int *err) +{ + struct cli_regexp_cmd_t *recmd = NULL; + char *cmd = (char *)cln->cmdline; + int found = 0; + int res; + + list_for_each_entry(recmd, ®exp_cmd_list, entry) + if (pcre_exec(recmd->re, NULL, cmd, strlen(cmd), + 0, 0, NULL, 0) >= 0) { + found = 1; + res = recmd->exec(cmd, cln); + if (res != CLI_CMD_OK) + break; + } + if (found) + *err = res; + + return found; +} + +static int cli_process_simple_cmd(struct cli_client_t *cln, int *err) +{ + struct cli_simple_cmd_t *sicmd = NULL; + char *cmd = (char *)cln->cmdline; + char *items[MAX_CMD_ITEMS] = { 0 }; + int found = 0; + int nb_items; + int indx; + int res; + + nb_items = split(cmd, items); + list_for_each_entry(sicmd, &simple_cmd_list, entry) { + if (sicmd->hdr_len <= 0 || nb_items < sicmd->hdr_len) + continue; + for (indx = 0; indx < sicmd->hdr_len; ++indx) { + if (strcmp(sicmd->hdr[indx], items[indx]) != 0) + break; + } + if (indx == sicmd->hdr_len) { + found = 1; + res = sicmd->exec(cmd, items, nb_items, cln); + if (res != CLI_CMD_OK) + break; + } + } + if (found) + *err = res; + + return found; +} + int __export cli_process_cmd(struct cli_client_t *cln) { - struct cli_simple_cmd_t *cmd1; - struct cli_regexp_cmd_t *cmd2; - char *f[MAX_CMD_ITEMS]; - int r, i, n, found = 0; + int found; + int err; if (cli_process_help_cmd(cln)) return 0; - n = split((char *)cln->cmdline, f); - - list_for_each_entry(cmd1, &simple_cmd_list, entry) { - if (cmd1->hdr_len && n >= cmd1->hdr_len) { - for (i = 0; i < cmd1->hdr_len; i++) { - if (strcmp(cmd1->hdr[i], f[i])) - break; - } - if (i < cmd1->hdr_len) - continue; - r = cmd1->exec((char *)cln->cmdline, f, n, cln); - switch (r) { - case CLI_CMD_EXIT: - cln->disconnect(cln); - case CLI_CMD_FAILED: - return -1; - case CLI_CMD_SYNTAX: - cli_send(cln, MSG_SYNTAX_ERROR); - return 0; - case CLI_CMD_INVAL: - cli_send(cln, MSG_INVAL_ERROR); - return 0; - case CLI_CMD_OK: - found = 1; - } - } - } + found = cli_process_regexp_cmd(cln, &err); + if (found && err != CLI_CMD_OK) + goto out_found; - list_for_each_entry(cmd2, ®exp_cmd_list, entry) { - r = cmd2->exec((char *)cln->cmdline, cln); - switch (r) { - case CLI_CMD_EXIT: - cln->disconnect(cln); - case CLI_CMD_FAILED: - return -1; - case CLI_CMD_SYNTAX: - cli_send(cln, MSG_SYNTAX_ERROR); - return 0; - case CLI_CMD_INVAL: - cli_send(cln, MSG_INVAL_ERROR); - return 0; - case CLI_CMD_OK: - found = 1; - } - } + found |= cli_process_simple_cmd(cln, &err); + if (found) + goto out_found; - if (!found) { - if (cli_send(cln, MSG_UNKNOWN_CMD)) - return -1; - } + if (cli_send(cln, MSG_UNKNOWN_CMD)) + return -1; + else + return 0; - return 0; +out_found: + switch (err) { + case CLI_CMD_EXIT: + cln->disconnect(cln); + case CLI_CMD_FAILED: + return -1; + case CLI_CMD_SYNTAX: + cli_send(cln, MSG_SYNTAX_ERROR); + return 0; + case CLI_CMD_INVAL: + cli_send(cln, MSG_INVAL_ERROR); + return 0; + case CLI_CMD_OK: + return 0; + } + return -1; } static void load_config(void) |