提交 15339d1d 编写于 作者: K Kozlov Dmitry

cli: simplified cli api

上级 dda81cb1
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
......@@ -20,6 +21,33 @@ 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;
......@@ -38,6 +66,19 @@ int __export cli_send(void *client, const char *data)
return telnet_send(cln, data, strlen(data));
}
int __export cli_sendv(void *client, const char *fmt, ...)
{
struct client_t *cln = (struct client_t *)client;
int r;
va_list ap;
va_start(ap, fmt);
r = telnet_sendv(cln, fmt, ap);
va_end(ap);
return r;
}
static char *skip_word(char *ptr)
{
......@@ -89,14 +130,13 @@ int process_cmd(struct client_t *cln)
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))
return -1;
}
list_for_each_entry(cmd2, &regexp_cmd_list, entry) {
if (cmd2->help && cmd1->help(f, n, cln))
return -1;
}
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;
}
......
......@@ -15,7 +15,7 @@ struct cli_simple_cmd_t
int hdr_len;
const char **hdr;
int (*exec)(const char *cmd, char * const *fields, int fields_cnt, void *client);
int (*help)(char * const *fields, int field_cnt, void *client);
void (*help)(char * const *fields, int field_cnt, void *client);
};
struct cli_regexp_cmd_t
......@@ -29,9 +29,16 @@ struct cli_regexp_cmd_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);
int cli_send(void *client, const char *data);
int cli_sendv(void *client, const char *fmt, ...);
#endif
......@@ -7,118 +7,49 @@
#include "cli.h"
#include "utils.h"
int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
char buf[128];
if (cli_send(client, "core:\r\n"))
return CLI_CMD_FAILED;
sprintf(buf, " mempool_allocated: %u\r\n", triton_stat.mempool_allocated);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " mempool_available: %u\r\n", triton_stat.mempool_available);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " thread_count: %u\r\n", triton_stat.thread_count);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " thread_active: %u\r\n", triton_stat.thread_active);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " context_count: %u\r\n", triton_stat.context_count);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " context_sleeping: %u\r\n", triton_stat.context_sleeping);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " context_pending: %u\r\n", triton_stat.context_pending);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " md_handler_count: %u\r\n", triton_stat.md_handler_count);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " md_handler_pending: %u\r\n", triton_stat.md_handler_pending);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " timer_count: %u\r\n", triton_stat.timer_count);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " timer_pending: %u\r\n", triton_stat.timer_pending);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
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);
//===========
if (cli_send(client, "ppp:\r\n"))
return CLI_CMD_FAILED;
sprintf(buf, " staring: %u\r\n", ppp_stat.starting);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " active: %u\r\n", ppp_stat.active);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " finishing: %u\r\n", ppp_stat.finishing);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
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;
}
int show_stat_help(char * const *fields, int fields_cnt, void *client)
static void show_stat_help(char * const *fields, int fields_cnt, void *client)
{
if (cli_send(client, "show stat - shows various statistics information\r\n"))
return -1;
return 0;
cli_send(client, "show stat - shows various statistics information\r\n");
}
const char *show_stat_hdr[] = {"show","stat"};
static struct cli_simple_cmd_t show_stat_cmd = {
.hdr_len = 2,
.hdr = show_stat_hdr,
.exec = show_stat_exec,
.help = show_stat_help,
};
//=============================
int exit_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
static int exit_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
return CLI_CMD_EXIT;
}
int exit_help(char * const *fields, int fields_cnt, void *client)
static void exit_help(char * const *fields, int fields_cnt, void *client)
{
if (cli_send(client, "exit - exit cli\r\n"))
return -1;
return 0;
cli_send(client, "exit - exit cli\r\n");
}
const char *exit_hdr[] = {"exit"};
static struct cli_simple_cmd_t exit_cmd = {
.hdr_len = 1,
.hdr = exit_hdr,
.exec = exit_exec,
.help = exit_help,
};
//=============================
int show_ses_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
static int show_ses_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
char buf[128];
char ip_str[17];
......@@ -128,11 +59,8 @@ int show_ses_exec(const char *cmd, char * const *fields, int fields_cnt, void *c
int day,hour,min,sec;
struct ppp_t *ppp;
if (cli_send(client, "interface: username: address: type: state: uptime:\r\n"))
return CLI_CMD_FAILED;
if (cli_send(client, "------------------------------------------------------------------------\r\n"))
return CLI_CMD_FAILED;
cli_send(client, "interface: username: address: type: state: uptime:\r\n");
cli_send(client, "------------------------------------------------------------------------\r\n");
pthread_rwlock_rdlock(&ppp_lock);
list_for_each_entry(ppp, &ppp_list, entry) {
......@@ -168,32 +96,18 @@ int show_ses_exec(const char *cmd, char * const *fields, int fields_cnt, void *c
sprintf(time_str, "%02i:%02i:%02i", hour, min, sec);
sprintf(buf, "%9s %15s %16s %6s %6s %10s\r\n", ppp->ifname, ppp->username ? ppp->username : "", ip_str, ppp->ctrl->name, state_str, time_str);
if (cli_send(client, buf)) {
pthread_rwlock_unlock(&ppp_lock);
return CLI_CMD_FAILED;
}
cli_send(client, buf);
}
pthread_rwlock_unlock(&ppp_lock);
return CLI_CMD_OK;
}
int show_ses_help(char * const *fields, int fields_cnt, void *client)
static void show_ses_help(char * const *fields, int fields_cnt, void *client)
{
if (cli_send(client, "show sessions - shows all sessions\r\n"))
return -1;
return 0;
cli_send(client, "show sessions - shows all sessions\r\n");
}
const char *show_ses_hdr[] = {"show", "sessions"};
static struct cli_simple_cmd_t show_ses_cmd = {
.hdr_len = 2,
.hdr = show_ses_hdr,
.exec = show_ses_exec,
.help = show_ses_help,
};
//=============================
static void ppp_terminate_soft(struct ppp_t *ppp)
......@@ -206,20 +120,20 @@ static void ppp_terminate_hard(struct ppp_t *ppp)
ppp_terminate(ppp, 1, TERM_ADMIN_RESET);
}
int terminate_help(char * const *fields, int fields_cnt, void *client);
int terminate_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
static void terminate_help(char * const *fields, int fields_cnt, void *client);
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 terminate_help(NULL, 0, client);
goto help;
if (fields_cnt == 3) {
if (!strcmp(fields[2], "hard"))
hard = 1;
else if (strcmp(fields[2], "soft"))
return terminate_help(NULL, 0, client);
goto help;
}
pthread_rwlock_rdlock(&ppp_lock);
......@@ -243,32 +157,23 @@ int terminate_exec(const char *cmd, char * const *fields, int fields_cnt, void *
}
pthread_rwlock_unlock(&ppp_lock);
return CLI_CMD_OK;
help:
terminate_help(fields, fields_cnt, client);
return CLI_CMD_OK;
}
int terminate_help(char * const *fields, int fields_cnt, void *client)
static void terminate_help(char * const *fields, int fields_cnt, void *client)
{
if (cli_send(client, "terminate <interface> [soft|hard]- terminate session\r\n"))
return -1;
if (cli_send(client, "terminate all [soft|hard]- terminate all session\r\n"))
return -1;
return 0;
cli_send(client, "terminate <interface> [soft|hard]- terminate session\r\n");
cli_send(client, "terminate all [soft|hard]- terminate all session\r\n");
}
const char *terminate_hdr[] = {"terminate"};
static struct cli_simple_cmd_t terminate_cmd = {
.hdr_len = 1,
.hdr = terminate_hdr,
.exec = terminate_exec,
.help = terminate_help,
};
static void __init init(void)
{
cli_register_simple_cmd(&show_stat_cmd);
cli_register_simple_cmd(&show_ses_cmd);
cli_register_simple_cmd(&terminate_cmd);
cli_register_simple_cmd(&exit_cmd);
cli_register_simple_cmd2(show_stat_exec, show_stat_help, 2, "show", "stat");
cli_register_simple_cmd2(show_ses_exec, show_ses_help, 2, "show", "sessions");
cli_register_simple_cmd2(terminate_exec, terminate_help, 1, "terminate");
cli_register_simple_cmd2(exit_exec, exit_help, 1, "exit");
}
......@@ -91,6 +91,9 @@ int telnet_send(struct client_t *cln, const void *_buf, int size)
struct buffer_t *b;
const uint8_t *buf = (const uint8_t *)_buf;
if (cln->disconnect)
return -1;
for (n = 0; n < size; n += k) {
k = write(cln->hnd.fd, buf + n, size - n);
if (k < 0) {
......@@ -105,13 +108,26 @@ int telnet_send(struct client_t *cln, const void *_buf, int size)
}
if (errno != EPIPE)
log_error("cli: write: %s\n", strerror(errno));
disconnect(cln);
//disconnect(cln);
cln->disconnect = 1;
return -1;
}
}
return 0;
}
int telnet_sendv(struct client_t *cln, const char *fmt, va_list ap)
{
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 client_t *cln)
{
return telnet_send(cln, BANNER, sizeof(BANNER));
......@@ -398,6 +414,10 @@ static int cln_read(struct triton_md_handler_t *h)
if (telnet_input_char(cln, recv_buf[i]))
return -1;
}
if (cln->disconnect) {
disconnect(cln);
return 0;
}
}
return 0;
......
#ifndef __TELNET_H
#define __TELNET_H
#include <stdarg.h>
struct client_t
{
struct list_head entry;
......@@ -18,9 +20,11 @@ struct client_t
int echo:1;
int telcmd:1;
int esc:1;
int disconnect:1;
};
int telnet_send(struct client_t *cln, const void *buf, int size);
int telnet_sendv(struct client_t *cln, const char *fmt, va_list ap);
void telnet_disconnect(struct client_t *cln);
int process_cmd(struct client_t *cln);
......
......@@ -1062,29 +1062,13 @@ static void start_udp_server(void)
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
char buf[128];
if (cli_send(client, "l2tp:\r\n"))
return CLI_CMD_FAILED;
sprintf(buf, " starting: %u\r\n", stat_starting);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " active: %u\r\n", stat_active);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
cli_send(client, "l2tp:\r\n");
cli_sendv(client, " starting: %u\r\n", stat_starting);
cli_sendv(client, " active: %u\r\n", stat_active);
return CLI_CMD_OK;
}
static const char *show_stat_hdr[] = {"show","stat"};
static struct cli_simple_cmd_t show_stat_cmd = {
.hdr_len = 2,
.hdr = show_stat_hdr,
.exec = show_stat_exec,
};
static void __init l2tp_init(void)
{
char *opt;
......@@ -1120,6 +1104,6 @@ static void __init l2tp_init(void)
start_udp_server();
cli_register_simple_cmd(&show_stat_cmd);
cli_register_simple_cmd2(&show_stat_exec, NULL, 2, "show", "stat");
}
......@@ -119,7 +119,7 @@ err:
return -1;
}
static int mac_filter_add(const char *addr, void *client)
static void mac_filter_add(const char *addr, void *client)
{
int n[ETH_ALEN];
struct mac_t *mac;
......@@ -127,14 +127,16 @@ static int mac_filter_add(const char *addr, void *client)
if (sscanf(addr, "%x:%x:%x:%x:%x:%x",
n + 0, n + 1, n + 2, n + 3, n + 4, n + 5) != 6) {
return cli_send(client, "invalid format\r\n");
cli_send(client, "invalid format\r\n");
return;
}
mac = _malloc(sizeof(*mac));
for (i = 0; i < ETH_ALEN; i++) {
if (n[i] > 255) {
_free(mac);
return cli_send(client, "invalid format\r\n");
cli_send(client, "invalid format\r\n");
return;
}
mac->addr[i] = n[i];
}
......@@ -142,11 +144,9 @@ static int mac_filter_add(const char *addr, void *client)
pthread_rwlock_wrlock(&lock);
list_add_tail(&mac->entry, &mac_list);
pthread_rwlock_unlock(&lock);
return 0;
}
static int mac_filter_del(const char *addr, void *client)
static void mac_filter_del(const char *addr, void *client)
{
int n[ETH_ALEN];
uint8_t a[ETH_ALEN];
......@@ -156,12 +156,14 @@ static int mac_filter_del(const char *addr, void *client)
if (sscanf(addr, "%x:%x:%x:%x:%x:%x",
n + 0, n + 1, n + 2, n + 3, n + 4, n + 5) != 6) {
return cli_send(client, "invalid format\r\n");
cli_send(client, "invalid format\r\n");
return;
}
for (i = 0; i < ETH_ALEN; i++) {
if (n[i] > 255) {
return cli_send(client, "invalid format\r\n");
cli_send(client, "invalid format\r\n");
return;
}
a[i] = n[i];
}
......@@ -178,16 +180,13 @@ static int mac_filter_del(const char *addr, void *client)
pthread_rwlock_unlock(&lock);
if (!found)
return cli_send(client, "not found\r\n");
return 0;
cli_send(client, "not found\r\n");
}
static int mac_filter_show(void *client)
static void mac_filter_show(void *client)
{
struct mac_t *mac;
const char *filter_type;
char buf[64];
if (type == 0)
filter_type = "deny";
......@@ -196,88 +195,60 @@ static int mac_filter_show(void *client)
else
filter_type = "disabled";
sprintf(buf, "filter type: %s\r\n", filter_type);
if (cli_send(client, buf))
return -1;
cli_sendv(client, "filter type: %s\r\n", filter_type);
pthread_rwlock_rdlock(&lock);
list_for_each_entry(mac, &mac_list, entry) {
sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\r\n",
cli_sendv(client, "%02x:%02x:%02x:%02x:%02x:%02x\r\n",
mac->addr[0], mac->addr[1], mac->addr[2],
mac->addr[3], mac->addr[4], mac->addr[5]);
if (cli_send(client, buf)) {
pthread_rwlock_unlock(&lock);
return -1;
}
}
pthread_rwlock_unlock(&lock);
return 0;
}
static int cmd_help(char * const *fields, int fields_cnt, void *client);
int cmd_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
static void cmd_help(char * const *fields, int fields_cnt, void *client);
static int cmd_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
if (fields_cnt == 2)
return cmd_help(fields, fields_cnt, client);
goto help;
if (!strcmp(fields[2], "reload")) {
if (!conf_mac_filter) {
if (cli_send(client, "error: mac-filter was not specified in the config\r\n"))
return CLI_CMD_FAILED;
} else if (mac_filter_load(conf_mac_filter)) {
if (cli_send(client, "error: check logs\r\n"))
return CLI_CMD_FAILED;
}
if (!conf_mac_filter)
cli_send(client, "error: mac-filter was not specified in the config\r\n");
else if (mac_filter_load(conf_mac_filter))
cli_send(client, "error: check logs\r\n");
} else if (!strcmp(fields[2], "add")) {
if (fields_cnt != 4)
return cmd_help(fields, fields_cnt, client);
if (mac_filter_add(fields[3], client))
return CLI_CMD_FAILED;
goto help;
mac_filter_add(fields[3], client);
} else if (!strcmp(fields[2], "del")) {
if (fields_cnt != 4)
return cmd_help(fields, fields_cnt, client);
if (mac_filter_del(fields[3], client))
return CLI_CMD_FAILED;
goto help;
mac_filter_del(fields[3], client);
} else if (!strcmp(fields[2], "show")) {
if (mac_filter_show(client))
return CLI_CMD_FAILED;
mac_filter_show(client);
}
return CLI_CMD_OK;
help:
cmd_help(fields, fields_cnt, client);
return CLI_CMD_OK;
}
static int cmd_help(char * const *fields, int fields_cnt, void *client)
static void cmd_help(char * const *fields, int fields_cnt, void *client)
{
if (cli_send(client, "pppoe mac-filter reload - reload mac-filter file\r\n"))
return -1;
if (cli_send(client, "pppoe mac-filter add <address> - add address to mac-filter list\r\n"))
return -1;
if (cli_send(client, "pppoe mac-filter del <address> - delete address from mac-filter list\r\n"))
return -1;
if (cli_send(client, "pppoe mac-filter show - show current mac-filter list\r\n"))
return -1;
return 0;
cli_send(client, "pppoe mac-filter reload - reload mac-filter file\r\n");
cli_send(client, "pppoe mac-filter add <address> - add address to mac-filter list\r\n");
cli_send(client, "pppoe mac-filter del <address> - delete address from mac-filter list\r\n");
cli_send(client, "pppoe mac-filter show - show current mac-filter list\r\n");
}
const char *cmd_hdr[] = {"pppoe", "mac-filter"};
static struct cli_simple_cmd_t cmd = {
.hdr_len = 2,
.hdr = cmd_hdr,
.exec = cmd_exec,
.help = cmd_help,
};
static void __init init(void)
{
const char *opt = conf_get_opt("pppoe", "mac-filter");
if (!opt || mac_filter_load(opt))
type = -1;
cli_register_simple_cmd(&cmd);
cli_register_simple_cmd2(cmd_exec, cmd_help, 2, "pppoe", "mac-filter");
}
......@@ -943,31 +943,6 @@ out_err:
_free(serv);
}
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
char buf[128];
if (cli_send(client, "pppoe:\r\n"))
return CLI_CMD_FAILED;
sprintf(buf, " active: %u\r\n", stat_active);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " delayed PADO: %u\r\n", stat_delayed_pado);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
return CLI_CMD_OK;
}
static const char *show_stat_hdr[] = {"show","stat"};
static struct cli_simple_cmd_t show_stat_cmd = {
.hdr_len = 2,
.hdr = show_stat_hdr,
.exec = show_stat_exec,
};
static int init_secret(void)
{
int fd;
......@@ -1024,7 +999,5 @@ static void __init pppoe_init(void)
conf_pado_delay = atoi(opt->val);
}
}
cli_register_simple_cmd(&show_stat_cmd);
}
......@@ -688,29 +688,13 @@ static struct pptp_serv_t serv=
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
char buf[128];
if (cli_send(client, "pptp:\r\n"))
return CLI_CMD_FAILED;
sprintf(buf, " starting: %u\r\n", stat_starting);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
sprintf(buf, " active: %u\r\n", stat_active);
if (cli_send(client, buf))
return CLI_CMD_FAILED;
cli_send(client, "pptp:\r\n");
cli_sendv(client," starting: %u\r\n", stat_starting);
cli_sendv(client," active: %u\r\n", stat_active);
return CLI_CMD_OK;
}
static const char *show_stat_hdr[] = {"show","stat"};
static struct cli_simple_cmd_t show_stat_cmd = {
.hdr_len = 2,
.hdr = show_stat_hdr,
.exec = show_stat_exec,
};
static void __init pptp_init(void)
{
struct sockaddr_in addr;
......@@ -772,6 +756,6 @@ static void __init pptp_init(void)
triton_md_enable_handler(&serv.hnd, MD_MODE_READ);
triton_context_wakeup(&serv.ctx);
cli_register_simple_cmd(&show_stat_cmd);
cli_register_simple_cmd2(show_stat_exec, NULL, 2, "show", "stat");
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册