summaryrefslogtreecommitdiff
path: root/accel-pptpd/cli
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pptpd/cli')
-rw-r--r--accel-pptpd/cli/CMakeLists.txt1
-rw-r--r--accel-pptpd/cli/cli.c227
-rw-r--r--accel-pptpd/cli/cli.h48
-rw-r--r--accel-pptpd/cli/cli_p.h22
-rw-r--r--accel-pptpd/cli/show_sessions.c434
-rw-r--r--accel-pptpd/cli/std_cmd.c324
-rw-r--r--accel-pptpd/cli/tcp.c371
-rw-r--r--accel-pptpd/cli/telnet.c757
8 files changed, 0 insertions, 2184 deletions
diff --git a/accel-pptpd/cli/CMakeLists.txt b/accel-pptpd/cli/CMakeLists.txt
deleted file mode 100644
index 8b137891..00000000
--- a/accel-pptpd/cli/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/accel-pptpd/cli/cli.c b/accel-pptpd/cli/cli.c
deleted file mode 100644
index ef168ded..00000000
--- a/accel-pptpd/cli/cli.c
+++ /dev/null
@@ -1,227 +0,0 @@
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "triton.h"
-
-#include "cli.h"
-#include "cli_p.h"
-#include "log.h"
-#include "events.h"
-
-#include "memdebug.h"
-
-#define MAX_CMD_ITEMS 100
-#define MSG_SYNTAX_ERROR "syntax error\r\n"
-#define MSG_INVAL_ERROR "invalid argument\r\n"
-#define MSG_UNKNOWN_CMD "command unknown\r\n"
-
-char *conf_cli_passwd;
-static const char *def_cli_prompt = "accel-pptp";
-char *conf_cli_prompt;
-
-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_simple_cmd2(
- int (*exec)(const char *cmd, char * const *fields, int fields_cnt, void *client),
- void (*help)(char * const *fields, int fields_cnt, void *client),
- int hdr_len,
- ...
- )
-{
- struct cli_simple_cmd_t *c;
- int i;
- va_list ap;
-
- va_start(ap, hdr_len);
-
- c = malloc(sizeof(*c));
- memset(c, 0, sizeof(*c));
-
- c->exec = exec;
- c->help = help;
- c->hdr_len = hdr_len;
- c->hdr = malloc(hdr_len * sizeof(void*));
-
- for (i = 0; i < hdr_len; i++)
- c->hdr[i] = va_arg(ap, char *);
-
- list_add_tail(&c->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 cli_client_t *cln = (struct cli_client_t *)client;
-
- return cln->send(cln, data, strlen(data));
-}
-
-int __export cli_sendv(void *client, const char *fmt, ...)
-{
- struct cli_client_t *cln = (struct cli_client_t *)client;
- int r;
-
- va_list ap;
- va_start(ap, fmt);
- r = cln->sendv(cln, fmt, ap);
- va_end(ap);
-
- return r;
-}
-
-
-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 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;
-
- n = split((char *)cln->cmdline, 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);
-
- list_for_each_entry(cmd2, &regexp_cmd_list, entry)
- if (cmd2->help)
- cmd1->help(f, n, cln);
-
- 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->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;
- }
- }
- }
-
- 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 0;
- case CLI_CMD_SYNTAX:
- cli_send(cln, MSG_SYNTAX_ERROR);
- return 0;
- case CLI_CMD_OK:
- found = 1;
- }
- }
-
- if (!found) {
- if (cli_send(cln, MSG_UNKNOWN_CMD))
- return -1;
- }
-
- return 0;
-}
-
-static void load_config(void)
-{
- const char *opt;
-
- if (conf_cli_passwd)
- _free(conf_cli_passwd);
- opt = conf_get_opt("cli", "password");
- if (opt)
- conf_cli_passwd = _strdup(opt);
- else
- conf_cli_passwd = NULL;
-
- if (conf_cli_prompt && conf_cli_prompt != def_cli_prompt)
- _free(conf_cli_prompt);
- opt = conf_get_opt("cli", "prompt");
- if (opt)
- conf_cli_prompt = _strdup(opt);
- else
- conf_cli_prompt = (char *)def_cli_prompt;
-}
-
-static void __init init(void)
-{
- load_config();
-
- triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
-}
diff --git a/accel-pptpd/cli/cli.h b/accel-pptpd/cli/cli.h
deleted file mode 100644
index cdceb2fa..00000000
--- a/accel-pptpd/cli/cli.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef __CLI_H
-#define __CLI_H
-
-#include <pcre.h>
-#include <list.h>
-
-#define CLI_CMD_OK 0
-#define CLI_CMD_FAILED -1
-#define CLI_CMD_EXIT -2
-#define CLI_CMD_SYNTAX 1
-#define CLI_CMD_INVAL 2
-
-struct cli_simple_cmd_t
-{
- struct list_head entry;
- int hdr_len;
- const char **hdr;
- int (*exec)(const char *cmd, char * const *fields, int fields_cnt, void *client);
- void (*help)(char * const *fields, int field_cnt, void *client);
-};
-
-struct cli_regexp_cmd_t
-{
- struct list_head entry;
- pcre *re;
- const char *pattern;
- int options;
- int (*exec)(const char *cmd, void *client);
- int (*help)(char * const *fields, int field_cnt, void *client);
-};
-
-struct ppp_t;
-
-void cli_register_simple_cmd(struct cli_simple_cmd_t *cmd);
-void cli_register_simple_cmd2(
- int (*exec)(const char *cmd, char * const *fields, int fields_cnt, void *client),
- void (*help)(char * const *fields, int fields_cnt, void *client),
- int hdr_len,
- ...
- );
-void cli_register_regexp_cmd(struct cli_regexp_cmd_t *cmd);
-void cli_show_ses_register(const char *name, const char *desc, void (*print)(const struct ppp_t *ppp, char *buf));
-
-int cli_send(void *client, const char *data);
-int cli_sendv(void *client, const char *fmt, ...);
-
-#endif
-
diff --git a/accel-pptpd/cli/cli_p.h b/accel-pptpd/cli/cli_p.h
deleted file mode 100644
index 0fcba309..00000000
--- a/accel-pptpd/cli/cli_p.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __CLI_P_H
-#define __CLI_P_H
-
-#include <stdarg.h>
-
-#include "triton.h"
-
-struct cli_client_t
-{
- uint8_t *cmdline;
- int (*send)(struct cli_client_t *, const void *buf, int size);
- int (*sendv)(struct cli_client_t *, const char *fmt, va_list ap);
- void (*disconnect)(struct cli_client_t *);
-};
-
-int cli_process_cmd(struct cli_client_t *cln);
-
-extern char *conf_cli_passwd;
-extern char *conf_cli_prompt;
-
-#endif
-
diff --git a/accel-pptpd/cli/show_sessions.c b/accel-pptpd/cli/show_sessions.c
deleted file mode 100644
index 90aeb3fc..00000000
--- a/accel-pptpd/cli/show_sessions.c
+++ /dev/null
@@ -1,434 +0,0 @@
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-#include <arpa/inet.h>
-
-#include "triton.h"
-#include "events.h"
-#include "ppp.h"
-#include "cli.h"
-#include "utils.h"
-#include "log.h"
-#include "memdebug.h"
-
-#define CELL_SIZE 128
-#define DEF_COLUMNS "ifname,username,calling-sid,ip,rate-limit,type,state,uptime"
-
-struct column_t
-{
- struct list_head entry;
- const char *name;
- const char *desc;
- void (*print)(const struct ppp_t *ppp, char *buf);
-};
-
-struct col_t
-{
- struct list_head entry;
- struct column_t *column;
- int width;
-};
-
-struct row_t
-{
- struct list_head entry;
- char *match_key;
- char *order_key;
- struct list_head cell_list;
-};
-
-struct cell_t
-{
- struct list_head entry;
- struct col_t *col;
- char buf[CELL_SIZE + 1];
-};
-
-static LIST_HEAD(col_list);
-
-void __export cli_show_ses_register(const char *name, const char *desc, void (*print)(const struct ppp_t *ppp, char *buf))
-{
- struct column_t *c = malloc(sizeof(*c));
- c->name = name;
- c->desc = desc;
- c->print = print;
- list_add_tail(&c->entry, &col_list);
-}
-
-static void show_ses_help(char * const *f, int f_cnt, void *cli)
-{
- struct column_t *col;
- char buf[129];
-
- cli_send(cli, "show sessions [columns] [order <column>] [match <column> <regexp>] - shows sessions\r\n");
- cli_send(cli, "\tcolumns:\r\n");
-
- list_for_each_entry(col, &col_list, entry) {
- snprintf(buf, 128, "\t\t%s - %s\r\n", col->name, col->desc);
- cli_send(cli, buf);
- }
-}
-
-static struct column_t *find_column(const char *name)
-{
- struct column_t *col;
-
- list_for_each_entry(col, &col_list, entry) {
- if (strcmp(col->name, name))
- continue;
- return col;
- }
-
- return NULL;
-}
-
-static void free_row(struct row_t *row)
-{
- struct cell_t *cell;
-
- while (!list_empty(&row->cell_list)) {
- cell = list_entry(row->cell_list.next, typeof(*cell), entry);
- list_del(&cell->entry);
- _free(cell);
- }
-
- _free(row);
-}
-
-static void insert_row(struct list_head *list, struct row_t *row)
-{
- struct row_t *row2, *row3;
-
- row3 = NULL;
- list_for_each_entry(row2, list, entry) {
- if (strcmp(row->order_key, row2->order_key) <= 0) {
- row3 = row2;
- break;
- }
- }
- if (row3)
- list_add_tail(&row->entry, &row3->entry);
- else
- list_add_tail(&row->entry, list);
-}
-
-static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
-{
- char *columns = NULL;
- struct column_t *match_key = NULL;
- char *match_pattern = NULL;
- struct column_t *order_key = NULL;
- pcre *re = NULL;
- const char *pcre_err;
- int pcre_offset;
- struct column_t *column;
- struct col_t *col;
- struct row_t *row;
- struct cell_t *cell;
- char *ptr1, *ptr2;
- int i, n, total_width, def_columns = 0;
- struct ppp_t *ppp;
- char *buf = NULL;
- LIST_HEAD(c_list);
- LIST_HEAD(r_list);
- LIST_HEAD(t_list);
-
- for (i = 2; i < f_cnt; i++) {
- if (!strcmp(f[i], "order")) {
- if (i == f_cnt - 1)
- return CLI_CMD_SYNTAX;
- order_key = find_column(f[++i]);
- if (!order_key) {
- cli_sendv(cli, "unknown column %s\r\n", f[i]);
- return CLI_CMD_OK;
- }
- } else if (!strcmp(f[i], "match")) {
- if (i == f_cnt - 2)
- return CLI_CMD_SYNTAX;
- match_key = find_column(f[++i]);
- if (!match_key) {
- cli_sendv(cli, "unknown column %s\r\n", f[i]);
- return CLI_CMD_OK;
- }
- match_pattern = f[++i];
- } else if (!columns)
- columns = f[i];
- else
- return CLI_CMD_SYNTAX;
- }
-
- if (match_key) {
- re = pcre_compile2(match_pattern, 0, NULL, &pcre_err, &pcre_offset, NULL);
- if (!re) {
- cli_sendv(cli, "match: %s at %i\r\n", pcre_err, pcre_offset);
- return CLI_CMD_OK;
- }
- }
-
- if (!columns) {
- columns = DEF_COLUMNS;
- def_columns = 1;
- }
-
- columns = _strdup(columns);
- ptr1 = columns;
- while (1) {
- ptr2 = strchr(ptr1, ',');
- if (ptr2)
- *ptr2 = 0;
- column = find_column(ptr1);
- if (column) {
- col = _malloc(sizeof(*col));
- col->column = column;
- col->width = strlen(column->name);
- list_add_tail(&col->entry, &c_list);
- } else {
- if (!def_columns) {
- cli_sendv(cli, "unknown column %s\r\n", ptr1);
- _free(columns);
- goto out;
- }
- }
- if (!ptr2)
- break;
- ptr1 = ptr2 + 1;
- }
- _free(columns);
-
- pthread_rwlock_rdlock(&ppp_lock);
- list_for_each_entry(ppp, &ppp_list, entry) {
- row = _malloc(sizeof(*row));
- if (!row)
- goto oom;
- memset(row, 0, sizeof(*row));
- INIT_LIST_HEAD(&row->cell_list);
- if (match_key || order_key)
- list_add_tail(&row->entry, &t_list);
- else
- list_add_tail(&row->entry, &r_list);
- list_for_each_entry(col, &c_list, entry) {
- cell = _malloc(sizeof(*cell));
- if (!cell)
- goto oom;
- cell->col = col;
- list_add_tail(&cell->entry, &row->cell_list);
- col->column->print(ppp, cell->buf);
- n = strlen(cell->buf);
- if (n > col->width)
- col->width = n;
- if (col->column == order_key)
- row->order_key = cell->buf;
- if (col->column == match_key)
- row->match_key = cell->buf;
- }
- }
- pthread_rwlock_unlock(&ppp_lock);
-
- if (order_key || match_key) {
- while(!list_empty(&t_list)) {
- row = list_entry(t_list.next, typeof(*row), entry);
- list_del(&row->entry);
- if (match_key) {
- if (pcre_exec(re, NULL, row->match_key, strlen(row->match_key), 0, 0, NULL, 0) < 0) {
- free_row(row);
- continue;
- }
- }
- if (order_key)
- insert_row(&r_list, row);
- else
- list_add_tail(&row->entry, &r_list);
- }
- }
-
- total_width = -1;
- list_for_each_entry(col, &c_list, entry)
- total_width += col->width + 3;
-
- buf = _malloc(total_width + 3);
- if (!buf)
- goto oom;
-
- ptr1 = buf;
- list_for_each_entry(col, &c_list, entry) {
- n = strlen(col->column->name);
- if (col->width > n + 1) {
- ptr2 = ptr1;
- memset(ptr1, ' ', col->width/2 - n/2 + 1);
- ptr1 += col->width/2 - n/2 + 1;
- sprintf(ptr1, "%s", col->column->name);
- ptr1 = strchr(ptr1, 0);
- memset(ptr1, ' ', col->width + 2 - (ptr1 - ptr2));
- ptr1 += col->width + 2 - (ptr1 - ptr2);
- *ptr1 = '|';
- ptr1++;
- } else if (col->width > n) {
- sprintf(ptr1, " %s |", col->column->name);
- ptr1 = strchr(ptr1, 0);
- } else {
- sprintf(ptr1, " %s |", col->column->name);
- ptr1 = strchr(ptr1, 0);
- }
- }
-
- strcpy(ptr1 - 1, "\r\n");
- cli_send(cli, buf);
-
- ptr1 = buf;
- list_for_each_entry(col, &c_list, entry) {
- memset(ptr1, '-', col->width + 2);
- ptr1 += col->width + 2;
- *ptr1 = '+';
- ptr1++;
- }
-
- strcpy(ptr1 - 1, "\r\n");
- cli_send(cli, buf);
-
- while (!list_empty(&r_list)) {
- row = list_entry(r_list.next, typeof(*row), entry);
- ptr1 = buf;
- list_for_each_entry(cell, &row->cell_list, entry) {
- ptr2 = ptr1;
- sprintf(ptr1, " %s ", cell->buf);
- ptr1 = strchr(ptr1, 0);
- n = ptr1 - ptr2;
- if (n - 2 < cell->col->width) {
- memset(ptr1, ' ', cell->col->width + 2 - (ptr1 - ptr2));
- ptr1 += cell->col->width + 2 - (ptr1 - ptr2);
- }
- *ptr1 = '|';
- ptr1++;
- }
- strcpy(ptr1 - 1, "\r\n");
- cli_send(cli, buf);
- list_del(&row->entry);
- free_row(row);
- }
-
- _free(buf);
-
-out:
- while (!list_empty(&c_list)) {
- col = list_entry(c_list.next, typeof(*col), entry);
- list_del(&col->entry);
- _free(col);
- }
-
- if (re)
- pcre_free(re);
-
- return CLI_CMD_OK;
-
-oom:
- if (buf)
- _free(buf);
-
- while (!list_empty(&t_list)) {
- row = list_entry(t_list.next, typeof(*row), entry);
- list_del(&row->entry);
- free_row(row);
- }
- cli_send(cli, "out of memory");
- goto out;
-}
-
-static void print_ifname(const struct ppp_t *ppp, char *buf)
-{
- snprintf(buf, CELL_SIZE, "%s", ppp->ifname);
-}
-
-static void print_username(const struct ppp_t *ppp, char *buf)
-{
- if (ppp->username)
- snprintf(buf, CELL_SIZE, "%s", ppp->username);
-}
-
-static void print_ip(const struct ppp_t *ppp, char *buf)
-{
- char str[17];
- u_inet_ntoa(ppp->peer_ipaddr, str);
- sprintf(buf, "%s", str);
-}
-
-static void print_type(const struct ppp_t *ppp, char *buf)
-{
- snprintf(buf, CELL_SIZE, "%s", ppp->ctrl->name);
-}
-
-static void print_state(const struct ppp_t *ppp, char *buf)
-{
- char *state;
- switch (ppp->state) {
- case PPP_STATE_STARTING:
- state = "start";
- break;
- case PPP_STATE_ACTIVE:
- state = "active";
- break;
- case PPP_STATE_FINISHING:
- state = "finish";
- break;
- default:
- state = "unk";
- }
- sprintf(buf, "%s", state);
-}
-
-static void print_uptime(const struct ppp_t *ppp, char *buf)
-{
- time_t uptime;
- int day,hour,min,sec;
- char time_str[14];
-
- if (ppp->stop_time)
- uptime = ppp->stop_time - ppp->start_time;
- else {
- time(&uptime);
- uptime -= ppp->start_time;
- }
-
- day = uptime/ (24*60*60); uptime %= (24*60*60);
- hour = uptime / (60*60); uptime %= (60*60);
- min = uptime / 60;
- sec = uptime % 60;
- if (day)
- snprintf(time_str, 13, "%i.%02i:%02i:%02i", day, hour, min, sec);
- else
- snprintf(time_str, 13, "%02i:%02i:%02i", hour, min, sec);
-
- sprintf(buf, "%s", time_str);
-}
-
-static void print_calling_sid(const struct ppp_t *ppp, char *buf)
-{
- snprintf(buf, CELL_SIZE, "%s", ppp->ctrl->calling_station_id);
-}
-
-static void print_called_sid(const struct ppp_t *ppp, char *buf)
-{
- snprintf(buf, CELL_SIZE, "%s", ppp->ctrl->called_station_id);
-}
-
-static void print_sid(const struct ppp_t *ppp, char *buf)
-{
- snprintf(buf, CELL_SIZE, "%s", ppp->sessionid);
-}
-
-void __init init(void)
-{
- cli_register_simple_cmd2(show_ses_exec, show_ses_help, 2, "show", "sessions");
-
- cli_show_ses_register("ifname", "interface name", print_ifname);
- cli_show_ses_register("username", "user name", print_username);
- cli_show_ses_register("ip", "IP address", print_ip);
- cli_show_ses_register("type", "VPN type", print_type);
- cli_show_ses_register("state", "state of session", print_state);
- cli_show_ses_register("uptime", "uptime", print_uptime);
- cli_show_ses_register("calling-sid", "calling station id", print_calling_sid);
- cli_show_ses_register("called-sid", "called station id", print_called_sid);
- cli_show_ses_register("sid", "session id", print_sid);
-}
-
diff --git a/accel-pptpd/cli/std_cmd.c b/accel-pptpd/cli/std_cmd.c
deleted file mode 100644
index a49bbce6..00000000
--- a/accel-pptpd/cli/std_cmd.c
+++ /dev/null
@@ -1,324 +0,0 @@
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-#include <arpa/inet.h>
-
-#include "triton.h"
-#include "events.h"
-#include "ppp.h"
-#include "cli.h"
-#include "utils.h"
-#include "log.h"
-#include "memdebug.h"
-
-static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
-{
- time_t dt;
- int day,hour;
- char statm_fname[128];
- FILE *f;
- unsigned long vmsize = 0, vmrss = 0;
- unsigned long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024;
-
- sprintf(statm_fname, "/proc/%i/statm", getpid());
- f = fopen(statm_fname, "r");
- if (f) {
- fscanf(f, "%lu %lu", &vmsize, &vmrss);
- fclose(f);
- }
-
- time(&dt);
- dt -= triton_stat.start_time;
- day = dt / (60 * 60 * 24);
- dt %= 60 * 60 * 24;
- hour = dt / (60 * 60);
- dt %= 60 * 60;
-
- cli_sendv(client, "uptime: %i.%02i:%02i:%02i\r\n", day, hour, dt / 60, dt % 60);
- cli_sendv(client, "cpu: %i%%\r\n", triton_stat.cpu);
- cli_sendv(client, "mem(rss/virt): %lu/%lu kB\r\n", vmrss * page_size_kb, vmsize * page_size_kb);
- cli_send(client, "core:\r\n");
- cli_sendv(client, " mempool_allocated: %u\r\n", triton_stat.mempool_allocated);
- cli_sendv(client, " mempool_available: %u\r\n", triton_stat.mempool_available);
- cli_sendv(client, " thread_count: %u\r\n", triton_stat.thread_count);
- cli_sendv(client, " thread_active: %u\r\n", triton_stat.thread_active);
- cli_sendv(client, " context_count: %u\r\n", triton_stat.context_count);
- cli_sendv(client, " context_sleeping: %u\r\n", triton_stat.context_sleeping);
- cli_sendv(client, " context_pending: %u\r\n", triton_stat.context_pending);
- cli_sendv(client, " md_handler_count: %u\r\n", triton_stat.md_handler_count);
- cli_sendv(client, " md_handler_pending: %u\r\n", triton_stat.md_handler_pending);
- cli_sendv(client, " timer_count: %u\r\n", triton_stat.timer_count);
- cli_sendv(client, " timer_pending: %u\r\n", triton_stat.timer_pending);
-
-//===========
- cli_send(client, "ppp:\r\n");
- cli_sendv(client, " staring: %u\r\n", ppp_stat.starting);
- cli_sendv(client, " active: %u\r\n", ppp_stat.active);
- cli_sendv(client, " finishing: %u\r\n", ppp_stat.finishing);
-
- return CLI_CMD_OK;
-}
-
-static void show_stat_help(char * const *fields, int fields_cnt, void *client)
-{
- cli_send(client, "show stat - shows various statistics information\r\n");
-}
-//=============================
-
-static int exit_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
-{
- return CLI_CMD_EXIT;
-}
-
-static void exit_help(char * const *fields, int fields_cnt, void *client)
-{
- cli_send(client, "exit - exit cli\r\n");
-}
-
-//=============================
-
-static void ppp_terminate_soft(struct ppp_t *ppp)
-{
- ppp_terminate(ppp, TERM_NAS_REQUEST, 0);
-}
-
-static void ppp_terminate_hard(struct ppp_t *ppp)
-{
- ppp_terminate(ppp, TERM_NAS_REQUEST, 1);
-}
-
-static int terminate_exec1(char * const *f, int f_cnt, void *cli)
-{
- struct ppp_t *ppp;
- int hard = 0;
- pcre *re;
- const char *pcre_err;
- int pcre_offset;
-
- if (f_cnt == 5) {
- if (!strcmp(f[4], "hard"))
- hard = 1;
- else if (strcmp(f[4], "soft"))
- return CLI_CMD_SYNTAX;
- } else if (f_cnt != 4)
- return CLI_CMD_SYNTAX;
-
- re = pcre_compile2(f[3], 0, NULL, &pcre_err, &pcre_offset, NULL);
- if (!re) {
- cli_sendv(cli, "match: %s at %i\r\n", pcre_err, pcre_offset);
- return CLI_CMD_OK;
- }
-
- pthread_rwlock_rdlock(&ppp_lock);
- list_for_each_entry(ppp, &ppp_list, entry) {
- if (pcre_exec(re, NULL, ppp->username, strlen(ppp->username), 0, 0, NULL, 0) < 0)
- continue;
- if (hard)
- triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard, ppp);
- else
- triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft, ppp);
- }
- pthread_rwlock_unlock(&ppp_lock);
-
- pcre_free(re);
-
- return CLI_CMD_OK;
-}
-
-static int terminate_exec2(int key, char * const *f, int f_cnt, void *cli)
-{
- struct ppp_t *ppp;
- int hard = 0;
- in_addr_t ipaddr = 0;
-
- if (f_cnt == 4) {
- if (!strcmp(f[3], "hard"))
- hard = 1;
- else if (strcmp(f[3], "soft"))
- return CLI_CMD_SYNTAX;
- } else if (f_cnt != 3)
- return CLI_CMD_SYNTAX;
-
- if (key == 1)
- ipaddr = inet_addr(f[2]);
-
- pthread_rwlock_rdlock(&ppp_lock);
- list_for_each_entry(ppp, &ppp_list, entry) {
- switch (key) {
- case 0:
- if (strcmp(ppp->username, f[2]))
- continue;
- break;
- case 1:
- if (ppp->peer_ipaddr != ipaddr)
- continue;
- break;
- case 2:
- if (strcmp(ppp->ctrl->calling_station_id, f[2]))
- continue;
- break;
- case 3:
- if (strcmp(ppp->sessionid, f[2]))
- continue;
- break;
- case 4:
- if (strcmp(ppp->ifname, f[2]))
- continue;
- break;
- }
- if (hard)
- triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard, ppp);
- else
- triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft, ppp);
- break;
- }
- pthread_rwlock_unlock(&ppp_lock);
-
- return CLI_CMD_OK;
-}
-
-static int terminate_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
-{
- struct ppp_t *ppp;
- int hard = 0;
-
- if (fields_cnt == 1)
- return CLI_CMD_SYNTAX;
-
- if (!strcmp(fields[1], "match") && fields_cnt > 3 && !strcmp(fields[2], "username"))
- return terminate_exec1(fields, fields_cnt, client);
- else if (!strcmp(fields[1], "username"))
- return terminate_exec2(0, fields, fields_cnt, client);
- else if (!strcmp(fields[1], "ip"))
- return terminate_exec2(1, fields, fields_cnt, client);
- else if (!strcmp(fields[1], "csid"))
- return terminate_exec2(2, fields, fields_cnt, client);
- else if (!strcmp(fields[1], "sid"))
- return terminate_exec2(3, fields, fields_cnt, client);
- else if (!strcmp(fields[1], "if"))
- return terminate_exec2(4, fields, fields_cnt, client);
- else if (strcmp(fields[1], "all"))
- return CLI_CMD_SYNTAX;
-
- if (fields_cnt == 3) {
- if (!strcmp(fields[2], "hard"))
- hard = 1;
- else if (strcmp(fields[2], "soft"))
- return CLI_CMD_SYNTAX;
- } else if (fields_cnt != 2)
- return CLI_CMD_SYNTAX;
-
- pthread_rwlock_rdlock(&ppp_lock);
- list_for_each_entry(ppp, &ppp_list, entry) {
- if (hard)
- triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard, ppp);
- else
- triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft, ppp);
- }
- pthread_rwlock_unlock(&ppp_lock);
-
- return CLI_CMD_OK;
-}
-
-static void terminate_help(char * const *fields, int fields_cnt, void *client)
-{
- cli_send(client, "terminate if <interface> [soft|hard]- terminate session by interface name\r\n");
- cli_send(client, "\t[match] username <username> [soft|hard]- terminate session by username\r\n");
- cli_send(client, "\tip <addresss> [soft|hard]- terminate session by ip address\r\n");
- cli_send(client, "\tcsid <id> [soft|hard]- terminate session by calling station id\r\n");
- cli_send(client, "\tsid <id> [soft|hard]- terminate session by session id\r\n");
- cli_send(client, "\tall [soft|hard]- terminate all sessions\r\n");
-}
-
-//=============================
-
-static void shutdown_help(char * const *fields, int fields_cnt, void *client)
-{
- cli_send(client, "shutdown [soft|hard|cancel]- shutdown daemon\r\n");
- cli_send(client, "\t\tdefault action - send termination signals to all clients and wait everybody disconnects\r\n");
- cli_send(client, "\t\tsoft - wait until all clients disconnects, don't accept new connections\r\n");
- cli_send(client, "\t\thard - shutdown now, don't wait anything\r\n");
- cli_send(client, "\t\tcancel - cancel 'shutdown soft' and return to normal operation\r\n");
-}
-
-static void ppp_terminate_soft2(struct ppp_t *ppp)
-{
- ppp_terminate(ppp, TERM_NAS_REBOOT, 0);
-}
-
-static void ppp_terminate_hard2(struct ppp_t *ppp)
-{
- ppp_terminate(ppp, TERM_NAS_REBOOT, 1);
-}
-
-static int shutdown_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
-{
- int hard = 0;
- struct ppp_t *ppp;
-
- if (f_cnt == 2) {
- if (!strcmp(f[1], "soft")) {
- ppp_shutdown_soft();
- return CLI_CMD_OK;
- } else if (!strcmp(f[1], "hard"))
- hard = 1;
- else if (!strcmp(f[1], "cancel")) {
- ppp_shutdown = 0;
- return CLI_CMD_OK;
- } else
- return CLI_CMD_SYNTAX;
- }
-
- ppp_shutdown_soft();
-
- pthread_rwlock_rdlock(&ppp_lock);
- list_for_each_entry(ppp, &ppp_list, entry) {
- if (hard)
- triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard2, ppp);
- else
- triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft2, ppp);
- }
- pthread_rwlock_unlock(&ppp_lock);
-
- return CLI_CMD_OK;
-}
-
-//==========================
-static int conf_reload_res;
-static struct triton_context_t *conf_reload_ctx;
-static void conf_reload_notify(int r)
-{
- if (!r)
- triton_event_fire(EV_CONFIG_RELOAD, NULL);
- conf_reload_res = r;
- triton_context_wakeup(conf_reload_ctx);
-}
-static int reload_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
-{
- if (f_cnt == 1) {
- conf_reload_ctx = triton_context_self();
- triton_conf_reload(conf_reload_notify);
- triton_context_schedule();
- if (conf_reload_res)
- cli_send(cli, "failed\r\n");
- return CLI_CMD_OK;
- } else
- return CLI_CMD_SYNTAX;
-}
-
-static void reload_help(char * const *fields, int fields_cnt, void *client)
-{
- cli_send(client, "reload - reload config file\r\n");
-}
-
-static void __init init(void)
-{
- cli_register_simple_cmd2(show_stat_exec, show_stat_help, 2, "show", "stat");
- cli_register_simple_cmd2(terminate_exec, terminate_help, 1, "terminate");
- cli_register_simple_cmd2(reload_exec, reload_help, 1, "reload");
- cli_register_simple_cmd2(shutdown_exec, shutdown_help, 1, "shutdown");
- cli_register_simple_cmd2(exit_exec, exit_help, 1, "exit");
-}
-
diff --git a/accel-pptpd/cli/tcp.c b/accel-pptpd/cli/tcp.c
deleted file mode 100644
index 260225f1..00000000
--- a/accel-pptpd/cli/tcp.c
+++ /dev/null
@@ -1,371 +0,0 @@
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <time.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-#include "triton.h"
-#include "log.h"
-#include "list.h"
-#include "memdebug.h"
-
-#include "cli_p.h"
-
-#define RECV_BUF_SIZE 1024
-
-struct tcp_client_t
-{
- struct cli_client_t cli_client;
- struct list_head entry;
- struct triton_md_handler_t hnd;
- struct list_head xmit_queue;
- struct buffer_t *xmit_buf;
- uint8_t *cmdline;
- int xmit_pos;
- int recv_pos;
- int auth:1;
- int disconnect:1;
-};
-
-struct buffer_t
-{
- struct list_head entry;
- int size;
- uint8_t buf[0];
-};
-
-static struct triton_context_t serv_ctx;
-static struct triton_md_handler_t serv_hnd;
-static LIST_HEAD(clients);
-
-static uint8_t *temp_buf;
-
-static void disconnect(struct tcp_client_t *cln)
-{
- struct buffer_t *b;
-
- log_debug("cli: disconnect\n");
-
- list_del(&cln->entry);
-
- triton_md_unregister_handler(&cln->hnd);
- close(cln->hnd.fd);
-
- if (cln->xmit_buf)
- _free(cln->xmit_buf);
-
- while (!list_empty(&cln->xmit_queue)) {
- b = list_entry(cln->xmit_queue.next, typeof(*b), entry);
- list_del(&b->entry);
- _free(b);
- }
-
- _free(cln->cmdline);
- _free(cln);
-}
-
-static void cli_client_disconnect(struct cli_client_t *tcln)
-{
- struct tcp_client_t *cln = container_of(tcln, typeof(*cln), cli_client);
- cln->disconnect = 1;
-}
-
-static void queue_buffer(struct tcp_client_t *cln, struct buffer_t *b)
-{
- if (cln->xmit_buf)
- list_add_tail(&b->entry, &cln->xmit_queue);
- else
- cln->xmit_buf = b;
-}
-
-static int cli_client_send(struct cli_client_t *tcln, const void *_buf, int size)
-{
- struct tcp_client_t *cln = container_of(tcln, typeof(*cln), cli_client);
- int n, k;
- struct buffer_t *b;
- const uint8_t *buf = (const uint8_t *)_buf;
-
- if (cln->disconnect)
- return -1;
-
- if (!list_empty(&cln->xmit_queue)) {
- b = _malloc(sizeof(*b) + size);
- b->size = size;
- memcpy(b->buf, buf, size);
- queue_buffer(cln, b);
- return 0;
- }
-
- for (n = 0; n < size; n += k) {
- k = write(cln->hnd.fd, buf + n, size - n);
- if (k < 0) {
- if (errno == EAGAIN) {
- b = _malloc(sizeof(*b) + size - n);
- b->size = size - n;
- memcpy(b->buf, buf, size - n);
- queue_buffer(cln, b);
-
- triton_md_enable_handler(&cln->hnd, MD_MODE_WRITE);
- break;
- }
- if (errno != EPIPE)
- log_error("cli: write: %s\n", strerror(errno));
- //disconnect(cln);
- cln->disconnect = 1;
- return -1;
- }
- }
- return 0;
-}
-
-static int cli_client_sendv(struct cli_client_t *tcln, const char *fmt, va_list ap)
-{
- struct tcp_client_t *cln = container_of(tcln, typeof(*cln), cli_client);
- int r = vsnprintf((char *)temp_buf, RECV_BUF_SIZE, fmt, ap);
-
- if (r >= RECV_BUF_SIZE) {
- strcpy((char *)temp_buf + RECV_BUF_SIZE - 5, "...\n");
- r = RECV_BUF_SIZE;
- }
-
- return cli_client_send(tcln, temp_buf, r);
-}
-
-static int cln_read(struct triton_md_handler_t *h)
-{
- struct tcp_client_t *cln = container_of(h, typeof(*cln), hnd);
- int n;
- char *d;
-
- while (1) {
- n = read(h->fd, cln->cmdline + cln->recv_pos, RECV_BUF_SIZE - cln->recv_pos);
- if (n == 0)
- break;
- if (n < 0) {
- if (errno != EAGAIN)
- log_error("cli: read: %s\n", strerror(errno));
- return 0;
- }
-
- cln->recv_pos += n;
-
- while (cln->recv_pos) {
- d = strchr((char *)cln->cmdline, '\n');
- if (!d) {
- if (cln->recv_pos == RECV_BUF_SIZE) {
- log_warn("cli: tcp: recv buffer overflow\n");
- goto drop;
- }
- break;
- }
-
- *d = 0;
-
- if (!cln->auth) {
- if (strcmp((char *)cln->cmdline, conf_cli_passwd))
- goto drop;
- cln->auth = 1;
- } else
- cli_process_cmd(&cln->cli_client);
-
- if (cln->disconnect)
- goto drop;
-
- cln->recv_pos -= (uint8_t *)d + 1 - cln->cmdline;
- memmove(cln->cmdline, d + 1, cln->recv_pos);
- }
- }
-
-drop:
- disconnect(cln);
- return -1;
-}
-
-static int cln_write(struct triton_md_handler_t *h)
-{
- struct tcp_client_t *cln = container_of(h, typeof(*cln), hnd);
- int k;
-
- while (1) {
- for (; cln->xmit_pos < cln->xmit_buf->size; cln->xmit_pos += k) {
- k = write(cln->hnd.fd, cln->xmit_buf->buf + cln->xmit_pos, cln->xmit_buf->size - cln->xmit_pos);
- if (k < 0) {
- if (errno == EAGAIN)
- return 0;
- if (errno != EPIPE)
- log_error("cli: tcp: write: %s\n", strerror(errno));
- disconnect(cln);
- return -1;
- }
- }
-
- _free(cln->xmit_buf);
- cln->xmit_pos = 0;
-
- if (list_empty(&cln->xmit_queue))
- break;
-
- cln->xmit_buf = list_entry(cln->xmit_queue.next, typeof(*cln->xmit_buf), entry);
- list_del(&cln->xmit_buf->entry);
- }
-
- triton_md_disable_handler(&cln->hnd, MD_MODE_WRITE);
-
- return 0;
-}
-
-static int serv_read(struct triton_md_handler_t *h)
-{
- struct sockaddr_in addr;
- socklen_t size = sizeof(addr);
- int sock;
- struct tcp_client_t *conn;
-
- while(1) {
- sock = accept(h->fd, (struct sockaddr *)&addr, &size);
- if (sock < 0) {
- if (errno == EAGAIN)
- return 0;
- log_error("cli: tcp: accept failed: %s\n", strerror(errno));
- continue;
- }
-
- log_info2("cli: tcp: new connection from %s\n", inet_ntoa(addr.sin_addr));
-
- if (fcntl(sock, F_SETFL, O_NONBLOCK)) {
- log_error("cli: tcp: failed to set nonblocking mode: %s, closing connection...\n", strerror(errno));
- close(sock);
- continue;
- }
-
- conn = _malloc(sizeof(*conn));
- memset(conn, 0, sizeof(*conn));
- conn->hnd.fd = sock;
- conn->hnd.read = cln_read;
- conn->hnd.write = cln_write;
- conn->cmdline = _malloc(RECV_BUF_SIZE);
- INIT_LIST_HEAD(&conn->xmit_queue);
-
- conn->cli_client.cmdline = conn->cmdline;
- conn->cli_client.send = cli_client_send;
- conn->cli_client.sendv = cli_client_sendv;
- conn->cli_client.disconnect = cli_client_disconnect;
-
- triton_md_register_handler(&serv_ctx, &conn->hnd);
- triton_md_enable_handler(&conn->hnd,MD_MODE_READ);
-
- list_add_tail(&conn->entry, &clients);
-
- if (!conf_cli_passwd)
- conn->auth = 1;
- }
- return 0;
-}
-
-static void serv_close(struct triton_context_t *ctx)
-{
- struct tcp_client_t *cln;
-
- while (!list_empty(&clients)) {
- cln = list_entry(clients.next, typeof(*cln), entry);
- disconnect(cln);
- }
-
- triton_md_unregister_handler(&serv_hnd);
- close(serv_hnd.fd);
- triton_context_unregister(ctx);
-}
-
-static struct triton_context_t serv_ctx = {
- .close = serv_close,
- .before_switch = log_switch,
-};
-
-static struct triton_md_handler_t serv_hnd = {
- .read = serv_read,
-};
-
-static void start_server(const char *host, int port)
-{
- struct sockaddr_in addr;
-
- serv_hnd.fd = socket(PF_INET, SOCK_STREAM, 0);
- if (serv_hnd.fd < 0) {
- log_emerg("cli: tcp: failed to create server socket: %s\n", strerror(errno));
- return;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- if (host)
- addr.sin_addr.s_addr = inet_addr(host);
- else
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
-
- setsockopt(serv_hnd.fd, SOL_SOCKET, SO_REUSEADDR, &serv_hnd.fd, 4);
- if (bind (serv_hnd.fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
- log_emerg("cli: tcp: failed to bind socket: %s\n", strerror(errno));
- close(serv_hnd.fd);
- return;
- }
-
- if (listen (serv_hnd.fd, 1) < 0) {
- log_emerg("cli: tcp: failed to listen socket: %s\n", strerror(errno));
- close(serv_hnd.fd);
- return;
- }
-
- if (fcntl(serv_hnd.fd, F_SETFL, O_NONBLOCK)) {
- log_emerg("cli: tcp: failed to set nonblocking mode: %s\n", strerror(errno));
- close(serv_hnd.fd);
- return;
- }
-
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = inet_addr(host);
-
- triton_context_register(&serv_ctx, NULL);
- triton_context_set_priority(&serv_ctx, 1);
- triton_md_register_handler(&serv_ctx, &serv_hnd);
- triton_md_enable_handler(&serv_hnd, MD_MODE_READ);
- triton_context_wakeup(&serv_ctx);
-}
-
-static void __init init(void)
-{
- const char *opt;
- char *host, *d;
- int port;
-
- opt = conf_get_opt("cli", "tcp");
- if (!opt)
- return;
-
- host = strdup(opt);
- d = strstr(host, ":");
- if (!d)
- goto err_fmt;
-
- *d = 0;
- port = atoi(d + 1);
- if (port <= 0)
- goto err_fmt;
-
- temp_buf = malloc(RECV_BUF_SIZE);
-
- start_server(host, port);
-
- return;
-err_fmt:
- log_emerg("cli: tcp: invalid format\n");
- free(host);
-}
-
diff --git a/accel-pptpd/cli/telnet.c b/accel-pptpd/cli/telnet.c
deleted file mode 100644
index 0ea19fb1..00000000
--- a/accel-pptpd/cli/telnet.c
+++ /dev/null
@@ -1,757 +0,0 @@
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <time.h>
-#include <ctype.h>
-#include <arpa/inet.h>
-#include <arpa/telnet.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "triton.h"
-#include "log.h"
-#include "ppp.h"
-#include "list.h"
-#include "memdebug.h"
-
-#include "cli_p.h"
-
-#define RECV_BUF_SIZE 1024
-
-#define MSG_AUTH_FAILED "\r\nAuthentication failed\r\n"
-#define MSG_SHUTDOWN_IN_PROGRESS "note: 'shutdown soft' is in progress...\r\n"
-
-#define ESC_LEFT "[D"
-#define ESC_RIGHT "[C"
-#define ESC_UP "[A"
-#define ESC_DOWN "[B"
-
-struct telnet_client_t
-{
- struct cli_client_t cli_client;
- struct list_head entry;
- struct triton_md_handler_t hnd;
- struct list_head xmit_queue;
- struct buffer_t *xmit_buf;
- int xmit_pos;
- struct list_head history;
- struct list_head *history_pos;
- uint8_t *cmdline;
- int cmdline_pos;
- int cmdline_pos2;
- int cmdline_len;
- int auth:1;
- int echo:1;
- int telcmd:1;
- int esc:1;
- int disconnect:1;
-};
-
-struct buffer_t
-{
- struct list_head entry;
- int size;
- struct buffer_t *p_buf;
- uint8_t buf[0];
-};
-
-static struct triton_context_t serv_ctx;
-static struct triton_md_handler_t serv_hnd;
-static LIST_HEAD(clients);
-
-static uint8_t *recv_buf;
-static uint8_t *temp_buf;
-
-static int conf_history_len = 100;
-static const char *conf_history_file = "/var/run/accel-pptp/history";
-static LIST_HEAD(history);
-static int history_len;
-static pthread_mutex_t history_lock = PTHREAD_MUTEX_INITIALIZER;
-
-static void disconnect(struct telnet_client_t *cln)
-{
- struct buffer_t *b, *b2;
-
- log_debug("cli: disconnect\n");
-
- triton_stop_collect_cpu_usage();
-
- list_del(&cln->entry);
-
- triton_md_unregister_handler(&cln->hnd);
- close(cln->hnd.fd);
-
- if (cln->xmit_buf)
- _free(cln->xmit_buf);
-
- while (!list_empty(&cln->xmit_queue)) {
- b = list_entry(cln->xmit_queue.next, typeof(*b), entry);
- list_del(&b->entry);
- _free(b);
- }
-
- pthread_mutex_lock(&history_lock);
- while (!list_empty(&cln->history)) {
- b = list_entry(cln->history.prev, typeof(*b), entry);
- list_del(&b->entry);
- if (!b->p_buf) {
- if (history_len == conf_history_len) {
- b2 = list_entry(history.next, typeof(*b2), entry);
- list_del(&b2->entry);
- _free(b2);
- } else
- history_len++;
- list_add_tail(&b->entry, &history);
- } else
- _free(b);
- }
- pthread_mutex_unlock(&history_lock);
-
- _free(cln->cmdline);
- _free(cln);
-}
-
-static void cli_client_disconnect(struct cli_client_t *tcln)
-{
- struct telnet_client_t *cln = container_of(tcln, typeof(*cln), cli_client);
- cln->disconnect = 1;
-}
-
-static void queue_buffer(struct telnet_client_t *cln, struct buffer_t *b)
-{
- if (cln->xmit_buf)
- list_add_tail(&b->entry, &cln->xmit_queue);
- else
- cln->xmit_buf = b;
-}
-
-static int telnet_send(struct telnet_client_t *cln, const void *_buf, int size)
-{
- int n, k;
- struct buffer_t *b;
- const uint8_t *buf = (const uint8_t *)_buf;
-
- if (cln->disconnect)
- return -1;
-
- if (!list_empty(&cln->xmit_queue)) {
- b = _malloc(sizeof(*b) + size);
- b->size = size;
- memcpy(b->buf, buf, size);
- queue_buffer(cln, b);
- return 0;
- }
-
- for (n = 0; n < size; n += k) {
- k = write(cln->hnd.fd, buf + n, size - n);
- if (k < 0) {
- if (errno == EAGAIN) {
- b = _malloc(sizeof(*b) + size - n);
- b->size = size - n;
- memcpy(b->buf, buf, size - n);
- queue_buffer(cln, b);
-
- triton_md_enable_handler(&cln->hnd, MD_MODE_WRITE);
- break;
- }
- if (errno != EPIPE)
- log_error("cli: write: %s\n", strerror(errno));
- //disconnect(cln);
- cln->disconnect = 1;
- return -1;
- }
- }
- return 0;
-}
-
-static int cli_client_send(struct cli_client_t *tcln, const void *buf, int size)
-{
- struct telnet_client_t *cln = container_of(tcln, typeof(*cln), cli_client);
- return telnet_send(cln, buf, size);
-}
-
-static int cli_client_sendv(struct cli_client_t *tcln, const char *fmt, va_list ap)
-{
- struct telnet_client_t *cln = container_of(tcln, typeof(*cln), cli_client);
- int r = vsnprintf((char *)temp_buf, RECV_BUF_SIZE, fmt, ap);
-
- if (r >= RECV_BUF_SIZE) {
- strcpy((char *)temp_buf + RECV_BUF_SIZE - 6, "...\r\n");
- r = RECV_BUF_SIZE;
- }
-
- return telnet_send(cln, temp_buf, r);
-}
-
-static int send_banner(struct telnet_client_t *cln)
-{
- if (telnet_send(cln, "accel-pptp version " ACCEL_PPTP_VERSION "\r\n", sizeof("accel-pptp version " ACCEL_PPTP_VERSION "\r\n")))
- return -1;
- return 0;
-}
-
-static int send_config(struct telnet_client_t *cln)
-{
- uint8_t buf[] = {IAC, WILL, TELOPT_ECHO, IAC, WILL, TELOPT_SGA, IAC, DONT, TELOPT_LINEMODE};
- return telnet_send(cln, buf, sizeof(buf));
-}
-
-static int send_password_request(struct telnet_client_t *cln)
-{
- uint8_t buf0[] = {IAC, WILL, TELOPT_ECHO};
- uint8_t buf1[] = "Password: ";
-
- if (telnet_send(cln, buf0, sizeof(buf0)))
- return -1;
-
- if (telnet_send(cln, buf1, sizeof(buf1)))
- return -1;
-
- return 0;
-}
-
-static int send_prompt(struct telnet_client_t *cln)
-{
- sprintf((char *)temp_buf, "%s%s# ", conf_cli_prompt, ppp_shutdown ? "(shutdown)" : "");
- return telnet_send(cln, temp_buf, strlen((char *)temp_buf));
-}
-
-/*static void print_buf(const uint8_t *buf, int size)
-{
- int i;
-
- for (i = 0; i < size; i++)
- log_debug("%x ", buf[i]);
- log_debug("\n");
-}*/
-
-static int send_cmdline_tail(struct telnet_client_t *cln, int corr)
-{
- if (telnet_send(cln, cln->cmdline + cln->cmdline_pos, cln->cmdline_len - cln->cmdline_pos))
- return -1;
-
- memset(temp_buf, '\b', cln->cmdline_len - cln->cmdline_pos - corr);
-
- if (telnet_send(cln, temp_buf, cln->cmdline_len - cln->cmdline_pos - corr))
- return -1;
-
- return 0;
-}
-
-static int load_history(struct telnet_client_t *cln)
-{
- struct buffer_t *b = list_entry(cln->history_pos, typeof(*b), entry);
- if (b->size < cln->cmdline_len) {
- memset(temp_buf, '\b', cln->cmdline_len - b->size);
- memset(temp_buf + cln->cmdline_len - b->size, ' ', cln->cmdline_len - b->size);
- if (telnet_send(cln, temp_buf, (cln->cmdline_len - b->size) * 2))
- return -1;
- }
- if (telnet_send(cln, "\r", 1))
- return -1;
- if (send_prompt(cln))
- return -1;
- memcpy(cln->cmdline, b->p_buf ? b->p_buf->buf : b->buf, b->size);
- cln->cmdline_pos = b->size;
- cln->cmdline_len = b->size;
- if (telnet_send(cln, b->p_buf ? b->p_buf->buf : b->buf, b->size))
- return -1;
-
- return 0;
-}
-
-static int telnet_input_char(struct telnet_client_t *cln, uint8_t c)
-{
- uint8_t buf[] = {IAC, DONT, 0};
- struct buffer_t *b;
-
- if (c == '\n')
- return 0;
-
- if (c == '\r') {
- cln->cmdline[cln->cmdline_len] = 0;
-
- if (cln->echo) {
- if (telnet_send(cln, "\r\n", 2))
- return -1;
- }
-
- if (!cln->auth) {
- if (strcmp((char *)cln->cmdline, conf_cli_passwd)) {
- if (telnet_send(cln, MSG_AUTH_FAILED, sizeof(MSG_AUTH_FAILED)))
- return -1;
- cln->disconnect = 1;
- return -1;
- }
- cln->auth = 1;
- if (ppp_shutdown) {
- if (telnet_send(cln, MSG_SHUTDOWN_IN_PROGRESS, sizeof(MSG_SHUTDOWN_IN_PROGRESS)))
- return -1;
- }
- } else if (cln->cmdline_len) {
- b = _malloc(sizeof(*b) + cln->cmdline_len);
- b->p_buf = NULL;
- memcpy(b->buf, cln->cmdline, cln->cmdline_len);
- b->size = cln->cmdline_len;
- list_add(&b->entry, cln->history.next);
- cln->history_pos = cln->history.next;
-
- if (cli_process_cmd(&cln->cli_client))
- return -1;
- }
-
- cln->cmdline_pos = 0;
- cln->cmdline_len = 0;
-
- return send_prompt(cln);
- }
-
- if (cln->telcmd) {
- if (cln->cmdline_pos2 == RECV_BUF_SIZE - 1) {
- log_error("cli: buffer overflow, dropping connection ...\n");
- disconnect(cln);
- return -1;
- }
-
- cln->cmdline[cln->cmdline_pos2] = c;
- cln->cmdline_pos2++;
-
- if (cln->cmdline[cln->cmdline_len] >= WILL && cln->cmdline[cln->cmdline_len] <= DONT && cln->cmdline_pos2 - cln->cmdline_len != 2)
- return 0;
-
- switch (cln->cmdline[cln->cmdline_len]) {
- case WILL:
- case WONT:
- buf[2] = c;
- if (telnet_send(cln, buf, 3))
- return -1;
- break;
- case DO:
- if (c == TELOPT_ECHO)
- cln->echo = 1;
- break;
- case SB:
- if (c != SE)
- return 0;
- }
-
- cln->telcmd = 0;
- } else if (cln->esc) {
- if (cln->cmdline_pos2 == RECV_BUF_SIZE - 1) {
- log_error("cli: buffer overflow, dropping connection ...\n");
- disconnect(cln);
- return -1;
- }
-
- cln->cmdline[cln->cmdline_pos2] = c;
- cln->cmdline_pos2++;
-
- if (cln->cmdline_pos2 - cln->cmdline_len != 2)
- return 0;
-
- cln->esc = 0;
-
- if (cln->auth) {
- if (!memcmp(cln->cmdline + cln->cmdline_len, ESC_LEFT, 2)) {
- if (cln->cmdline_pos) {
- if (telnet_send(cln, "\b", 1))
- return -1;
- cln->cmdline_pos--;
- }
- } else if (!memcmp(cln->cmdline + cln->cmdline_len, ESC_RIGHT, 2)) {
- if (cln->cmdline_pos < cln->cmdline_len) {
- if (send_cmdline_tail(cln, 1))
- return -1;
- cln->cmdline_pos++;
- }
- } else if (!memcmp(cln->cmdline + cln->cmdline_len, ESC_UP, 2)) {
- if (cln->history_pos == cln->history.next) {
- b = list_entry(cln->history_pos, typeof(*b), entry);
- memcpy(b->buf, cln->cmdline, cln->cmdline_len);
- b->size = cln->cmdline_len;
- }
- cln->history_pos = cln->history_pos->next;
- if (cln->history_pos == &cln->history) {
- cln->history_pos = cln->history_pos->prev;
- return 0;
- }
- if (load_history(cln))
- return -1;
- } else if (!memcmp(cln->cmdline + cln->cmdline_len, ESC_DOWN, 2)) {
- cln->history_pos = cln->history_pos->prev;
- if (cln->history_pos == &cln->history) {
- cln->history_pos = cln->history_pos->next;
- return 0;
- }
- if (load_history(cln))
- return -1;
- }
- }
- } else {
- switch (c) {
- case 0xff:
- cln->cmdline_pos2 = cln->cmdline_len;
- cln->telcmd = 1;
- return 0;
- case 0x1b:
- cln->cmdline_pos2 = cln->cmdline_len;
- cln->esc = 1;
- return 0;
- case 0x7f:
- if (cln->cmdline_pos) {
- if (cln->cmdline_pos < cln->cmdline_len) {
- memmove(cln->cmdline + cln->cmdline_pos - 1, cln->cmdline + cln->cmdline_pos, cln->cmdline_len - cln->cmdline_pos);
-
- cln->cmdline[cln->cmdline_len - 1] = ' ';
-
- if (telnet_send(cln, "\b", 1))
- return -1;
-
- cln->cmdline_pos--;
-
- if (send_cmdline_tail(cln, 0))
- return -1;
- } else {
- buf[0] = '\b';
- buf[1] = ' ';
- buf[2] = '\b';
- if (telnet_send(cln, buf, 3))
- return -1;
- cln->cmdline_pos--;
- }
-
- cln->cmdline_len--;
- }
- return 0;
- case 3:
- cln->disconnect = 1;
- return -1;
- }
-
- if (isprint(c)) {
- if (cln->cmdline_len == RECV_BUF_SIZE - 1)
- return 0;
-
- if (cln->cmdline_pos < cln->cmdline_len)
- memmove(cln->cmdline + cln->cmdline_pos + 1, cln->cmdline + cln->cmdline_pos, cln->cmdline_len - cln->cmdline_pos);
- cln->cmdline[cln->cmdline_pos] = c;
- cln->cmdline_pos++;
- cln->cmdline_len++;
-
- if (cln->echo) {
- if (!cln->auth) {
- if (telnet_send(cln, "*", 1))
- return -1;
- } else {
- if (telnet_send(cln, &c, 1))
- return -1;
- }
- }
-
- if (cln->cmdline_pos < cln->cmdline_len) {
- if (send_cmdline_tail(cln, 0))
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-static int cln_read(struct triton_md_handler_t *h)
-{
- struct telnet_client_t *cln = container_of(h, typeof(*cln), hnd);
- int i, n;
-
- while (1) {
- n = read(h->fd, recv_buf, RECV_BUF_SIZE);
- if (n == 0) {
- disconnect(cln);
- return -1;
- }
- if (n < 0) {
- if (errno != EAGAIN)
- log_error("cli: telnet: read: %s\n", strerror(errno));
- return 0;
- }
- /*log_debug("cli: read(%i): ", n);
- print_buf(cln->recv_buf + cln->recv_pos, n);*/
- for (i = 0; i < n; i++) {
- if (telnet_input_char(cln, recv_buf[i]))
- break;
- }
- if (cln->disconnect) {
- disconnect(cln);
- return -1;
- }
- }
-
- return 0;
-}
-
-static int cln_write(struct triton_md_handler_t *h)
-{
- struct telnet_client_t *cln = container_of(h, typeof(*cln), hnd);
- int k;
-
- while (1) {
- for (; cln->xmit_pos < cln->xmit_buf->size; cln->xmit_pos += k) {
- k = write(cln->hnd.fd, cln->xmit_buf->buf + cln->xmit_pos, cln->xmit_buf->size - cln->xmit_pos);
- if (k < 0) {
- if (errno == EAGAIN)
- return 0;
- if (errno != EPIPE)
- log_error("cli: telnet: write: %s\n", strerror(errno));
- disconnect(cln);
- return -1;
- }
- }
-
- _free(cln->xmit_buf);
- cln->xmit_pos = 0;
-
- if (list_empty(&cln->xmit_queue))
- break;
-
- cln->xmit_buf = list_entry(cln->xmit_queue.next, typeof(*cln->xmit_buf), entry);
- list_del(&cln->xmit_buf->entry);
- }
-
- triton_md_disable_handler(&cln->hnd, MD_MODE_WRITE);
-
- return 0;
-}
-
-static int serv_read(struct triton_md_handler_t *h)
-{
- struct sockaddr_in addr;
- socklen_t size = sizeof(addr);
- int sock;
- struct telnet_client_t *conn;
- struct buffer_t *b, *b2;
-
- while(1) {
- sock = accept(h->fd, (struct sockaddr *)&addr, &size);
- if (sock < 0) {
- if (errno == EAGAIN)
- return 0;
- log_error("cli: telnet: accept failed: %s\n", strerror(errno));
- continue;
- }
-
- log_info2("cli: telnet: new connection from %s\n", inet_ntoa(addr.sin_addr));
-
- if (fcntl(sock, F_SETFL, O_NONBLOCK)) {
- log_error("cli: telnet: failed to set nonblocking mode: %s, closing connection...\n", strerror(errno));
- close(sock);
- continue;
- }
-
- conn = _malloc(sizeof(*conn));
- memset(conn, 0, sizeof(*conn));
- conn->hnd.fd = sock;
- conn->hnd.read = cln_read;
- conn->hnd.write = cln_write;
- conn->cmdline = _malloc(RECV_BUF_SIZE);
- INIT_LIST_HEAD(&conn->xmit_queue);
- INIT_LIST_HEAD(&conn->history);
-
- b = _malloc(sizeof(*b) + RECV_BUF_SIZE);
- b->p_buf = b;
- b->size = 0;
- list_add_tail(&b->entry, &conn->history);
-
- pthread_mutex_lock(&history_lock);
- list_for_each_entry(b, &history, entry) {
- b2 = _malloc(sizeof(*b));
- b2->p_buf = b;
- b2->size = b->size;
- list_add(&b2->entry, conn->history.next);
- }
- pthread_mutex_unlock(&history_lock);
-
- conn->history_pos = conn->history.next;
-
- conn->cli_client.cmdline = conn->cmdline;
- conn->cli_client.send = cli_client_send;
- conn->cli_client.sendv = cli_client_sendv;
- conn->cli_client.disconnect = cli_client_disconnect;
-
- triton_md_register_handler(&serv_ctx, &conn->hnd);
- triton_md_enable_handler(&conn->hnd,MD_MODE_READ);
-
- list_add_tail(&conn->entry, &clients);
-
- if (send_banner(conn))
- continue;
-
- if (send_config(conn))
- continue;
-
- if (conf_cli_passwd)
- send_password_request(conn);
- else {
- conn->auth = 1;
- if (ppp_shutdown) {
- if (telnet_send(conn, MSG_SHUTDOWN_IN_PROGRESS, sizeof(MSG_SHUTDOWN_IN_PROGRESS)))
- continue;
- }
- send_prompt(conn);
- }
- triton_collect_cpu_usage();
- }
- return 0;
-}
-static void serv_close(struct triton_context_t *ctx)
-{
- struct telnet_client_t *cln;
-
- while (!list_empty(&clients)) {
- cln = list_entry(clients.next, typeof(*cln), entry);
- disconnect(cln);
- }
-
- triton_md_unregister_handler(&serv_hnd);
- close(serv_hnd.fd);
- triton_context_unregister(ctx);
-}
-
-static struct triton_context_t serv_ctx = {
- .close = serv_close,
- .before_switch = log_switch,
-};
-
-static struct triton_md_handler_t serv_hnd = {
- .read = serv_read,
-};
-
-static void start_server(const char *host, int port)
-{
- struct sockaddr_in addr;
-
- serv_hnd.fd = socket(PF_INET, SOCK_STREAM, 0);
- if (serv_hnd.fd < 0) {
- log_emerg("cli: telnet: failed to create server socket: %s\n", strerror(errno));
- return;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- if (host)
- addr.sin_addr.s_addr = inet_addr(host);
- else
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
-
- setsockopt(serv_hnd.fd, SOL_SOCKET, SO_REUSEADDR, &serv_hnd.fd, 4);
- if (bind (serv_hnd.fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
- log_emerg("cli: telnet: failed to bind socket: %s\n", strerror(errno));
- close(serv_hnd.fd);
- return;
- }
-
- if (listen (serv_hnd.fd, 1) < 0) {
- log_emerg("cli: telnet: failed to listen socket: %s\n", strerror(errno));
- close(serv_hnd.fd);
- return;
- }
-
- if (fcntl(serv_hnd.fd, F_SETFL, O_NONBLOCK)) {
- log_emerg("cli: telnet: failed to set nonblocking mode: %s\n", strerror(errno));
- close(serv_hnd.fd);
- return;
- }
-
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = inet_addr(host);
-
- triton_context_register(&serv_ctx, NULL);
- triton_context_set_priority(&serv_ctx, 1);
- triton_md_register_handler(&serv_ctx, &serv_hnd);
- triton_md_enable_handler(&serv_hnd, MD_MODE_READ);
- triton_context_wakeup(&serv_ctx);
-}
-
-static void save_history_file(void)
-{
- int fd;
- struct buffer_t *b;
-
- fd = open(conf_history_file, O_WRONLY | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
- if (!fd)
- return;
-
- list_for_each_entry(b, &history, entry) {
- b->buf[b->size] = '\n';
- write(fd, b->buf, b->size + 1);
- }
-
- close(fd);
-}
-
-static void load_history_file(void)
-{
- struct buffer_t *b;
- FILE *f;
-
- f = fopen(conf_history_file, "r");
- if (!f)
- return;
-
- while (fgets((char *)temp_buf, RECV_BUF_SIZE, f)) {
- b = _malloc(sizeof(*b) + strlen((char *)temp_buf));
- b->p_buf = NULL;
- b->size = strlen((char *)temp_buf) - 1;
- memcpy(b->buf, temp_buf, b->size);
- list_add_tail(&b->entry, &history);
- }
-
- fclose(f);
-}
-
-static void __init init(void)
-{
- const char *opt;
- char *host, *d;
- int port;
-
- opt = conf_get_opt("cli", "telnet");
- if (!opt)
- return;
-
- host = strdup(opt);
- d = strstr(host, ":");
- if (!d)
- goto err_fmt;
-
- *d = 0;
- port = atoi(d + 1);
- if (port <= 0)
- goto err_fmt;
-
- opt = conf_get_opt("cli", "history-file");
- if (opt)
- conf_history_file = _strdup(opt);
-
- recv_buf = malloc(RECV_BUF_SIZE);
- temp_buf = malloc(RECV_BUF_SIZE);
-
- load_history_file();
-
- start_server(host, port);
-
- atexit(save_history_file);
-
- return;
-err_fmt:
- log_emerg("cli: telnet: invalid format\n");
- free(host);
-}
-