[asterisk-commits] rizzo: trunk r47180 - /trunk/apps/app_dial.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Nov 3 17:50:18 MST 2006


Author: rizzo
Date: Fri Nov  3 18:50:18 2006
New Revision: 47180

URL: http://svn.digium.com/view/asterisk?rev=47180&view=rev
Log:
move another block into a function.
On passing, avoid two null-pointer string dereference
while printing messages (which are
sometimes not fatal in some platforms, but still wrong).
These two lines at least should be merged to 1.4 once i am
done with all the changes here.


Modified:
    trunk/apps/app_dial.c

Modified: trunk/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_dial.c?rev=47180&r1=47179&r2=47180&view=diff
==============================================================================
--- trunk/apps/app_dial.c (original)
+++ trunk/apps/app_dial.c Fri Nov  3 18:50:18 2006
@@ -808,6 +808,103 @@
 	return 0;
 }
 
+static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
+	char *parse, unsigned int *calldurationlimit)
+{
+	char *limit_str, *warning_str, *warnfreq_str;
+	const char *var;
+	int play_to_caller=0,play_to_callee=0;
+	int delta;
+
+	limit_str = strsep(&warnfreq_str, ":");
+	warning_str = strsep(&warnfreq_str, ":");
+	warnfreq_str = parse;
+
+	config->timelimit = atol(limit_str);
+	if (warning_str)
+		config->play_warning = atol(warning_str);
+	if (warnfreq_str)
+		config->warning_freq = atol(warnfreq_str);
+
+	if (!config->timelimit) {
+		ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
+		config->timelimit = config->play_warning = config->warning_freq = 0;
+		config->warning_sound = NULL;
+		return -1;	/* error */
+	} else if ( (delta = config->play_warning - config->timelimit) > 0) {
+		int w = config->warning_freq;
+
+		/* If the first warning is requested _after_ the entire call would end,
+		   and no warning frequency is requested, then turn off the warning. If
+		   a warning frequency is requested, reduce the 'first warning' time by
+		   that frequency until it falls within the call's total time limit.
+		   Graphically:
+				  timelim->|    delta        |<-playwarning
+			0__________________|_________________|
+					 | w  |    |    |    |
+
+		   so the number of intervals to cut is 1+(delta-1)/w
+		*/
+
+		if (w == 0) {
+			config->play_warning = 0;
+		} else {
+			config->play_warning -= w * ( 1 + (delta-1)/w );
+			if (config->play_warning < 1)
+				config->play_warning = config->warning_freq = 0;
+		}
+	}
+
+	var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
+	play_to_caller = var ? ast_true(var) : 1;
+	
+	var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
+	play_to_callee = var ? ast_true(var) : 0;
+	
+	if (!play_to_caller && !play_to_callee)
+		play_to_caller = 1;
+	
+	var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
+	config->warning_sound = S_OR(var, "timeleft");
+
+	/* The code looking at config wants a NULL, not just "", to decide
+	 * that the message should not be played, so we replace "" with NULL.
+	 * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
+	 * not found.
+	 */
+	var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
+	config->end_sound = S_OR(var, NULL);
+	var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
+	config->start_sound = S_OR(var, NULL);
+
+	/* undo effect of S(x) in case they are both used */
+	*calldurationlimit = 0;
+	/* more efficient to do it like S(x) does since no advanced opts */
+	if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
+		*calldurationlimit = config->timelimit / 1000;
+		if (option_verbose > 2)
+			ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n",
+				*calldurationlimit);
+		config->timelimit = play_to_caller = play_to_callee =
+		config->play_warning = config->warning_freq = 0;
+	} else if (option_verbose > 2) {
+		ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
+		ast_verbose(VERBOSE_PREFIX_4 "timelimit      = %ld\n", config->timelimit);
+		ast_verbose(VERBOSE_PREFIX_4 "play_warning   = %ld\n", config->play_warning);
+		ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
+		ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
+		ast_verbose(VERBOSE_PREFIX_4 "warning_freq   = %ld\n", config->warning_freq);
+		ast_verbose(VERBOSE_PREFIX_4 "start_sound    = %s\n", S_OR(config->start_sound, ""));
+		ast_verbose(VERBOSE_PREFIX_4 "warning_sound  = %s\n", config->warning_sound);
+		ast_verbose(VERBOSE_PREFIX_4 "end_sound      = %s\n", S_OR(config->end_sound, ""));
+	}
+        if (play_to_caller)
+                ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
+        if (play_to_callee)
+                ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
+	return 0;
+}
+
 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags)
 {
 	int res = -1;	/* default: error */
@@ -821,6 +918,8 @@
 	char numsubst[AST_MAX_EXTENSION];
 	char cidname[AST_MAX_EXTENSION];
 	int privdb_val = 0;
+
+	struct ast_bridge_config config;
 	unsigned int calldurationlimit = 0;
 	long timelimit = 0;
 	long play_warning = 0;
@@ -853,11 +952,13 @@
 		return -1;
 	}
 
-	u = ast_module_user_add(chan);
+	u = ast_module_user_add(chan);	/* XXX is this the right place ? */
 
 	parse = ast_strdupa(data);
 
 	AST_STANDARD_APP_ARGS(args, parse);
+
+	memset(&config,0,sizeof(struct ast_bridge_config));
 
 	if (!ast_strlen_zero(args.options) &&
 			ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options))
@@ -892,77 +993,8 @@
 	}
 
 	if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
-		char *limit_str, *warning_str, *warnfreq_str;
-		const char *var;
-
-		warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
-		limit_str = strsep(&warnfreq_str, ":");
-		warning_str = strsep(&warnfreq_str, ":");
-
-		timelimit = atol(limit_str);
-		if (warning_str)
-			play_warning = atol(warning_str);
-		if (warnfreq_str)
-			warning_freq = atol(warnfreq_str);
-
-		if (!timelimit) {
-			ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
+		if (do_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
 			goto done;
-		} else if (play_warning > timelimit) {
-			/* If the first warning is requested _after_ the entire call would end,
-			   and no warning frequency is requested, then turn off the warning. If
-			   a warning frequency is requested, reduce the 'first warning' time by
-			   that frequency until it falls within the call's total time limit.
-			*/
-
-			if (!warning_freq) {
-				play_warning = 0;
-			} else {
-				/* XXX fix this!! */
-				while (play_warning > timelimit)
-					play_warning -= warning_freq;
-				if (play_warning < 1)
-					play_warning = warning_freq = 0;
-			}
-		}
-
-		var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
-		play_to_caller = var ? ast_true(var) : 1;
-		
-		var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
-		play_to_callee = var ? ast_true(var) : 0;
-		
-		if (!play_to_caller && !play_to_callee)
-			play_to_caller = 1;
-		
-		var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
-		warning_sound = S_OR(var, "timeleft");
-		
-		var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
-		end_sound = S_OR(var, NULL);	/* XXX not much of a point in doing this! */
-		
-		var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
-		start_sound = S_OR(var, NULL);	/* XXX not much of a point in doing this! */
-
-		/* undo effect of S(x) in case they are both used */
-		calldurationlimit = 0;
-		/* more efficient to do it like S(x) does since no advanced opts */
-		if (!play_warning && !start_sound && !end_sound && timelimit) {
-			calldurationlimit = timelimit / 1000;
-			if (option_verbose > 2)
-				ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
-			timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
-		} else if (option_verbose > 2) {
-			ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
-			ast_verbose(VERBOSE_PREFIX_4 "timelimit      = %ld\n", timelimit);
-			ast_verbose(VERBOSE_PREFIX_4 "play_warning   = %ld\n", play_warning);
-			ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
-			ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
-			ast_verbose(VERBOSE_PREFIX_4 "warning_freq   = %ld\n", warning_freq);
-			ast_verbose(VERBOSE_PREFIX_4 "start_sound    = %s\n", start_sound);
-			ast_verbose(VERBOSE_PREFIX_4 "warning_sound  = %s\n", warning_sound);
-			ast_verbose(VERBOSE_PREFIX_4 "end_sound      = %s\n", end_sound);
-		}
 	}
 
 	if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
@@ -1671,7 +1703,7 @@
 		res = 0;
 
 done:
-	ast_module_user_remove(u);    
+	ast_module_user_remove(u);    	/* XXX probably not the right place for this. */
 	return res;
 }
 



More information about the asterisk-commits mailing list