localize some variables
[asterisk/asterisk.git] / apps / app_dial.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief dial() & retrydial() - Trivial application to dial a channel and send an URL on answer
22  *
23  * \author Mark Spencer <markster@digium.com>
24  * 
25  * \ingroup applications
26  */
27
28 #include <stdlib.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <sys/time.h>
35 #include <sys/signal.h>
36 #include <netinet/in.h>
37
38 #include "asterisk.h"
39
40 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
41
42 #include "asterisk/lock.h"
43 #include "asterisk/file.h"
44 #include "asterisk/logger.h"
45 #include "asterisk/channel.h"
46 #include "asterisk/pbx.h"
47 #include "asterisk/options.h"
48 #include "asterisk/module.h"
49 #include "asterisk/translate.h"
50 #include "asterisk/say.h"
51 #include "asterisk/config.h"
52 #include "asterisk/features.h"
53 #include "asterisk/musiconhold.h"
54 #include "asterisk/callerid.h"
55 #include "asterisk/utils.h"
56 #include "asterisk/app.h"
57 #include "asterisk/causes.h"
58 #include "asterisk/rtp.h"
59 #include "asterisk/manager.h"
60 #include "asterisk/privacy.h"
61 #include "asterisk/stringfields.h"
62
63 static char *app = "Dial";
64
65 static char *synopsis = "Place a call and connect to the current channel";
66
67 static char *descrip =
68 "  Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
69 "This applicaiton will place calls to one or more specified channels. As soon\n"
70 "as one of the requested channels answers, the originating channel will be\n"
71 "answered, if it has not already been answered. These two channels will then\n"
72 "be active in a bridged call. All other channels that were requested will then\n"
73 "be hung up.\n"
74 "  Unless there is a timeout specified, the Dial application will wait\n"
75 "indefinitely until one of the called channels answers, the user hangs up, or\n"
76 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
77 "continue if no requested channels can be called, or if the timeout expires.\n\n"
78 "  This application sets the following channel variables upon completion:\n"
79 "    DIALEDTIME   - This is the time from dialing a channel until when it\n"
80 "                   is disconnected.\n" 
81 "    ANSWEREDTIME - This is the amount of time for actual call.\n"
82 "    DIALSTATUS   - This is the status of the call:\n"
83 "                   CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n" 
84 "                   DONTCALL | TORTURE\n"
85 "  For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
86 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
87 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
88 "wants to send the caller to the 'torture' script.\n"
89 "  This application will report normal termination if the originating channel\n"
90 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
91 "ends the call.\n"
92 "  The optional URL will be sent to the called party if the channel supports it.\n"
93 "  If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
94 "application will be put into that group (as in Set(GROUP()=...).\n\n"
95 "  Options:\n"
96 "    A(x) - Play an announcement to the called party, using 'x' as the file.\n"
97 "    C    - Reset the CDR for this call.\n"
98 "    d    - Allow the calling user to dial a 1 digit extension while waiting for\n"
99 "           a call to be answered. Exit to that extension if it exists in the\n"
100 "           current context, or the context defined in the EXITCONTEXT variable,\n"
101 "           if it exists.\n"
102 "    D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
103 "           party has answered, but before the call gets bridged. The 'called'\n"
104 "           DTMF string is sent to the called party, and the 'calling' DTMF\n"
105 "           string is sent to the calling party. Both parameters can be used\n"
106 "           alone.\n"   
107 "    f    - Force the callerid of the *calling* channel to be set as the\n"
108 "           extension associated with the channel using a dialplan 'hint'.\n"
109 "           For example, some PSTNs do not allow CallerID to be set to anything\n"
110 "           other than the number assigned to the caller.\n"
111 "    g    - Proceed with dialplan execution at the current extension if the\n"
112 "           destination channel hangs up.\n"
113 "    G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
114 "           the specified priority and the called party to the specified priority+1.\n"
115 "           Optionally, an extension, or extension and context may be specified. \n"
116 "           Otherwise, the current extension is used.\n"
117 "    h    - Allow the called party to hang up by sending the '*' DTMF digit.\n"
118 "    H    - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
119 "    j    - Jump to priority n+101 if all of the requested channels were busy.\n"
120 "    L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
121 "           left. Repeat the warning every 'z' ms. The following special\n"
122 "           variables can be used with this option:\n"
123 "           * LIMIT_PLAYAUDIO_CALLER   yes|no (default yes)\n"
124 "                                      Play sounds to the caller.\n"
125 "           * LIMIT_PLAYAUDIO_CALLEE   yes|no\n"
126 "                                      Play sounds to the callee.\n"
127 "           * LIMIT_TIMEOUT_FILE       File to play when time is up.\n"
128 "           * LIMIT_CONNECT_FILE       File to play when call begins.\n"
129 "           * LIMIT_WARNING_FILE       File to play as warning if 'y' is defined.\n"
130 "                                      The default is to say the time remaining.\n"
131 "    m([class]) - Provide hold music to the calling party until a requested\n"
132 "           channel answers. A specific MusicOnHold class can be\n"
133 "           specified.\n"
134 "    M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
135 "           to the calling channel. Arguments can be specified to the Macro\n"
136 "           using '^' as a delimeter. The Macro can set the variable\n"
137 "           MACRO_RESULT to specify the following actions after the Macro is\n" 
138 "           finished executing.\n"
139 "           * ABORT        Hangup both legs of the call.\n"
140 "           * CONGESTION   Behave as if line congestion was encountered.\n"
141 "           * BUSY         Behave as if a busy signal was encountered. This will also\n"
142 "                          have the application jump to priority n+101 if the\n"
143 "                          'j' option is set.\n"
144 "           * CONTINUE     Hangup the called party and allow the calling party\n"
145 "                          to continue dialplan execution at the next priority.\n"
146 "           * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
147 "                          specified priority. Optionally, an extension, or\n"
148 "                          extension and priority can be specified.\n"
149 "    n    - This option is a modifier for the screen/privacy mode. It specifies\n"
150 "           that no introductions are to be saved in the priv-callerintros\n"
151 "           directory.\n"
152 "    N    - This option is a modifier for the screen/privacy mode. It specifies\n"
153 "           that if callerID is present, do not screen the call.\n"
154 "    o    - Specify that the CallerID that was present on the *calling* channel\n"
155 "           be set as the CallerID on the *called* channel. This was the\n"
156 "           behavior of Asterisk 1.0 and earlier.\n"
157 "    p    - This option enables screening mode. This is basically Privacy mode\n"
158 "           without memory.\n"
159 "    P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
160 "           it is provided. The current extension is used if a database\n"
161 "           family/key is not specified.\n"
162 "    r    - Indicate ringing to the calling party. Pass no audio to the calling\n"
163 "           party until the called channel has answered.\n"
164 "    S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
165 "           answered the call.\n"       
166 "    t    - Allow the called party to transfer the calling party by sending the\n"
167 "           DTMF sequence defined in features.conf.\n"
168 "    T    - Allow the calling party to transfer the called party by sending the\n"
169 "           DTMF sequence defined in features.conf.\n"
170 "    w    - Allow the called party to enable recording of the call by sending\n"
171 "           the DTMF sequence defined for one-touch recording in features.conf.\n"
172 "    W    - Allow the calling party to enable recording of the call by sending\n"
173 "           the DTMF sequence defined for one-touch recording in features.conf.\n";
174
175 /* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
176 static char *rapp = "RetryDial";
177 static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
178 static char *rdescrip =
179 "  RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
180 "place a call using the normal Dial application. If no channel can be reached,\n"
181 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
182 "seconds before retying the call. After 'retires' number of attempts, the\n"
183 "calling channel will continue at the next priority in the dialplan. If the\n"
184 "'retries' setting is set to 0, this application will retry endlessly.\n"
185 "  While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
186 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
187 "one, The call will jump to that extension immediately.\n"
188 "  The 'dialargs' are specified in the same format that arguments are provided\n"
189 "to the Dial application.\n";
190
191 enum {
192         OPT_ANNOUNCE =          (1 << 0),
193         OPT_RESETCDR =          (1 << 1),
194         OPT_DTMF_EXIT =         (1 << 2),
195         OPT_SENDDTMF =          (1 << 3),
196         OPT_FORCECLID =         (1 << 4),
197         OPT_GO_ON =             (1 << 5),
198         OPT_CALLEE_HANGUP =     (1 << 6),
199         OPT_CALLER_HANGUP =     (1 << 7),
200         OPT_PRIORITY_JUMP =     (1 << 8),
201         OPT_DURATION_LIMIT =    (1 << 9),
202         OPT_MUSICBACK =         (1 << 10),
203         OPT_CALLEE_MACRO =      (1 << 11),
204         OPT_SCREEN_NOINTRO =    (1 << 12),
205         OPT_SCREEN_NOCLID =     (1 << 13),
206         OPT_ORIGINAL_CLID =     (1 << 14),
207         OPT_SCREENING =         (1 << 15),
208         OPT_PRIVACY =           (1 << 16),
209         OPT_RINGBACK =          (1 << 17),
210         OPT_DURATION_STOP =     (1 << 18),
211         OPT_CALLEE_TRANSFER =   (1 << 19),
212         OPT_CALLER_TRANSFER =   (1 << 20),
213         OPT_CALLEE_MONITOR =    (1 << 21),
214         OPT_CALLER_MONITOR =    (1 << 22),
215         OPT_GOTO =              (1 << 23),
216 } dial_exec_option_flags;
217
218 #define DIAL_STILLGOING                 (1 << 30)
219 #define DIAL_NOFORWARDHTML              (1 << 31)
220
221 enum {
222         OPT_ARG_ANNOUNCE = 0,
223         OPT_ARG_SENDDTMF,
224         OPT_ARG_GOTO,
225         OPT_ARG_DURATION_LIMIT,
226         OPT_ARG_MUSICBACK,
227         OPT_ARG_CALLEE_MACRO,
228         OPT_ARG_PRIVACY,
229         OPT_ARG_DURATION_STOP,
230         /* note: this entry _MUST_ be the last one in the enum */
231         OPT_ARG_ARRAY_SIZE,
232 } dial_exec_option_args;
233
234 AST_APP_OPTIONS(dial_exec_options, {
235         AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
236         AST_APP_OPTION('C', OPT_RESETCDR),
237         AST_APP_OPTION('d', OPT_DTMF_EXIT),
238         AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
239         AST_APP_OPTION('f', OPT_FORCECLID),
240         AST_APP_OPTION('g', OPT_GO_ON),
241         AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
242         AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
243         AST_APP_OPTION('H', OPT_CALLER_HANGUP),
244         AST_APP_OPTION('j', OPT_PRIORITY_JUMP),
245         AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
246         AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
247         AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
248         AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
249         AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
250         AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
251         AST_APP_OPTION('p', OPT_SCREENING),
252         AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
253         AST_APP_OPTION('r', OPT_RINGBACK),
254         AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
255         AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
256         AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
257         AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
258         AST_APP_OPTION('W', OPT_CALLER_MONITOR),
259 });
260
261 /* We define a custom "local user" structure because we
262    use it not only for keeping track of what is in use but
263    also for keeping track of who we're dialing. */
264
265 struct dial_localuser {
266         struct ast_channel *chan;
267         unsigned int flags;
268         int forwards;
269         struct dial_localuser *next;
270 };
271
272 LOCAL_USER_DECL;
273
274 static void hanguptree(struct dial_localuser *outgoing, struct ast_channel *exception)
275 {
276         /* Hang up a tree of stuff */
277         struct dial_localuser *oo;
278         while (outgoing) {
279                 /* Hangup any existing lines we have open */
280                 if (outgoing->chan && (outgoing->chan != exception))
281                         ast_hangup(outgoing->chan);
282                 oo = outgoing;
283                 outgoing=outgoing->next;
284                 free(oo);
285         }
286 }
287
288 #define AST_MAX_FORWARDS   8
289
290 #define AST_MAX_WATCHERS 256
291
292 #define HANDLE_CAUSE(cause, chan) do { \
293         switch(cause) { \
294         case AST_CAUSE_BUSY: \
295                 if (chan->cdr) \
296                         ast_cdr_busy(chan->cdr); \
297                 numbusy++; \
298                 break; \
299         case AST_CAUSE_CONGESTION: \
300                 if (chan->cdr) \
301                         ast_cdr_failed(chan->cdr); \
302                 numcongestion++; \
303                 break; \
304         case AST_CAUSE_UNREGISTERED: \
305                 if (chan->cdr) \
306                         ast_cdr_failed(chan->cdr); \
307                 numnochan++; \
308                 break; \
309         case AST_CAUSE_NORMAL_CLEARING: \
310                 break; \
311         default: \
312                 numnochan++; \
313                 break; \
314         } \
315 } while (0)
316
317
318 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri) 
319 {
320         char rexten[2] = { exten, '\0' };
321
322         if (context) {
323                 if (!ast_goto_if_exists(chan, context, rexten, pri))
324                         return 1;
325         } else {
326                 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
327                         return 1;
328                 else if (!ast_strlen_zero(chan->macrocontext)) {
329                         if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
330                                 return 1;
331                 }
332         }
333         return 0;
334 }
335
336
337 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
338 {
339         const char *context = S_OR(chan->macrocontext, chan->context);
340         const char *exten = S_OR(chan->macroexten, chan->exten);
341
342         return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
343 }
344
345 static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
346 {
347         manager_event(EVENT_FLAG_CALL, "Dial", 
348                            "Source: %s\r\n"
349                            "Destination: %s\r\n"
350                            "CallerID: %s\r\n"
351                            "CallerIDName: %s\r\n"
352                            "SrcUniqueID: %s\r\n"
353                            "DestUniqueID: %s\r\n",
354                            src->name, dst->name, src->cid.cid_num ? src->cid.cid_num : "<unknown>",
355                            src->cid.cid_name ? src->cid.cid_name : "<unknown>", src->uniqueid,
356                            dst->uniqueid);
357 }
358
359 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)
360 {
361         int numbusy = busystart;
362         int numcongestion = congestionstart;
363         int numnochan = nochanstart;
364         int prestart = busystart + congestionstart + nochanstart;
365         int orig = *to;
366         struct ast_channel *peer = NULL;
367         /* single is set if only one destination is enabled */
368         int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
369         
370         if (single) {
371                 /* Turn off hold music, etc */
372                 ast_deactivate_generator(in);
373                 /* If we are calling a single channel, make them compatible for in-band tone purpose */
374                 ast_channel_make_compatible(outgoing->chan, in);
375         }
376         
377         
378         while (*to && !peer) {
379                 struct dial_localuser *o;
380                 int pos = 0;    /* how many channels do we handle */
381                 int numlines = prestart;
382                 struct ast_channel *winner;
383                 struct ast_channel *watchers[AST_MAX_WATCHERS];
384
385                 watchers[pos++] = in;
386                 for (o = outgoing; o; o = o->next) {
387                         /* Keep track of important channels */
388                         if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
389                                 watchers[pos++] = o->chan;
390                         numlines++;
391                 }
392                 if (pos == 1) { /* only the input channel is available */
393                         if (numlines == (numbusy + numcongestion + numnochan)) {
394                                 if (option_verbose > 2)
395                                         ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
396                                 if (numbusy)
397                                         strcpy(status, "BUSY"); 
398                                 else if (numcongestion)
399                                         strcpy(status, "CONGESTION");
400                                 else if (numnochan)
401                                         strcpy(status, "CHANUNAVAIL");
402                                 if (ast_opt_priority_jumping || priority_jump)
403                                         ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
404                         } else {
405                                 if (option_verbose > 2)
406                                         ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
407                         }
408                         *to = 0;
409                         return NULL;
410                 }
411                 winner = ast_waitfor_n(watchers, pos, to);
412                 for (o = outgoing; o; o = o->next) {
413                         struct ast_frame *f;
414                         struct ast_channel *c = o->chan;
415
416                         if (c == NULL)
417                                 continue;
418                         if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
419                                 if (!peer) {
420                                         if (option_verbose > 2)
421                                                 ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
422                                         peer = c;
423                                         ast_copy_flags(peerflags, o,
424                                                        OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
425                                                        OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
426                                                        OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
427                                                        DIAL_NOFORWARDHTML);
428                                 }
429                                 continue;
430                         }
431                         if (c != winner)
432                                 continue;
433                         if (!ast_strlen_zero(c->call_forward)) {
434                                 char tmpchan[256];
435                                 char *stuff;
436                                 char *tech;
437                                 int cause;
438
439                                 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
440                                 if ((stuff = strchr(tmpchan, '/'))) {
441                                         *stuff++ = '\0';
442                                         tech = tmpchan;
443                                 } else {
444                                         const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
445                                         snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
446                                         stuff = tmpchan;
447                                         tech = "Local";
448                                 }
449                                 /* Before processing channel, go ahead and check for forwarding */
450                                 o->forwards++;
451                                 if (o->forwards < AST_MAX_FORWARDS) {
452                                         if (option_verbose > 2)
453                                                 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
454                                         /* Setup parameters */
455                                         c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
456                                         if (!c)
457                                                 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
458                                 } else {
459                                         if (option_verbose > 2)
460                                                 ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name);
461                                         cause = AST_CAUSE_CONGESTION;
462                                         c = o->chan = NULL;
463                                 }
464                                 if (!c) {
465                                         ast_clear_flag(o, DIAL_STILLGOING);     
466                                         HANDLE_CAUSE(cause, in);
467                                 } else {
468                                         ast_rtp_make_compatible(c, in);
469                                         if (c->cid.cid_num)
470                                                 free(c->cid.cid_num);
471                                         c->cid.cid_num = NULL;
472                                         if (c->cid.cid_name)
473                                                 free(c->cid.cid_name);
474                                         c->cid.cid_name = NULL;
475
476                                         if (ast_test_flag(o, OPT_FORCECLID)) {
477                                                 c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
478                                                 ast_string_field_set(c, accountcode, winner->accountcode);
479                                                 c->cdrflags = winner->cdrflags;
480                                         } else {
481                                                 c->cid.cid_num = ast_strdup(in->cid.cid_num);
482                                                 c->cid.cid_name = ast_strdup(in->cid.cid_name);
483                                                 ast_string_field_set(c, accountcode, in->accountcode);
484                                                 c->cdrflags = in->cdrflags;
485                                         }
486
487                                         if (in->cid.cid_ani) {
488                                                 if (c->cid.cid_ani)
489                                                         free(c->cid.cid_ani);
490                                                 c->cid.cid_ani = ast_strdup(in->cid.cid_ani);
491                                         }
492                                         if (c->cid.cid_rdnis) 
493                                                 free(c->cid.cid_rdnis);
494                                         c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
495                                         if (ast_call(c, tmpchan, 0)) {
496                                                 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
497                                                 ast_clear_flag(o, DIAL_STILLGOING);     
498                                                 ast_hangup(c);
499                                                 c = o->chan = NULL;
500                                                 numnochan++;
501                                         } else {
502                                                 senddialevent(in, c);
503                                                 /* After calling, set callerid to extension */
504                                                 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
505                                                         char cidname[AST_MAX_EXTENSION];
506                                                         ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
507                                                 }
508                                         }
509                                 }
510                                 /* Hangup the original channel now, in case we needed it */
511                                 ast_hangup(winner);
512                                 continue;
513                         }
514                         f = ast_read(winner);
515                         if (!f) {
516                                 in->hangupcause = c->hangupcause;
517                                 ast_hangup(c);
518                                 c = o->chan = NULL;
519                                 ast_clear_flag(o, DIAL_STILLGOING);
520                                 HANDLE_CAUSE(in->hangupcause, in);
521                                 continue;
522                         }
523                         if (f->frametype == AST_FRAME_CONTROL) {
524                                 switch(f->subclass) {
525                                 case AST_CONTROL_ANSWER:
526                                         /* This is our guy if someone answered. */
527                                         if (!peer) {
528                                                 if (option_verbose > 2)
529                                                         ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
530                                                 peer = c;
531                                                 ast_copy_flags(peerflags, o,
532                                                                OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
533                                                                OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
534                                                                OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
535                                                                DIAL_NOFORWARDHTML);
536                                         }
537                                         /* If call has been answered, then the eventual hangup is likely to be normal hangup */
538                                         in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
539                                         c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
540                                         break;
541                                 case AST_CONTROL_BUSY:
542                                         if (option_verbose > 2)
543                                                 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
544                                         in->hangupcause = c->hangupcause;
545                                         ast_hangup(c);
546                                         c = o->chan = NULL;
547                                         ast_clear_flag(o, DIAL_STILLGOING);     
548                                         HANDLE_CAUSE(AST_CAUSE_BUSY, in);
549                                         break;
550                                 case AST_CONTROL_CONGESTION:
551                                         if (option_verbose > 2)
552                                                 ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
553                                         in->hangupcause = c->hangupcause;
554                                         ast_hangup(c);
555                                         c = o->chan = NULL;
556                                         ast_clear_flag(o, DIAL_STILLGOING);
557                                         HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
558                                         break;
559                                 case AST_CONTROL_RINGING:
560                                         if (option_verbose > 2)
561                                                 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
562                                         if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
563                                                 ast_indicate(in, AST_CONTROL_RINGING);
564                                                 (*sentringing)++;
565                                         }
566                                         break;
567                                 case AST_CONTROL_PROGRESS:
568                                         if (option_verbose > 2)
569                                                 ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
570                                         if (!ast_test_flag(outgoing, OPT_RINGBACK))
571                                                 ast_indicate(in, AST_CONTROL_PROGRESS);
572                                         break;
573                                 case AST_CONTROL_VIDUPDATE:
574                                         if (option_verbose > 2)
575                                                 ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
576                                         ast_indicate(in, AST_CONTROL_VIDUPDATE);
577                                         break;
578                                 case AST_CONTROL_PROCEEDING:
579                                         if (option_verbose > 2)
580                                                 ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
581                                         if (!ast_test_flag(outgoing, OPT_RINGBACK))
582                                                 ast_indicate(in, AST_CONTROL_PROCEEDING);
583                                         break;
584                                 case AST_CONTROL_HOLD:
585                                         if (option_verbose > 2)
586                                                 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
587                                         ast_indicate(in, AST_CONTROL_HOLD);
588                                         break;
589                                 case AST_CONTROL_UNHOLD:
590                                         if (option_verbose > 2)
591                                                 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
592                                         ast_indicate(in, AST_CONTROL_UNHOLD);
593                                         break;
594                                 case AST_CONTROL_OFFHOOK:
595                                 case AST_CONTROL_FLASH:
596                                         /* Ignore going off hook and flash */
597                                         break;
598                                 case -1:
599                                         if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
600                                                 if (option_verbose > 2)
601                                                         ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
602                                                 ast_indicate(in, -1);
603                                                 (*sentringing) = 0;
604                                         }
605                                         break;
606                                 default:
607                                         if (option_debug)
608                                                 ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
609                                 }
610                         } else if (single) {
611                                 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
612                                 if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
613                                         if (ast_write(in, f)) 
614                                                 ast_log(LOG_WARNING, "Unable to forward voice frame\n");
615                                 } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
616                                         if (ast_write(in, f))
617                                                 ast_log(LOG_WARNING, "Unable to forward image\n");
618                                 } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
619                                         if (ast_write(in, f))
620                                                 ast_log(LOG_WARNING, "Unable to send text\n");
621                                 } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
622                                         if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
623                                                 ast_log(LOG_WARNING, "Unable to send URL\n");
624                                 }
625                         }
626                         ast_frfree(f);
627                 } /* end for */
628                 if (winner == in) {
629                         struct ast_frame *f = ast_read(in);
630 #if 0
631                         if (f && (f->frametype != AST_FRAME_VOICE))
632                                 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
633                         else if (!f || (f->frametype != AST_FRAME_VOICE))
634                                 printf("Hangup received on %s\n", in->name);
635 #endif
636                         if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
637                                 /* Got hung up */
638                                 *to = -1;
639                                 strcpy(status, "CANCEL");
640                                 if (f)
641                                         ast_frfree(f);
642                                 return NULL;
643                         }
644
645                         if (f && (f->frametype == AST_FRAME_DTMF)) {
646                                 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
647                                         const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
648                                         if (onedigit_goto(in, context, (char) f->subclass, 1)) {
649                                                 if (option_verbose > 2)
650                                                         ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
651                                                 *to=0;
652                                                 *result = f->subclass;
653                                                 strcpy(status, "CANCEL");
654                                                 ast_frfree(f);
655                                                 return NULL;
656                                         }
657                                 }
658
659                                 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) && 
660                                                   (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
661                                         if (option_verbose > 2)
662                                                 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
663                                         *to=0;
664                                         strcpy(status, "CANCEL");
665                                         ast_frfree(f);
666                                         return NULL;
667                                 }
668                         }
669
670                         /* Forward HTML stuff */
671                         if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) 
672                                 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
673                                         ast_log(LOG_WARNING, "Unable to send URL\n");
674                         
675
676                         if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF)))  {
677                                 if (ast_write(outgoing->chan, f))
678                                         ast_log(LOG_WARNING, "Unable to forward voice\n");
679                         }
680                         if (single && (f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_VIDUPDATE)) {
681                                 if (option_verbose > 2)
682                                         ast_verbose(VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", in->name,outgoing->chan->name);
683                                 ast_indicate(outgoing->chan, AST_CONTROL_VIDUPDATE);
684                         }
685                         ast_frfree(f);
686                 }
687                 if (!*to && (option_verbose > 2))
688                         ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
689         }
690
691         return peer;
692 }
693
694 static void replace_macro_delimiter(char *s)
695 {
696         for (; *s; s++)
697                 if (*s == '^')
698                         *s = '|';
699 }
700
701 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags)
702 {
703         int res = -1;
704         struct localuser *u;
705         char *tech, *number, *rest, *cur;
706         char privcid[256];
707         char privintro[1024];
708         struct dial_localuser *outgoing = NULL, *tmp;
709         struct ast_channel *peer;
710         int to;
711         int numbusy = 0;
712         int numcongestion = 0;
713         int numnochan = 0;
714         int cause;
715         char numsubst[AST_MAX_EXTENSION];
716         char cidname[AST_MAX_EXTENSION];
717         char toast[80];
718         char *l;
719         int privdb_val = 0;
720         unsigned int calldurationlimit = 0;
721         struct ast_bridge_config config;
722         long timelimit = 0;
723         long play_warning = 0;
724         long warning_freq = 0;
725         const char *warning_sound = NULL;
726         const char *end_sound = NULL;
727         const char *start_sound = NULL;
728         char *dtmfcalled = NULL, *dtmfcalling = NULL;
729         const char *var;
730         char status[256];
731         int play_to_caller = 0, play_to_callee = 0;
732         int sentringing = 0, moh = 0;
733         const char *outbound_group = NULL;
734         const char *macro_result = NULL;
735         char *macro_transfer_dest = NULL;
736         int digit = 0, result = 0;
737         time_t start_time, answer_time, end_time;
738         struct ast_app *app = NULL;
739
740         char *parse;
741         AST_DECLARE_APP_ARGS(args,
742                              AST_APP_ARG(peers);
743                              AST_APP_ARG(timeout);
744                              AST_APP_ARG(options);
745                              AST_APP_ARG(url);
746         );
747         struct ast_flags opts = { 0, };
748         char *opt_args[OPT_ARG_ARRAY_SIZE];
749
750         if (ast_strlen_zero(data)) {
751                 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
752                 return -1;
753         }
754
755         LOCAL_USER_ADD(u);
756
757         if (!(parse = ast_strdupa(data)))
758                 goto done;
759
760         AST_STANDARD_APP_ARGS(args, parse);
761
762         if (!ast_strlen_zero(args.options) &&
763                         ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options))
764                 goto done;
765
766         if (ast_strlen_zero(args.peers)) {
767                 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
768                 goto done;
769         }
770
771         if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
772                 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
773                 if (!calldurationlimit) {
774                         ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
775                         goto done;
776                 }
777                 if (option_verbose > 2)
778                         ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
779         }
780
781         if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
782                 parse = opt_args[OPT_ARG_SENDDTMF];
783                 dtmfcalled = strsep(&parse, ":");
784                 dtmfcalling = parse;
785         }
786
787         if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
788                 char *limit_str, *warning_str, *warnfreq_str;
789
790                 parse = opt_args[OPT_ARG_DURATION_LIMIT];
791                 limit_str = strsep(&parse, ":");
792                 warning_str = strsep(&parse, ":");
793                 warnfreq_str = parse;
794
795                 timelimit = atol(limit_str);
796                 if (warning_str)
797                         play_warning = atol(warning_str);
798                 if (warnfreq_str)
799                         warning_freq = atol(warnfreq_str);
800
801                 if (!timelimit) {
802                         ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
803                         goto done;
804                 } else if (play_warning > timelimit) {
805                         /* If the first warning is requested _after_ the entire call would end,
806                            and no warning frequency is requested, then turn off the warning. If
807                            a warning frequency is requested, reduce the 'first warning' time by
808                            that frequency until it falls within the call's total time limit.
809                         */
810
811                         if (!warning_freq) {
812                                 play_warning = 0;
813                         } else {
814                                 /* XXX fix this!! */
815                                 while (play_warning > timelimit)
816                                         play_warning -= warning_freq;
817                                 if (play_warning < 1)
818                                         play_warning = warning_freq = 0;
819                         }
820                 }
821
822                 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
823                 play_to_caller = var ? ast_true(var) : 1;
824                 
825                 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
826                 play_to_callee = var ? ast_true(var) : 0;
827                 
828                 if (!play_to_caller && !play_to_callee)
829                         play_to_caller = 1;
830                 
831                 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
832                 warning_sound = (!ast_strlen_zero(var)) ? var : "timeleft";
833                 
834                 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
835                 end_sound = (!ast_strlen_zero(var)) ? var : NULL;
836                 
837                 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
838                 start_sound = (!ast_strlen_zero(var)) ? var : NULL;
839
840                 /* undo effect of S(x) in case they are both used */
841                 calldurationlimit = 0;
842                 /* more efficient to do it like S(x) does since no advanced opts */
843                 if (!play_warning && !start_sound && !end_sound && timelimit) {
844                         calldurationlimit = timelimit / 1000;
845                         if (option_verbose > 2)
846                                 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
847                         timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
848                 } else if (option_verbose > 2) {
849                         ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
850                         ast_verbose(VERBOSE_PREFIX_4 "timelimit      = %ld\n", timelimit);
851                         ast_verbose(VERBOSE_PREFIX_4 "play_warning   = %ld\n", play_warning);
852                         ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
853                         ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
854                         ast_verbose(VERBOSE_PREFIX_4 "warning_freq   = %ld\n", warning_freq);
855                         ast_verbose(VERBOSE_PREFIX_4 "start_sound    = %s\n", start_sound);
856                         ast_verbose(VERBOSE_PREFIX_4 "warning_sound  = %s\n", warning_sound);
857                         ast_verbose(VERBOSE_PREFIX_4 "end_sound      = %s\n", end_sound);
858                 }
859         }
860
861         if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
862                 ast_cdr_reset(chan->cdr, NULL);
863         if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
864                 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
865         if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
866                 char callerid[60];
867
868                 l = chan->cid.cid_num;
869                 if (!ast_strlen_zero(l)) {
870                         ast_shrink_phone_number(l);
871                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
872                                 if (option_verbose > 2)
873                                         ast_verbose(VERBOSE_PREFIX_3  "Privacy DB is '%s', clid is '%s'\n",
874                                                      opt_args[OPT_ARG_PRIVACY], l);
875                                 privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
876                         }
877                         else {
878                                 if (option_verbose > 2)
879                                         ast_verbose(VERBOSE_PREFIX_3  "Privacy Screening, clid is '%s'\n", l);
880                                 privdb_val = AST_PRIVACY_UNKNOWN;
881                         }
882                 } else {
883                         char *tnam, *tn2;
884
885                         tnam = ast_strdupa(chan->name);
886                         /* clean the channel name so slashes don't try to end up in disk file name */
887                         for(tn2 = tnam; *tn2; tn2++) {
888                                 if( *tn2=='/')
889                                         *tn2 = '=';  /* any other chars to be afraid of? */
890                         }
891                         if (option_verbose > 2)
892                                 ast_verbose(VERBOSE_PREFIX_3  "Privacy-- callerid is empty\n");
893
894                         snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
895                         l = callerid;
896                         privdb_val = AST_PRIVACY_UNKNOWN;
897                 }
898                 
899                 ast_copy_string(privcid,l,sizeof(privcid));
900
901                 if( strncmp(privcid,"NOCALLERID",10) != 0 && ast_test_flag(&opts, OPT_SCREEN_NOCLID) ) { /* if callerid is set, and ast_test_flag(&opts, OPT_SCREEN_NOCLID) is set also */  
902                         if (option_verbose > 2)
903                                 ast_verbose( VERBOSE_PREFIX_3  "CallerID set (%s); N option set; Screening should be off\n", privcid);
904                         privdb_val = AST_PRIVACY_ALLOW;
905                 }
906                 else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
907                         if (option_verbose > 2)
908                                 ast_verbose( VERBOSE_PREFIX_3  "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
909                 }
910                 
911                 if(privdb_val == AST_PRIVACY_DENY ) {
912                         if (option_verbose > 2)
913                                 ast_verbose( VERBOSE_PREFIX_3  "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
914                         res=0;
915                         goto out;
916                 }
917                 else if(privdb_val == AST_PRIVACY_KILL ) {
918                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
919                         res = 0;
920                         goto out; /* Is this right? */
921                 }
922                 else if(privdb_val == AST_PRIVACY_TORTURE ) {
923                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
924                         res = 0;
925                         goto out; /* is this right??? */
926
927                 }
928                 else if(privdb_val == AST_PRIVACY_UNKNOWN ) {
929                         /* Get the user's intro, store it in priv-callerintros/$CID, 
930                            unless it is already there-- this should be done before the 
931                            call is actually dialed  */
932
933                         /* make sure the priv-callerintros dir exists? */
934
935                         snprintf(privintro,sizeof(privintro), "priv-callerintros/%s", privcid);
936                         if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
937                                 /* the DELUX version of this code would allow this caller the
938                                    option to hear and retape their previously recorded intro.
939                                 */
940                         }
941                         else {
942                                 int duration; /* for feedback from play_and_wait */
943                                 /* the file doesn't exist yet. Let the caller submit his
944                                    vocal intro for posterity */
945                                 /* priv-recordintro script:
946
947                                    "At the tone, please say your name:"
948
949                                 */
950                                 ast_play_and_record(chan, "priv-recordintro", privintro, 4, "gsm", &duration, 128, 2000, 0);  /* NOTE: I've reduced the total time to 4 sec */
951                                                                                 /* don't think we'll need a lock removed, we took care of
952                                                                                    conflicts by naming the privintro file */
953                         }
954                 }
955         }
956
957         /* If a channel group has been specified, get it for use when we create peer channels */
958         outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
959
960         ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP);
961         /* loop through the list of dial destinations */
962         rest = args.peers;
963         while ((cur = strsep(&rest, "&")) ) {
964                 /* Get a technology/[device:]number pair */
965                 number = cur;
966                 tech = strsep(&number, "/");
967                 if (!number) {
968                         ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
969                         goto out;
970                 }
971                 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
972                         goto out;
973                 if (opts.flags) {
974                         ast_copy_flags(tmp, &opts,
975                                        OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
976                                        OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
977                                        OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
978                                        OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
979                         ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);       
980                 }
981                 ast_copy_string(numsubst, number, sizeof(numsubst));
982                 /* Request the peer */
983                 tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
984                 if (!tmp->chan) {
985                         /* If we can't, just go on to the next call */
986                         ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
987                         HANDLE_CAUSE(cause, chan);
988                         if (!rest)      /* we are on the last destination */
989                                 chan->hangupcause = cause;
990                         continue;
991                 }
992                 pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
993                 if (!ast_strlen_zero(tmp->chan->call_forward)) {
994                         char tmpchan[256];
995                         char *stuff;
996                         char *tech;
997                         ast_copy_string(tmpchan, tmp->chan->call_forward, sizeof(tmpchan));
998                         if ((stuff = strchr(tmpchan, '/'))) {
999                                 *stuff++ = '\0';
1000                                 tech = tmpchan;
1001                         } else {
1002                                 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tmp->chan->call_forward, tmp->chan->context);
1003                                 stuff = tmpchan;
1004                                 tech = "Local";
1005                         }
1006                         tmp->forwards++;
1007                         if (tmp->forwards < AST_MAX_FORWARDS) {
1008                                 if (option_verbose > 2)
1009                                         ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
1010                                 ast_hangup(tmp->chan);
1011                                 /* Setup parameters */
1012                                 tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause);
1013                                 if (!tmp->chan)
1014                                         ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
1015                         } else {
1016                                 if (option_verbose > 2)
1017                                         ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tmp->chan->name);
1018                                 ast_hangup(tmp->chan);
1019                                 tmp->chan = NULL;
1020                                 cause = AST_CAUSE_CONGESTION;
1021                         }
1022                         if (!tmp->chan) {
1023                                 HANDLE_CAUSE(cause, chan);
1024                                 continue;
1025                         }
1026                 }
1027
1028                 /* Setup outgoing SDP to match incoming one */
1029                 ast_rtp_make_compatible(tmp->chan, chan);
1030                 
1031                 /* Inherit specially named variables from parent channel */
1032                 ast_channel_inherit_variables(chan, tmp->chan);
1033
1034                 tmp->chan->appl = "AppDial";
1035                 tmp->chan->data = "(Outgoing Line)";
1036                 tmp->chan->whentohangup = 0;
1037                 if (tmp->chan->cid.cid_num)
1038                         free(tmp->chan->cid.cid_num);
1039                 tmp->chan->cid.cid_num = NULL;
1040                 if (tmp->chan->cid.cid_name)
1041                         free(tmp->chan->cid.cid_name);
1042                 tmp->chan->cid.cid_name = NULL;
1043                 if (tmp->chan->cid.cid_ani)
1044                         free(tmp->chan->cid.cid_ani);
1045                 tmp->chan->cid.cid_ani = NULL;
1046
1047                 if (chan->cid.cid_num) 
1048                         tmp->chan->cid.cid_num = strdup(chan->cid.cid_num);
1049                 if (chan->cid.cid_name) 
1050                         tmp->chan->cid.cid_name = strdup(chan->cid.cid_name);
1051                 if (chan->cid.cid_ani) 
1052                         tmp->chan->cid.cid_ani = strdup(chan->cid.cid_ani);
1053                 
1054                 /* Copy language from incoming to outgoing */
1055                 ast_string_field_set(tmp->chan, language, chan->language);
1056                 ast_string_field_set(tmp->chan, accountcode, chan->accountcode);
1057                 tmp->chan->cdrflags = chan->cdrflags;
1058                 if (ast_strlen_zero(tmp->chan->musicclass))
1059                         ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
1060                 if (chan->cid.cid_rdnis)
1061                         tmp->chan->cid.cid_rdnis = strdup(chan->cid.cid_rdnis);
1062                 /* Pass callingpres setting */
1063                 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
1064                 /* Pass type of number */
1065                 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
1066                 /* Pass type of tns */
1067                 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
1068                 /* Presense of ADSI CPE on outgoing channel follows ours */
1069                 tmp->chan->adsicpe = chan->adsicpe;
1070                 /* Pass the transfer capability */
1071                 tmp->chan->transfercapability = chan->transfercapability;
1072
1073                 /* If we have an outbound group, set this peer channel to it */
1074                 if (outbound_group)
1075                         ast_app_group_set_channel(tmp->chan, outbound_group);
1076
1077                 /* Place the call, but don't wait on the answer */
1078                 res = ast_call(tmp->chan, numsubst, 0);
1079
1080                 /* Save the info in cdr's that we called them */
1081                 if (chan->cdr)
1082                         ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
1083
1084                 /* check the results of ast_call */
1085                 if (res) {
1086                         /* Again, keep going even if there's an error */
1087                         if (option_debug)
1088                                 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
1089                         else if (option_verbose > 2)
1090                                 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
1091                         ast_hangup(tmp->chan);
1092                         tmp->chan = NULL;
1093                         continue;
1094                 } else {
1095                         senddialevent(chan, tmp->chan);
1096                         if (option_verbose > 2)
1097                                 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
1098                         if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
1099                                 ast_set_callerid(tmp->chan, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
1100                 }
1101                 /* Put them in the list of outgoing thingies...  We're ready now. 
1102                    XXX If we're forcibly removed, these outgoing calls won't get
1103                    hung up XXX */
1104                 ast_set_flag(tmp, DIAL_STILLGOING);     
1105                 tmp->next = outgoing;
1106                 outgoing = tmp;
1107                 /* If this line is up, don't try anybody else */
1108                 if (outgoing->chan->_state == AST_STATE_UP)
1109                         break;
1110         }
1111         
1112         if (ast_strlen_zero(args.timeout)) {
1113                 to = -1;
1114         } else {
1115                 to = atoi(args.timeout);
1116                 if (to > 0)
1117                         to *= 1000;
1118                 else
1119                         ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1120         }
1121
1122         if (!outgoing) {
1123                 strcpy(status, "CHANUNAVAIL");
1124         } else {
1125                 /* Our status will at least be NOANSWER */
1126                 strcpy(status, "NOANSWER");
1127                 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
1128                         moh=1;
1129                         ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK]);
1130                 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
1131                         ast_indicate(chan, AST_CONTROL_RINGING);
1132                         sentringing++;
1133                 }
1134         }
1135
1136         time(&start_time);
1137         peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
1138         
1139         if (!peer) {
1140                 if (result) {
1141                         res = result;
1142                 } else if (to) { /* Musta gotten hung up */
1143                         res = -1;
1144                 } else { /* Nobody answered, next please? */
1145                         res = 0;
1146                 }
1147         } else {
1148                 time(&answer_time);
1149                 strcpy(status, "ANSWER");
1150                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
1151                    we will always return with -1 so that it is hung up properly after the 
1152                    conversation.  */
1153                 hanguptree(outgoing, peer);
1154                 outgoing = NULL;
1155                 /* If appropriate, log that we have a destination channel */
1156                 if (chan->cdr)
1157                         ast_cdr_setdestchan(chan->cdr, peer->name);
1158                 if (peer->name)
1159                         pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1160
1161                 number = (char *)pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1162                 if (!number)
1163                         number = numsubst;
1164                 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1165                 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1166                         if (option_debug)
1167                                 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
1168                         ast_channel_sendurl( peer, args.url );
1169                 }
1170                 if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
1171                         int res2;
1172                         int loopcount = 0;
1173                         if( privdb_val == AST_PRIVACY_UNKNOWN ) {
1174
1175                                 /* Get the user's intro, store it in priv-callerintros/$CID, 
1176                                    unless it is already there-- this should be done before the 
1177                                    call is actually dialed  */
1178
1179                                 /* all ring indications and moh for the caller has been halted as soon as the 
1180                                    target extension was picked up. We are going to have to kill some
1181                                    time and make the caller believe the peer hasn't picked up yet */
1182
1183                                 if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1184                                         ast_indicate(chan, -1);
1185                                         ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK]);
1186                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1187                                         ast_indicate(chan, AST_CONTROL_RINGING);
1188                                         sentringing++;
1189                                 }
1190
1191                                 /* Start autoservice on the other chan ?? */
1192                                 res2 = ast_autoservice_start(chan);
1193                                 /* Now Stream the File */
1194                                 if (!res2) {
1195                                         do {
1196                                                 if (!res2)
1197                                                         res2 = ast_play_and_wait(peer,"priv-callpending");
1198                                                 if( res2 < '1' || (ast_test_flag(&opts, OPT_PRIVACY) && res2>'5') || (ast_test_flag(&opts, OPT_SCREENING) && res2 > '4') ) /* uh, interrupting with a bad answer is ... ignorable! */
1199                                                         res2 = 0;
1200                                                 
1201                                                 /* priv-callpending script: 
1202                                                    "I have a caller waiting, who introduces themselves as:"
1203                                                 */
1204                                                 if (!res2)
1205                                                         res2 = ast_play_and_wait(peer,privintro);
1206                                                 if( res2 < '1' || (ast_test_flag(&opts, OPT_PRIVACY) && res2>'5') || (ast_test_flag(&opts, OPT_SCREENING) && res2 > '4') ) /* uh, interrupting with a bad answer is ... ignorable! */
1207                                                         res2 = 0;
1208                                                 /* now get input from the called party, as to their choice */
1209                                                 if( !res2 ) {
1210                                                         if( ast_test_flag(&opts, OPT_PRIVACY) )
1211                                                                 res2 = ast_play_and_wait(peer,"priv-callee-options");
1212                                                         if( ast_test_flag(&opts, OPT_SCREENING) )
1213                                                                 res2 = ast_play_and_wait(peer,"screen-callee-options");
1214                                                 }
1215                                                 /*! \page DialPrivacy Dial Privacy scripts
1216                                                 \par priv-callee-options script:
1217                                                         "Dial 1 if you wish this caller to reach you directly in the future,
1218                                                                 and immediately connect to their incoming call
1219                                                          Dial 2 if you wish to send this caller to voicemail now and 
1220                                                                 forevermore.
1221                                                          Dial 3 to send this callerr to the torture menus, now and forevermore.
1222                                                          Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1223                                                          Dial 5 to allow this caller to come straight thru to you in the future,
1224                                                                 but right now, just this once, send them to voicemail."
1225                                                 \par screen-callee-options script:
1226                                                         "Dial 1 if you wish to immediately connect to the incoming call
1227                                                          Dial 2 if you wish to send this caller to voicemail.
1228                                                          Dial 3 to send this callerr to the torture menus.
1229                                                          Dial 4 to send this caller to a simple "go away" menu.
1230                                                 */
1231                                                 if(!res2 || res2 < '1' || (ast_test_flag(&opts, OPT_PRIVACY) && res2 > '5') || (ast_test_flag(&opts, OPT_SCREENING) && res2 > '4') ) {
1232                                                         /* invalid option */
1233                                                         res2 = ast_play_and_wait(peer, "vm-sorry");
1234                                                 }
1235                                                 loopcount++; /* give the callee a couple chances to make a choice */
1236                                         } while( (!res2 || res2 < '1' || (ast_test_flag(&opts, OPT_PRIVACY) && res2 > '5') || (ast_test_flag(&opts, OPT_SCREENING) && res2 > '4')) && loopcount < 2 );
1237                                 }
1238
1239                                 switch(res2) {
1240                                 case '1':
1241                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1242                                                 if (option_verbose > 2)
1243                                                         ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1244                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1245                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1246                                         }
1247                                         break;
1248                                 case '2':
1249                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1250                                                 if (option_verbose > 2)
1251                                                         ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
1252                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1253                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
1254                                         }
1255                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1256                                                 ast_moh_stop(chan);
1257                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1258                                                 ast_indicate(chan, -1);
1259                                                 sentringing=0;
1260                                         }
1261                                         res2 = ast_autoservice_stop(chan);
1262                                         ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1263                                         res=0;
1264                                         goto out;
1265                                 case '3':
1266                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1267                                                 if (option_verbose > 2)
1268                                                         ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
1269                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1270                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
1271                                         }
1272                                         ast_copy_string(status, "TORTURE", sizeof(status));
1273                                         
1274                                         res = 0;
1275                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1276                                                 ast_moh_stop(chan);
1277                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1278                                                 ast_indicate(chan, -1);
1279                                                 sentringing=0;
1280                                         }
1281                                         res2 = ast_autoservice_stop(chan);
1282                                         ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1283                                         goto out; /* Is this right? */
1284                                 case '4':
1285                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1286                                                 if (option_verbose > 2)
1287                                                         ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
1288                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1289                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
1290                                         }
1291
1292                                         ast_copy_string(status, "DONTCALL", sizeof(status));
1293                                         res = 0;
1294                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1295                                                 ast_moh_stop(chan);
1296                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1297                                                 ast_indicate(chan, -1);
1298                                                 sentringing=0;
1299                                         }
1300                                         res2 = ast_autoservice_stop(chan);
1301                                         ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1302                                         goto out; /* Is this right? */
1303                                 case '5':
1304                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1305                                                 if (option_verbose > 2)
1306                                                         ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1307                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1308                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1309                                                 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1310                                                         ast_moh_stop(chan);
1311                                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1312                                                         ast_indicate(chan, -1);
1313                                                         sentringing=0;
1314                                                 }
1315                                                 res2 = ast_autoservice_stop(chan);
1316                                                 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1317                                                 res=0;
1318                                                 goto out;
1319                                         } /* if not privacy, then 5 is the same as "default" case */
1320                                 default:
1321                                         /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do?  */
1322                                         /* well, there seems basically two choices. Just patch the caller thru immediately,
1323                                                   or,... put 'em thru to voicemail. */
1324                                         /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1325                                         ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1326                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1327                                                 ast_moh_stop(chan);
1328                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1329                                                 ast_indicate(chan, -1);
1330                                                 sentringing=0;
1331                                         }
1332                                         res2 = ast_autoservice_stop(chan);
1333                                         ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1334                                         res=0;
1335                                         goto out;
1336                                 }
1337                                 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1338                                         ast_moh_stop(chan);
1339                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1340                                         ast_indicate(chan, -1);
1341                                         sentringing=0;
1342                                 }
1343                                 res2 = ast_autoservice_stop(chan);
1344                                 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll 
1345                                    just clog things up, and it's not useful information, not being tied to a CID */
1346                                 if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
1347                                         ast_filedelete(privintro, NULL);
1348                                         if( ast_fileexists(privintro, NULL, NULL ) > 0 )
1349                                                 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
1350                                         else if (option_verbose > 2)
1351                                                 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1352                                 }
1353                         }
1354                 }
1355                 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1356                         res = 0;
1357                 } else {
1358                         /* Start autoservice on the other chan */
1359                         res = ast_autoservice_start(chan);
1360                         /* Now Stream the File */
1361                         if (!res)
1362                                 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1363                         if (!res) {
1364                                 digit = ast_waitstream(peer, AST_DIGIT_ANY); 
1365                         }
1366                         /* Ok, done. stop autoservice */
1367                         res = ast_autoservice_stop(chan);
1368                         if (digit > 0 && !res)
1369                                 res = ast_senddigit(chan, digit); 
1370                         else
1371                                 res = digit;
1372
1373                 }
1374
1375                 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1376                         replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1377                         ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1378                         ast_parseable_goto(peer, opt_args[OPT_ARG_GOTO]);
1379                         peer->priority++;
1380                         ast_pbx_start(peer);
1381                         hanguptree(outgoing, NULL);
1382                         res = 0;
1383                         goto done;
1384                 }
1385
1386                 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1387                         res = ast_autoservice_start(chan);
1388                         if (res) {
1389                                 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1390                                 res = -1;
1391                         }
1392
1393                         app = pbx_findapp("Macro");
1394
1395                         if (app && !res) {
1396                                 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1397                                 res = pbx_exec(peer, app, opt_args[OPT_ARG_CALLEE_MACRO]);
1398                                 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
1399                                 res = 0;
1400                         } else {
1401                                 ast_log(LOG_ERROR, "Could not find application Macro\n");
1402                                 res = -1;
1403                         }
1404
1405                         if (ast_autoservice_stop(chan) < 0) {
1406                                 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1407                                 res = -1;
1408                         }
1409
1410                         if (!res) {
1411                                 if ((macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1412                                         if (!strcasecmp(macro_result, "BUSY")) {
1413                                                 ast_copy_string(status, macro_result, sizeof(status));
1414                                                 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1415                                                         if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
1416                                                                 ast_set_flag(peerflags, OPT_GO_ON);
1417                                                         }
1418                                                 } else
1419                                                         ast_set_flag(peerflags, OPT_GO_ON);
1420                                                 res = -1;
1421                                         }
1422                                         else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1423                                                 ast_copy_string(status, macro_result, sizeof(status));
1424                                                 ast_set_flag(peerflags, OPT_GO_ON);     
1425                                                 res = -1;
1426                                         }
1427                                         else if (!strcasecmp(macro_result, "CONTINUE")) {
1428                                                 /* hangup peer and keep chan alive assuming the macro has changed 
1429                                                    the context / exten / priority or perhaps 
1430                                                    the next priority in the current exten is desired.
1431                                                 */
1432                                                 ast_set_flag(peerflags, OPT_GO_ON);     
1433                                                 res = -1;
1434                                         } else if (!strcasecmp(macro_result, "ABORT")) {
1435                                                 /* Hangup both ends unless the caller has the g flag */
1436                                                 res = -1;
1437                                         } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1438                                                 res = -1;
1439                                                 /* perform a transfer to a new extension */
1440                                                 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1441                                                         replace_macro_delimiter(macro_transfer_dest);
1442                                                         if (!ast_parseable_goto(chan, macro_transfer_dest))
1443                                                                 ast_set_flag(peerflags, OPT_GO_ON);
1444
1445                                                 }
1446                                         }
1447                                 }
1448                         }
1449                 }
1450
1451                 if (!res) {
1452                         if (calldurationlimit > 0) {
1453                                 time_t now;
1454
1455                                 time(&now);
1456                                 chan->whentohangup = now + calldurationlimit;
1457                         }
1458                         if (!ast_strlen_zero(dtmfcalled)) { 
1459                                 if (option_verbose > 2)
1460                                         ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1461                                 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1462                         }
1463                         if (!ast_strlen_zero(dtmfcalling)) {
1464                                 if (option_verbose > 2)
1465                                         ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1466                                 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1467                         }
1468                 }
1469                 
1470                 if (!res) {
1471                         memset(&config,0,sizeof(struct ast_bridge_config));
1472                         if (play_to_caller)
1473                                 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
1474                         if (play_to_callee)
1475                                 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
1476                         if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
1477                                 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1478                         if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
1479                                 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1480                         if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
1481                                 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1482                         if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
1483                                 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1484                         if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
1485                                 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1486                         if (ast_test_flag(peerflags, OPT_CALLER_MONITOR)) 
1487                                 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1488
1489                         config.timelimit = timelimit;
1490                         config.play_warning = play_warning;
1491                         config.warning_freq = warning_freq;
1492                         config.warning_sound = warning_sound;
1493                         config.end_sound = end_sound;
1494                         config.start_sound = start_sound;
1495                         if (moh) {
1496                                 moh = 0;
1497                                 ast_moh_stop(chan);
1498                         } else if (sentringing) {
1499                                 sentringing = 0;
1500                                 ast_indicate(chan, -1);
1501                         }
1502                         /* Be sure no generators are left on it */
1503                         ast_deactivate_generator(chan);
1504                         /* Make sure channels are compatible */
1505                         res = ast_channel_make_compatible(chan, peer);
1506                         if (res < 0) {
1507                                 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1508                                 ast_hangup(peer);
1509                                 LOCAL_USER_REMOVE(u);
1510                                 return -1;
1511                         }
1512                         res = ast_bridge_call(chan,peer,&config);
1513                         time(&end_time);
1514                         snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1515                         pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1516                         
1517                 } else {
1518                         time(&end_time);
1519                         res = -1;
1520                 }
1521                 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1522                 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1523                 
1524                 if (res != AST_PBX_NO_HANGUP_PEER) {
1525                         if (!chan->_softhangup)
1526                                 chan->hangupcause = peer->hangupcause;
1527                         ast_hangup(peer);
1528                 }
1529         }       
1530 out:
1531         if (moh) {
1532                 moh = 0;
1533                 ast_moh_stop(chan);
1534         } else if (sentringing) {
1535                 sentringing = 0;
1536                 ast_indicate(chan, -1);
1537         }
1538         hanguptree(outgoing, NULL);
1539         pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
1540         if (option_debug)
1541                 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
1542         
1543         if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE))
1544                 res = 0;
1545
1546 done:
1547         LOCAL_USER_REMOVE(u);    
1548         return res;
1549 }
1550
1551 static int dial_exec(struct ast_channel *chan, void *data)
1552 {
1553         struct ast_flags peerflags;
1554         memset(&peerflags, 0, sizeof(peerflags));
1555         return dial_exec_full(chan, data, &peerflags);
1556 }
1557
1558 static int retrydial_exec(struct ast_channel *chan, void *data)
1559 {
1560         char *announce = NULL, *dialdata = NULL;
1561         const char *context = NULL;
1562         int sleep = 0, loops = 0, res = -1;
1563         struct localuser *u;
1564         struct ast_flags peerflags;
1565         
1566         if (ast_strlen_zero(data)) {
1567                 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1568                 return -1;
1569         }       
1570
1571         LOCAL_USER_ADD(u);
1572
1573         if (!(announce = ast_strdupa(data)))
1574                 goto done;
1575
1576         memset(&peerflags, 0, sizeof(peerflags));
1577
1578         if ((dialdata = strchr(announce, '|'))) {
1579                 *dialdata++ = '\0';
1580                 if ((sleep = atoi(dialdata))) {
1581                         sleep *= 1000;
1582                 } else {
1583                         ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1584                         goto done;
1585                 }
1586                 if ((dialdata = strchr(dialdata, '|'))) {
1587                         *dialdata++ = '\0';
1588                         if (!(loops = atoi(dialdata))) {
1589                                 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1590                                 goto done;
1591                         }
1592                 }
1593         }
1594         
1595         if ((dialdata = strchr(dialdata, '|'))) {
1596                 *dialdata++ = '\0';
1597         } else {
1598                 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1599                 goto done;
1600         }
1601                 
1602         if (sleep < 1000)
1603                 sleep = 10000;
1604
1605         if (!loops)
1606                 loops = -1;     /* run forever */
1607         
1608         context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1609
1610         res = 0;
1611         while (loops) {
1612                 chan->data = "Retrying";
1613                 if (ast_test_flag(chan, AST_FLAG_MOH))
1614                         ast_moh_stop(chan);
1615
1616                 if ((res = dial_exec_full(chan, dialdata, &peerflags)) == 0) {
1617                         if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
1618                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1619                                         res = ast_waitstream(chan, AST_DIGIT_ANY);
1620                                 if (!res && sleep) {
1621                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1622                                                 ast_moh_start(chan, NULL);
1623                                         res = ast_waitfordigit(chan, sleep);
1624                                 }
1625                         } else {
1626                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1627                                         res = ast_waitstream(chan, "");
1628                                 if (sleep) {
1629                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1630                                                 ast_moh_start(chan, NULL);
1631                                         if (!res) 
1632                                                 res = ast_waitfordigit(chan, sleep);
1633                                 }
1634                         }
1635                 }
1636
1637                 if (res < 0)
1638                         break;
1639                 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1640                         if (onedigit_goto(chan, context, (char) res, 1)) {
1641                                 res = 0;
1642                                 break;
1643                         }
1644                 }
1645                 loops--;
1646         }
1647         if (loops == 0)
1648                 res = 0;
1649         
1650         if (ast_test_flag(chan, AST_FLAG_MOH))
1651                 ast_moh_stop(chan);
1652 done:
1653         LOCAL_USER_REMOVE(u);
1654         return res;
1655 }
1656
1657 static int unload_module(void *mod)
1658 {
1659         int res;
1660
1661         res = ast_unregister_application(app);
1662         res |= ast_unregister_application(rapp);
1663
1664         STANDARD_HANGUP_LOCALUSERS;
1665         
1666         return res;
1667 }
1668
1669 static int load_module(void *mod)
1670 {
1671         int res;
1672
1673         res = ast_register_application(app, dial_exec, synopsis, descrip);
1674         res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1675         
1676         return res;
1677 }
1678
1679 static const char *description(void)
1680 {
1681         return "Dialing Application";
1682 }
1683
1684 static const char *key(void)
1685 {
1686         return ASTERISK_GPL_KEY;
1687 }
1688
1689 STD_MOD(MOD_1, NULL, NULL, NULL);