summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2012-05-08 21:41:58 +0000
committerRichard Mudgett <rmudgett@digium.com>2012-05-08 21:41:58 +0000
commitb1a94ddcdd7d787dae5a02c865c0473f997605bc (patch)
treeff2ab42e258348a4237f39efc6d58bc3e8bdf8be /apps
parentdb4fb48f5851546e5c711ca13942f5a5fb4cd12a (diff)
Make FollowMe app_exec() not declare a 28k struct on the stack.
Helping to stamp out stack abuse. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@365749 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps')
-rw-r--r--apps/app_followme.c103
1 files changed, 57 insertions, 46 deletions
diff --git a/apps/app_followme.c b/apps/app_followme.c
index 9cbe9dc9f..7e14ffcf9 100644
--- a/apps/app_followme.c
+++ b/apps/app_followme.c
@@ -1143,7 +1143,7 @@ static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, st
static int app_exec(struct ast_channel *chan, const char *data)
{
- struct fm_args targs = { 0, };
+ struct fm_args *targs;
struct ast_bridge_config config;
struct call_followme *f;
struct number *nm, *newnm;
@@ -1170,6 +1170,11 @@ static int app_exec(struct ast_channel *chan, const char *data)
return -1;
}
+ targs = ast_calloc(1, sizeof(*targs));
+ if (!targs) {
+ return -1;
+ }
+
AST_RWLIST_RDLOCK(&followmes);
AST_RWLIST_TRAVERSE(&followmes, f, entry) {
if (!strcasecmp(f->name, args.followmeid) && (f->active))
@@ -1185,42 +1190,44 @@ static int app_exec(struct ast_channel *chan, const char *data)
if (!f) {
ast_log(LOG_WARNING, "Profile requested, %s, not found in the configuration.\n", args.followmeid);
+ ast_free(targs);
return 0;
}
/* XXX TODO: Reinsert the db check value to see whether or not follow-me is on or off */
- if (args.options)
- ast_app_parse_options(followme_opts, &targs.followmeflags, NULL, args.options);
+ if (args.options) {
+ ast_app_parse_options(followme_opts, &targs->followmeflags, NULL, args.options);
+ }
/* Lock the profile lock and copy out everything we need to run with before unlocking it again */
ast_mutex_lock(&f->lock);
- targs.mohclass = ast_strdupa(f->moh);
- ast_copy_string(targs.context, f->context, sizeof(targs.context));
- ast_copy_string(targs.takecall, f->takecall, sizeof(targs.takecall));
- ast_copy_string(targs.nextindp, f->nextindp, sizeof(targs.nextindp));
- ast_copy_string(targs.callfromprompt, f->callfromprompt, sizeof(targs.callfromprompt));
- ast_copy_string(targs.norecordingprompt, f->norecordingprompt, sizeof(targs.norecordingprompt));
- ast_copy_string(targs.optionsprompt, f->optionsprompt, sizeof(targs.optionsprompt));
- ast_copy_string(targs.plsholdprompt, f->plsholdprompt, sizeof(targs.plsholdprompt));
- ast_copy_string(targs.statusprompt, f->statusprompt, sizeof(targs.statusprompt));
- ast_copy_string(targs.sorryprompt, f->sorryprompt, sizeof(targs.sorryprompt));
+ targs->mohclass = ast_strdupa(f->moh);
+ ast_copy_string(targs->context, f->context, sizeof(targs->context));
+ ast_copy_string(targs->takecall, f->takecall, sizeof(targs->takecall));
+ ast_copy_string(targs->nextindp, f->nextindp, sizeof(targs->nextindp));
+ ast_copy_string(targs->callfromprompt, f->callfromprompt, sizeof(targs->callfromprompt));
+ ast_copy_string(targs->norecordingprompt, f->norecordingprompt, sizeof(targs->norecordingprompt));
+ ast_copy_string(targs->optionsprompt, f->optionsprompt, sizeof(targs->optionsprompt));
+ ast_copy_string(targs->plsholdprompt, f->plsholdprompt, sizeof(targs->plsholdprompt));
+ ast_copy_string(targs->statusprompt, f->statusprompt, sizeof(targs->statusprompt));
+ ast_copy_string(targs->sorryprompt, f->sorryprompt, sizeof(targs->sorryprompt));
/* Copy the numbers we're going to use into another list in case the master list should get modified
(and locked) while we're trying to do a follow-me */
- AST_LIST_HEAD_INIT_NOLOCK(&targs.cnumbers);
+ AST_LIST_HEAD_INIT_NOLOCK(&targs->cnumbers);
AST_LIST_TRAVERSE(&f->numbers, nm, entry) {
newnm = create_followme_number(nm->number, nm->timeout, nm->order);
if (newnm) {
- AST_LIST_INSERT_TAIL(&targs.cnumbers, newnm, entry);
+ AST_LIST_INSERT_TAIL(&targs->cnumbers, newnm, entry);
}
}
ast_mutex_unlock(&f->lock);
/* Forget the 'N' option if the call is already up. */
if (ast_channel_state(chan) == AST_STATE_UP) {
- ast_clear_flag(&targs.followmeflags, FOLLOWMEFLAG_NOANSWER);
+ ast_clear_flag(&targs->followmeflags, FOLLOWMEFLAG_NOANSWER);
}
- if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_NOANSWER)) {
+ if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_NOANSWER)) {
ast_indicate(chan, AST_CONTROL_RINGING);
} else {
/* Answer the call */
@@ -1228,39 +1235,41 @@ static int app_exec(struct ast_channel *chan, const char *data)
ast_answer(chan);
}
- if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_STATUSMSG))
- ast_stream_and_wait(chan, targs.statusprompt, "");
+ if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_STATUSMSG)) {
+ ast_stream_and_wait(chan, targs->statusprompt, "");
+ }
- if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_RECORDNAME)) {
+ if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_RECORDNAME)) {
int duration = 5;
- snprintf(targs.namerecloc, sizeof(targs.namerecloc), "%s/followme.%s",
+ snprintf(targs->namerecloc, sizeof(targs->namerecloc), "%s/followme.%s",
ast_config_AST_SPOOL_DIR, ast_channel_uniqueid(chan));
- if (ast_play_and_record(chan, "vm-rec-name", targs.namerecloc, 5, "sln", &duration,
+ if (ast_play_and_record(chan, "vm-rec-name", targs->namerecloc, 5, "sln", &duration,
NULL, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE), 0, NULL) < 0) {
goto outrun;
}
- if (!ast_fileexists(targs.namerecloc, NULL, ast_channel_language(chan))) {
- targs.namerecloc[0] = '\0';
+ if (!ast_fileexists(targs->namerecloc, NULL, ast_channel_language(chan))) {
+ targs->namerecloc[0] = '\0';
}
}
- if (!ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_DISABLEHOLDPROMPT)) {
- if (ast_streamfile(chan, targs.plsholdprompt, ast_channel_language(chan)))
+ if (!ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_DISABLEHOLDPROMPT)) {
+ if (ast_streamfile(chan, targs->plsholdprompt, ast_channel_language(chan))) {
goto outrun;
+ }
if (ast_waitstream(chan, "") < 0)
goto outrun;
}
- ast_moh_start(chan, S_OR(targs.mohclass, NULL), NULL);
+ ast_moh_start(chan, S_OR(targs->mohclass, NULL), NULL);
}
ast_channel_lock(chan);
- ast_connected_line_copy_from_caller(&targs.connected_in, ast_channel_caller(chan));
+ ast_connected_line_copy_from_caller(&targs->connected_in, ast_channel_caller(chan));
ast_channel_unlock(chan);
- outbound = findmeexec(&targs, chan);
+ outbound = findmeexec(targs, chan);
if (!outbound) {
- if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_NOANSWER)) {
+ if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_NOANSWER)) {
if (ast_channel_state(chan) != AST_STATE_UP) {
ast_answer(chan);
}
@@ -1268,8 +1277,9 @@ static int app_exec(struct ast_channel *chan, const char *data)
ast_moh_stop(chan);
}
- if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_UNREACHABLEMSG))
- ast_stream_and_wait(chan, targs.sorryprompt, "");
+ if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_UNREACHABLEMSG)) {
+ ast_stream_and_wait(chan, targs->sorryprompt, "");
+ }
res = 0;
} else {
caller = chan;
@@ -1284,14 +1294,14 @@ static int app_exec(struct ast_channel *chan, const char *data)
config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup;
/* Update connected line to caller if available. */
- if (targs.pending_out_connected_update) {
- if (ast_channel_connected_line_sub(outbound, caller, &targs.connected_out, 0) &&
- ast_channel_connected_line_macro(outbound, caller, &targs.connected_out, 1, 0)) {
- ast_channel_update_connected_line(caller, &targs.connected_out, NULL);
+ if (targs->pending_out_connected_update) {
+ if (ast_channel_connected_line_sub(outbound, caller, &targs->connected_out, 0) &&
+ ast_channel_connected_line_macro(outbound, caller, &targs->connected_out, 1, 0)) {
+ ast_channel_update_connected_line(caller, &targs->connected_out, NULL);
}
}
- if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_NOANSWER)) {
+ if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_NOANSWER)) {
if (ast_channel_state(caller) != AST_STATE_UP) {
ast_answer(caller);
}
@@ -1310,10 +1320,10 @@ static int app_exec(struct ast_channel *chan, const char *data)
}
/* Update connected line to winner if changed. */
- if (targs.pending_in_connected_update) {
- if (ast_channel_connected_line_sub(caller, outbound, &targs.connected_in, 0) &&
- ast_channel_connected_line_macro(caller, outbound, &targs.connected_in, 0, 0)) {
- ast_channel_update_connected_line(outbound, &targs.connected_in, NULL);
+ if (targs->pending_in_connected_update) {
+ if (ast_channel_connected_line_sub(caller, outbound, &targs->connected_in, 0) &&
+ ast_channel_connected_line_macro(caller, outbound, &targs->connected_in, 0, 0)) {
+ ast_channel_update_connected_line(outbound, &targs->connected_in, NULL);
}
}
@@ -1322,14 +1332,15 @@ static int app_exec(struct ast_channel *chan, const char *data)
}
outrun:
- while ((nm = AST_LIST_REMOVE_HEAD(&targs.cnumbers, entry))) {
+ while ((nm = AST_LIST_REMOVE_HEAD(&targs->cnumbers, entry))) {
ast_free(nm);
}
- if (!ast_strlen_zero(targs.namerecloc)) {
- unlink(targs.namerecloc);
+ if (!ast_strlen_zero(targs->namerecloc)) {
+ unlink(targs->namerecloc);
}
- ast_party_connected_line_free(&targs.connected_in);
- ast_party_connected_line_free(&targs.connected_out);
+ ast_party_connected_line_free(&targs->connected_in);
+ ast_party_connected_line_free(&targs->connected_out);
+ ast_free(targs);
if (f->realtime) {
/* Not in list */