Index: asterisk-1.6.1/main/manager.c =================================================================== --- asterisk-1.6.1.orig/main/manager.c 2009-04-08 15:52:09.000000000 +0200 +++ asterisk-1.6.1/main/manager.c 2009-04-08 17:47:02.000000000 +0200 @@ -51,6 +51,8 @@ #include #include #include +#include +#include #include "asterisk/channel.h" #include "asterisk/file.h" @@ -149,6 +151,11 @@ {{ "restart", "gracefully", NULL }}, }; +struct event_filter { + regex_t regx; + struct event_filter *next; +}; + /* In order to understand what the heck is going on with the * mansession_session and mansession structs, we need to have a bit of a history * lesson. @@ -206,6 +213,7 @@ struct eventqent *last_ev; /*!< last event processed. */ int writetimeout; /*!< Timeout for ast_carefulwrite() */ int pending_event; /*!< Pending events indicator in case when waiting_thread is NULL */ + struct event_filter *filter; AST_LIST_HEAD_NOLOCK(mansession_datastores, ast_datastore) datastores; /*!< Data stores on the session */ AST_LIST_ENTRY(mansession_session) list; }; @@ -240,6 +248,7 @@ int writetimeout; /*! Per user Timeout for ast_carefulwrite() */ int displayconnects; /*!< XXX unused */ int keep; /*!< mark entries created on a reload */ + struct event_filter *filter; AST_RWLIST_ENTRY(ast_manager_user) list; }; @@ -1120,6 +1129,7 @@ s->session->readperm = user->readperm; s->session->writeperm = user->writeperm; s->session->writetimeout = user->writetimeout; + s->session->filter = user->filter; s->session->sessionstart = time(NULL); set_eventmask(s, astman_get_header(m, "Events")); @@ -2616,6 +2626,19 @@ return 0; } +static int match_filter(struct mansession *s, const char *data) +{ + struct event_filter *filter = s->session->filter; + + while (filter) { + if (!regexec(&filter->regx, data, 0, NULL, 0)) { + return 1; // match + } + filter = filter->next; + } + return 0; +} + /*! * Send any applicable events to the client listening on this socket. * Wait only for a finite time on each event, and drop all events whether @@ -2634,8 +2657,11 @@ if (!ret && s->session->authenticated && (s->session->readperm & eqe->category) == eqe->category && (s->session->send_events & eqe->category) == eqe->category) { - if (send_string(s, eqe->eventdata) < 0) - ret = -1; /* don't send more */ + + if (!match_filter(s, eqe->eventdata)) { + if (send_string(s, eqe->eventdata) < 0) + ret = -1; /* don't send more */ + } } s->session->last_ev = unref_event(s->session->last_ev); } @@ -4216,6 +4242,7 @@ while ((cat = ast_category_browse(cfg, cat))) { struct ast_ha *oldha; + struct event_filter *filter = NULL; if (!strcasecmp(cat, "general")) continue; @@ -4236,8 +4263,18 @@ /* Insert into list */ AST_RWLIST_INSERT_TAIL(&users, user, list); + } else { + struct event_filter *filter; + while (user->filter) { + filter = user->filter; + user->filter = filter->next; + + regfree(&filter->regx); + free(filter); + } } + /* Make sure we keep this user and don't destroy it during cleanup */ user->keep = 1; oldha = user->ha; @@ -4264,9 +4301,23 @@ ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", var->value, var->lineno); else user->writetimeout = value; + } else if (!strcasecmp(var->name, "eventfilter")) { + const char *value = var->value; + struct event_filter *new = malloc(sizeof(struct event_filter)); + if (new) { + if (regcomp(&new->regx, value, 0)) { + // failed + free(new); + } else { + new->next = filter; + filter = new; + } + } + } else ast_debug(1, "%s is an unknown option.\n", var->name); } + user->filter = filter; ast_free_ha(oldha); } ast_config_destroy(cfg);