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