[asterisk-commits] branch oej/02-labarea r22164 - in /team/oej/02-labarea: ./ apps/ cdr/ channel...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sat Apr 22 23:51:44 MST 2006


Author: oej
Date: Sun Apr 23 01:51:43 2006
New Revision: 22164

URL: http://svn.digium.com/view/asterisk?rev=22164&view=rev
Log:
Update to trunk

Added:
    team/oej/02-labarea/configs/say.conf.sample
      - copied unchanged from r22128, trunk/configs/say.conf.sample
Modified:
    team/oej/02-labarea/   (props changed)
    team/oej/02-labarea/app.c
    team/oej/02-labarea/apps/app_dial.c
    team/oej/02-labarea/apps/app_directory.c
    team/oej/02-labarea/apps/app_dumpchan.c
    team/oej/02-labarea/apps/app_meetme.c
    team/oej/02-labarea/apps/app_playback.c
    team/oej/02-labarea/apps/app_queue.c
    team/oej/02-labarea/apps/app_voicemail.c
    team/oej/02-labarea/asterisk.c
    team/oej/02-labarea/cdr.c
    team/oej/02-labarea/cdr/cdr_odbc.c
    team/oej/02-labarea/channel.c
    team/oej/02-labarea/channels/chan_features.c
    team/oej/02-labarea/channels/chan_local.c
    team/oej/02-labarea/channels/chan_mgcp.c
    team/oej/02-labarea/channels/chan_sip.c
    team/oej/02-labarea/channels/chan_skinny.c
    team/oej/02-labarea/channels/chan_zap.c
    team/oej/02-labarea/cli.c
    team/oej/02-labarea/contrib/scripts/safe_asterisk
    team/oej/02-labarea/contrib/scripts/safe_asterisk.8
    team/oej/02-labarea/enum.c
    team/oej/02-labarea/file.c
    team/oej/02-labarea/funcs/func_callerid.c
    team/oej/02-labarea/include/asterisk/channel.h
    team/oej/02-labarea/include/asterisk/file.h
    team/oej/02-labarea/include/asterisk/frame.h
    team/oej/02-labarea/include/asterisk/say.h
    team/oej/02-labarea/include/asterisk/utils.h
    team/oej/02-labarea/manager.c
    team/oej/02-labarea/pbx.c
    team/oej/02-labarea/res/res_adsi.c
    team/oej/02-labarea/res/res_agi.c
    team/oej/02-labarea/res/res_features.c
    team/oej/02-labarea/res/res_musiconhold.c
    team/oej/02-labarea/say.c

Propchange: team/oej/02-labarea/
------------------------------------------------------------------------------
Binary property 'branch-1.2-merged' - no diff available.

Modified: team/oej/02-labarea/app.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/app.c?rev=22164&r1=22163&r2=22164&view=diff
==============================================================================
--- team/oej/02-labarea/app.c (original)
+++ team/oej/02-labarea/app.c Sun Apr 23 01:51:43 2006
@@ -155,10 +155,7 @@
 	struct ast_dsp *sildet;
 	/* Play prompt if requested */
 	if (prompt) {
-		res = ast_streamfile(c, prompt, c->language);
-		if (res < 0)
-			return res;
-		res = ast_waitstream(c,"");
+		res = ast_stream_and_wait(c, prompt, c->language, "");
 		if (res < 0)
 			return res;
 	}
@@ -573,9 +570,7 @@
 	if (playfile) {
 		d = ast_play_and_wait(chan, playfile);
 		if (d > -1)
-			d = ast_streamfile(chan, "beep",chan->language);
-		if (!d)
-			d = ast_waitstream(chan,"");
+			d = ast_stream_and_wait(chan, "beep", chan->language, "");
 		if (d < 0)
 			return -1;
 	}
@@ -749,8 +744,7 @@
 	}
 	if (outmsg > 1) {
 		/* Let them know recording is stopped */
-		if(!ast_streamfile(chan, "auth-thankyou", chan->language))
-			ast_waitstream(chan, "");
+		ast_stream_and_wait(chan, "auth-thankyou", chan->language, "");
 	}
 	if (sildet)
 		ast_dsp_free(sildet);
@@ -794,9 +788,7 @@
 		if (!beep)
 			d = ast_play_and_wait(chan, playfile);
 		if (d > -1)
-			d = ast_streamfile(chan, "beep",chan->language);
-		if (!d)
-			d = ast_waitstream(chan,"");
+			d = ast_stream_and_wait(chan, "beep",chan->language, "");
 		if (d < 0)
 			return -1;
 	}
@@ -981,8 +973,7 @@
 	}
 	if (outmsg > 1) {
 		/* Let them know it worked */
-		ast_streamfile(chan, "auth-thankyou", chan->language);
-		ast_waitstream(chan, "");
+		ast_stream_and_wait(chan, "auth-thankyou", chan->language, "");
 	}	
 	return res;
 }
@@ -1205,16 +1196,14 @@
 				cmd = '3';
 				break;
 			} else {
-				ast_streamfile(chan, "vm-msgsaved", chan->language);
-				ast_waitstream(chan, "");
+				ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
 				cmd = 't';
 				return res;
 			}
 		case '2':
 			/* Review */
 			ast_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n");
-			ast_streamfile(chan, recordfile, chan->language);
-			cmd = ast_waitstream(chan, AST_DIGIT_ANY);
+			cmd = ast_stream_and_wait(chan, recordfile, chan->language, AST_DIGIT_ANY);
 			break;
 		case '3':
 			message_exists = 0;
@@ -1300,19 +1289,15 @@
 	case AST_ACTION_NOOP:
 		return 0;
 	case AST_ACTION_BACKGROUND:
-		res = ast_streamfile(chan, (char *)option->adata, chan->language);
-		if (!res) {
-			res = ast_waitstream(chan, AST_DIGIT_ANY);
-		} else {
+		res = ast_stream_and_wait(chan, (char *)option->adata, chan->language, AST_DIGIT_ANY);
+		if (res < 0) {
 			ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
 			res = 0;
 		}
 		return res;
 	case AST_ACTION_PLAYBACK:
-		res = ast_streamfile(chan, (char *)option->adata, chan->language);
-		if (!res) {
-			res = ast_waitstream(chan, "");
-		} else {
+		res = ast_stream_and_wait(chan, (char *)option->adata, chan->language, "");
+		if (res < 0) {
 			ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
 			res = 0;
 		}
@@ -1341,7 +1326,8 @@
 		c = ast_strdupa(option->adata);
 		if (c) {
 			while((n = strsep(&c, ";")))
-				if ((res = ast_streamfile(chan, n, chan->language)) || (res = ast_waitstream(chan, (option->action == AST_ACTION_BACKLIST) ? AST_DIGIT_ANY : "")))
+				if ((res = ast_stream_and_wait(chan, n, chan->language,
+						(option->action == AST_ACTION_BACKLIST) ? AST_DIGIT_ANY : "")))
 					break;
 			ast_stopstream(chan);
 		}

Modified: team/oej/02-labarea/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/apps/app_dial.c?rev=22164&r1=22163&r2=22164&view=diff
==============================================================================
--- team/oej/02-labarea/apps/app_dial.c (original)
+++ team/oej/02-labarea/apps/app_dial.c Sun Apr 23 01:51:43 2006
@@ -154,6 +154,16 @@
 "    o    - Specify that the CallerID that was present on the *calling* channel\n"
 "           be set as the CallerID on the *called* channel. This was the\n"
 "           behavior of Asterisk 1.0 and earlier.\n"
+"    O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
+"             only, if specified on non-Zaptel interface, it will be ignored).\n"
+"             When the destination answers (presumably an operator services\n"
+"             station), the originator no longer has control of their line.\n"
+"             They may hang up, but the switch will not release their line\n"
+"             until the destination party hangs up (the operator). Specified\n"
+"             without an arg, or with 1 as an arg, the originator hanging up\n"
+"             will cause the phone to ring back immediately. With a 2 specified,\n"
+"             when the \"operator\" flashes the trunk, it will ring their phone\n"
+"             back.\n"
 "    p    - This option enables screening mode. This is basically Privacy mode\n"
 "           without memory.\n"
 "    P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
@@ -213,6 +223,7 @@
 	OPT_CALLEE_MONITOR =	(1 << 21),
 	OPT_CALLER_MONITOR =	(1 << 22),
 	OPT_GOTO =		(1 << 23),
+	OPT_OPERMODE = 		(1 << 24),
 } dial_exec_option_flags;
 
 #define DIAL_STILLGOING			(1 << 30)
@@ -227,6 +238,7 @@
 	OPT_ARG_CALLEE_MACRO,
 	OPT_ARG_PRIVACY,
 	OPT_ARG_DURATION_STOP,
+	OPT_ARG_OPERMODE,
 	/* note: this entry _MUST_ be the last one in the enum */
 	OPT_ARG_ARRAY_SIZE,
 } dial_exec_option_args;
@@ -247,6 +259,7 @@
 	AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
 	AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
 	AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
+	AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
 	AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
 	AST_APP_OPTION('p', OPT_SCREENING),
 	AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
@@ -334,28 +347,17 @@
 }
 
 
-static char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
+static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
 {
-	char *context;
-	char *exten;
-	if (!ast_strlen_zero(chan->macrocontext))
-		context = chan->macrocontext;
-	else
-		context = chan->context;
-
-	if (!ast_strlen_zero(chan->macroexten))
-		exten = chan->macroexten;
-	else
-		exten = chan->exten;
-
-	if (ast_get_hint(NULL, 0, name, namelen, chan, context, exten))
-		return name;
-	else
-		return "";
+	const char *context = S_OR(chan->macrocontext, chan->context);
+	const char *exten = S_OR(chan->macroexten, chan->exten);
+
+	return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
 }
 
 static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
 {
+	/* XXX do we need also CallerIDnum ? */
 	manager_event(EVENT_FLAG_CALL, "Dial", 
 			   "Source: %s\r\n"
 			   "Destination: %s\r\n"
@@ -363,32 +365,21 @@
 			   "CallerIDName: %s\r\n"
 			   "SrcUniqueID: %s\r\n"
 			   "DestUniqueID: %s\r\n",
-			   src->name, dst->name, src->cid.cid_num ? src->cid.cid_num : "<unknown>",
-			   src->cid.cid_name ? src->cid.cid_name : "<unknown>", src->uniqueid,
+			   src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
+			   S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
 			   dst->uniqueid);
 }
 
 static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int priority_jump, int *result)
 {
-	struct dial_localuser *o;
-	int found;
-	int numlines;
 	int numbusy = busystart;
 	int numcongestion = congestionstart;
 	int numnochan = nochanstart;
 	int prestart = busystart + congestionstart + nochanstart;
-	int cause;
 	int orig = *to;
-	struct ast_frame *f;
 	struct ast_channel *peer = NULL;
-	struct ast_channel *watchers[AST_MAX_WATCHERS];
-	int pos;
-	int single;
-	struct ast_channel *winner;
-	const char *context = NULL;
-	char cidname[AST_MAX_EXTENSION];
-
-	single = (outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK));
+	/* single is set if only one destination is enabled */
+	int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
 	
 	if (single) {
 		/* Turn off hold music, etc */
@@ -399,21 +390,20 @@
 	
 	
 	while (*to && !peer) {
-		o = outgoing;
-		found = -1;
-		pos = 1;
-		numlines = prestart;
-		watchers[0] = in;
-		while (o) {
+		struct dial_localuser *o;
+		int pos = 0;	/* how many channels do we handle */
+		int numlines = prestart;
+		struct ast_channel *winner;
+		struct ast_channel *watchers[AST_MAX_WATCHERS];
+
+		watchers[pos++] = in;
+		for (o = outgoing; o; o = o->next) {
 			/* Keep track of important channels */
-			if (ast_test_flag(o, DIAL_STILLGOING) && o->chan) {
+			if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
 				watchers[pos++] = o->chan;
-				found = 1;
-			}
-			o = o->next;
 			numlines++;
 		}
-		if (found < 0) {
+		if (pos == 1) {	/* only the input channel is available */
 			if (numlines == (numbusy + numcongestion + numnochan)) {
 				if (option_verbose > 2)
 					ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
@@ -433,239 +423,224 @@
 			return NULL;
 		}
 		winner = ast_waitfor_n(watchers, pos, to);
-		o = outgoing;
-		while (o) {
-			if (ast_test_flag(o, DIAL_STILLGOING) && o->chan && (o->chan->_state == AST_STATE_UP)) {
+		for (o = outgoing; o; o = o->next) {
+			struct ast_frame *f;
+			struct ast_channel *c = o->chan;
+
+			if (c == NULL)
+				continue;
+			if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
 				if (!peer) {
 					if (option_verbose > 2)
-						ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
-					peer = o->chan;
+						ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
+					peer = c;
 					ast_copy_flags(peerflags, o,
 						       OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
 						       OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
 						       OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
 						       DIAL_NOFORWARDHTML);
 				}
-			} else if (o->chan && (o->chan == winner)) {
-				if (!ast_strlen_zero(o->chan->call_forward)) {
-					char tmpchan[256];
-					char *stuff;
-					char *tech;
-					const char *forward_context;
-
-					ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
-					if ((stuff = strchr(tmpchan, '/'))) {
-						*stuff = '\0';
-						stuff++;
-						tech = tmpchan;
+				continue;
+			}
+			if (c != winner)
+				continue;
+			if (!ast_strlen_zero(c->call_forward)) {
+				char tmpchan[256];
+				char *stuff;
+				char *tech;
+				int cause;
+
+				ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
+				if ((stuff = strchr(tmpchan, '/'))) {
+					*stuff++ = '\0';
+					tech = tmpchan;
+				} else {
+					const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
+					snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
+					stuff = tmpchan;
+					tech = "Local";
+				}
+				/* Before processing channel, go ahead and check for forwarding */
+				o->forwards++;
+				if (o->forwards < AST_MAX_FORWARDS) {
+					if (option_verbose > 2)
+						ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
+					/* Setup parameters */
+					c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
+					if (!c)
+						ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
+				} else {
+					if (option_verbose > 2)
+						ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name);
+					cause = AST_CAUSE_CONGESTION;
+					c = o->chan = NULL;
+				}
+				if (!c) {
+					ast_clear_flag(o, DIAL_STILLGOING);	
+					HANDLE_CAUSE(cause, in);
+				} else {
+					ast_rtp_make_compatible(c, in);
+					if (c->cid.cid_num)
+						free(c->cid.cid_num);
+					c->cid.cid_num = NULL;
+					if (c->cid.cid_name)
+						free(c->cid.cid_name);
+					c->cid.cid_name = NULL;
+
+					if (ast_test_flag(o, OPT_FORCECLID)) {
+						c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
+						ast_string_field_set(c, accountcode, winner->accountcode);
+						c->cdrflags = winner->cdrflags;
 					} else {
-						forward_context = pbx_builtin_getvar_helper(o->chan, "FORWARD_CONTEXT");
-						snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, forward_context ? forward_context : o->chan->context);
-						stuff = tmpchan;
-						tech = "Local";
+						c->cid.cid_num = ast_strdup(in->cid.cid_num);
+						c->cid.cid_name = ast_strdup(in->cid.cid_name);
+						ast_string_field_set(c, accountcode, in->accountcode);
+						c->cdrflags = in->cdrflags;
 					}
-					/* Before processing channel, go ahead and check for forwarding */
-					o->forwards++;
-					if (o->forwards < AST_MAX_FORWARDS) {
-						if (option_verbose > 2)
-							ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
-						/* Setup parameters */
-						o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
-						if (!o->chan)
-							ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
+
+					if (in->cid.cid_ani) {
+						if (c->cid.cid_ani)
+							free(c->cid.cid_ani);
+						c->cid.cid_ani = ast_strdup(in->cid.cid_ani);
+					}
+					if (c->cid.cid_rdnis) 
+						free(c->cid.cid_rdnis);
+					c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
+					if (ast_call(c, tmpchan, 0)) {
+						ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
+						ast_clear_flag(o, DIAL_STILLGOING);	
+						ast_hangup(c);
+						c = o->chan = NULL;
+						numnochan++;
 					} else {
-						if (option_verbose > 2)
-							ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", o->chan->name);
-						cause = AST_CAUSE_CONGESTION;
-						o->chan = NULL;
-					}
-					if (!o->chan) {
-						ast_clear_flag(o, DIAL_STILLGOING);	
-						HANDLE_CAUSE(cause, in);
-					} else {
-						ast_rtp_make_compatible(o->chan, in);
-						if (o->chan->cid.cid_num)
-							free(o->chan->cid.cid_num);
-						o->chan->cid.cid_num = NULL;
-						if (o->chan->cid.cid_name)
-							free(o->chan->cid.cid_name);
-						o->chan->cid.cid_name = NULL;
-
-						if (ast_test_flag(o, OPT_FORCECLID)) {
-							char *newcid = NULL;
-
-							if (!ast_strlen_zero(in->macroexten))
-								newcid = in->macroexten;
-							else
-								newcid = in->exten;
-							o->chan->cid.cid_num = strdup(newcid);
-							ast_string_field_set(o->chan, accountcode, winner->accountcode);
-							o->chan->cdrflags = winner->cdrflags;
-							if (!o->chan->cid.cid_num)
-								ast_log(LOG_WARNING, "Out of memory\n");
-						} else {
-							if (in->cid.cid_num) {
-								o->chan->cid.cid_num = strdup(in->cid.cid_num);
-								if (!o->chan->cid.cid_num)
-									ast_log(LOG_WARNING, "Out of memory\n");	
-							}
-							if (in->cid.cid_name) {
-								o->chan->cid.cid_name = strdup(in->cid.cid_name);
-								if (!o->chan->cid.cid_name)
-									ast_log(LOG_WARNING, "Out of memory\n");	
-							}
-							ast_string_field_set(o->chan, accountcode, in->accountcode);
-							o->chan->cdrflags = in->cdrflags;
-						}
-
-						if (in->cid.cid_ani) {
-							if (o->chan->cid.cid_ani)
-								free(o->chan->cid.cid_ani);
-							o->chan->cid.cid_ani = strdup(in->cid.cid_ani);
-							if (!o->chan->cid.cid_ani)
-								ast_log(LOG_WARNING, "Out of memory\n");
-						}
-						if (o->chan->cid.cid_rdnis) 
-							free(o->chan->cid.cid_rdnis);
-						if (!ast_strlen_zero(in->macroexten))
-							o->chan->cid.cid_rdnis = strdup(in->macroexten);
-						else
-							o->chan->cid.cid_rdnis = strdup(in->exten);
-						if (ast_call(o->chan, tmpchan, 0)) {
-							ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
-							ast_clear_flag(o, DIAL_STILLGOING);	
-							ast_hangup(o->chan);
-							o->chan = NULL;
-							numnochan++;
-						} else {
-							senddialevent(in, o->chan);
-							/* After calling, set callerid to extension */
-							if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
-								ast_set_callerid(o->chan, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
+						senddialevent(in, c);
+						/* After calling, set callerid to extension */
+						if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
+							char cidname[AST_MAX_EXTENSION];
+							ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
 						}
 					}
-					/* Hangup the original channel now, in case we needed it */
-					ast_hangup(winner);
-					continue;
 				}
-				f = ast_read(winner);
-				if (f) {
-					if (f->frametype == AST_FRAME_CONTROL) {
-						switch(f->subclass) {
-						case AST_CONTROL_ANSWER:
-							/* This is our guy if someone answered. */
-							if (!peer) {
-								if (option_verbose > 2)
-									ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
-								peer = o->chan;
-								ast_copy_flags(peerflags, o,
-									       OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
-									       OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
-									       OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
-									       DIAL_NOFORWARDHTML);
-							}
-							/* If call has been answered, then the eventual hangup is likely to be normal hangup */
-							in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
-							o->chan->hangupcause = AST_CAUSE_NORMAL_CLEARING;
-							break;
-						case AST_CONTROL_BUSY:
-							if (option_verbose > 2)
-								ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
-							in->hangupcause = o->chan->hangupcause;
-							ast_hangup(o->chan);
-							o->chan = NULL;
-							ast_clear_flag(o, DIAL_STILLGOING);	
-							HANDLE_CAUSE(AST_CAUSE_BUSY, in);
-							break;
-						case AST_CONTROL_CONGESTION:
-							if (option_verbose > 2)
-								ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
-							in->hangupcause = o->chan->hangupcause;
-							ast_hangup(o->chan);
-							o->chan = NULL;
-							ast_clear_flag(o, DIAL_STILLGOING);
-							HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
-							break;
-						case AST_CONTROL_RINGING:
-							if (option_verbose > 2)
-								ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
-							if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
-								ast_indicate(in, AST_CONTROL_RINGING);
-								(*sentringing)++;
-							}
-							break;
-						case AST_CONTROL_PROGRESS:
-							if (option_verbose > 2)
-								ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", o->chan->name,in->name);
-							if (!ast_test_flag(outgoing, OPT_RINGBACK))
-								ast_indicate(in, AST_CONTROL_PROGRESS);
-							break;
-						case AST_CONTROL_VIDUPDATE:
-							if (option_verbose > 2)
-								ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", o->chan->name,in->name);
-							ast_indicate(in, AST_CONTROL_VIDUPDATE);
-							break;
-						case AST_CONTROL_PROCEEDING:
-							if (option_verbose > 2)
-								ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", o->chan->name,in->name);
-							if (!ast_test_flag(outgoing, OPT_RINGBACK))
-								ast_indicate(in, AST_CONTROL_PROCEEDING);
-							break;
-						case AST_CONTROL_HOLD:
-							if (option_verbose > 2)
-								ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", o->chan->name);
-							ast_indicate(in, AST_CONTROL_HOLD);
-							break;
-						case AST_CONTROL_UNHOLD:
-							if (option_verbose > 2)
-								ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", o->chan->name);
-							ast_indicate(in, AST_CONTROL_UNHOLD);
-							break;
-						case AST_CONTROL_OFFHOOK:
-						case AST_CONTROL_FLASH:
-							/* Ignore going off hook and flash */
-							break;
-						case -1:
-							if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
-								if (option_verbose > 2)
-									ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
-								ast_indicate(in, -1);
-								(*sentringing) = 0;
-							}
-							break;
-						default:
-							if (option_debug)
-								ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
-						}
-					} else if (single && (f->frametype == AST_FRAME_VOICE) && 
-								!(ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK))) {
-						if (ast_write(in, f)) 
-							ast_log(LOG_WARNING, "Unable to forward voice frame\n");
-					} else if (single && (f->frametype == AST_FRAME_IMAGE) && 
-								!(ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK))) {
-						if (ast_write(in, f))
-							ast_log(LOG_WARNING, "Unable to forward image\n");
-					} else if (single && (f->frametype == AST_FRAME_TEXT) && 
-								!(ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK))) {
-						if (ast_write(in, f))
-							ast_log(LOG_WARNING, "Unable to send text\n");
-					} else if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
-						if(ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
-							ast_log(LOG_WARNING, "Unable to send URL\n");
-
-					ast_frfree(f);
-				} else {
-					in->hangupcause = o->chan->hangupcause;
-					ast_hangup(o->chan);
-					o->chan = NULL;
+				/* Hangup the original channel now, in case we needed it */
+				ast_hangup(winner);
+				continue;
+			}
+			f = ast_read(winner);
+			if (!f) {
+				in->hangupcause = c->hangupcause;
+				ast_hangup(c);
+				c = o->chan = NULL;
+				ast_clear_flag(o, DIAL_STILLGOING);
+				HANDLE_CAUSE(in->hangupcause, in);
+				continue;
+			}
+			if (f->frametype == AST_FRAME_CONTROL) {
+				switch(f->subclass) {
+				case AST_CONTROL_ANSWER:
+					/* This is our guy if someone answered. */
+					if (!peer) {
+						if (option_verbose > 2)
+							ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
+						peer = c;
+						ast_copy_flags(peerflags, o,
+							       OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
+							       OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
+							       OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
+							       DIAL_NOFORWARDHTML);
+					}
+					/* If call has been answered, then the eventual hangup is likely to be normal hangup */
+					in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
+					c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
+					break;
+				case AST_CONTROL_BUSY:
+					if (option_verbose > 2)
+						ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
+					in->hangupcause = c->hangupcause;
+					ast_hangup(c);
+					c = o->chan = NULL;
+					ast_clear_flag(o, DIAL_STILLGOING);	
+					HANDLE_CAUSE(AST_CAUSE_BUSY, in);
+					break;
+				case AST_CONTROL_CONGESTION:
+					if (option_verbose > 2)
+						ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
+					in->hangupcause = c->hangupcause;
+					ast_hangup(c);
+					c = o->chan = NULL;
 					ast_clear_flag(o, DIAL_STILLGOING);
-					HANDLE_CAUSE(in->hangupcause, in);
+					HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
+					break;
+				case AST_CONTROL_RINGING:
+					if (option_verbose > 2)
+						ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
+					if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
+						ast_indicate(in, AST_CONTROL_RINGING);
+						(*sentringing)++;
+					}
+					break;
+				case AST_CONTROL_PROGRESS:
+					if (option_verbose > 2)
+						ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
+					if (!ast_test_flag(outgoing, OPT_RINGBACK))
+						ast_indicate(in, AST_CONTROL_PROGRESS);
+					break;
+				case AST_CONTROL_VIDUPDATE:
+					if (option_verbose > 2)
+						ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
+					ast_indicate(in, AST_CONTROL_VIDUPDATE);
+					break;
+				case AST_CONTROL_PROCEEDING:
+					if (option_verbose > 2)
+						ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
+					if (!ast_test_flag(outgoing, OPT_RINGBACK))
+						ast_indicate(in, AST_CONTROL_PROCEEDING);
+					break;
+				case AST_CONTROL_HOLD:
+					if (option_verbose > 2)
+						ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
+					ast_indicate(in, AST_CONTROL_HOLD);
+					break;
+				case AST_CONTROL_UNHOLD:
+					if (option_verbose > 2)
+						ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
+					ast_indicate(in, AST_CONTROL_UNHOLD);
+					break;
+				case AST_CONTROL_OFFHOOK:
+				case AST_CONTROL_FLASH:
+					/* Ignore going off hook and flash */
+					break;
+				case -1:
+					if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
+						if (option_verbose > 2)
+							ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
+						ast_indicate(in, -1);
+						(*sentringing) = 0;
+					}
+					break;
+				default:
+					if (option_debug)
+						ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
 				}
-			}
-			o = o->next;
-		}
+			} else if (single) {
+				/* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
+				if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
+					if (ast_write(in, f)) 
+						ast_log(LOG_WARNING, "Unable to forward voice frame\n");
+				} else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
+					if (ast_write(in, f))
+						ast_log(LOG_WARNING, "Unable to forward image\n");
+				} else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
+					if (ast_write(in, f))
+						ast_log(LOG_WARNING, "Unable to send text\n");
+				} else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
+					if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
+						ast_log(LOG_WARNING, "Unable to send URL\n");
+				}
+			}
+			ast_frfree(f);
+		} /* end for */
 		if (winner == in) {
-			f = ast_read(in);
+			struct ast_frame *f = ast_read(in);
 #if 0
 			if (f && (f->frametype != AST_FRAME_VOICE))
 				printf("Frame type: %d, %d\n", f->frametype, f->subclass);
@@ -683,7 +658,7 @@
 
 			if (f && (f->frametype == AST_FRAME_DTMF)) {
 				if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
-					context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
+					const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
 					if (onedigit_goto(in, context, (char) f->subclass, 1)) {
 						if (option_verbose > 2)
 							ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
@@ -728,17 +703,34 @@
 	}
 
 	return peer;
-	
+}
+
+static void replace_macro_delimiter(char *s)
+{
+	for (; *s; s++)
+		if (*s == '^')
+			*s = '|';
+}
+
+
+/* returns true if there is a valid privacy reply */
+static int valid_priv_reply(struct ast_flags *opts, int res)
+{
+	if (res < '1')
+		return 0;
+	if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
+		return 1;
+	if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
+		return 1;
+	return 0;
 }
 
 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags)
 {
 	int res = -1;
 	struct localuser *u;
-	char *tech, *number, *rest, *cur;
-	char privcid[256];
-	char privintro[1024];
-	struct dial_localuser *outgoing = NULL, *tmp;
+	char *rest, *cur;
+	struct dial_localuser *outgoing = NULL;
 	struct ast_channel *peer;
 	int to;
 	int numbusy = 0;
@@ -747,11 +739,8 @@
 	int cause;
 	char numsubst[AST_MAX_EXTENSION];
 	char cidname[AST_MAX_EXTENSION];
-	char toast[80];
-	char *l;
 	int privdb_val = 0;
 	unsigned int calldurationlimit = 0;
-	struct ast_bridge_config config;
 	long timelimit = 0;
 	long play_warning = 0;
 	long warning_freq = 0;
@@ -759,18 +748,16 @@
 	const char *end_sound = NULL;
 	const char *start_sound = NULL;
 	char *dtmfcalled = NULL, *dtmfcalling = NULL;
-	const char *var;
 	char status[256];
 	int play_to_caller = 0, play_to_callee = 0;
 	int sentringing = 0, moh = 0;
 	const char *outbound_group = NULL;
-	const char *macro_result = NULL;
-	char *macro_transfer_dest = NULL;
-	int digit = 0, result = 0;
-	time_t start_time, answer_time, end_time;
-	struct ast_app *app = NULL;
-
+	int result = 0;
+	time_t start_time;
+	char privintro[1024];
+	char privcid[256];
 	char *parse;
+	int opermode = 0;
 	AST_DECLARE_APP_ARGS(args,
 			     AST_APP_ARG(peers);
 			     AST_APP_ARG(timeout);
@@ -787,50 +774,50 @@
 
 	LOCAL_USER_ADD(u);
 
-	if (!(parse = ast_strdupa(data))) {
-		LOCAL_USER_REMOVE(u);
-		return -1;
-	}
-	
+	if (!(parse = ast_strdupa(data)))
+		goto done;
+
 	AST_STANDARD_APP_ARGS(args, parse);
 
-	if (!ast_strlen_zero(args.options)) {
-		if (ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
-			LOCAL_USER_REMOVE(u);
-			return -1;
-		}
-	}
+	if (!ast_strlen_zero(args.options) &&
+			ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options))
+		goto done;
 
 	if (ast_strlen_zero(args.peers)) {
 		ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
-		LOCAL_USER_REMOVE(u);
-		return -1;
+		goto done;
+	}
+
+	if (ast_test_flag(&opts, OPT_OPERMODE)) {
+		if (ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]))
+			opermode = 1;
+		else opermode = atoi(opt_args[OPT_ARG_OPERMODE]);
+		if (option_verbose > 2)
+			ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
 	}
 
 	if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
 		calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
 		if (!calldurationlimit) {
 			ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
-			LOCAL_USER_REMOVE(u);
-			return -1;
+			goto done;
 		}
 		if (option_verbose > 2)
 			ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
 	}
 
 	if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
-		parse = opt_args[OPT_ARG_SENDDTMF];
-		dtmfcalled = strsep(&parse, ":");
-		dtmfcalling = parse;
+		dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
+		dtmfcalled = strsep(&dtmfcalling, ":");
 	}
 
 	if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
 		char *limit_str, *warning_str, *warnfreq_str;
-
-		parse = opt_args[OPT_ARG_DURATION_LIMIT];
-		limit_str = strsep(&parse, ":");
-		warning_str = strsep(&parse, ":");
-		warnfreq_str = parse;
+		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)
@@ -840,8 +827,7 @@
 
 		if (!timelimit) {
 			ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
-			LOCAL_USER_REMOVE(u);
-			return -1;
+			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
@@ -852,6 +838,7 @@
 			if (!warning_freq) {
 				play_warning = 0;
 			} else {
+				/* XXX fix this!! */
 				while (play_warning > timelimit)
 					play_warning -= warning_freq;
 				if (play_warning < 1)
@@ -869,13 +856,13 @@
 			play_to_caller = 1;
 		
 		var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
-		warning_sound = (!ast_strlen_zero(var)) ? var : "timeleft";
+		warning_sound = S_OR(var, "timeleft");
 		
 		var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
-		end_sound = (!ast_strlen_zero(var)) ? var : NULL;
+		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 = (!ast_strlen_zero(var)) ? var : NULL;
+		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;
@@ -904,8 +891,7 @@
 		opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
 	if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
 		char callerid[60];
-
-		l = chan->cid.cid_num;
+		char *l = chan->cid.cid_num;	/* XXX watch out, we are overwriting it */
 		if (!ast_strlen_zero(l)) {
 			ast_shrink_phone_number(l);
 			if( ast_test_flag(&opts, OPT_PRIVACY) ) {
@@ -998,26 +984,19 @@
 	outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
 
 	ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP);
-	cur = args.peers;
-	do {
-		/* Remember where to start next time */
-		rest = strchr(cur, '&');
-		if (rest) {
-			*rest = 0;
-			rest++;
-		}
+	/* loop through the list of dial destinations */
+	rest = args.peers;
+	while ((cur = strsep(&rest, "&")) ) {
+		struct dial_localuser *tmp;
 		/* Get a technology/[device:]number pair */
-		tech = cur;
-		number = strchr(tech, '/');
+		char *number = cur;
+		char *tech = strsep(&number, "/");
 		if (!number) {
 			ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
 			goto out;
 		}
-		*number = '\0';
-		number++;		
-		if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
+		if (!(tmp = ast_calloc(1, sizeof(*tmp))))
 			goto out;
-		}
 		if (opts.flags) {
 			ast_copy_flags(tmp, &opts,
 				       OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
@@ -1033,8 +1012,7 @@
 			/* If we can't, just go on to the next call */
 			ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
 			HANDLE_CAUSE(cause, chan);
-			cur = rest;
-			if (!cur)
+			if (!rest)	/* we are on the last destination */
 				chan->hangupcause = cause;
 			continue;
 		}
@@ -1045,8 +1023,7 @@
 			char *tech;
 			ast_copy_string(tmpchan, tmp->chan->call_forward, sizeof(tmpchan));
 			if ((stuff = strchr(tmpchan, '/'))) {
-				*stuff = '\0';
-				stuff++;
+				*stuff++ = '\0';
 				tech = tmpchan;
 			} else {
 				snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tmp->chan->call_forward, tmp->chan->context);
@@ -1071,7 +1048,6 @@
 			}
 			if (!tmp->chan) {
 				HANDLE_CAUSE(cause, chan);
-				cur = rest;
 				continue;
 			}
 		}
@@ -1085,22 +1061,18 @@
 		tmp->chan->appl = "AppDial";
 		tmp->chan->data = "(Outgoing Line)";
 		tmp->chan->whentohangup = 0;
+
 		if (tmp->chan->cid.cid_num)
 			free(tmp->chan->cid.cid_num);
-		tmp->chan->cid.cid_num = NULL;
+		tmp->chan->cid.cid_num = ast_strdup(chan->cid.cid_num);
+
 		if (tmp->chan->cid.cid_name)
 			free(tmp->chan->cid.cid_name);
-		tmp->chan->cid.cid_name = NULL;
+		tmp->chan->cid.cid_name = ast_strdup(chan->cid.cid_name);
+
 		if (tmp->chan->cid.cid_ani)
 			free(tmp->chan->cid.cid_ani);
-		tmp->chan->cid.cid_ani = NULL;
-
-		if (chan->cid.cid_num) 
-			tmp->chan->cid.cid_num = strdup(chan->cid.cid_num);
-		if (chan->cid.cid_name) 
-			tmp->chan->cid.cid_name = strdup(chan->cid.cid_name);
-		if (chan->cid.cid_ani) 
-			tmp->chan->cid.cid_ani = strdup(chan->cid.cid_ani);
+		tmp->chan->cid.cid_ani = ast_strdup(chan->cid.cid_ani);
 		
 		/* Copy language from incoming to outgoing */
 		ast_string_field_set(tmp->chan, language, chan->language);
@@ -1108,8 +1080,8 @@
 		tmp->chan->cdrflags = chan->cdrflags;
 		if (ast_strlen_zero(tmp->chan->musicclass))
 			ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
-		if (chan->cid.cid_rdnis)
-			tmp->chan->cid.cid_rdnis = strdup(chan->cid.cid_rdnis);
+		/* XXX don't we free previous values ? */
+		tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
 		/* Pass callingpres setting */
 		tmp->chan->cid.cid_pres = chan->cid.cid_pres;
 		/* Pass type of number */
@@ -1141,7 +1113,6 @@
 				ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
 			ast_hangup(tmp->chan);
 			tmp->chan = NULL;
-			cur = rest;
 			continue;
 		} else {
 			senddialevent(chan, tmp->chan);
@@ -1159,19 +1130,21 @@
 		/* If this line is up, don't try anybody else */
 		if (outgoing->chan->_state == AST_STATE_UP)
 			break;
-		cur = rest;
-	} while (cur);
+	}
 	
-	if (!ast_strlen_zero(args.timeout)) {
+	if (ast_strlen_zero(args.timeout)) {
+		to = -1;
+	} else {
 		to = atoi(args.timeout);
 		if (to > 0)
 			to *= 1000;
 		else
 			ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
-	} else
-		to = -1;
-
-	if (outgoing) {
+	}
+
+	if (!outgoing) {
+		strcpy(status, "CHANUNAVAIL");
+	} else {
 		/* Our status will at least be NOANSWER */
 		strcpy(status, "NOANSWER");
 		if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
@@ -1181,8 +1154,7 @@
 			ast_indicate(chan, AST_CONTROL_RINGING);
 			sentringing++;
 		}
-	} else
-		strcpy(status, "CHANUNAVAIL");
+	}
 
 	time(&start_time);
 	peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
@@ -1190,17 +1162,16 @@
 	if (!peer) {
 		if (result) {
 			res = result;
-		} else if (to) 
-			/* Musta gotten hung up */
+		} else if (to) { /* Musta gotten hung up */
 			res = -1;
-		else 
-		 	/* Nobody answered, next please? */
+		} else { /* Nobody answered, next please? */
 			res = 0;
-		
-		goto out;
-	}
-	if (peer) {
-		time(&answer_time);
+		}
+		/* almost done, although the 'else' block is 400 lines */
+	} else {
+		const char *number;
+		time_t end_time, answer_time = time(NULL);
+
 		strcpy(status, "ANSWER");
 		/* Ah ha!  Someone answered within the desired timeframe.  Of course after this

[... 4453 lines stripped ...]


More information about the asterisk-commits mailing list