summaryrefslogtreecommitdiff
path: root/accel-pptpd/cli/cli.c
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-11-10 12:53:48 +0300
committerKozlov Dmitry <dima@server>2010-11-10 12:53:48 +0300
commitb6516bc491fcb7d9344f9cc720e20a5a20f94a32 (patch)
treef4ea34419b5cff7af67aacdd44279c0f89df516c /accel-pptpd/cli/cli.c
parente2754301d6ff0020c5ff349491ad814cbc70161c (diff)
downloadaccel-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.c151
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, &regexp_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, &regexp_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;
+}
+