diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-12-17 21:21:19 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-12-17 21:21:19 +0000 |
commit | f4fd2b3522ec04bb34c8365e6dfee0773af3e430 (patch) | |
tree | 374d1b43c1d59ef0f256f946295dbb8c7bea1e4d /apps/app_macro.c | |
parent | 8e05ee78f439f9d4c4880ac26f5a9444a7dd9e06 (diff) |
Merged revisions 165319 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk
................
r165319 | tilghman | 2008-12-17 15:18:57 -0600 (Wed, 17 Dec 2008) | 11 lines
Merged revisions 165317 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r165317 | tilghman | 2008-12-17 15:14:37 -0600 (Wed, 17 Dec 2008) | 4 lines
Reverse the fix from issue #6176 and add proper handling for that issue.
(Closes issue #13962, closes issue #13363)
Fixed by myself (license 14)
........
................
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@165321 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_macro.c')
-rw-r--r-- | apps/app_macro.c | 74 |
1 files changed, 55 insertions, 19 deletions
diff --git a/apps/app_macro.c b/apps/app_macro.c index 68bbf16a4..cdd6ef0b1 100644 --- a/apps/app_macro.c +++ b/apps/app_macro.c @@ -97,7 +97,32 @@ static char *if_synopsis = "Conditional Macro Implementation"; static char *exclusive_synopsis = "Exclusive Macro Implementation"; static char *exit_synopsis = "Exit From Macro"; +static void macro_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan); +struct ast_datastore_info macro_ds_info = { + .type = "MACRO", + .chan_fixup = macro_fixup, +}; + +static void macro_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan) +{ + int i; + char varname[10]; + pbx_builtin_setvar_helper(new_chan, "MACRO_DEPTH", "0"); + pbx_builtin_setvar_helper(new_chan, "MACRO_CONTEXT", NULL); + pbx_builtin_setvar_helper(new_chan, "MACRO_EXTEN", NULL); + pbx_builtin_setvar_helper(new_chan, "MACRO_PRIORITY", NULL); + pbx_builtin_setvar_helper(new_chan, "MACRO_OFFSET", NULL); + for (i = 1; i < 100; i++) { + snprintf(varname, sizeof(varname), "ARG%d", i); + while (pbx_builtin_getvar_helper(new_chan, varname)) { + /* Kill all levels of arguments */ + pbx_builtin_setvar_helper(new_chan, varname, NULL); + } + } +} + +>>>>>>> .merge-right.r165319 static struct ast_exten *find_matching_priority(struct ast_context *c, const char *exten, int priority, const char *callerid) { struct ast_exten *e; @@ -152,18 +177,32 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) const char *inhangupc; int offset, depth = 0, maxdepth = 7; int setmacrocontext=0; - int autoloopflag, dead = 0, inhangup = 0; + int autoloopflag, inhangup = 0; char *save_macro_exten; char *save_macro_context; char *save_macro_priority; char *save_macro_offset; + struct ast_datastore *macro_store = ast_channel_datastore_find(chan, ¯o_ds_info, NULL); if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "Macro() requires arguments. See \"core show application macro\" for help.\n"); return -1; } + do { + if (macro_store) { + break; + } + if (!(macro_store = ast_channel_datastore_alloc(¯o_ds_info, NULL))) { + ast_log(LOG_WARNING, "Unable to allocate new datastore.\n"); + break; + } + /* Just the existence of this datastore is enough. */ + macro_store->inheritance = DATASTORE_INHERIT_FOREVER; + ast_channel_datastore_add(chan, macro_store); + } while (0); + /* does the user want a deeper rabbit hole? */ s = pbx_builtin_getvar_helper(chan, "MACRO_RECURSION"); if (s) @@ -307,12 +346,10 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) case AST_PBX_KEEPALIVE: ast_debug(2, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name); ast_verb(2, "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name); - dead = 1; goto out; default: ast_debug(2, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro); ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro); - dead = 1; goto out; } } @@ -385,31 +422,30 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) chan->priority++; } out: + + /* Don't let the channel change now. */ + ast_channel_lock(chan); + /* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */ snprintf(depthc, sizeof(depthc), "%d", depth); - if (!dead) { - pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); - ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); - } + pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); + ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); for (x = 1; x < argc; x++) { /* Restore old arguments and delete ours */ snprintf(varname, sizeof(varname), "ARG%d", x); if (oldargs[x]) { - if (!dead) - pbx_builtin_setvar_helper(chan, varname, oldargs[x]); + pbx_builtin_setvar_helper(chan, varname, oldargs[x]); ast_free(oldargs[x]); - } else if (!dead) { + } else { pbx_builtin_setvar_helper(chan, varname, NULL); } } /* Restore macro variables */ - if (!dead) { - pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten); - pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context); - pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority); - } + pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten); + pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context); + pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority); if (save_macro_exten) ast_free(save_macro_exten); if (save_macro_context) @@ -417,13 +453,13 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) if (save_macro_priority) ast_free(save_macro_priority); - if (!dead && setmacrocontext) { + if (setmacrocontext) { chan->macrocontext[0] = '\0'; chan->macroexten[0] = '\0'; chan->macropriority = 0; } - if (!dead && !strcasecmp(chan->context, fullmacro)) { + if (!strcasecmp(chan->context, fullmacro)) { /* If we're leaving the macro normally, restore original information */ chan->priority = oldpriority; ast_copy_string(chan->context, oldcontext, sizeof(chan->context)); @@ -443,8 +479,7 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) } } - if (!dead) - pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset); + pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset); if (save_macro_offset) ast_free(save_macro_offset); @@ -456,6 +491,7 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) res = 0; } } + ast_channel_unlock(chan); return res; } |