aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-03-10 21:48:20 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-03-10 21:48:20 +0000
commitd7a3bcf49b7224604a90914d4256fd02efbbfcc9 (patch)
treedff4bf7db6d813c70ce9ad1d03b9e41527b7c6eb /main
parent5f074afc2205cd5859857437dd9ff8944d20d1a4 (diff)
(closes issue #6019)
Reported by: ssokol Patches: 20080304__bug6019.diff.txt uploaded by Corydon76 (license 14) Tested by: putnopvut git-svn-id: http://svn.digium.com/svn/asterisk/trunk@107231 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/pbx.c94
1 files changed, 83 insertions, 11 deletions
diff --git a/main/pbx.c b/main/pbx.c
index 2e3260a34..029b68b8a 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -123,6 +123,8 @@ AST_APP_OPTIONS(waitexten_opts, {
struct ast_context;
struct ast_app;
+AST_THREADSTORAGE(switch_data);
+
/*!
\brief ast_exten: An extension
The dialplan is saved as a linked list with each context
@@ -166,7 +168,6 @@ struct ast_sw {
char *data; /*!< Data load */
int eval;
AST_LIST_ENTRY(ast_sw) list;
- char *tmpdata;
char stuff[0];
};
@@ -413,6 +414,7 @@ static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
static int autofallthrough = 1;
static int extenpatternmatchnew = 0;
+static char *overrideswitch = NULL;
/*! \brief Subscription for device state change events */
static struct ast_event_sub *device_state_sub;
@@ -1644,6 +1646,7 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan,
struct ast_sw *sw = NULL;
struct ast_exten pattern = {NULL, };
struct scoreboard score = {0, };
+ struct ast_str *tmpdata = NULL;
pattern.label = label;
pattern.priority = priority;
@@ -1707,6 +1710,65 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan,
log_match_char_tree(tmp->pattern_tree, ":: ");
#endif
+ do {
+ if (!ast_strlen_zero(overrideswitch)) {
+ char *osw = ast_strdupa(overrideswitch), *name;
+ struct ast_switch *asw;
+ ast_switch_f *aswf = NULL;
+ char *datap;
+ int eval = 0;
+
+ name = strsep(&osw, "/");
+ asw = pbx_findswitch(name);
+
+ if (!asw) {
+ ast_log(LOG_WARNING, "No such switch '%s'\n", name);
+ break;
+ }
+
+ if (osw && strchr(osw, '$')) {
+ eval = 1;
+ }
+
+ if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) {
+ ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!");
+ break;
+ } else if (eval) {
+ /* Substitute variables now */
+ pbx_substitute_variables_helper(chan, osw, tmpdata->str, tmpdata->len);
+ datap = tmpdata->str;
+ } else {
+ datap = osw;
+ }
+
+ /* equivalent of extension_match_core() at the switch level */
+ if (action == E_CANMATCH)
+ aswf = asw->canmatch;
+ else if (action == E_MATCHMORE)
+ aswf = asw->matchmore;
+ else /* action == E_MATCH */
+ aswf = asw->exists;
+ if (!aswf) {
+ res = 0;
+ } else {
+ if (chan) {
+ ast_autoservice_start(chan);
+ }
+ res = aswf(chan, context, exten, priority, callerid, datap);
+ if (chan) {
+ ast_autoservice_stop(chan);
+ }
+ }
+ if (res) { /* Got a match */
+ q->swo = asw;
+ q->data = datap;
+ q->foundcontext = context;
+ /* XXX keep status = STATUS_NO_CONTEXT ? */
+ return NULL;
+ }
+ }
+ } while (0);
+
if (extenpatternmatchnew) {
new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid);
eroot = score.exten;
@@ -1828,8 +1890,13 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan,
}
/* Substitute variables now */
- if (sw->eval)
- pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1);
+ if (sw->eval) {
+ if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) {
+ ast_log(LOG_WARNING, "Can't evaluate switch?!");
+ continue;
+ }
+ pbx_substitute_variables_helper(chan, sw->data, tmpdata->str, tmpdata->len);
+ }
/* equivalent of extension_match_core() at the switch level */
if (action == E_CANMATCH)
@@ -1838,7 +1905,7 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan,
aswf = asw->matchmore;
else /* action == E_MATCH */
aswf = asw->exists;
- datap = sw->eval ? sw->tmpdata : sw->data;
+ datap = sw->eval ? tmpdata->str : sw->data;
if (!aswf)
res = 0;
else {
@@ -3618,6 +3685,18 @@ int pbx_set_extenpatternmatchnew(int newval)
return oldval;
}
+void pbx_set_overrideswitch(const char *newval)
+{
+ if (overrideswitch) {
+ ast_free(overrideswitch);
+ }
+ if (!ast_strlen_zero(newval)) {
+ overrideswitch = ast_strdup(newval);
+ } else {
+ overrideswitch = NULL;
+ }
+}
+
/*!
* \brief lookup for a context with a given name,
* \retval with conlock held if found.
@@ -5781,11 +5860,6 @@ int ast_context_add_switch2(struct ast_context *con, const char *value,
if (data)
length += strlen(data);
length++;
- if (eval) {
- /* Create buffer for evaluation of variables */
- length += SWITCH_DATA_LENGTH;
- length++;
- }
/* allocate new sw structure ... */
if (!(new_sw = ast_calloc(1, length)))
@@ -5803,8 +5877,6 @@ int ast_context_add_switch2(struct ast_context *con, const char *value,
strcpy(new_sw->data, "");
p++;
}
- if (eval)
- new_sw->tmpdata = p;
new_sw->eval = eval;
new_sw->registrar = registrar;