diff --git a/apps/app_macro.c b/apps/app_macro.c index d2da165237..26e4262b1b 100644 --- a/apps/app_macro.c +++ b/apps/app_macro.c @@ -190,8 +190,8 @@ static void macro_fixup(void *data, struct ast_channel *old_chan, struct ast_cha static struct ast_exten *find_matching_priority(struct ast_context *c, const char *exten, int priority, const char *callerid) { struct ast_exten *e; - struct ast_include *i; struct ast_context *c2; + int idx; for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) { if (ast_extension_match(ast_get_extension_name(e), exten)) { @@ -210,7 +210,9 @@ static struct ast_exten *find_matching_priority(struct ast_context *c, const cha } /* No match; run through includes */ - for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) { + for (idx = 0; idx < ast_context_includes_count(c); idx++) { + const struct ast_include *i = ast_context_includes_get(c, idx); + for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) { if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) { e = find_matching_priority(c2, exten, priority, callerid); diff --git a/apps/app_while.c b/apps/app_while.c index 273b466787..cc048dfb3a 100644 --- a/apps/app_while.c +++ b/apps/app_while.c @@ -117,8 +117,8 @@ static const char *get_index(struct ast_channel *chan, const char *prefix, int i static struct ast_exten *find_matching_priority(struct ast_context *c, const char *exten, int priority, const char *callerid) { struct ast_exten *e; - struct ast_include *i; struct ast_context *c2; + int idx; for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) { if (ast_extension_match(ast_get_extension_name(e), exten)) { @@ -137,7 +137,9 @@ static struct ast_exten *find_matching_priority(struct ast_context *c, const cha } /* No match; run through includes */ - for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) { + for (idx = 0; idx < ast_context_includes_count(c); idx++) { + const struct ast_include *i = ast_context_includes_get(c, idx); + for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) { if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) { e = find_matching_priority(c2, exten, priority, callerid); diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index afdcc8da4f..378bb556dc 100644 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -1227,7 +1227,7 @@ int pbx_checkcondition(const char *condition); const char *ast_get_context_name(struct ast_context *con); const char *ast_get_extension_name(struct ast_exten *exten); struct ast_context *ast_get_extension_context(struct ast_exten *exten); -const char *ast_get_include_name(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_switch_name(struct ast_sw *sw); const char *ast_get_switch_data(struct ast_sw *sw); @@ -1249,7 +1249,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_extension_registrar(struct ast_exten *e); -const char *ast_get_include_registrar(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_switch_registrar(struct ast_sw *sw); /*! @} */ @@ -1261,13 +1261,19 @@ struct ast_exten *ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority); struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten, struct ast_exten *priority); -struct ast_include *ast_walk_context_includes(struct ast_context *con, - struct ast_include *inc); +const struct ast_include *ast_walk_context_includes(const struct ast_context *con, + const struct ast_include *inc); struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip); struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw); /*! @} */ +/*! @name Iterator functions ... */ +/*! @{ */ +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); +/*! @} */ + /*! * \brief Create a human-readable string, specifying all variables and their corresponding values. * \param chan Channel from which to read variables diff --git a/main/pbx.c b/main/pbx.c index f065b1a283..f6768bb548 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -255,17 +255,6 @@ struct ast_exten { char stuff[0]; }; -/*! \brief ast_include: include= support in extensions.conf */ -struct ast_include { - const char *name; - const char *rname; /*!< Context to include */ - const char *registrar; /*!< Registrar */ - int hastime; /*!< If time construct exists */ - struct ast_timing timing; /*!< time construct */ - struct ast_include *next; /*!< Link them together */ - char stuff[0]; -}; - /*! \brief ast_sw: Switch statement in extensions.conf */ struct ast_sw { char *name; @@ -313,7 +302,7 @@ struct ast_context { struct ast_hashtab *root_table; /*!< For exact matches on the extensions in the pattern tree, and for traversals of the pattern_tree */ struct match_char *pattern_tree; /*!< A tree to speed up extension pattern matching */ struct ast_context *next; /*!< Link them together */ - struct ast_include *includes; /*!< Include other contexts */ + struct ast_includes includes; /*!< Include other contexts */ struct ast_ignorepat *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 */ int refcount; /*!< each module that would have created this context should inc/dec this as appropriate */ @@ -1001,14 +990,6 @@ int check_contexts(char *file, int line ) } #endif -static inline int include_valid(struct ast_include *i) -{ - if (!i->hastime) - return 1; - - return ast_check_timing(&(i->timing)); -} - static void pbx_destroy(struct ast_pbx *p) { ast_free(p); @@ -2399,7 +2380,7 @@ struct fake_context /* this struct is purely for matching in the hashtab */ struct ast_hashtab *root_table; struct match_char *pattern_tree; struct ast_context *next; - struct ast_include *includes; + struct ast_includes includes; struct ast_ignorepat *ignorepats; const char *registrar; int refcount; @@ -2459,11 +2440,11 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan, int x, res; struct ast_context *tmp = NULL; struct ast_exten *e = NULL, *eroot = NULL; - struct ast_include *i = NULL; struct ast_sw *sw = NULL; struct ast_exten pattern = {NULL, }; struct scoreboard score = {0, }; struct ast_str *tmpdata = NULL; + int idx; pattern.label = label; pattern.priority = priority; @@ -2729,9 +2710,11 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan, } q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */ /* Now try any includes we have in this context */ - for (i = tmp->includes; i; i = i->next) { + for (idx = 0; idx < ast_context_includes_count(tmp); idx++) { + const struct ast_include *i = ast_context_includes_get(tmp, idx); + if (include_valid(i)) { - if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) { + if ((e = pbx_find_extension(chan, bypass, q, include_rname(i), exten, priority, label, callerid, action))) { #ifdef NEED_DEBUG_HERE ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten); #endif @@ -4755,13 +4738,6 @@ static struct ast_context *find_context_locked(const char *context) return c; } -/*! \brief Free an ast_include and associated data. */ -static void include_free(struct ast_include *include) -{ - ast_destroy_timing(&(include->timing)); - ast_free(include); -} - /*! * \brief Remove included contexts. * This function locks contexts list by &conlist, search for the right context @@ -4793,21 +4769,22 @@ int ast_context_remove_include(const char *context, const char *include, const c */ int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar) { - struct ast_include *i, *pi = NULL; int ret = -1; + int idx; ast_wrlock_context(con); /* find our include */ - for (i = con->includes; i; pi = i, i = i->next) { - if (!strcmp(i->name, include) && - (!registrar || !strcmp(i->registrar, registrar))) { + for (idx = 0; idx < ast_context_includes_count(con); idx++) { + struct ast_include *i = AST_VECTOR_GET(&con->includes, idx); + + if (!strcmp(ast_get_include_name(i), include) && + (!registrar || !strcmp(ast_get_include_registrar(i), registrar))) { + /* remove from list */ ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar); - if (pi) - pi->next = i->next; - else - con->includes = i->next; + AST_VECTOR_REMOVE_ORDERED(&con->includes, idx); + /* free include and return */ include_free(i); ret = 0; @@ -5406,7 +5383,7 @@ static void print_ext(struct ast_exten *e, char * buf, int buflen) } /* XXX not verified */ -static int show_dialplan_helper(int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[]) +static int show_dialplan_helper(int fd, const char *context, const char *exten, struct dialplan_counters *dpc, const struct ast_include *rinclude, int includecount, const char *includes[]) { struct ast_context *c = NULL; int res = 0, old_total_exten = dpc->total_exten; @@ -5415,8 +5392,8 @@ static int show_dialplan_helper(int fd, const char *context, const char *exten, /* walk all contexts ... */ while ( (c = ast_walk_contexts(c)) ) { + int idx; struct ast_exten *e; - struct ast_include *i; struct ast_ignorepat *ip; #ifndef LOW_MEMORY char buf[1024], buf2[1024]; @@ -5504,8 +5481,9 @@ static int show_dialplan_helper(int fd, const char *context, const char *exten, } /* walk included and write info ... */ - i = NULL; - while ( (i = ast_walk_context_includes(c, i)) ) { + for (idx = 0; idx < ast_context_includes_count(c); idx++) { + const struct ast_include *i = ast_context_includes_get(c, idx); + snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i)); if (exten) { /* Check all includes for the requested extension */ @@ -5757,7 +5735,7 @@ static void manager_dpsendack(struct mansession *s, const struct message *m) static int manager_show_dialplan_helper(struct mansession *s, const struct message *m, const char *actionidtext, const char *context, const char *exten, struct dialplan_counters *dpc, - struct ast_include *rinclude) + const struct ast_include *rinclude) { struct ast_context *c; int res = 0, old_total_exten = dpc->total_exten; @@ -5778,8 +5756,8 @@ static int manager_show_dialplan_helper(struct mansession *s, const struct messa c = NULL; /* walk all contexts ... */ while ( (c = ast_walk_contexts(c)) ) { + int idx; struct ast_exten *e; - struct ast_include *i; struct ast_ignorepat *ip; if (context && strcmp(ast_get_context_name(c), context) != 0) @@ -5835,8 +5813,9 @@ static int manager_show_dialplan_helper(struct mansession *s, const struct messa } } - i = NULL; /* walk included and write info ... */ - while ( (i = ast_walk_context_includes(c, i)) ) { + for (idx = 0; idx < ast_context_includes_count(c); idx++) { + const struct ast_include *i = ast_context_includes_get(c, idx); + if (exten) { /* Check all includes for the requested extension */ manager_show_dialplan_helper(s, m, actionidtext, ast_get_include_name(i), exten, dpc, i); @@ -6114,7 +6093,7 @@ struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, tmp->root = NULL; tmp->root_table = NULL; tmp->registrar = ast_strdup(registrar); - tmp->includes = NULL; + AST_VECTOR_INIT(&tmp->includes, 0); tmp->ignorepats = NULL; tmp->refcount = 1; } else { @@ -6166,16 +6145,19 @@ 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) { - struct ast_include *i; + int idx; struct ast_ignorepat *ip; 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); /* copy in the includes, switches, and ignorepats */ /* walk through includes */ - for (i = NULL; (i = ast_walk_context_includes(old, i)) ; ) { - if (strcmp(ast_get_include_registrar(i), registrar) == 0) + for (idx = 0; idx < ast_context_includes_count(old); idx++) { + const struct ast_include *i = ast_context_includes_get(old, idx); + + if (!strcmp(ast_get_include_registrar(i), registrar)) { continue; /* not mine */ + } ast_context_add_include2(new, ast_get_include_name(i), ast_get_include_registrar(i)); } @@ -6586,53 +6568,32 @@ int ast_context_add_include2(struct ast_context *con, const char *value, const char *registrar) { struct ast_include *new_include; - char *c; - struct ast_include *i, *il = NULL; /* include, include_last */ - int length; - char *p; - - length = sizeof(struct ast_include); - length += 2 * (strlen(value) + 1); + int idx; /* allocate new include structure ... */ - if (!(new_include = ast_calloc(1, length))) + new_include = include_alloc(value, registrar); + if (!new_include) { return -1; - /* Fill in this structure. Use 'p' for assignments, as the fields - * in the structure are 'const char *' - */ - p = new_include->stuff; - new_include->name = p; - strcpy(p, value); - p += strlen(value) + 1; - new_include->rname = p; - strcpy(p, value); - /* Strip off timing info, and process if it is there */ - if ( (c = strchr(p, ',')) ) { - *c++ = '\0'; - new_include->hastime = ast_build_timing(&(new_include->timing), c); } - new_include->next = NULL; - new_include->registrar = registrar; ast_wrlock_context(con); /* ... go to last include and check if context is already included too... */ - for (i = con->includes; i; i = i->next) { - if (!strcasecmp(i->name, new_include->name)) { + for (idx = 0; idx < ast_context_includes_count(con); idx++) { + const struct ast_include *i = ast_context_includes_get(con, idx); + + if (!strcasecmp(ast_get_include_name(i), ast_get_include_name(new_include))) { include_free(new_include); ast_unlock_context(con); errno = EEXIST; return -1; } - il = i; } /* ... include new context into context list, unlock, return */ - if (il) - il->next = new_include; - else - con->includes = new_include; - ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); + AST_VECTOR_APPEND(&con->includes, new_include); + ast_verb(3, "Including context '%s' in context '%s'\n", + ast_get_include_name(new_include), ast_get_context_name(con)); ast_unlock_context(con); @@ -7834,17 +7795,15 @@ int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const cha static void __ast_internal_context_destroy( struct ast_context *con) { - struct ast_include *tmpi; struct ast_sw *sw; struct ast_exten *e, *el, *en; struct ast_ignorepat *ipi; struct ast_context *tmp = con; - for (tmpi = tmp->includes; tmpi; ) { /* Free includes */ - struct ast_include *tmpil = tmpi; - tmpi = tmpi->next; - include_free(tmpil); - } + /* Free includes */ + AST_VECTOR_CALLBACK_VOID(&tmp->includes, include_free); + AST_VECTOR_FREE(&tmp->includes); + for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */ struct ast_ignorepat *ipl = ipi; ipi = ipi->next; @@ -7910,8 +7869,8 @@ void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *context struct ast_hashtab_iter *exten_iter; struct ast_hashtab_iter *prio_iter; struct ast_ignorepat *ip, *ipl = NULL, *ipn = NULL; - struct ast_include *i, *pi = NULL, *ni = NULL; struct ast_sw *sw = NULL; + int idx; /* remove any ignorepats whose registrar matches */ for (ip = tmp->ignorepats; ip; ip = ipn) { @@ -7930,23 +7889,13 @@ void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *context ipl = ip; } /* remove any includes whose registrar matches */ - for (i = tmp->includes; i; i = ni) { - ni = i->next; - if (strcmp(i->registrar, registrar) == 0) { - /* remove from list */ - if (pi) { - pi->next = i->next; - /* free include */ - include_free(i); - continue; /* don't change pi */ - } else { - tmp->includes = i->next; - /* free include */ - include_free(i); - continue; /* don't change pi */ - } + for (idx = ast_context_includes_count(tmp) - 1; idx >= 0; idx--) { + struct ast_include *i = AST_VECTOR_GET(&tmp->includes, idx); + + if (!strcmp(ast_get_include_registrar(i), registrar)) { + AST_VECTOR_REMOVE_ORDERED(&tmp->includes, idx); + include_free(i); } - pi = i; } /* remove any switches whose registrar matches */ AST_LIST_TRAVERSE_SAFE_BEGIN(&tmp->alts, sw, list) { @@ -8006,7 +7955,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, */ /* 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 */ - if (strcmp(tmp->registrar, registrar) == 0 && tmp->refcount < 2 && !tmp->root && !tmp->ignorepats && !tmp->includes && AST_LIST_EMPTY(&tmp->alts)) { + if (strcmp(tmp->registrar, registrar) == 0 && tmp->refcount < 2 && !tmp->root && !tmp->ignorepats && !ast_context_includes_count(tmp) && AST_LIST_EMPTY(&tmp->alts)) { ast_debug(1, "delete ctx %s %s\n", tmp->name, tmp->registrar); ast_hashtab_remove_this_object(contexttab, tmp); @@ -8407,11 +8356,6 @@ const char *ast_get_extension_label(struct ast_exten *exten) return exten ? exten->label : NULL; } -const char *ast_get_include_name(struct ast_include *inc) -{ - return inc ? inc->name : NULL; -} - const char *ast_get_ignorepat_name(struct ast_ignorepat *ip) { return ip ? ip->pattern : NULL; @@ -8435,11 +8379,6 @@ const char *ast_get_extension_registrar(struct ast_exten *e) return e ? e->registrar : NULL; } -const char *ast_get_include_registrar(struct ast_include *i) -{ - return i ? i->registrar : NULL; -} - const char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip) { return ip ? ip->registrar : NULL; @@ -8517,13 +8456,43 @@ struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten, return priority ? priority->peer : exten; } -struct ast_include *ast_walk_context_includes(struct ast_context *con, - struct ast_include *inc) +const struct ast_include *ast_walk_context_includes(const struct ast_context *con, + const struct ast_include *inc) { - if (!inc) - return con ? con->includes : NULL; - else - return inc->next; + if (inc) { + int idx; + int next = 0; + + for (idx = 0; idx < ast_context_includes_count(con); idx++) { + const struct ast_include *include = AST_VECTOR_GET(&con->includes, idx); + + if (next) { + return include; + } + + if (inc == include) { + next = 1; + } + } + + return NULL; + } + + if (!ast_context_includes_count(con)) { + return NULL; + } + + return ast_context_includes_get(con, 0); +} + +int ast_context_includes_count(const struct ast_context *con) +{ + return AST_VECTOR_SIZE(&con->includes); +} + +const struct ast_include *ast_context_includes_get(const struct ast_context *con, int idx) +{ + return AST_VECTOR_GET(&con->includes, idx); } struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con, @@ -8537,16 +8506,19 @@ struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con, int ast_context_verify_includes(struct ast_context *con) { - struct ast_include *inc = NULL; + int idx; int res = 0; - while ( (inc = ast_walk_context_includes(con, inc)) ) { - if (ast_context_find(inc->rname)) + for (idx = 0; idx < ast_context_includes_count(con); idx++) { + const struct ast_include *inc = ast_context_includes_get(con, idx); + + if (ast_context_find(include_rname(inc))) { continue; + } res = -1; ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", - ast_get_context_name(con), inc->rname); + ast_get_context_name(con), include_rname(inc)); break; } diff --git a/main/pbx_include.c b/main/pbx_include.c new file mode 100644 index 0000000000..46a41fb20f --- /dev/null +++ b/main/pbx_include.c @@ -0,0 +1,112 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2016, CFWare, LLC + * + * Corey Farrell + * + * 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 include routines. + * + * \author Corey Farrell + */ + +/*** MODULEINFO + core + ***/ + +#include "asterisk.h" + +ASTERISK_REGISTER_FILE() + +#include "asterisk/_private.h" +#include "asterisk/pbx.h" +#include "pbx_private.h" + +/*! ast_include: include= support in extensions.conf */ +struct ast_include { + const char *name; + /*! Context to include */ + const char *rname; + /*! Registrar */ + const char *registrar; + /*! If time construct exists */ + int hastime; + /*! time construct */ + struct ast_timing timing; + char stuff[0]; +}; + +const char *ast_get_include_name(const struct ast_include *inc) +{ + return inc ? inc->name : NULL; +} + +const char *include_rname(const struct ast_include *inc) +{ + return inc ? inc->rname : NULL; +} + +const char *ast_get_include_registrar(const struct ast_include *inc) +{ + return inc ? inc->registrar : NULL; +} + +int include_valid(const struct ast_include *inc) +{ + if (!inc->hastime) { + return 1; + } + + return ast_check_timing(&(inc->timing)); +} + +struct ast_include *include_alloc(const char *value, const char *registrar) +{ + struct ast_include *new_include; + char *c; + int valuebufsz = strlen(value) + 1; + char *p; + + /* allocate new include structure ... */ + new_include = ast_calloc(1, sizeof(*new_include) + (valuebufsz * 2)); + if (!new_include) { + return NULL; + } + + /* Fill in this structure. Use 'p' for assignments, as the fields + * in the structure are 'const char *' + */ + p = new_include->stuff; + new_include->name = p; + strcpy(p, value); + p += valuebufsz; + new_include->rname = p; + strcpy(p, value); + /* Strip off timing info, and process if it is there */ + if ((c = strchr(p, ',')) ) { + *c++ = '\0'; + new_include->hastime = ast_build_timing(&(new_include->timing), c); + } + new_include->registrar = registrar; + + return new_include; +} + +void include_free(struct ast_include *inc) +{ + ast_destroy_timing(&(inc->timing)); + ast_free(inc); +} diff --git a/main/pbx_private.h b/main/pbx_private.h index e091941887..22d454ad02 100644 --- a/main/pbx_private.h +++ b/main/pbx_private.h @@ -31,6 +31,17 @@ void set_ext_pri(struct ast_channel *c, const char *exten, int pri); /*! pbx.c function needed by pbx_app.c */ void unreference_cached_app(struct ast_app *app); +/*! pbx_includes.c */ +struct ast_include; +AST_VECTOR(ast_includes, struct ast_include *); + +/*! Allocate and initialize an ast_include. */ +struct ast_include *include_alloc(const char *value, const char *registrar); +/*! Free an ast_include and associated data. */ +void include_free(struct ast_include *inc); +int include_valid(const struct ast_include *inc); +const char *include_rname(const struct ast_include *inc); + /*! pbx_builtins.c functions needed by pbx.c */ int indicate_congestion(struct ast_channel *, const char *); int indicate_busy(struct ast_channel *, const char *); diff --git a/pbx/pbx_config.c b/pbx/pbx_config.c index eb2a64f70e..478c0a3211 100644 --- a/pbx/pbx_config.c +++ b/pbx/pbx_config.c @@ -189,15 +189,25 @@ static char *handle_cli_dialplan_remove_include(struct ast_cli_entry *e, int cmd /*! \brief return true if 'name' is included by context c */ static int lookup_ci(struct ast_context *c, const char *name) { - struct ast_include *i = NULL; + int idx; + int ret = 0; - if (ast_rdlock_context(c)) /* error, skip */ + if (ast_rdlock_context(c)) { + /* error, skip */ return 0; - while ( (i = ast_walk_context_includes(c, i)) ) - if (!strcmp(name, ast_get_include_name(i))) + } + + for (idx = 0; idx < ast_context_includes_count(c); idx++) { + const struct ast_include *i = ast_context_includes_get(c, idx); + + if (!strcmp(name, ast_get_include_name(i))) { + ret = -1; break; + } + } ast_unlock_context(c); - return i ? -1 /* success */ : 0; + + return ret; } /*! \brief return true if 'name' is in the ignorepats for context c */ @@ -282,12 +292,13 @@ static char *complete_dialplan_remove_include(struct ast_cli_args *a) } /* walk contexts and their includes, return the n-th match */ while (!res && (c = ast_walk_contexts(c))) { - struct ast_include *i = NULL; + int idx; if (ast_rdlock_context(c)) /* error ? skip this one */ continue; - while ( !res && (i = ast_walk_context_includes(c, i)) ) { + for (idx = 0; idx < ast_context_includes_count(c); idx++) { + const struct ast_include *i = ast_context_includes_get(c, idx); const char *i_name = ast_get_include_name(i); struct ast_context *nc = NULL; int already_served = 0; @@ -906,7 +917,7 @@ static char *handle_cli_dialplan_save(struct ast_cli_entry *e, int cmd, struct a for (c = NULL; (c = ast_walk_contexts(c)); ) { int context_header_written = 0; struct ast_exten *ext, *last_written_e = NULL; - struct ast_include *i; + int idx; struct ast_ignorepat *ip; struct ast_sw *sw; @@ -983,14 +994,17 @@ static char *handle_cli_dialplan_save(struct ast_cli_entry *e, int cmd, struct a fprintf(output, "\n"); /* walk through includes */ - for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) { + for (idx = 0; idx < ast_context_includes_count(c); idx++) { + const struct ast_include *i = ast_context_includes_get(c, idx); + if (strcmp(ast_get_include_registrar(i), registrar) != 0) continue; /* not mine */ PUT_CTX_HDR; fprintf(output, "include => %s\n", ast_get_include_name(i)); } - if (ast_walk_context_includes(c, NULL)) + if (ast_context_includes_count(c)) { fprintf(output, "\n"); + } /* walk through switches */ for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) { diff --git a/res/ael/pval.c b/res/ael/pval.c index ce9458c06d..8b6760f996 100644 --- a/res/ael/pval.c +++ b/res/ael/pval.c @@ -4410,7 +4410,7 @@ static int context_used(struct ael_extension *exten_list, struct ast_context *co { struct ael_extension *exten; /* Check the simple elements first */ - if (ast_walk_context_extensions(context, NULL) || ast_walk_context_includes(context, NULL) || 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_walk_context_ignorepats(context, NULL) || ast_walk_context_switches(context, NULL)) { return 1; } for (exten = exten_list; exten; exten = exten->next_exten) { diff --git a/utils/conf2ael.c b/utils/conf2ael.c index 76a3ad3f2d..8b2043082a 100644 --- a/utils/conf2ael.c +++ b/utils/conf2ael.c @@ -664,8 +664,8 @@ struct ast_exten *ast_walk_context_extensions(struct ast_context *con, struct as return NULL; } -struct ast_include *ast_walk_context_includes(struct ast_context *con, struct ast_include *inc); -struct ast_include *ast_walk_context_includes(struct ast_context *con, struct ast_include *inc) +const struct ast_include *ast_walk_context_includes(const struct ast_context *con, const struct ast_include *inc); +const struct ast_include *ast_walk_context_includes(const struct ast_context *con, const struct ast_include *inc) { return NULL; } diff --git a/utils/extconf.c b/utils/extconf.c index 48053aed66..3a0b2e97c9 100644 --- a/utils/extconf.c +++ b/utils/extconf.c @@ -4381,6 +4381,19 @@ static struct ast_include *ast_walk_context_includes(struct ast_context *con, return inc->next; } +int ast_context_includes_count(struct ast_context *con); +int ast_context_includes_count(struct ast_context *con) +{ + int c = 0; + struct ast_include *inc = NULL; + + while ((inc = ast_walk_context_includes(con, inc))) { + c++; + } + + return c; +} + struct ast_include *localized_walk_context_includes(struct ast_context *con, struct ast_include *inc); struct ast_include *localized_walk_context_includes(struct ast_context *con,