summaryrefslogtreecommitdiff
path: root/main/pbx.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/pbx.c')
-rw-r--r--main/pbx.c378
1 files changed, 184 insertions, 194 deletions
diff --git a/main/pbx.c b/main/pbx.c
index f6768bb54..f9fad0388 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -255,23 +255,6 @@ struct ast_exten {
char stuff[0];
};
-/*! \brief ast_sw: Switch statement in extensions.conf */
-struct ast_sw {
- char *name;
- const char *registrar; /*!< Registrar */
- char *data; /*!< Data load */
- int eval;
- AST_LIST_ENTRY(ast_sw) list;
- 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 */
struct match_char
{
@@ -303,11 +286,11 @@ struct ast_context {
struct match_char *pattern_tree; /*!< A tree to speed up extension pattern matching */
struct ast_context *next; /*!< Link them together */
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 */
+ struct ast_sws alts; /*!< Alternative switches */
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 autohints; /*!< Whether autohints support is enabled or not */
- AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
char name[0]; /*!< Name of the context */
};
@@ -2381,11 +2364,11 @@ struct fake_context /* this struct is purely for matching in the hashtab */
struct match_char *pattern_tree;
struct ast_context *next;
struct ast_includes includes;
- struct ast_ignorepat *ignorepats;
+ struct ast_ignorepats ignorepats;
+ struct ast_sws alts;
const char *registrar;
int refcount;
int autohints;
- AST_LIST_HEAD_NOLOCK(, ast_sw) alts;
ast_mutex_t macrolock;
char name[256];
};
@@ -2440,7 +2423,6 @@ 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_sw *sw = NULL;
struct ast_exten pattern = {NULL, };
struct scoreboard score = {0, };
struct ast_str *tmpdata = NULL;
@@ -2664,23 +2646,28 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan,
}
/* Check alternative switches */
- AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
- struct ast_switch *asw = pbx_findswitch(sw->name);
+ for (idx = 0; idx < ast_context_switches_count(tmp); idx++) {
+ const struct ast_sw *sw = ast_context_switches_get(tmp, idx);
+ struct ast_switch *asw = pbx_findswitch(ast_get_switch_name(sw));
ast_switch_f *aswf = NULL;
- char *datap;
+ const char *datap;
if (!asw) {
- ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
+ ast_log(LOG_WARNING, "No such switch '%s'\n", ast_get_switch_name(sw));
continue;
}
/* Substitute variables now */
- if (sw->eval) {
+ if (ast_get_switch_eval(sw)) {
if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) {
ast_log(LOG_WARNING, "Can't evaluate switch?!\n");
continue;
}
- pbx_substitute_variables_helper(chan, sw->data, ast_str_buffer(tmpdata), ast_str_size(tmpdata));
+ pbx_substitute_variables_helper(chan, ast_get_switch_data(sw),
+ ast_str_buffer(tmpdata), ast_str_size(tmpdata));
+ datap = ast_str_buffer(tmpdata);
+ } else {
+ datap = ast_get_switch_data(sw);
}
/* equivalent of extension_match_core() at the switch level */
@@ -2690,7 +2677,6 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan,
aswf = asw->matchmore;
else /* action == E_MATCH */
aswf = asw->exists;
- datap = sw->eval ? ast_str_buffer(tmpdata) : sw->data;
if (!aswf)
res = 0;
else {
@@ -4826,24 +4812,29 @@ int ast_context_remove_switch(const char *context, const char *sw, const char *d
*/
int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
{
- struct ast_sw *i;
+ int idx;
int ret = -1;
ast_wrlock_context(con);
/* walk switches */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
- if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
- (!registrar || !strcmp(i->registrar, registrar))) {
+ for (idx = 0; idx < ast_context_switches_count(con); idx++) {
+ struct ast_sw *i = AST_VECTOR_GET(&con->alts, idx);
+
+ if (!strcmp(ast_get_switch_name(i), sw) &&
+ !strcmp(ast_get_switch_data(i), data) &&
+ (!registrar || !strcmp(ast_get_switch_registrar(i), registrar))) {
+
/* found, remove from list */
ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar);
- AST_LIST_REMOVE_CURRENT(list);
- ast_free(i); /* free switch and return */
+ AST_VECTOR_REMOVE_ORDERED(&con->alts, idx);
+
+ /* free switch and return */
+ sw_free(i);
ret = 0;
break;
}
}
- AST_LIST_TRAVERSE_SAFE_END;
ast_unlock_context(con);
@@ -5394,7 +5385,6 @@ static int show_dialplan_helper(int fd, const char *context, const char *exten,
while ( (c = ast_walk_contexts(c)) ) {
int idx;
struct ast_exten *e;
- struct ast_ignorepat *ip;
#ifndef LOW_MEMORY
char buf[1024], buf2[1024];
#else
@@ -5512,10 +5502,11 @@ static int show_dialplan_helper(int fd, const char *context, const char *exten,
}
/* walk ignore patterns and write info ... */
- ip = NULL;
- while ( (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);
const char *ipname = ast_get_ignorepat_name(ip);
char ignorepat[AST_MAX_EXTENSION];
+
snprintf(buf, sizeof(buf), "'%s'", ipname);
snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname);
if (!exten || ast_extension_match(ignorepat, exten)) {
@@ -5524,8 +5515,9 @@ static int show_dialplan_helper(int fd, const char *context, const char *exten,
}
}
if (!rinclude) {
- struct ast_sw *sw = NULL;
- while ( (sw = ast_walk_context_switches(c, sw)) ) {
+ for (idx = 0; idx < ast_context_switches_count(c); idx++) {
+ const struct ast_sw *sw = ast_context_switches_get(c, idx);
+
snprintf(buf, sizeof(buf), "'%s/%s'",
ast_get_switch_name(sw),
ast_get_switch_data(sw));
@@ -5758,7 +5750,6 @@ static int manager_show_dialplan_helper(struct mansession *s, const struct messa
while ( (c = ast_walk_contexts(c)) ) {
int idx;
struct ast_exten *e;
- struct ast_ignorepat *ip;
if (context && strcmp(ast_get_context_name(c), context) != 0)
continue; /* not the name we want */
@@ -5829,8 +5820,8 @@ static int manager_show_dialplan_helper(struct mansession *s, const struct messa
}
}
- ip = NULL; /* walk ignore patterns and write info ... */
- while ( (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);
const char *ipname = ast_get_ignorepat_name(ip);
char ignorepat[AST_MAX_EXTENSION];
@@ -5844,8 +5835,9 @@ static int manager_show_dialplan_helper(struct mansession *s, const struct messa
}
}
if (!rinclude) {
- struct ast_sw *sw = NULL;
- while ( (sw = ast_walk_context_switches(c, sw)) ) {
+ for (idx = 0; idx < ast_context_switches_count(c); idx++) {
+ const struct ast_sw *sw = ast_context_switches_get(c, idx);
+
if (!dpc->total_items++)
manager_dpsendack(s, m);
astman_append(s, "Event: ListDialplan\r\n%s", actionidtext);
@@ -6094,7 +6086,8 @@ struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts,
tmp->root_table = NULL;
tmp->registrar = ast_strdup(registrar);
AST_VECTOR_INIT(&tmp->includes, 0);
- tmp->ignorepats = NULL;
+ AST_VECTOR_INIT(&tmp->ignorepats, 0);
+ AST_VECTOR_INIT(&tmp->alts, 0);
tmp->refcount = 1;
} else {
ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
@@ -6146,8 +6139,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)
{
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 */
@@ -6162,16 +6153,22 @@ static void context_merge_incls_swits_igps_other_registrars(struct ast_context *
}
/* walk through switches */
- for (sw = NULL; (sw = ast_walk_context_switches(old, sw)) ; ) {
- if (strcmp(ast_get_switch_registrar(sw), registrar) == 0)
+ for (idx = 0; idx < ast_context_switches_count(old); idx++) {
+ const struct ast_sw *sw = ast_context_switches_get(old, idx);
+
+ if (!strcmp(ast_get_switch_registrar(sw), registrar)) {
continue; /* not mine */
+ }
ast_context_add_switch2(new, ast_get_switch_name(sw), ast_get_switch_data(sw), ast_get_switch_eval(sw), ast_get_switch_registrar(sw));
}
/* walk thru ignorepats ... */
- for (ip = NULL; (ip = ast_walk_context_ignorepats(old, ip)); ) {
- if (strcmp(ast_get_ignorepat_registrar(ip), registrar) == 0)
+ for (idx = 0; idx < ast_context_ignorepats_count(old); idx++) {
+ const struct ast_ignorepat *ip = ast_context_ignorepats_get(old, idx);
+
+ if (strcmp(ast_get_ignorepat_registrar(ip), registrar) == 0) {
continue; /* not mine */
+ }
ast_context_add_ignorepat2(new, ast_get_ignorepat_name(ip), ast_get_ignorepat_registrar(ip));
}
}
@@ -6628,43 +6625,24 @@ int ast_context_add_switch(const char *context, const char *sw, const char *data
int ast_context_add_switch2(struct ast_context *con, const char *value,
const char *data, int eval, const char *registrar)
{
+ int idx;
struct ast_sw *new_sw;
- struct ast_sw *i;
- int length;
- char *p;
-
- length = sizeof(struct ast_sw);
- length += strlen(value) + 1;
- if (data)
- length += strlen(data);
- length++;
/* allocate new sw structure ... */
- if (!(new_sw = ast_calloc(1, length)))
+ if (!(new_sw = sw_alloc(value, data, eval, registrar))) {
return -1;
- /* ... fill in this structure ... */
- p = new_sw->stuff;
- new_sw->name = p;
- strcpy(new_sw->name, value);
- p += strlen(value) + 1;
- new_sw->data = p;
- if (data) {
- strcpy(new_sw->data, data);
- p += strlen(data) + 1;
- } else {
- strcpy(new_sw->data, "");
- p++;
}
- new_sw->eval = eval;
- new_sw->registrar = registrar;
/* ... try to lock this context ... */
ast_wrlock_context(con);
/* ... go to last sw and check if context is already swd too... */
- AST_LIST_TRAVERSE(&con->alts, i, list) {
- if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
- ast_free(new_sw);
+ for (idx = 0; idx < ast_context_switches_count(con); idx++) {
+ const struct ast_sw *i = ast_context_switches_get(con, idx);
+
+ if (!strcasecmp(ast_get_switch_name(i), ast_get_switch_name(new_sw)) &&
+ !strcasecmp(ast_get_switch_data(i), ast_get_switch_data(new_sw))) {
+ sw_free(new_sw);
ast_unlock_context(con);
errno = EEXIST;
return -1;
@@ -6672,9 +6650,10 @@ int ast_context_add_switch2(struct ast_context *con, const char *value,
}
/* ... sw new context into context list, unlock, return */
- AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
+ AST_VECTOR_APPEND(&con->alts, new_sw);
- ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
+ ast_verb(3, "Including switch '%s/%s' in context '%s'\n",
+ ast_get_switch_name(new_sw), ast_get_switch_data(new_sw), ast_get_context_name(con));
ast_unlock_context(con);
@@ -6700,24 +6679,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)
{
- struct ast_ignorepat *ip, *ipl = NULL;
+ int idx;
ast_wrlock_context(con);
- for (ip = con->ignorepats; ip; ip = ip->next) {
- if (!strcmp(ip->pattern, ignorepat) &&
- (!registrar || (registrar == ip->registrar))) {
- if (ipl) {
- ipl->next = ip->next;
- ast_free(ip);
- } else {
- con->ignorepats = ip->next;
- ast_free(ip);
- }
+ for (idx = 0; idx < ast_context_ignorepats_count(con); idx++) {
+ struct ast_ignorepat *ip = AST_VECTOR_GET(&con->ignorepats, idx);
+
+ if (!strcmp(ast_get_ignorepat_name(ip), ignorepat) &&
+ (!registrar || (registrar == ast_get_ignorepat_registrar(ip)))) {
+ AST_VECTOR_REMOVE_ORDERED(&con->ignorepats, idx);
+ ignorepat_free(ip);
ast_unlock_context(con);
return 0;
}
- ipl = ip;
}
ast_unlock_context(con);
@@ -6744,41 +6719,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)
{
- struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
- int length;
- char *pattern;
- length = sizeof(struct ast_ignorepat);
- length += strlen(value) + 1;
- if (!(ignorepat = ast_calloc(1, length)))
+ struct ast_ignorepat *ignorepat = ignorepat_alloc(value, registrar);
+ int idx;
+
+ if (!ignorepat) {
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);
- for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
- ignorepatl = ignorepatc;
- if (!strcasecmp(ignorepatc->pattern, value)) {
+ for (idx = 0; idx < ast_context_ignorepats_count(con); idx++) {
+ const struct ast_ignorepat *i = ast_context_ignorepats_get(con, idx);
+
+ if (!strcasecmp(ast_get_ignorepat_name(i), value)) {
/* Already there */
ast_unlock_context(con);
- ast_free(ignorepat);
+ ignorepat_free(ignorepat);
errno = EEXIST;
return -1;
}
}
- if (ignorepatl)
- ignorepatl->next = ignorepat;
- else
- con->ignorepats = ignorepat;
+ AST_VECTOR_APPEND(&con->ignorepats, ignorepat);
ast_unlock_context(con);
- return 0;
+ return 0;
}
int ast_ignore_pattern(const char *context, const char *pattern)
@@ -6789,10 +6752,12 @@ int ast_ignore_pattern(const char *context, const char *pattern)
ast_rdlock_contexts();
con = ast_context_find(context);
if (con) {
- struct ast_ignorepat *pat;
+ int idx;
- for (pat = con->ignorepats; pat; pat = pat->next) {
- if (ast_extension_match(pat->pattern, pattern)) {
+ for (idx = 0; idx < ast_context_ignorepats_count(con); idx++) {
+ const struct ast_ignorepat *pat = ast_context_ignorepats_get(con, idx);
+
+ if (ast_extension_match(ast_get_ignorepat_name(pat), pattern)) {
ret = 1;
break;
}
@@ -7795,20 +7760,21 @@ 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_sw *sw;
struct ast_exten *e, *el, *en;
- struct ast_ignorepat *ipi;
struct ast_context *tmp = con;
/* 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;
- ast_free(ipl);
- }
+ /* Free ignorepats */
+ AST_VECTOR_CALLBACK_VOID(&tmp->ignorepats, ignorepat_free);
+ AST_VECTOR_FREE(&tmp->ignorepats);
+
+ /* Free switches */
+ AST_VECTOR_CALLBACK_VOID(&tmp->alts, sw_free);
+ AST_VECTOR_FREE(&tmp->alts);
+
if (tmp->registrar)
ast_free(tmp->registrar);
@@ -7820,8 +7786,6 @@ static void __ast_internal_context_destroy( struct ast_context *con)
if (tmp->pattern_tree)
destroy_pattern_tree(tmp->pattern_tree);
- while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list)))
- ast_free(sw);
for (e = tmp->root; e;) {
for (en = e->peer; en;) {
el = en;
@@ -7868,25 +7832,16 @@ void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *context
/* then search thru and remove any extens that match registrar. */
struct ast_hashtab_iter *exten_iter;
struct ast_hashtab_iter *prio_iter;
- struct ast_ignorepat *ip, *ipl = NULL, *ipn = NULL;
- struct ast_sw *sw = NULL;
int idx;
/* remove any ignorepats whose registrar matches */
- for (ip = tmp->ignorepats; ip; ip = ipn) {
- ipn = ip->next;
- if (!strcmp(ip->registrar, registrar)) {
- if (ipl) {
- ipl->next = ip->next;
- ast_free(ip);
- continue; /* don't change ipl */
- } else {
- tmp->ignorepats = ip->next;
- ast_free(ip);
- continue; /* don't change ipl */
- }
+ for (idx = ast_context_ignorepats_count(tmp) - 1; idx >= 0; idx--) {
+ struct ast_ignorepat *ip = AST_VECTOR_GET(&tmp->ignorepats, idx);
+
+ if (!strcmp(ast_get_ignorepat_registrar(ip), registrar)) {
+ AST_VECTOR_REMOVE_ORDERED(&tmp->ignorepats, idx);
+ ignorepat_free(ip);
}
- ipl = ip;
}
/* remove any includes whose registrar matches */
for (idx = ast_context_includes_count(tmp) - 1; idx >= 0; idx--) {
@@ -7898,13 +7853,14 @@ void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *context
}
}
/* remove any switches whose registrar matches */
- AST_LIST_TRAVERSE_SAFE_BEGIN(&tmp->alts, sw, list) {
- if (strcmp(sw->registrar,registrar) == 0) {
- AST_LIST_REMOVE_CURRENT(list);
- ast_free(sw);
+ for (idx = ast_context_switches_count(tmp) - 1; idx >= 0; idx--) {
+ struct ast_sw *sw = AST_VECTOR_GET(&tmp->alts, idx);
+
+ if (!strcmp(ast_get_switch_registrar(sw), registrar)) {
+ AST_VECTOR_REMOVE_ORDERED(&tmp->alts, idx);
+ sw_free(sw);
}
}
- AST_LIST_TRAVERSE_SAFE_END;
if (tmp->root_table) { /* it is entirely possible that the context is EMPTY */
exten_iter = ast_hashtab_start_traversal(tmp->root_table);
@@ -7955,7 +7911,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 && !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_context_switches_count(tmp)) {
ast_debug(1, "delete ctx %s %s\n", tmp->name, tmp->registrar);
ast_hashtab_remove_this_object(contexttab, tmp);
@@ -8356,11 +8312,6 @@ const char *ast_get_extension_label(struct ast_exten *exten)
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)
{
return exten ? exten->priority : -1;
@@ -8379,11 +8330,6 @@ const char *ast_get_extension_registrar(struct ast_exten *e)
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)
{
return e ? e->matchcid : 0;
@@ -8404,26 +8350,6 @@ void *ast_get_extension_app_data(struct ast_exten *e)
return e ? e->data : NULL;
}
-const char *ast_get_switch_name(struct ast_sw *sw)
-{
- return sw ? sw->name : NULL;
-}
-
-const char *ast_get_switch_data(struct ast_sw *sw)
-{
- return sw ? sw->data : NULL;
-}
-
-int ast_get_switch_eval(struct ast_sw *sw)
-{
- return sw->eval;
-}
-
-const char *ast_get_switch_registrar(struct ast_sw *sw)
-{
- return sw ? sw->registrar : NULL;
-}
-
/*
* Walking functions ...
*/
@@ -8441,13 +8367,43 @@ struct ast_exten *ast_walk_context_extensions(struct ast_context *con,
return exten->next;
}
-struct ast_sw *ast_walk_context_switches(struct ast_context *con,
- struct ast_sw *sw)
+const struct ast_sw *ast_walk_context_switches(const struct ast_context *con,
+ const struct ast_sw *sw)
{
- if (!sw)
- return con ? AST_LIST_FIRST(&con->alts) : NULL;
- else
- return AST_LIST_NEXT(sw, list);
+ if (sw) {
+ int idx;
+ int next = 0;
+
+ for (idx = 0; idx < ast_context_switches_count(con); idx++) {
+ const struct ast_sw *s = ast_context_switches_get(con, idx);
+
+ if (next) {
+ return s;
+ }
+
+ if (sw == s) {
+ next = 1;
+ }
+ }
+
+ return NULL;
+ }
+
+ if (!ast_context_switches_count(con)) {
+ return NULL;
+ }
+
+ return ast_context_switches_get(con, 0);
+}
+
+int ast_context_switches_count(const struct ast_context *con)
+{
+ return AST_VECTOR_SIZE(&con->alts);
+}
+
+const struct ast_sw *ast_context_switches_get(const struct ast_context *con, int idx)
+{
+ return AST_VECTOR_GET(&con->alts, idx);
}
struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten,
@@ -8495,13 +8451,47 @@ const struct ast_include *ast_context_includes_get(const struct ast_context *con
return AST_VECTOR_GET(&con->includes, idx);
}
-struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con,
- struct ast_ignorepat *ip)
+const struct ast_ignorepat *ast_walk_context_ignorepats(const struct ast_context *con,
+ const struct ast_ignorepat *ip)
{
- if (!ip)
- return con ? con->ignorepats : NULL;
- else
- return ip->next;
+ if (!con) {
+ return NULL;
+ }
+
+ 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)