diff options
author | Kozlov Dmitry <dima@server> | 2010-11-26 16:06:47 +0300 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-11-26 16:06:47 +0300 |
commit | e5eddec6f9baf27aab61931bb657bc9764a2f6b4 (patch) | |
tree | a5066501833eaaf01004521a64ddbe84d47714a0 | |
parent | 46bf66f9f5c6d078e2c51407662e8774c16cf1ef (diff) | |
download | accel-ppp-e5eddec6f9baf27aab61931bb657bc9764a2f6b4.tar.gz accel-ppp-e5eddec6f9baf27aab61931bb657bc9764a2f6b4.zip |
cli: show sessions: implemented sorting by username and regexp matching username
-rw-r--r-- | accel-pptpd/cli/std_cmd.c | 120 | ||||
-rw-r--r-- | accel-pptpd/triton/mempool.c | 5 |
2 files changed, 120 insertions, 5 deletions
diff --git a/accel-pptpd/cli/std_cmd.c b/accel-pptpd/cli/std_cmd.c index 47604df8..75ff900d 100644 --- a/accel-pptpd/cli/std_cmd.c +++ b/accel-pptpd/cli/std_cmd.c @@ -6,6 +6,8 @@ #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) { @@ -51,19 +53,81 @@ static void exit_help(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]; + struct row_t + { + struct list_head entry; + char buf[128]; + char *match_key; + char *order_key; + }; char ip_str[17]; char *state_str; char time_str[12]; time_t uptime; int day,hour,min,sec; struct ppp_t *ppp; + int i; + enum order_type {ORDER_NONE, ORDER_USERNAME}; + enum match_type {MATCH_NONE, MATCH_USERNAME}; + int order = ORDER_NONE; + int match = MATCH_NONE; + struct row_t *row, *row2, *row3; + pcre *re; + const char *pcre_err; + int pcre_offset; + LIST_HEAD(rows); + LIST_HEAD(temp_rows); + + for (i = 2; i < fields_cnt; i++) { + if (!strcmp(fields[i], "order")) { + if (i == fields_cnt - 1) + return CLI_CMD_SYNTAX; + i++; + if (!strcmp(fields[i], "username")) + order = ORDER_USERNAME; + else { + cli_send(client, "only order by username is supported yet\r\n"); + return CLI_CMD_OK; + } + } else if (!strcmp(fields[i], "match")) { + if (i == fields_cnt - 2) + return CLI_CMD_SYNTAX; + i++; + if (!strcmp(fields[i], "username")) + match = MATCH_USERNAME; + else { + cli_send(client, "only match by username is supported yet\r\n"); + return CLI_CMD_OK; + } + i++; + re = pcre_compile2(fields[i], 0, NULL, &pcre_err, &pcre_offset, NULL); + if (!re) { + cli_sendv(client, "match: %s at %i\r\n", pcre_err, pcre_offset); + return CLI_CMD_OK; + } + } else + return CLI_CMD_SYNTAX; + } + 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) { + row = _malloc(sizeof(*row)); + if (!row) { + log_emerg("out of memory\n"); + cli_send(client, "out of memory\r\n"); + break; + } + + if (order == ORDER_USERNAME) + row->order_key = _strdup(ppp->username); + + if (match == MATCH_USERNAME) + row->match_key = _strdup(ppp->username); + u_inet_ntoa(ppp->peer_ipaddr, ip_str); switch (ppp->state) { @@ -95,17 +159,65 @@ static int show_ses_exec(const char *cmd, char * const *fields, int fields_cnt, else 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); - cli_send(client, buf); + sprintf(row->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 (order || match) + list_add_tail(&row->entry, &temp_rows); + else + list_add_tail(&row->entry, &rows); + //cli_send(client, buf); } pthread_rwlock_unlock(&ppp_lock); + + if (match || order) { + while (!list_empty(&temp_rows)) { + row = list_entry(temp_rows.next, typeof(*row), entry); + list_del(&row->entry); + if (match == MATCH_USERNAME) { + if (pcre_exec(re, NULL, row->match_key, strlen(row->match_key), 0, 0, NULL, 0) < 0) { + _free(row->match_key); + if (order) + _free(row->order_key); + _free(row); + continue; + } + } + if (order == ORDER_USERNAME) { + row3 = NULL; + list_for_each_entry(row2, &rows, 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, &rows); + } else + list_add_tail(&row->entry, &rows); + } + } + + while (!list_empty(&rows)) { + row = list_entry(rows.next, typeof(*row), entry); + list_del(&row->entry); + cli_send(client, row->buf); + if (match == MATCH_USERNAME) + _free(row->match_key); + if (order == ORDER_USERNAME) + _free(row->order_key); + _free(row); + } + + if (match == MATCH_USERNAME) + pcre_free(re); return CLI_CMD_OK; } static void show_ses_help(char * const *fields, int fields_cnt, void *client) { - cli_send(client, "show sessions - shows all sessions\r\n"); + cli_send(client, "show sessions [order username] [match username <regexp>] - shows all sessions\r\n"); } //============================= diff --git a/accel-pptpd/triton/mempool.c b/accel-pptpd/triton/mempool.c index 5ffc5e36..da11825c 100644 --- a/accel-pptpd/triton/mempool.c +++ b/accel-pptpd/triton/mempool.c @@ -253,7 +253,10 @@ void sigclean(int num) while (!list_empty(&p->items)) { it = list_entry(p->items.next, typeof(*it), entry); list_del(&it->entry); - _free(it); + if (p->mmap) + munmap(it, size); + else + _free(it); triton_stat.mempool_allocated -= size; triton_stat.mempool_available -= size; } |