Index: main/manager.c =================================================================== --- main/manager.c (Revision 263582) +++ main/manager.c (Arbeitskopie) @@ -51,6 +51,8 @@ #include #include #include +#include +#include #include "asterisk/channel.h" #include "asterisk/file.h" @@ -775,6 +777,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. @@ -833,6 +840,7 @@ int writetimeout; /*!< Timeout for ast_carefulwrite() */ int pending_event; /*!< Pending events indicator in case when waiting_thread is NULL */ time_t noncetime; /*!< Timer for nonce value expiration */ + struct event_filter *filter; unsigned long oldnonce; /*!< Stale nonce value */ unsigned long nc; /*!< incremental nonce counter */ AST_LIST_HEAD_NOLOCK(mansession_datastores, ast_datastore) datastores; /*!< Data stores on the session */ @@ -880,6 +888,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; char *a1_hash; /*!< precalculated A1 for Digest auth */ AST_RWLIST_ENTRY(ast_manager_user) list; }; @@ -2124,6 +2133,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); s->session->sessionstart_tv = ast_tvnow(); set_eventmask(s, astman_get_header(m, "Events")); @@ -3608,6 +3618,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 @@ -3626,8 +3649,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); } @@ -5847,6 +5873,7 @@ while ((cat = ast_category_browse(cfg, cat))) { struct ast_ha *oldha; + struct event_filter *filter = NULL; if (!strcasecmp(cat, "general")) { continue; @@ -5869,8 +5896,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; @@ -5899,10 +5936,23 @@ } 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);