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
char *data; /*!< Data load */
int eval;
AST_LIST_ENTRY(ast_sw) list;
- char *tmpdata;
char stuff[0];
};
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;
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;
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;
}
/* 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)
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 {
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.
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)))
strcpy(new_sw->data, "");
p++;
}
- if (eval)
- new_sw->tmpdata = p;
new_sw->eval = eval;
new_sw->registrar = registrar;
static int autofallthrough_config = 1;
static int clearglobalvars_config = 0;
static int extenpatternmatchnew_config = 0;
+static char *overrideswitch_config = NULL;
AST_MUTEX_DEFINE_STATIC(save_dialplan_lock);
*/
static char *handle_cli_dialplan_save(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- char filename[256];
+ char filename[256], overrideswitch[256] = "";
struct ast_context *c;
struct ast_config *cfg;
struct ast_variable *v;
}
/* fireout general info */
- fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\nextenpatternmatchnew=%s\n\n",
+ if (overrideswitch_config) {
+ snprintf(overrideswitch, sizeof(overrideswitch), "overrideswitch=%s\n", overrideswitch_config);
+ }
+ fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\n%sextenpatternmatchnew=%s\n\n",
static_config ? "yes" : "no",
write_protect_config ? "yes" : "no",
autofallthrough_config ? "yes" : "no",
clearglobalvars_config ? "yes" : "no",
+ overrideswitch_config ? overrideswitch : "",
extenpatternmatchnew_config ? "yes" : "no");
if ((v = ast_variable_browse(cfg, "globals"))) {
{
if (static_config && !write_protect_config)
ast_cli_unregister(&cli_dialplan_save);
+ if (overrideswitch_config) {
+ ast_free(overrideswitch_config);
+ }
ast_cli_unregister_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
ast_context_destroy(NULL, registrar);
return 0;
struct ast_variable *v;
const char *cxt;
const char *aft;
- const char *newpm;
+ const char *newpm, *ovsw;
struct ast_flags config_flags = { 0 };
cfg = ast_config_load(config_file, config_flags);
if (!cfg)
if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew")))
extenpatternmatchnew_config = ast_true(newpm);
clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars"));
-
+ if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) {
+ if (overrideswitch_config) {
+ ast_free(overrideswitch_config);
+ }
+ if (!ast_strlen_zero(ovsw)) {
+ overrideswitch_config = ast_strdup(ovsw);
+ } else {
+ overrideswitch_config = NULL;
+ }
+ }
if ((cxt = ast_variable_retrieve(cfg, "general", "userscontext")))
ast_copy_string(userscontext, cxt, sizeof(userscontext));
for (con = NULL; (con = ast_walk_contexts(con));)
ast_context_verify_includes(con);
+ pbx_set_overrideswitch(overrideswitch_config);
pbx_set_autofallthrough(autofallthrough_config);
pbx_set_extenpatternmatchnew(extenpatternmatchnew_config);