mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-08 10:58:15 +00:00
pbx: Create pbx_include.c for management of 'struct ast_include'.
This changes context includes from a linked list to a vector, makes 'struct ast_include' opaque to pbx.c. Although ast_walk_context_includes 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_includes_count (AST_VECTOR_SIZE) * ast_context_includes_get (AST_VECTOR_GET) As with ast_walk_context_includes callers of these functions are expected to have locked contexts. Only a few places in Asterisk walked the includes, they have been converted to use the new functions. const have been applied where possible to parameters for ast_include functions. Change-Id: Ib5c882e27cf96fb2aec67a39c18b4c71c9c83b60
This commit is contained in:
@@ -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)
|
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_exten *e;
|
||||||
struct ast_include *i;
|
|
||||||
struct ast_context *c2;
|
struct ast_context *c2;
|
||||||
|
int idx;
|
||||||
|
|
||||||
for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) {
|
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)) {
|
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 */
|
/* 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)) {
|
for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) {
|
||||||
if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) {
|
if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) {
|
||||||
e = find_matching_priority(c2, exten, priority, callerid);
|
e = find_matching_priority(c2, exten, priority, callerid);
|
||||||
|
|||||||
@@ -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)
|
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_exten *e;
|
||||||
struct ast_include *i;
|
|
||||||
struct ast_context *c2;
|
struct ast_context *c2;
|
||||||
|
int idx;
|
||||||
|
|
||||||
for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) {
|
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)) {
|
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 */
|
/* 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)) {
|
for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) {
|
||||||
if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) {
|
if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) {
|
||||||
e = find_matching_priority(c2, exten, priority, callerid);
|
e = find_matching_priority(c2, exten, priority, callerid);
|
||||||
|
|||||||
@@ -1227,7 +1227,7 @@ int pbx_checkcondition(const char *condition);
|
|||||||
const char *ast_get_context_name(struct ast_context *con);
|
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(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(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);
|
||||||
@@ -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_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(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(struct ast_ignorepat *ip);
|
||||||
const char *ast_get_switch_registrar(struct ast_sw *sw);
|
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 *priority);
|
||||||
struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten,
|
struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten,
|
||||||
struct ast_exten *priority);
|
struct ast_exten *priority);
|
||||||
struct ast_include *ast_walk_context_includes(struct ast_context *con,
|
const struct ast_include *ast_walk_context_includes(const struct ast_context *con,
|
||||||
struct ast_include *inc);
|
const struct ast_include *inc);
|
||||||
struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con,
|
struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con,
|
||||||
struct ast_ignorepat *ip);
|
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);
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
|
/*! @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.
|
* \brief Create a human-readable string, specifying all variables and their corresponding values.
|
||||||
* \param chan Channel from which to read variables
|
* \param chan Channel from which to read variables
|
||||||
|
|||||||
224
main/pbx.c
224
main/pbx.c
@@ -255,17 +255,6 @@ struct ast_exten {
|
|||||||
char stuff[0];
|
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 */
|
/*! \brief ast_sw: Switch statement in extensions.conf */
|
||||||
struct ast_sw {
|
struct ast_sw {
|
||||||
char *name;
|
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 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 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_include *includes; /*!< Include other contexts */
|
struct ast_includes includes; /*!< Include other contexts */
|
||||||
struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
|
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 */
|
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 */
|
||||||
@@ -1001,14 +990,6 @@ int check_contexts(char *file, int line )
|
|||||||
}
|
}
|
||||||
#endif
|
#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)
|
static void pbx_destroy(struct ast_pbx *p)
|
||||||
{
|
{
|
||||||
ast_free(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 ast_hashtab *root_table;
|
||||||
struct match_char *pattern_tree;
|
struct match_char *pattern_tree;
|
||||||
struct ast_context *next;
|
struct ast_context *next;
|
||||||
struct ast_include *includes;
|
struct ast_includes includes;
|
||||||
struct ast_ignorepat *ignorepats;
|
struct ast_ignorepat *ignorepats;
|
||||||
const char *registrar;
|
const char *registrar;
|
||||||
int refcount;
|
int refcount;
|
||||||
@@ -2459,11 +2440,11 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan,
|
|||||||
int x, res;
|
int x, res;
|
||||||
struct ast_context *tmp = NULL;
|
struct ast_context *tmp = NULL;
|
||||||
struct ast_exten *e = NULL, *eroot = NULL;
|
struct ast_exten *e = NULL, *eroot = NULL;
|
||||||
struct ast_include *i = NULL;
|
|
||||||
struct ast_sw *sw = NULL;
|
struct ast_sw *sw = NULL;
|
||||||
struct ast_exten pattern = {NULL, };
|
struct ast_exten pattern = {NULL, };
|
||||||
struct scoreboard score = {0, };
|
struct scoreboard score = {0, };
|
||||||
struct ast_str *tmpdata = NULL;
|
struct ast_str *tmpdata = NULL;
|
||||||
|
int idx;
|
||||||
|
|
||||||
pattern.label = label;
|
pattern.label = label;
|
||||||
pattern.priority = priority;
|
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 */
|
q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
|
||||||
/* Now try any includes we have in this context */
|
/* 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 (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
|
#ifdef NEED_DEBUG_HERE
|
||||||
ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten);
|
ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten);
|
||||||
#endif
|
#endif
|
||||||
@@ -4755,13 +4738,6 @@ static struct ast_context *find_context_locked(const char *context)
|
|||||||
return c;
|
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.
|
* \brief Remove included contexts.
|
||||||
* This function locks contexts list by &conlist, search for the right context
|
* 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)
|
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 ret = -1;
|
||||||
|
int idx;
|
||||||
|
|
||||||
ast_wrlock_context(con);
|
ast_wrlock_context(con);
|
||||||
|
|
||||||
/* find our include */
|
/* find our include */
|
||||||
for (i = con->includes; i; pi = i, i = i->next) {
|
for (idx = 0; idx < ast_context_includes_count(con); idx++) {
|
||||||
if (!strcmp(i->name, include) &&
|
struct ast_include *i = AST_VECTOR_GET(&con->includes, idx);
|
||||||
(!registrar || !strcmp(i->registrar, registrar))) {
|
|
||||||
|
if (!strcmp(ast_get_include_name(i), include) &&
|
||||||
|
(!registrar || !strcmp(ast_get_include_registrar(i), registrar))) {
|
||||||
|
|
||||||
/* remove from list */
|
/* remove from list */
|
||||||
ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar);
|
ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar);
|
||||||
if (pi)
|
AST_VECTOR_REMOVE_ORDERED(&con->includes, idx);
|
||||||
pi->next = i->next;
|
|
||||||
else
|
|
||||||
con->includes = i->next;
|
|
||||||
/* free include and return */
|
/* free include and return */
|
||||||
include_free(i);
|
include_free(i);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@@ -5406,7 +5383,7 @@ static void print_ext(struct ast_exten *e, char * buf, int buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* XXX not verified */
|
/* 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;
|
struct ast_context *c = NULL;
|
||||||
int res = 0, old_total_exten = dpc->total_exten;
|
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 ... */
|
/* walk all contexts ... */
|
||||||
while ( (c = ast_walk_contexts(c)) ) {
|
while ( (c = ast_walk_contexts(c)) ) {
|
||||||
|
int idx;
|
||||||
struct ast_exten *e;
|
struct ast_exten *e;
|
||||||
struct ast_include *i;
|
|
||||||
struct ast_ignorepat *ip;
|
struct ast_ignorepat *ip;
|
||||||
#ifndef LOW_MEMORY
|
#ifndef LOW_MEMORY
|
||||||
char buf[1024], buf2[1024];
|
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 ... */
|
/* walk included and write info ... */
|
||||||
i = NULL;
|
for (idx = 0; idx < ast_context_includes_count(c); idx++) {
|
||||||
while ( (i = ast_walk_context_includes(c, i)) ) {
|
const struct ast_include *i = ast_context_includes_get(c, idx);
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i));
|
snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i));
|
||||||
if (exten) {
|
if (exten) {
|
||||||
/* Check all includes for the requested extension */
|
/* 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,
|
static int manager_show_dialplan_helper(struct mansession *s, const struct message *m,
|
||||||
const char *actionidtext, const char *context,
|
const char *actionidtext, const char *context,
|
||||||
const char *exten, struct dialplan_counters *dpc,
|
const char *exten, struct dialplan_counters *dpc,
|
||||||
struct ast_include *rinclude)
|
const struct ast_include *rinclude)
|
||||||
{
|
{
|
||||||
struct ast_context *c;
|
struct ast_context *c;
|
||||||
int res = 0, old_total_exten = dpc->total_exten;
|
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 ... */
|
c = NULL; /* walk all contexts ... */
|
||||||
while ( (c = ast_walk_contexts(c)) ) {
|
while ( (c = ast_walk_contexts(c)) ) {
|
||||||
|
int idx;
|
||||||
struct ast_exten *e;
|
struct ast_exten *e;
|
||||||
struct ast_include *i;
|
|
||||||
struct ast_ignorepat *ip;
|
struct ast_ignorepat *ip;
|
||||||
|
|
||||||
if (context && strcmp(ast_get_context_name(c), context) != 0)
|
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 ... */
|
for (idx = 0; idx < ast_context_includes_count(c); idx++) {
|
||||||
while ( (i = ast_walk_context_includes(c, i)) ) {
|
const struct ast_include *i = ast_context_includes_get(c, idx);
|
||||||
|
|
||||||
if (exten) {
|
if (exten) {
|
||||||
/* Check all includes for the requested extension */
|
/* Check all includes for the requested extension */
|
||||||
manager_show_dialplan_helper(s, m, actionidtext, ast_get_include_name(i), exten, dpc, i);
|
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 = NULL;
|
||||||
tmp->root_table = NULL;
|
tmp->root_table = NULL;
|
||||||
tmp->registrar = ast_strdup(registrar);
|
tmp->registrar = ast_strdup(registrar);
|
||||||
tmp->includes = NULL;
|
AST_VECTOR_INIT(&tmp->includes, 0);
|
||||||
tmp->ignorepats = NULL;
|
tmp->ignorepats = NULL;
|
||||||
tmp->refcount = 1;
|
tmp->refcount = 1;
|
||||||
} else {
|
} 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)
|
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_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);
|
||||||
/* copy in the includes, switches, and ignorepats */
|
/* copy in the includes, switches, and ignorepats */
|
||||||
/* walk through includes */
|
/* walk through includes */
|
||||||
for (i = NULL; (i = ast_walk_context_includes(old, i)) ; ) {
|
for (idx = 0; idx < ast_context_includes_count(old); idx++) {
|
||||||
if (strcmp(ast_get_include_registrar(i), registrar) == 0)
|
const struct ast_include *i = ast_context_includes_get(old, idx);
|
||||||
|
|
||||||
|
if (!strcmp(ast_get_include_registrar(i), registrar)) {
|
||||||
continue; /* not mine */
|
continue; /* not mine */
|
||||||
|
}
|
||||||
ast_context_add_include2(new, ast_get_include_name(i), ast_get_include_registrar(i));
|
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)
|
const char *registrar)
|
||||||
{
|
{
|
||||||
struct ast_include *new_include;
|
struct ast_include *new_include;
|
||||||
char *c;
|
int idx;
|
||||||
struct ast_include *i, *il = NULL; /* include, include_last */
|
|
||||||
int length;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
length = sizeof(struct ast_include);
|
|
||||||
length += 2 * (strlen(value) + 1);
|
|
||||||
|
|
||||||
/* allocate new include structure ... */
|
/* allocate new include structure ... */
|
||||||
if (!(new_include = ast_calloc(1, length)))
|
new_include = include_alloc(value, registrar);
|
||||||
|
if (!new_include) {
|
||||||
return -1;
|
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);
|
ast_wrlock_context(con);
|
||||||
|
|
||||||
/* ... go to last include and check if context is already included too... */
|
/* ... go to last include and check if context is already included too... */
|
||||||
for (i = con->includes; i; i = i->next) {
|
for (idx = 0; idx < ast_context_includes_count(con); idx++) {
|
||||||
if (!strcasecmp(i->name, new_include->name)) {
|
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);
|
include_free(new_include);
|
||||||
ast_unlock_context(con);
|
ast_unlock_context(con);
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
il = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ... include new context into context list, unlock, return */
|
/* ... include new context into context list, unlock, return */
|
||||||
if (il)
|
AST_VECTOR_APPEND(&con->includes, new_include);
|
||||||
il->next = new_include;
|
ast_verb(3, "Including context '%s' in context '%s'\n",
|
||||||
else
|
ast_get_include_name(new_include), ast_get_context_name(con));
|
||||||
con->includes = new_include;
|
|
||||||
ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
|
|
||||||
|
|
||||||
ast_unlock_context(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)
|
static void __ast_internal_context_destroy( struct ast_context *con)
|
||||||
{
|
{
|
||||||
struct ast_include *tmpi;
|
|
||||||
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_ignorepat *ipi;
|
||||||
struct ast_context *tmp = con;
|
struct ast_context *tmp = con;
|
||||||
|
|
||||||
for (tmpi = tmp->includes; tmpi; ) { /* Free includes */
|
/* Free includes */
|
||||||
struct ast_include *tmpil = tmpi;
|
AST_VECTOR_CALLBACK_VOID(&tmp->includes, include_free);
|
||||||
tmpi = tmpi->next;
|
AST_VECTOR_FREE(&tmp->includes);
|
||||||
include_free(tmpil);
|
|
||||||
}
|
|
||||||
for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */
|
for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */
|
||||||
struct ast_ignorepat *ipl = ipi;
|
struct ast_ignorepat *ipl = ipi;
|
||||||
ipi = ipi->next;
|
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 *exten_iter;
|
||||||
struct ast_hashtab_iter *prio_iter;
|
struct ast_hashtab_iter *prio_iter;
|
||||||
struct ast_ignorepat *ip, *ipl = NULL, *ipn = NULL;
|
struct ast_ignorepat *ip, *ipl = NULL, *ipn = NULL;
|
||||||
struct ast_include *i, *pi = NULL, *ni = NULL;
|
|
||||||
struct ast_sw *sw = NULL;
|
struct ast_sw *sw = NULL;
|
||||||
|
int idx;
|
||||||
|
|
||||||
/* remove any ignorepats whose registrar matches */
|
/* remove any ignorepats whose registrar matches */
|
||||||
for (ip = tmp->ignorepats; ip; ip = ipn) {
|
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;
|
ipl = ip;
|
||||||
}
|
}
|
||||||
/* remove any includes whose registrar matches */
|
/* remove any includes whose registrar matches */
|
||||||
for (i = tmp->includes; i; i = ni) {
|
for (idx = ast_context_includes_count(tmp) - 1; idx >= 0; idx--) {
|
||||||
ni = i->next;
|
struct ast_include *i = AST_VECTOR_GET(&tmp->includes, idx);
|
||||||
if (strcmp(i->registrar, registrar) == 0) {
|
|
||||||
/* remove from list */
|
if (!strcmp(ast_get_include_registrar(i), registrar)) {
|
||||||
if (pi) {
|
AST_VECTOR_REMOVE_ORDERED(&tmp->includes, idx);
|
||||||
pi->next = i->next;
|
include_free(i);
|
||||||
/* 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 */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pi = i;
|
|
||||||
}
|
}
|
||||||
/* remove any switches whose registrar matches */
|
/* remove any switches whose registrar matches */
|
||||||
AST_LIST_TRAVERSE_SAFE_BEGIN(&tmp->alts, sw, list) {
|
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, */
|
/* 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 && !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_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);
|
||||||
|
|
||||||
@@ -8407,11 +8356,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_include_name(struct ast_include *inc)
|
|
||||||
{
|
|
||||||
return inc ? inc->name : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ast_get_ignorepat_name(struct ast_ignorepat *ip)
|
const char *ast_get_ignorepat_name(struct ast_ignorepat *ip)
|
||||||
{
|
{
|
||||||
return ip ? ip->pattern : NULL;
|
return ip ? ip->pattern : NULL;
|
||||||
@@ -8435,11 +8379,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_include_registrar(struct ast_include *i)
|
|
||||||
{
|
|
||||||
return i ? i->registrar : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip)
|
const char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip)
|
||||||
{
|
{
|
||||||
return ip ? ip->registrar : NULL;
|
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;
|
return priority ? priority->peer : exten;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ast_include *ast_walk_context_includes(struct ast_context *con,
|
const struct ast_include *ast_walk_context_includes(const struct ast_context *con,
|
||||||
struct ast_include *inc)
|
const struct ast_include *inc)
|
||||||
{
|
{
|
||||||
if (!inc)
|
if (inc) {
|
||||||
return con ? con->includes : NULL;
|
int idx;
|
||||||
else
|
int next = 0;
|
||||||
return inc->next;
|
|
||||||
|
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,
|
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)
|
int ast_context_verify_includes(struct ast_context *con)
|
||||||
{
|
{
|
||||||
struct ast_include *inc = NULL;
|
int idx;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
while ( (inc = ast_walk_context_includes(con, inc)) ) {
|
for (idx = 0; idx < ast_context_includes_count(con); idx++) {
|
||||||
if (ast_context_find(inc->rname))
|
const struct ast_include *inc = ast_context_includes_get(con, idx);
|
||||||
|
|
||||||
|
if (ast_context_find(include_rname(inc))) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
res = -1;
|
res = -1;
|
||||||
ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
112
main/pbx_include.c
Normal file
112
main/pbx_include.c
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* 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 include 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"
|
||||||
|
|
||||||
|
/*! 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);
|
||||||
|
}
|
||||||
@@ -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 */
|
/*! 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_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 */
|
/*! pbx_builtins.c functions needed by pbx.c */
|
||||||
int indicate_congestion(struct ast_channel *, const char *);
|
int indicate_congestion(struct ast_channel *, const char *);
|
||||||
int indicate_busy(struct ast_channel *, const char *);
|
int indicate_busy(struct ast_channel *, const char *);
|
||||||
|
|||||||
@@ -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 */
|
/*! \brief return true if 'name' is included by context c */
|
||||||
static int lookup_ci(struct ast_context *c, const char *name)
|
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;
|
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;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
ast_unlock_context(c);
|
ast_unlock_context(c);
|
||||||
return i ? -1 /* success */ : 0;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief return true if 'name' is in the ignorepats for context c */
|
/*! \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 */
|
/* walk contexts and their includes, return the n-th match */
|
||||||
while (!res && (c = ast_walk_contexts(c))) {
|
while (!res && (c = ast_walk_contexts(c))) {
|
||||||
struct ast_include *i = NULL;
|
int idx;
|
||||||
|
|
||||||
if (ast_rdlock_context(c)) /* error ? skip this one */
|
if (ast_rdlock_context(c)) /* error ? skip this one */
|
||||||
continue;
|
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);
|
const char *i_name = ast_get_include_name(i);
|
||||||
struct ast_context *nc = NULL;
|
struct ast_context *nc = NULL;
|
||||||
int already_served = 0;
|
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)); ) {
|
for (c = NULL; (c = ast_walk_contexts(c)); ) {
|
||||||
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;
|
||||||
struct ast_include *i;
|
int idx;
|
||||||
struct ast_ignorepat *ip;
|
struct ast_ignorepat *ip;
|
||||||
struct ast_sw *sw;
|
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");
|
fprintf(output, "\n");
|
||||||
|
|
||||||
/* walk through includes */
|
/* 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)
|
if (strcmp(ast_get_include_registrar(i), registrar) != 0)
|
||||||
continue; /* not mine */
|
continue; /* not mine */
|
||||||
PUT_CTX_HDR;
|
PUT_CTX_HDR;
|
||||||
fprintf(output, "include => %s\n", ast_get_include_name(i));
|
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");
|
fprintf(output, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* walk through switches */
|
/* walk through switches */
|
||||||
for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) {
|
for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) {
|
||||||
|
|||||||
@@ -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_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;
|
return 1;
|
||||||
}
|
}
|
||||||
for (exten = exten_list; exten; exten = exten->next_exten) {
|
for (exten = exten_list; exten; exten = exten->next_exten) {
|
||||||
|
|||||||
@@ -664,8 +664,8 @@ struct ast_exten *ast_walk_context_extensions(struct ast_context *con, struct as
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
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_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)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4381,6 +4381,19 @@ static struct ast_include *ast_walk_context_includes(struct ast_context *con,
|
|||||||
return inc->next;
|
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 *localized_walk_context_includes(struct ast_context *con,
|
||||||
struct ast_include *inc);
|
struct ast_include *inc);
|
||||||
struct ast_include *localized_walk_context_includes(struct ast_context *con,
|
struct ast_include *localized_walk_context_includes(struct ast_context *con,
|
||||||
|
|||||||
Reference in New Issue
Block a user