diff options
Diffstat (limited to 'main/app.c')
-rw-r--r-- | main/app.c | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/main/app.c b/main/app.c index d9f56a4aa..f937b0e30 100644 --- a/main/app.c +++ b/main/app.c @@ -247,28 +247,79 @@ int ast_app_getdata_full(struct ast_channel *c, const char *prompt, char *s, int return res; } -int ast_app_run_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char * const macro_name, const char * const macro_args) +static int app_exec_dialplan(struct ast_channel *autoservice_chan, struct ast_channel *exec_chan, const char * const args, int use_gosub) { - struct ast_app *macro_app; + + struct ast_app *app; int res; - char buf[1024]; + char * app_type = use_gosub ? "GoSub" : "Macro"; - macro_app = pbx_findapp("Macro"); - if (!macro_app) { - ast_log(LOG_WARNING, "Cannot run macro '%s' because the 'Macro' application in not available\n", macro_name); + app = pbx_findapp(app_type); + if (!app) { + ast_log(LOG_WARNING, "Cannot run '%s' because the '%s' application is not available\n", args, app_type); return -1; } - snprintf(buf, sizeof(buf), "%s%s%s", macro_name, ast_strlen_zero(macro_args) ? "" : ",", S_OR(macro_args, "")); if (autoservice_chan) { ast_autoservice_start(autoservice_chan); } - res = pbx_exec(macro_chan, macro_app, buf); + res = pbx_exec(exec_chan, app, args); + if (use_gosub && !res) { + struct ast_pbx_args gosub_args = {{0}}; + struct ast_pbx *pbx = ast_channel_pbx(exec_chan); + /* supress warning about a pbx already being on the channel */ + ast_channel_pbx_set(exec_chan, NULL); + gosub_args.no_hangup_chan = 1; + ast_pbx_run_args(exec_chan, &gosub_args); + if (ast_channel_pbx(exec_chan)) { + ast_free(ast_channel_pbx(exec_chan)); + } + ast_channel_pbx_set(exec_chan, pbx); + } if (autoservice_chan) { ast_autoservice_stop(autoservice_chan); } return res; } +int ast_app_run_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char * const name, const char * const args) +{ + char buf[1024]; + snprintf(buf, sizeof(buf), "%s%s%s", name, ast_strlen_zero(args) ? "" : ",", S_OR(args, "")); + return app_exec_dialplan(autoservice_chan, macro_chan, buf, 0); +} + +int ast_app_run_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char * const location, const char * const args) +{ + char buf[1024]; + size_t offset = snprintf(buf, sizeof(buf), "%s", location); + /* need to bump the priority by one if we already have a pbx */ + if (ast_channel_pbx(sub_chan)) { + int iprio; + const char * priority = location; + const char * next = strchr(priority,','); + /* jump to the priority portion of the location */ + if (next) { + priority = next + 1; + } + next = strchr(priority,','); + if (next) { + priority = next + 1; + } + /* if the priority isn't numeric, it's as if we never took this branch... */ + if (sscanf(priority, "%d", &iprio)) { + offset = priority - location; + iprio++; + if (offset < sizeof(buf)) { + offset += snprintf(buf + offset, sizeof(buf) - offset, "%d", iprio); + } + } + } + if (offset < sizeof(buf)) { + snprintf(buf + offset, sizeof(buf) - offset, "%s%s%s", ast_strlen_zero(args) ? "" : "(", S_OR(args, ""), ast_strlen_zero(args) ? "" : ")"); + } + return app_exec_dialplan(autoservice_chan, sub_chan, buf, 1); +} + static int (*ast_has_voicemail_func)(const char *mailbox, const char *folder) = NULL; static int (*ast_inboxcount_func)(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL; static int (*ast_inboxcount2_func)(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs) = NULL; |