pbx: Create pbx_ignorepat.c for management of 'struct ast_ignorepat'.

This changes context ignore patterns from a linked list to a vector,
makes 'struct ast_ignorepat' opaque to pbx.c.

Although ast_walk_context_ignorepats is maintained the procedure is no
longer efficient except for the first call (inc==NULL).  This
functionality is replaced by two new functions implemented by vector
macros.
* ast_context_ignorepats_count (AST_VECTOR_SIZE)
* ast_context_ignorepats_get (AST_VECTOR_GET)

As with ast_walk_context_ignorepats callers of these functions are
expected to have locked contexts.  Only a few places in Asterisk walked
the ignorepats, they have been converted to use the new functions.

Change-Id: I78f2157d275ef1b7d624b4ff7d770d38e5d7f20a
changes/13/3213/5
Corey Farrell 9 years ago
parent be36bd7ca5
commit e2e8713b84

@ -1228,7 +1228,7 @@ const char *ast_get_context_name(struct ast_context *con);
const char *ast_get_extension_name(struct ast_exten *exten); const char *ast_get_extension_name(struct ast_exten *exten);
struct ast_context *ast_get_extension_context(struct ast_exten *exten); struct ast_context *ast_get_extension_context(struct ast_exten *exten);
const char *ast_get_include_name(const struct ast_include *include); const char *ast_get_include_name(const struct ast_include *include);
const char *ast_get_ignorepat_name(struct ast_ignorepat *ip); const char *ast_get_ignorepat_name(const struct ast_ignorepat *ip);
const char *ast_get_switch_name(struct ast_sw *sw); const char *ast_get_switch_name(struct ast_sw *sw);
const char *ast_get_switch_data(struct ast_sw *sw); const char *ast_get_switch_data(struct ast_sw *sw);
int ast_get_switch_eval(struct ast_sw *sw); int ast_get_switch_eval(struct ast_sw *sw);
@ -1250,7 +1250,7 @@ void *ast_get_extension_app_data(struct ast_exten *e);
const char *ast_get_context_registrar(struct ast_context *c); const char *ast_get_context_registrar(struct ast_context *c);
const char *ast_get_extension_registrar(struct ast_exten *e); const char *ast_get_extension_registrar(struct ast_exten *e);
const char *ast_get_include_registrar(const struct ast_include *i); const char *ast_get_include_registrar(const struct ast_include *i);
const char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip); const char *ast_get_ignorepat_registrar(const struct ast_ignorepat *ip);
const char *ast_get_switch_registrar(struct ast_sw *sw); const char *ast_get_switch_registrar(struct ast_sw *sw);
/*! @} */ /*! @} */
@ -1263,8 +1263,8 @@ struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten,
struct ast_exten *priority); struct ast_exten *priority);
const struct ast_include *ast_walk_context_includes(const struct ast_context *con, const struct ast_include *ast_walk_context_includes(const struct ast_context *con,
const struct ast_include *inc); const struct ast_include *inc);
struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con, const struct ast_ignorepat *ast_walk_context_ignorepats(const struct ast_context *con,
struct ast_ignorepat *ip); const struct ast_ignorepat *ip);
struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw); struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw);
/*! @} */ /*! @} */
@ -1272,6 +1272,8 @@ struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw
/*! @{ */ /*! @{ */
int ast_context_includes_count(const struct ast_context *con); int ast_context_includes_count(const struct ast_context *con);
const struct ast_include *ast_context_includes_get(const struct ast_context *con, int idx); const struct ast_include *ast_context_includes_get(const struct ast_context *con, int idx);
int ast_context_ignorepats_count(const struct ast_context *con);
const struct ast_ignorepat *ast_context_ignorepats_get(const struct ast_context *con, int idx);
/*! @} */ /*! @} */
/*! /*!

@ -265,13 +265,6 @@ struct ast_sw {
char stuff[0]; char stuff[0];
}; };
/*! \brief ast_ignorepat: Ignore patterns in dial plan */
struct ast_ignorepat {
const char *registrar;
struct ast_ignorepat *next;
const char pattern[0];
};
/*! \brief match_char: forms a syntax tree for quick matching of extension patterns */ /*! \brief match_char: forms a syntax tree for quick matching of extension patterns */
struct match_char struct match_char
{ {
@ -303,7 +296,7 @@ struct ast_context {
struct match_char *pattern_tree; /*!< A tree to speed up extension pattern matching */ struct match_char *pattern_tree; /*!< A tree to speed up extension pattern matching */
struct ast_context *next; /*!< Link them together */ struct ast_context *next; /*!< Link them together */
struct ast_includes includes; /*!< Include other contexts */ struct ast_includes includes; /*!< Include other contexts */
struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */ struct ast_ignorepats ignorepats; /*!< Patterns for which to continue playing dialtone */
char *registrar; /*!< Registrar -- make sure you malloc this, as the registrar may have to survive module unloads */ char *registrar; /*!< Registrar -- make sure you malloc this, as the registrar may have to survive module unloads */
int refcount; /*!< each module that would have created this context should inc/dec this as appropriate */ int refcount; /*!< each module that would have created this context should inc/dec this as appropriate */
int autohints; /*!< Whether autohints support is enabled or not */ int autohints; /*!< Whether autohints support is enabled or not */
@ -2381,7 +2374,7 @@ struct fake_context /* this struct is purely for matching in the hashtab */
struct match_char *pattern_tree; struct match_char *pattern_tree;
struct ast_context *next; struct ast_context *next;
struct ast_includes includes; struct ast_includes includes;
struct ast_ignorepat *ignorepats; struct ast_ignorepats ignorepats;
const char *registrar; const char *registrar;
int refcount; int refcount;
int autohints; int autohints;
@ -5394,7 +5387,6 @@ static int show_dialplan_helper(int fd, const char *context, const char *exten,
while ( (c = ast_walk_contexts(c)) ) { while ( (c = ast_walk_contexts(c)) ) {
int idx; int idx;
struct ast_exten *e; struct ast_exten *e;
struct ast_ignorepat *ip;
#ifndef LOW_MEMORY #ifndef LOW_MEMORY
char buf[1024], buf2[1024]; char buf[1024], buf2[1024];
#else #else
@ -5512,10 +5504,11 @@ static int show_dialplan_helper(int fd, const char *context, const char *exten,
} }
/* walk ignore patterns and write info ... */ /* walk ignore patterns and write info ... */
ip = NULL; for (idx = 0; idx < ast_context_ignorepats_count(c); idx++) {
while ( (ip = ast_walk_context_ignorepats(c, ip)) ) { const struct ast_ignorepat *ip = ast_context_ignorepats_get(c, idx);
const char *ipname = ast_get_ignorepat_name(ip); const char *ipname = ast_get_ignorepat_name(ip);
char ignorepat[AST_MAX_EXTENSION]; char ignorepat[AST_MAX_EXTENSION];
snprintf(buf, sizeof(buf), "'%s'", ipname); snprintf(buf, sizeof(buf), "'%s'", ipname);
snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname); snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname);
if (!exten || ast_extension_match(ignorepat, exten)) { if (!exten || ast_extension_match(ignorepat, exten)) {
@ -5758,7 +5751,6 @@ static int manager_show_dialplan_helper(struct mansession *s, const struct messa
while ( (c = ast_walk_contexts(c)) ) { while ( (c = ast_walk_contexts(c)) ) {
int idx; int idx;
struct ast_exten *e; struct ast_exten *e;
struct ast_ignorepat *ip;
if (context && strcmp(ast_get_context_name(c), context) != 0) if (context && strcmp(ast_get_context_name(c), context) != 0)
continue; /* not the name we want */ continue; /* not the name we want */
@ -5829,8 +5821,8 @@ static int manager_show_dialplan_helper(struct mansession *s, const struct messa
} }
} }
ip = NULL; /* walk ignore patterns and write info ... */ for (idx = 0; idx < ast_context_ignorepats_count(c); idx++) {
while ( (ip = ast_walk_context_ignorepats(c, ip)) ) { const struct ast_ignorepat *ip = ast_context_ignorepats_get(c, idx);
const char *ipname = ast_get_ignorepat_name(ip); const char *ipname = ast_get_ignorepat_name(ip);
char ignorepat[AST_MAX_EXTENSION]; char ignorepat[AST_MAX_EXTENSION];
@ -6094,7 +6086,7 @@ struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts,
tmp->root_table = NULL; tmp->root_table = NULL;
tmp->registrar = ast_strdup(registrar); tmp->registrar = ast_strdup(registrar);
AST_VECTOR_INIT(&tmp->includes, 0); AST_VECTOR_INIT(&tmp->includes, 0);
tmp->ignorepats = NULL; AST_VECTOR_INIT(&tmp->ignorepats, 0);
tmp->refcount = 1; tmp->refcount = 1;
} else { } else {
ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name); ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
@ -6146,7 +6138,6 @@ AST_LIST_HEAD_NOLOCK(store_hints, store_hint);
static void context_merge_incls_swits_igps_other_registrars(struct ast_context *new, struct ast_context *old, const char *registrar) static void context_merge_incls_swits_igps_other_registrars(struct ast_context *new, struct ast_context *old, const char *registrar)
{ {
int idx; int idx;
struct ast_ignorepat *ip;
struct ast_sw *sw; struct ast_sw *sw;
ast_verb(3, "merging incls/swits/igpats from old(%s) to new(%s) context, registrar = %s\n", ast_get_context_name(old), ast_get_context_name(new), registrar); ast_verb(3, "merging incls/swits/igpats from old(%s) to new(%s) context, registrar = %s\n", ast_get_context_name(old), ast_get_context_name(new), registrar);
@ -6169,9 +6160,12 @@ static void context_merge_incls_swits_igps_other_registrars(struct ast_context *
} }
/* walk thru ignorepats ... */ /* walk thru ignorepats ... */
for (ip = NULL; (ip = ast_walk_context_ignorepats(old, ip)); ) { for (idx = 0; idx < ast_context_ignorepats_count(old); idx++) {
if (strcmp(ast_get_ignorepat_registrar(ip), registrar) == 0) const struct ast_ignorepat *ip = ast_context_ignorepats_get(old, idx);
if (strcmp(ast_get_ignorepat_registrar(ip), registrar) == 0) {
continue; /* not mine */ continue; /* not mine */
}
ast_context_add_ignorepat2(new, ast_get_ignorepat_name(ip), ast_get_ignorepat_registrar(ip)); ast_context_add_ignorepat2(new, ast_get_ignorepat_name(ip), ast_get_ignorepat_registrar(ip));
} }
} }
@ -6700,24 +6694,20 @@ int ast_context_remove_ignorepat(const char *context, const char *ignorepat, con
int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar) int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
{ {
struct ast_ignorepat *ip, *ipl = NULL; int idx;
ast_wrlock_context(con); ast_wrlock_context(con);
for (ip = con->ignorepats; ip; ip = ip->next) { for (idx = 0; idx < ast_context_ignorepats_count(con); idx++) {
if (!strcmp(ip->pattern, ignorepat) && struct ast_ignorepat *ip = AST_VECTOR_GET(&con->ignorepats, idx);
(!registrar || (registrar == ip->registrar))) {
if (ipl) { if (!strcmp(ast_get_ignorepat_name(ip), ignorepat) &&
ipl->next = ip->next; (!registrar || (registrar == ast_get_ignorepat_registrar(ip)))) {
ast_free(ip); AST_VECTOR_REMOVE_ORDERED(&con->ignorepats, idx);
} else { ignorepat_free(ip);
con->ignorepats = ip->next;
ast_free(ip);
}
ast_unlock_context(con); ast_unlock_context(con);
return 0; return 0;
} }
ipl = ip;
} }
ast_unlock_context(con); ast_unlock_context(con);
@ -6744,41 +6734,29 @@ int ast_context_add_ignorepat(const char *context, const char *value, const char
int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar) int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
{ {
struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; struct ast_ignorepat *ignorepat = ignorepat_alloc(value, registrar);
int length; int idx;
char *pattern;
length = sizeof(struct ast_ignorepat); if (!ignorepat) {
length += strlen(value) + 1;
if (!(ignorepat = ast_calloc(1, length)))
return -1; return -1;
/* The cast to char * is because we need to write the initial value. }
* The field is not supposed to be modified otherwise. Also, gcc 4.2
* sees the cast as dereferencing a type-punned pointer and warns about
* it. This is the workaround (we're telling gcc, yes, that's really
* what we wanted to do).
*/
pattern = (char *) ignorepat->pattern;
strcpy(pattern, value);
ignorepat->next = NULL;
ignorepat->registrar = registrar;
ast_wrlock_context(con); ast_wrlock_context(con);
for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { for (idx = 0; idx < ast_context_ignorepats_count(con); idx++) {
ignorepatl = ignorepatc; const struct ast_ignorepat *i = ast_context_ignorepats_get(con, idx);
if (!strcasecmp(ignorepatc->pattern, value)) {
if (!strcasecmp(ast_get_ignorepat_name(i), value)) {
/* Already there */ /* Already there */
ast_unlock_context(con); ast_unlock_context(con);
ast_free(ignorepat); ignorepat_free(ignorepat);
errno = EEXIST; errno = EEXIST;
return -1; return -1;
} }
} }
if (ignorepatl) AST_VECTOR_APPEND(&con->ignorepats, ignorepat);
ignorepatl->next = ignorepat;
else
con->ignorepats = ignorepat;
ast_unlock_context(con); ast_unlock_context(con);
return 0;
return 0;
} }
int ast_ignore_pattern(const char *context, const char *pattern) int ast_ignore_pattern(const char *context, const char *pattern)
@ -6789,10 +6767,12 @@ int ast_ignore_pattern(const char *context, const char *pattern)
ast_rdlock_contexts(); ast_rdlock_contexts();
con = ast_context_find(context); con = ast_context_find(context);
if (con) { if (con) {
struct ast_ignorepat *pat; int idx;
for (pat = con->ignorepats; pat; pat = pat->next) { for (idx = 0; idx < ast_context_ignorepats_count(con); idx++) {
if (ast_extension_match(pat->pattern, pattern)) { const struct ast_ignorepat *pat = ast_context_ignorepats_get(con, idx);
if (ast_extension_match(ast_get_ignorepat_name(pat), pattern)) {
ret = 1; ret = 1;
break; break;
} }
@ -7797,18 +7777,16 @@ static void __ast_internal_context_destroy( struct ast_context *con)
{ {
struct ast_sw *sw; struct ast_sw *sw;
struct ast_exten *e, *el, *en; struct ast_exten *e, *el, *en;
struct ast_ignorepat *ipi;
struct ast_context *tmp = con; struct ast_context *tmp = con;
/* Free includes */ /* Free includes */
AST_VECTOR_CALLBACK_VOID(&tmp->includes, include_free); AST_VECTOR_CALLBACK_VOID(&tmp->includes, include_free);
AST_VECTOR_FREE(&tmp->includes); AST_VECTOR_FREE(&tmp->includes);
for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */ /* Free ignorepats */
struct ast_ignorepat *ipl = ipi; AST_VECTOR_CALLBACK_VOID(&tmp->ignorepats, ignorepat_free);
ipi = ipi->next; AST_VECTOR_FREE(&tmp->ignorepats);
ast_free(ipl);
}
if (tmp->registrar) if (tmp->registrar)
ast_free(tmp->registrar); ast_free(tmp->registrar);
@ -7868,25 +7846,17 @@ void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *context
/* then search thru and remove any extens that match registrar. */ /* then search thru and remove any extens that match registrar. */
struct ast_hashtab_iter *exten_iter; struct ast_hashtab_iter *exten_iter;
struct ast_hashtab_iter *prio_iter; struct ast_hashtab_iter *prio_iter;
struct ast_ignorepat *ip, *ipl = NULL, *ipn = NULL;
struct ast_sw *sw = NULL; struct ast_sw *sw = NULL;
int idx; int idx;
/* remove any ignorepats whose registrar matches */ /* remove any ignorepats whose registrar matches */
for (ip = tmp->ignorepats; ip; ip = ipn) { for (idx = ast_context_ignorepats_count(tmp) - 1; idx >= 0; idx--) {
ipn = ip->next; struct ast_ignorepat *ip = AST_VECTOR_GET(&tmp->ignorepats, idx);
if (!strcmp(ip->registrar, registrar)) {
if (ipl) { if (!strcmp(ast_get_ignorepat_registrar(ip), registrar)) {
ipl->next = ip->next; AST_VECTOR_REMOVE_ORDERED(&tmp->ignorepats, idx);
ast_free(ip); ignorepat_free(ip);
continue; /* don't change ipl */
} else {
tmp->ignorepats = ip->next;
ast_free(ip);
continue; /* don't change ipl */
}
} }
ipl = ip;
} }
/* remove any includes whose registrar matches */ /* remove any includes whose registrar matches */
for (idx = ast_context_includes_count(tmp) - 1; idx >= 0; idx--) { for (idx = ast_context_includes_count(tmp) - 1; idx >= 0; idx--) {
@ -7955,7 +7925,7 @@ void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *context
/* delete the context if it's registrar matches, is empty, has refcount of 1, */ /* delete the context if it's registrar matches, is empty, has refcount of 1, */
/* it's not empty, if it has includes, ignorepats, or switches that are registered from /* it's not empty, if it has includes, ignorepats, or switches that are registered from
another registrar. It's not empty if there are any extensions */ another registrar. It's not empty if there are any extensions */
if (strcmp(tmp->registrar, registrar) == 0 && tmp->refcount < 2 && !tmp->root && !tmp->ignorepats && !ast_context_includes_count(tmp) && AST_LIST_EMPTY(&tmp->alts)) { if (strcmp(tmp->registrar, registrar) == 0 && tmp->refcount < 2 && !tmp->root && !ast_context_ignorepats_count(tmp) && !ast_context_includes_count(tmp) && AST_LIST_EMPTY(&tmp->alts)) {
ast_debug(1, "delete ctx %s %s\n", tmp->name, tmp->registrar); ast_debug(1, "delete ctx %s %s\n", tmp->name, tmp->registrar);
ast_hashtab_remove_this_object(contexttab, tmp); ast_hashtab_remove_this_object(contexttab, tmp);
@ -8356,11 +8326,6 @@ const char *ast_get_extension_label(struct ast_exten *exten)
return exten ? exten->label : NULL; return exten ? exten->label : NULL;
} }
const char *ast_get_ignorepat_name(struct ast_ignorepat *ip)
{
return ip ? ip->pattern : NULL;
}
int ast_get_extension_priority(struct ast_exten *exten) int ast_get_extension_priority(struct ast_exten *exten)
{ {
return exten ? exten->priority : -1; return exten ? exten->priority : -1;
@ -8379,11 +8344,6 @@ const char *ast_get_extension_registrar(struct ast_exten *e)
return e ? e->registrar : NULL; return e ? e->registrar : NULL;
} }
const char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip)
{
return ip ? ip->registrar : NULL;
}
int ast_get_extension_matchcid(struct ast_exten *e) int ast_get_extension_matchcid(struct ast_exten *e)
{ {
return e ? e->matchcid : 0; return e ? e->matchcid : 0;
@ -8495,13 +8455,47 @@ const struct ast_include *ast_context_includes_get(const struct ast_context *con
return AST_VECTOR_GET(&con->includes, idx); return AST_VECTOR_GET(&con->includes, idx);
} }
struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con, const struct ast_ignorepat *ast_walk_context_ignorepats(const struct ast_context *con,
struct ast_ignorepat *ip) const struct ast_ignorepat *ip)
{ {
if (!ip) if (!con) {
return con ? con->ignorepats : NULL; return NULL;
else }
return ip->next;
if (ip) {
int idx;
int next = 0;
for (idx = 0; idx < ast_context_ignorepats_count(con); idx++) {
const struct ast_ignorepat *i = ast_context_ignorepats_get(con, idx);
if (next) {
return i;
}
if (ip == i) {
next = 1;
}
}
return NULL;
}
if (!ast_context_ignorepats_count(con)) {
return NULL;
}
return ast_context_ignorepats_get(con, 0);
}
int ast_context_ignorepats_count(const struct ast_context *con)
{
return AST_VECTOR_SIZE(&con->ignorepats);
}
const struct ast_ignorepat *ast_context_ignorepats_get(const struct ast_context *con, int idx)
{
return AST_VECTOR_GET(&con->ignorepats, idx);
} }
int ast_context_verify_includes(struct ast_context *con) int ast_context_verify_includes(struct ast_context *con)

@ -0,0 +1,82 @@
/*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 2016, CFWare, LLC
*
* Corey Farrell <git@cfware.com>
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
/*! \file
*
* \brief Dialplan context ignorepat routines.
*
* \author Corey Farrell <git@cfware.com>
*/
/*** MODULEINFO
<support_level>core</support_level>
***/
#include "asterisk.h"
ASTERISK_REGISTER_FILE()
#include "asterisk/_private.h"
#include "asterisk/pbx.h"
#include "pbx_private.h"
/*! \brief ast_ignorepat: Ignore patterns in dial plan */
struct ast_ignorepat {
const char *registrar;
const char pattern[0];
};
const char *ast_get_ignorepat_name(const struct ast_ignorepat *ip)
{
return ip ? ip->pattern : NULL;
}
const char *ast_get_ignorepat_registrar(const struct ast_ignorepat *ip)
{
return ip ? ip->registrar : NULL;
}
struct ast_ignorepat *ignorepat_alloc(const char *value, const char *registrar)
{
struct ast_ignorepat *ignorepat;
int length = strlen(value) + 1;
char *pattern;
/* allocate new include structure ... */
ignorepat = ast_calloc(1, sizeof(*ignorepat) + length);
if (!ignorepat) {
return NULL;
}
/* The cast to char * is because we need to write the initial value.
* The field is not supposed to be modified otherwise. Also, gcc 4.2
* sees the cast as dereferencing a type-punned pointer and warns about
* it. This is the workaround (we're telling gcc, yes, that's really
* what we wanted to do).
*/
pattern = (char *) ignorepat->pattern;
strcpy(pattern, value);
ignorepat->registrar = registrar;
return ignorepat;
}
void ignorepat_free(struct ast_ignorepat *ip)
{
ast_free(ip);
}

@ -31,6 +31,13 @@ void set_ext_pri(struct ast_channel *c, const char *exten, int pri);
/*! pbx.c function needed by pbx_app.c */ /*! pbx.c function needed by pbx_app.c */
void unreference_cached_app(struct ast_app *app); void unreference_cached_app(struct ast_app *app);
/*! pbx_ignorepat.c */
struct ast_ignorepat;
AST_VECTOR(ast_ignorepats, struct ast_ignorepat *);
struct ast_ignorepat *ignorepat_alloc(const char *value, const char *registrar);
void ignorepat_free(struct ast_ignorepat *ip);
/*! pbx_includes.c */ /*! pbx_includes.c */
struct ast_include; struct ast_include;
AST_VECTOR(ast_includes, struct ast_include *); AST_VECTOR(ast_includes, struct ast_include *);

@ -213,15 +213,25 @@ static int lookup_ci(struct ast_context *c, const char *name)
/*! \brief return true if 'name' is in the ignorepats for context c */ /*! \brief return true if 'name' is in the ignorepats for context c */
static int lookup_c_ip(struct ast_context *c, const char *name) static int lookup_c_ip(struct ast_context *c, const char *name)
{ {
struct ast_ignorepat *ip = NULL; int idx;
int ret = 0;
if (ast_rdlock_context(c)) /* error, skip */ if (ast_rdlock_context(c)) {
/* error, skip */
return 0; return 0;
while ( (ip = ast_walk_context_ignorepats(c, ip)) ) }
if (!strcmp(name, ast_get_ignorepat_name(ip)))
for (idx = 0; idx < ast_context_ignorepats_count(c); idx++) {
const struct ast_ignorepat *ip = ast_context_ignorepats_get(c, idx);
if (!strcmp(name, ast_get_ignorepat_name(ip))) {
ret = -1;
break; break;
}
}
ast_unlock_context(c); ast_unlock_context(c);
return ip ? -1 /* success */ : 0;
return ret;
} }
/*! \brief moves to the n-th word in the string, or empty string if none */ /*! \brief moves to the n-th word in the string, or empty string if none */
@ -918,7 +928,6 @@ static char *handle_cli_dialplan_save(struct ast_cli_entry *e, int cmd, struct a
int context_header_written = 0; int context_header_written = 0;
struct ast_exten *ext, *last_written_e = NULL; struct ast_exten *ext, *last_written_e = NULL;
int idx; int idx;
struct ast_ignorepat *ip;
struct ast_sw *sw; struct ast_sw *sw;
/* try to lock context and fireout all info */ /* try to lock context and fireout all info */
@ -1019,7 +1028,9 @@ static char *handle_cli_dialplan_save(struct ast_cli_entry *e, int cmd, struct a
fprintf(output, "\n"); fprintf(output, "\n");
/* fireout ignorepats ... */ /* fireout ignorepats ... */
for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) { for (idx = 0; idx < ast_context_ignorepats_count(c); idx++) {
const struct ast_ignorepat *ip = ast_context_ignorepats_get(c, idx);
if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0) if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0)
continue; /* not mine */ continue; /* not mine */
PUT_CTX_HDR; PUT_CTX_HDR;
@ -1486,12 +1497,13 @@ static char *complete_dialplan_remove_ignorepat(struct ast_cli_args *a)
} }
for (c = NULL; !ret && (c = ast_walk_contexts(c));) { for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
struct ast_ignorepat *ip; int idx;
if (ast_rdlock_context(c)) /* error, skip it */ if (ast_rdlock_context(c)) /* error, skip it */
continue; continue;
for (idx = 0; idx < ast_context_ignorepats_count(c); idx++) {
for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) { const struct ast_ignorepat *ip = ast_context_ignorepats_get(c, idx);
if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) { if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) {
/* n-th match */ /* n-th match */
struct ast_context *cw = NULL; struct ast_context *cw = NULL;

@ -4410,7 +4410,7 @@ static int context_used(struct ael_extension *exten_list, struct ast_context *co
{ {
struct ael_extension *exten; struct ael_extension *exten;
/* Check the simple elements first */ /* Check the simple elements first */
if (ast_walk_context_extensions(context, NULL) || ast_context_includes_count(context) || ast_walk_context_ignorepats(context, NULL) || ast_walk_context_switches(context, NULL)) { if (ast_walk_context_extensions(context, NULL) || ast_context_includes_count(context) || ast_context_ignorepats_count(context) || ast_walk_context_switches(context, NULL)) {
return 1; return 1;
} }
for (exten = exten_list; exten; exten = exten->next_exten) { for (exten = exten_list; exten; exten = exten->next_exten) {

@ -670,12 +670,6 @@ const struct ast_include *ast_walk_context_includes(const struct ast_context *co
return NULL; return NULL;
} }
struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip);
struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip)
{
return NULL;
}
struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw); struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw);
struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw) struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw)
{ {

@ -4402,6 +4402,31 @@ struct ast_include *localized_walk_context_includes(struct ast_context *con,
return ast_walk_context_includes(con, inc); return ast_walk_context_includes(con, inc);
} }
static struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con,
struct ast_ignorepat *ip);
static struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con,
struct ast_ignorepat *ip)
{
if (!ip)
return con ? con->ignorepats : NULL;
else
return ip->next;
}
int ast_context_ignorepats_count(struct ast_context *con);
int ast_context_ignorepats_count(struct ast_context *con)
{
int c = 0;
struct ast_ignorepat *ip = NULL;
while ((ip = ast_walk_context_ignorepats(con, ip))) {
c++;
}
return c;
}
static struct ast_sw *ast_walk_context_switches(struct ast_context *con, static struct ast_sw *ast_walk_context_switches(struct ast_context *con,
struct ast_sw *sw); struct ast_sw *sw);

Loading…
Cancel
Save