summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-11-26 16:06:47 +0300
committerKozlov Dmitry <dima@server>2010-11-26 16:06:47 +0300
commite5eddec6f9baf27aab61931bb657bc9764a2f6b4 (patch)
treea5066501833eaaf01004521a64ddbe84d47714a0
parent46bf66f9f5c6d078e2c51407662e8774c16cf1ef (diff)
downloadaccel-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.c120
-rw-r--r--accel-pptpd/triton/mempool.c5
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;
}