summaryrefslogtreecommitdiff
path: root/accel-pppd/cli
diff options
context:
space:
mode:
authorGuillaume Nault <g.nault@alphalink.fr>2013-02-08 14:27:11 +0100
committerKozlov Dmitry <xeb@mail.ru>2013-02-12 00:05:19 +0400
commit5f78642b1899c43249f3eec34bc4b60aa1b64afd (patch)
tree404c976cb5b2576873c1f366f7a5dcdbb348466d /accel-pppd/cli
parentcce2110e7ac9343372a65d82ec0791130a7580bf (diff)
downloadaccel-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.c133
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, &regexp_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, &regexp_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)