[asterisk-commits] rmudgett: trunk r365749 - /trunk/apps/app_followme.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue May 8 16:42:03 CDT 2012


Author: rmudgett
Date: Tue May  8 16:41:58 2012
New Revision: 365749

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=365749
Log:
Make FollowMe app_exec() not declare a 28k struct on the stack.

Helping to stamp out stack abuse.

Modified:
    trunk/apps/app_followme.c

Modified: trunk/apps/app_followme.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_followme.c?view=diff&rev=365749&r1=365748&r2=365749
==============================================================================
--- trunk/apps/app_followme.c (original)
+++ trunk/apps/app_followme.c Tue May  8 16:41:58 2012
@@ -1143,7 +1143,7 @@
 
 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 @@
 		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 @@
 
 	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);
-	}
-
-	if (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_NOANSWER)) {
+		ast_clear_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 @@
 			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_RECORDNAME)) {
+		if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_STATUSMSG)) {
+			ast_stream_and_wait(chan, targs->statusprompt, "");
+		}
+
+		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_test_flag(&targs.followmeflags, FOLLOWMEFLAG_DISABLEHOLDPROMPT)) {
-			if (ast_streamfile(chan, targs.plsholdprompt, ast_channel_language(chan)))
+			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))) {
 				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 @@
 			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 @@
 		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 (ast_test_flag(&targs.followmeflags, FOLLOWMEFLAG_NOANSWER)) {
+		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_channel_state(caller) != AST_STATE_UP) {
 				ast_answer(caller);
 			}
@@ -1310,10 +1320,10 @@
 		}
 
 		/* 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 @@
 	}
 
 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);
-	}
-	ast_party_connected_line_free(&targs.connected_in);
-	ast_party_connected_line_free(&targs.connected_out);
+	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_free(targs);
 
 	if (f->realtime) {
 		/* Not in list */




More information about the asterisk-commits mailing list