diff options
author | Kozlov Dmitry <dima@server> | 2010-11-10 12:53:48 +0300 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-11-10 12:53:48 +0300 |
commit | b6516bc491fcb7d9344f9cc720e20a5a20f94a32 (patch) | |
tree | f4ea34419b5cff7af67aacdd44279c0f89df516c /accel-pptpd/cli/cli.c | |
parent | e2754301d6ff0020c5ff349491ad814cbc70161c (diff) | |
download | accel-ppp-b6516bc491fcb7d9344f9cc720e20a5a20f94a32.tar.gz accel-ppp-b6516bc491fcb7d9344f9cc720e20a5a20f94a32.zip |
initial telnet cli support
Diffstat (limited to 'accel-pptpd/cli/cli.c')
-rw-r--r-- | accel-pptpd/cli/cli.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/accel-pptpd/cli/cli.c b/accel-pptpd/cli/cli.c new file mode 100644 index 00000000..92df1c38 --- /dev/null +++ b/accel-pptpd/cli/cli.c @@ -0,0 +1,151 @@ +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "triton.h" + +#include "telnet.h" +#include "cli.h" +#include "log.h" + +#define MAX_CMD_ITEMS 100 +#define MSG_SYNTAX_ERROR "syntax error\r\n" +#define MSG_UNKNOWN_CMD "command unknown\r\n" + +static LIST_HEAD(simple_cmd_list); +static LIST_HEAD(regexp_cmd_list); + +void __export cli_register_simple_cmd(struct cli_simple_cmd_t *cmd) +{ + list_add_tail(&cmd->entry, &simple_cmd_list); +} + +void __export cli_register_regexp_cmd(struct cli_regexp_cmd_t *cmd) +{ + int err; + cmd->re = pcre_compile2(cmd->pattern, cmd->options, &err, NULL, NULL, NULL); + if (!cmd->re) { + log_emerg("cli: failed to compile regexp %s: %i\n", cmd->pattern, err); + _exit(EXIT_FAILURE); + } + list_add_tail(&cmd->entry, &simple_cmd_list); +} + +int __export cli_send(void *client, const char *data) +{ + struct client_t *cln = (struct client_t *)client; + + return telnet_send(cln, data, strlen(data)); +} + + +static char *skip_word(char *ptr) +{ + for(; *ptr; ptr++) + if (*ptr == ' ' || *ptr == '\t' || *ptr == '\n') + break; + return ptr; +} +static char *skip_space(char *ptr) +{ + for(; *ptr; ptr++) + if (*ptr != ' ' && *ptr != '\t') + break; + return ptr; +} +static int split(char *buf, char **ptr) +{ + int i; + + ptr[0] = buf; + + for (i = 1; i <= MAX_CMD_ITEMS; i++) { + buf = skip_word(buf); + if (!*buf) + return i; + + *buf = 0; + + buf = skip_space(buf + 1); + if (!*buf) + return i; + + ptr[i] = buf; + } + + buf = skip_word(buf); + *buf = 0; + + return i; +} + +int process_cmd(struct 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; + + n = split((char *)cln->recv_buf, f); + + if (n >= 1 && !strcmp(f[0], "help")) { + list_for_each_entry(cmd1, &simple_cmd_list, entry) { + if (cmd1->help && cmd1->help(f, n, cln)) + return -1; + } + list_for_each_entry(cmd2, ®exp_cmd_list, entry) { + if (cmd2->help && cmd1->help(f, n, cln)) + return -1; + } + + return 0; + } + + 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->recv_buf, f, n, cln); + switch (r) { + case CLI_CMD_EXIT: + telnet_disconnect(cln); + case CLI_CMD_FAILED: + return -1; + case CLI_CMD_SYNTAX: + if (telnet_send(cln, MSG_SYNTAX_ERROR, sizeof(MSG_SYNTAX_ERROR))) + return -1; + return 0; + case CLI_CMD_OK: + found = 1; + } + } + } + + list_for_each_entry(cmd2, ®exp_cmd_list, entry) { + r = cmd2->exec((char *)cln->recv_buf, cln); + switch (r) { + case CLI_CMD_EXIT: + telnet_disconnect(cln); + case CLI_CMD_FAILED: + return -1; + case CLI_CMD_SYNTAX: + if (telnet_send(cln, MSG_SYNTAX_ERROR, sizeof(MSG_SYNTAX_ERROR))) + return -1; + return 0; + case CLI_CMD_OK: + found = 1; + } + } + + if (!found) { + if (telnet_send(cln, MSG_UNKNOWN_CMD, sizeof(MSG_UNKNOWN_CMD))) + return -1; + } + + return 0; +} + |