diff --git a/apps/app_macro.c b/apps/app_macro.c index 5296e87234..eac1cc1573 100644 --- a/apps/app_macro.c +++ b/apps/app_macro.c @@ -477,6 +477,23 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) chan->macropriority = 0; } + /*!\note + * This section is used to restore a behavior that we mistakenly + * changed in issue #6176, then mistakenly reverted in #13962 and + * #13363. A corresponding change is made in main/pbx.c, where we + * check this variable for existence, then look for the "h" extension + * in that context. + */ + if (ast_check_hangup(chan) || res < 0) { + /* Don't need to lock the channel, as we aren't dereferencing emc. + * The intent here is to grab the deepest context, without overwriting + * in any above context. */ + const char *emc = pbx_builtin_getvar_helper(chan, "EXIT_MACRO_CONTEXT"); + if (!emc) { + pbx_builtin_setvar_helper(chan, "EXIT_MACRO_CONTEXT", fullmacro); + } + } + if (!strcasecmp(chan->context, fullmacro)) { /* If we're leaving the macro normally, restore original information */ chan->priority = oldpriority; diff --git a/main/pbx.c b/main/pbx.c index 44a769a6a4..187447588b 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -2365,6 +2365,7 @@ static int __ast_pbx_run(struct ast_channel *c) int res = 0; int autoloopflag; int error = 0; /* set an error conditions */ + const char *emc; /* A little initial setup here */ if (c->pbx) { @@ -2542,7 +2543,15 @@ static int __ast_pbx_run(struct ast_channel *c) ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); if (res != AST_PBX_KEEPALIVE) ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING); - if ((res != AST_PBX_KEEPALIVE) && !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) { + ast_channel_lock(c); + if ((emc = pbx_builtin_getvar_helper(c, "EXIT_MACRO_CONTEXT"))) { + emc = ast_strdupa(emc); + } + ast_channel_unlock(c); + if ((res != AST_PBX_KEEPALIVE) && !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) && + ((emc && ast_exists_extension(c, emc, "h", 1, c->cid.cid_num)) || + (ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num) && (emc = c->context)))) { + ast_copy_string(c->context, emc, sizeof(c->context)); set_ext_pri(c, "h", 1); if (c->cdr && ast_opt_end_cdr_before_h_exten) { ast_cdr_end(c->cdr);