issue #5850
[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 = strdup(in->cid.cid_ani);
516                                                         if (!o->chan->cid.cid_ani)
517                                                                 ast_log(LOG_WARNING, "Out of memory\n");
518                                                 }
519                                                 if (o->chan->cid.cid_rdnis) 
520                                                         free(o->chan->cid.cid_rdnis);
521                                                 if (!ast_strlen_zero(in->macroexten))
522                                                         o->chan->cid.cid_rdnis = strdup(in->macroexten);
523                                                 else
524                                                         o->chan->cid.cid_rdnis = strdup(in->exten);
525                                                 if (ast_call(o->chan, tmpchan, 0)) {
526                                                         ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
527                                                         ast_clear_flag(o, DIAL_STILLGOING);     
528                                                         ast_hangup(o->chan);
529                                                         o->chan = NULL;
530                                                         numnochan++;
531                                                 } else {
532                                                         senddialevent(in, o->chan);
533                                                         /* After calling, set callerid to extension */
534                                                         if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
535                                                                 ast_set_callerid(o->chan, ast_strlen_zero(in->macroexten) ? in->exten : in->macroexten, get_cid_name(cidname, sizeof(cidname), in), NULL);
536                                                 }
537                                         }
538                                         /* Hangup the original channel now, in case we needed it */
539                                         ast_hangup(winner);
540                                         continue;
541                                 }
542                                 f = ast_read(winner);
543                                 if (f) {
544                                         if (f->frametype == AST_FRAME_CONTROL) {
545                                                 switch(f->subclass) {
546                                                 case AST_CONTROL_ANSWER:
547                                                         /* This is our guy if someone answered. */
548                                                         if (!peer) {
549                                                                 if (option_verbose > 2)
550                                                                         ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
551                                                                 peer = o->chan;
552                                                                 ast_copy_flags(peerflags, o,
553                                                                                OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
554                                                                                OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
555                                                                                OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
556                                                                                DIAL_NOFORWARDHTML);
557                                                         }
558                                                         /* If call has been answered, then the eventual hangup is likely to be normal hangup */
559                                                         in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
560                                                         o->chan->hangupcause = AST_CAUSE_NORMAL_CLEARING;
561                                                         break;
562                                                 case AST_CONTROL_BUSY:
563                                                         if (option_verbose > 2)
564                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
565                                                         in->hangupcause = o->chan->hangupcause;
566                                                         ast_hangup(o->chan);
567                                                         o->chan = NULL;
568                                                         ast_clear_flag(o, DIAL_STILLGOING);     
569                                                         HANDLE_CAUSE(AST_CAUSE_BUSY, in);
570                                                         break;
571                                                 case AST_CONTROL_CONGESTION:
572                                                         if (option_verbose > 2)
573                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
574                                                         in->hangupcause = o->chan->hangupcause;
575                                                         ast_hangup(o->chan);
576                                                         o->chan = NULL;
577                                                         ast_clear_flag(o, DIAL_STILLGOING);
578                                                         HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
579                                                         break;
580                                                 case AST_CONTROL_RINGING:
581                                                         if (option_verbose > 2)
582                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
583                                                         if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
584                                                                 ast_indicate(in, AST_CONTROL_RINGING);
585                                                                 (*sentringing)++;
586                                                         }
587                                                         break;
588                                                 case AST_CONTROL_PROGRESS:
589                                                         if (option_verbose > 2)
590                                                                 ast_verbose ( VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", o->chan->name,in->name);
591                                                         if (!ast_test_flag(outgoing, OPT_RINGBACK))
592                                                                 ast_indicate(in, AST_CONTROL_PROGRESS);
593                                                         break;
594                                                 case AST_CONTROL_VIDUPDATE:
595                                                         if (option_verbose > 2)
596                                                                 ast_verbose ( VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", o->chan->name,in->name);
597                                                         ast_indicate(in, AST_CONTROL_VIDUPDATE);
598                                                         break;
599                                                 case AST_CONTROL_PROCEEDING:
600                                                         if (option_verbose > 2)
601                                                                 ast_verbose ( VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", o->chan->name,in->name);
602                                                         if (!ast_test_flag(outgoing, OPT_RINGBACK))
603                                                                 ast_indicate(in, AST_CONTROL_PROCEEDING);
604                                                         break;
605                                                 case AST_CONTROL_HOLD:
606                                                         if (option_verbose > 2)
607                                                                 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", o->chan->name);
608                                                         ast_indicate(in, AST_CONTROL_HOLD);
609                                                         break;
610                                                 case AST_CONTROL_UNHOLD:
611                                                         if (option_verbose > 2)
612                                                                 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", o->chan->name);
613                                                         ast_indicate(in, AST_CONTROL_UNHOLD);
614                                                         break;
615                                                 case AST_CONTROL_OFFHOOK:
616                                                 case AST_CONTROL_FLASH:
617                                                         /* Ignore going off hook and flash */
618                                                         break;
619                                                 case -1:
620                                                         if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
621                                                                 if (option_verbose > 2)
622                                                                         ast_verbose( VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
623                                                                 ast_indicate(in, -1);
624                                                                 (*sentringing) = 0;
625                                                         }
626                                                         break;
627                                                 default:
628                                                         ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
629                                                 }
630                                         } else if (single && (f->frametype == AST_FRAME_VOICE) && 
631                                                                 !(ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK))) {
632                                                 if (ast_write(in, f)) 
633                                                         ast_log(LOG_DEBUG, "Unable to forward frame\n");
634                                         } else if (single && (f->frametype == AST_FRAME_IMAGE) && 
635                                                                 !(ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK))) {
636                                                 if (ast_write(in, f))
637                                                         ast_log(LOG_DEBUG, "Unable to forward image\n");
638                                         } else if (single && (f->frametype == AST_FRAME_TEXT) && 
639                                                                 !(ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK))) {
640                                                 if (ast_write(in, f))
641                                                         ast_log(LOG_DEBUG, "Unable to text\n");
642                                         } else if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
643                                                 ast_channel_sendhtml(in, f->subclass, f->data, f->datalen);
644
645                                         ast_frfree(f);
646                                 } else {
647                                         in->hangupcause = o->chan->hangupcause;
648                                         ast_hangup(o->chan);
649                                         o->chan = NULL;
650                                         ast_clear_flag(o, DIAL_STILLGOING);
651                                 }
652                         }
653                         o = o->next;
654                 }
655                 if (winner == in) {
656                         f = ast_read(in);
657 #if 0
658                         if (f && (f->frametype != AST_FRAME_VOICE))
659                                 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
660                         else if (!f || (f->frametype != AST_FRAME_VOICE))
661                                 printf("Hangup received on %s\n", in->name);
662 #endif
663                         if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
664                                 /* Got hung up */
665                                 *to=-1;
666                                 strcpy(status, "CANCEL");
667                                 if (f)
668                                         ast_frfree(f);
669                                 return NULL;
670                         }
671
672                         if (f && (f->frametype == AST_FRAME_DTMF)) {
673                                 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
674                                         context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
675                                         if (onedigit_goto(in, context, (char) f->subclass, 1)) {
676                                                 if (option_verbose > 3)
677                                                         ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
678                                                 *to=0;
679                                                 *result = f->subclass;
680                                                 strcpy(status, "CANCEL");
681                                                 ast_frfree(f);
682                                                 return NULL;
683                                         }
684                                 }
685
686                                 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) && 
687                                                   (f->subclass == '*')) { /* hmm it it not guarenteed to be '*' anymore. */
688                                         if (option_verbose > 3)
689                                                 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
690                                         *to=0;
691                                         strcpy(status, "CANCEL");
692                                         ast_frfree(f);
693                                         return NULL;
694                                 }
695                         }
696
697                         /* Forward HTML stuff */
698                         if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) 
699                                 ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen);
700                         
701
702                         if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF)))  {
703                                 if (ast_write(outgoing->chan, f))
704                                         ast_log(LOG_WARNING, "Unable to forward voice\n");
705                         }
706                         if (single && (f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_VIDUPDATE)) {
707                                 if (option_verbose > 2)
708                                         ast_verbose ( VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", in->name,outgoing->chan->name);
709                                 ast_indicate(outgoing->chan, AST_CONTROL_VIDUPDATE);
710                         }
711                         ast_frfree(f);
712                 }
713                 if (!*to && (option_verbose > 2))
714                         ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
715         }
716
717         return peer;
718         
719 }
720
721 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags)
722 {
723         int res=-1;
724         struct localuser *u;
725         char *tech, *number, *rest, *cur;
726         char privcid[256];
727         char privintro[1024];
728         struct localuser *outgoing=NULL, *tmp;
729         struct ast_channel *peer;
730         int to;
731         int numbusy = 0;
732         int numcongestion = 0;
733         int numnochan = 0;
734         int cause;
735         char numsubst[AST_MAX_EXTENSION];
736         char restofit[AST_MAX_EXTENSION];
737         char cidname[AST_MAX_EXTENSION];
738         char *newnum;
739         char *l;
740         int privdb_val=0;
741         unsigned int calldurationlimit=0;
742         struct ast_bridge_config config;
743         long timelimit = 0;
744         long play_warning = 0;
745         long warning_freq=0;
746         char *warning_sound=NULL;
747         char *end_sound=NULL;
748         char *start_sound=NULL;
749         char *dtmfcalled=NULL, *dtmfcalling=NULL;
750         char *var;
751         char status[256];
752         int play_to_caller=0,play_to_callee=0;
753         int sentringing=0, moh=0;
754         char *outbound_group = NULL;
755         char *macro_result = NULL, *macro_transfer_dest = NULL;
756         int digit = 0, result = 0;
757         time_t start_time, answer_time, end_time;
758         struct ast_app *app = NULL;
759
760         char *parse;
761         AST_DECLARE_APP_ARGS(args,
762                              AST_APP_ARG(peers);
763                              AST_APP_ARG(timeout);
764                              AST_APP_ARG(options);
765                              AST_APP_ARG(url);
766         );
767         struct ast_flags opts = { 0, };
768         char *opt_args[OPT_ARG_ARRAY_SIZE];
769
770         if (ast_strlen_zero(data)) {
771                 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
772                 return -1;
773         }
774
775         LOCAL_USER_ADD(u);
776
777         if (!(parse = ast_strdupa(data))) {
778                 ast_log(LOG_WARNING, "Memory allocation failure\n");
779                 LOCAL_USER_REMOVE(u);
780                 return -1;
781         }
782         
783         AST_STANDARD_APP_ARGS(args, parse);
784
785         if (!ast_strlen_zero(args.options)) {
786                 if (ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
787                         LOCAL_USER_REMOVE(u);
788                         return -1;
789                 }
790         }
791
792         if (ast_strlen_zero(args.peers)) {
793                 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
794                 LOCAL_USER_REMOVE(u);
795                 return -1;
796         }
797
798         if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
799                 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
800                 if (option_verbose > 2)
801                         ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n",calldurationlimit);                 
802         }
803
804         if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
805                 parse = opt_args[OPT_ARG_SENDDTMF];
806                 dtmfcalled = strsep(&parse, ":");
807                 dtmfcalling = parse;
808         }
809
810         if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
811                 char *limit_str, *warning_str, *warnfreq_str;
812
813                 parse = opt_args[OPT_ARG_DURATION_LIMIT];
814                 limit_str = strsep(&parse, ":");
815                 warning_str = strsep(&parse, ":");
816                 warnfreq_str = parse;
817
818                 timelimit = atol(limit_str);
819                 if (warning_str)
820                         play_warning = atol(warning_str);
821                 if (warnfreq_str)
822                         warning_freq = atol(warnfreq_str);
823
824                 if (!timelimit) {
825                         timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
826                         warning_sound = NULL;
827                 }
828
829                 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
830                 play_to_caller = var ? ast_true(var) : 1;
831                 
832                 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
833                 play_to_callee = var ? ast_true(var) : 0;
834                 
835                 if (!play_to_caller && !play_to_callee)
836                         play_to_caller=1;
837                 
838                 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
839                 warning_sound = var ? var : "timeleft";
840                 
841                 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
842                 end_sound = var ? var : NULL;
843                 
844                 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
845                 start_sound = var ? var : NULL;
846
847                 /* undo effect of S(x) in case they are both used */
848                 calldurationlimit = 0; 
849                 /* more efficient do it like S(x) does since no advanced opts*/
850                 if (!play_warning && !start_sound && !end_sound && timelimit) { 
851                         calldurationlimit = timelimit/1000;
852                         timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
853                 } else if (option_verbose > 2) {
854                         ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
855                         ast_verbose(VERBOSE_PREFIX_3 "- timelimit     = %ld\n", timelimit);
856                         ast_verbose(VERBOSE_PREFIX_3 "- play_warning  = %ld\n", play_warning);
857                         ast_verbose(VERBOSE_PREFIX_3 "- play_to_caller= %s\n", play_to_caller ? "yes" : "no");
858                         ast_verbose(VERBOSE_PREFIX_3 "- play_to_callee= %s\n", play_to_callee ? "yes" : "no");
859                         ast_verbose(VERBOSE_PREFIX_3 "- warning_freq  = %ld\n", warning_freq);
860                         ast_verbose(VERBOSE_PREFIX_3 "- start_sound   = %s\n", start_sound ? start_sound : "UNDEF");
861                         ast_verbose(VERBOSE_PREFIX_3 "- warning_sound = %s\n", warning_sound ? warning_sound : "UNDEF");
862                         ast_verbose(VERBOSE_PREFIX_3 "- end_sound     = %s\n", end_sound ? end_sound : "UNDEF");
863                 }
864         }
865
866         if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
867                 ast_cdr_reset(chan->cdr, NULL);
868         if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
869                 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
870         if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
871                 char callerid[60];
872
873                 l = chan->cid.cid_num;
874                 if (!ast_strlen_zero(l)) {
875                         ast_shrink_phone_number(l);
876                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
877                                 if (option_verbose > 2)
878                                         ast_verbose( VERBOSE_PREFIX_3  "Privacy DB is '%s', clid is '%s'\n",
879                                                      opt_args[OPT_ARG_PRIVACY], l);
880                                 privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
881                         }
882                         else {
883                                 if (option_verbose > 2)
884                                         ast_verbose( VERBOSE_PREFIX_3  "Privacy Screening, clid is '%s'\n", l);
885                                 privdb_val = AST_PRIVACY_UNKNOWN;
886                         }
887                 } else {
888                         char *tnam, *tn2;
889
890                         tnam = ast_strdupa(chan->name);
891                         /* clean the channel name so slashes don't try to end up in disk file name */
892                         for(tn2 = tnam; *tn2; tn2++) {
893                                 if( *tn2=='/')
894                                         *tn2 = '=';  /* any other chars to be afraid of? */
895                         }
896                         if (option_verbose > 2)
897                                 ast_verbose( VERBOSE_PREFIX_3  "Privacy-- callerid is empty\n");
898
899                         snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
900                         l = callerid;
901                         privdb_val = AST_PRIVACY_UNKNOWN;
902                 }
903                 
904                 ast_copy_string(privcid,l,sizeof(privcid));
905
906                 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 */  
907                         if (option_verbose > 2)
908                                 ast_verbose( VERBOSE_PREFIX_3  "CallerID set (%s); N option set; Screening should be off\n", privcid);
909                         privdb_val = AST_PRIVACY_ALLOW;
910                 }
911                 else if( ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
912                         if (option_verbose > 2)
913                                 ast_verbose( VERBOSE_PREFIX_3  "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
914                 }
915                 
916                 if( privdb_val == AST_PRIVACY_DENY ) {
917                         ast_verbose( VERBOSE_PREFIX_3  "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
918                         res=0;
919                         goto out;
920                 }
921                 else if( privdb_val == AST_PRIVACY_KILL ) {
922                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
923                         res = 0;
924                         goto out; /* Is this right? */
925                 }
926                 else if( privdb_val == AST_PRIVACY_TORTURE ) {
927                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
928                         res = 0;
929                         goto out; /* is this right??? */
930
931                 }
932                 else if( privdb_val == AST_PRIVACY_UNKNOWN ) {
933                         /* Get the user's intro, store it in priv-callerintros/$CID, 
934                            unless it is already there-- this should be done before the 
935                            call is actually dialed  */
936
937                         /* make sure the priv-callerintros dir exists? */
938
939                         snprintf(privintro,sizeof(privintro),"priv-callerintros/%s", privcid);
940                         if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
941                                 /* the DELUX version of this code would allow this caller the
942                                    option to hear and retape their previously recorded intro.
943                                 */
944                         }
945                         else {
946                                 int duration; /* for feedback from play_and_wait */
947                                 /* the file doesn't exist yet. Let the caller submit his
948                                    vocal intro for posterity */
949                                 /* priv-recordintro script:
950
951                                    "At the tone, please say your name:"
952
953                                 */
954                                 ast_play_and_record(chan, "priv-recordintro", privintro, 4, "gsm", &duration, 128, 2000, 0);  /* NOTE: I've reduced the total time to 4 sec */
955                                                                                                                         /* don't think we'll need a lock removed, we took care of
956                                                                                                                            conflicts by naming the privintro file */
957                         }
958                 }
959         }
960
961         /* If a channel group has been specified, get it for use when we create peer channels */
962         outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
963
964         ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID);
965         cur = args.peers;
966         do {
967                 /* Remember where to start next time */
968                 rest = strchr(cur, '&');
969                 if (rest) {
970                         *rest = 0;
971                         rest++;
972                 }
973                 /* Get a technology/[device:]number pair */
974                 tech = cur;
975                 number = strchr(tech, '/');
976                 if (!number) {
977                         ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
978                         goto out;
979                 }
980                 *number = '\0';
981                 number++;
982                 tmp = malloc(sizeof(struct localuser));
983                 if (!tmp) {
984                         ast_log(LOG_WARNING, "Out of memory\n");
985                         goto out;
986                 }
987                 memset(tmp, 0, sizeof(struct localuser));
988                 if (opts.flags) {
989                         ast_copy_flags(tmp, &opts,
990                                        OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
991                                        OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
992                                        OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
993                                        OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
994                         ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);       
995                 }
996                 ast_copy_string(numsubst, number, sizeof(numsubst));
997                 /* If we're dialing by extension, look at the extension to know what to dial */
998                 if ((newnum = strstr(numsubst, "BYEXTENSION"))) {
999                         /* strlen("BYEXTENSION") == 11 */
1000                         ast_copy_string(restofit, newnum + 11, sizeof(restofit));
1001                         snprintf(newnum, sizeof(numsubst) - (newnum - numsubst), "%s%s", chan->exten,restofit);
1002                         if (option_debug)
1003                                 ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
1004                 }
1005                 /* Request the peer */
1006                 tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
1007                 if (!tmp->chan) {
1008                         /* If we can't, just go on to the next call */
1009                         ast_log(LOG_NOTICE, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
1010                         HANDLE_CAUSE(cause, chan);
1011                         cur = rest;
1012                         if (!cur)
1013                                 chan->hangupcause = cause;
1014                         continue;
1015                 }
1016                 pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
1017                 if (!ast_strlen_zero(tmp->chan->call_forward)) {
1018                         char tmpchan[256];
1019                         char *stuff;
1020                         char *tech;
1021                         ast_copy_string(tmpchan, tmp->chan->call_forward, sizeof(tmpchan));
1022                         if ((stuff = strchr(tmpchan, '/'))) {
1023                                 *stuff = '\0';
1024                                 stuff++;
1025                                 tech = tmpchan;
1026                         } else {
1027                                 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tmp->chan->call_forward, tmp->chan->context);
1028                                 stuff = tmpchan;
1029                                 tech = "Local";
1030                         }
1031                         tmp->forwards++;
1032                         if (tmp->forwards < AST_MAX_FORWARDS) {
1033                                 if (option_verbose > 2)
1034                                         ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
1035                                 ast_hangup(tmp->chan);
1036                                 /* Setup parameters */
1037                                 tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause);
1038                                 if (!tmp->chan)
1039                                         ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
1040                         } else {
1041                                 if (option_verbose > 2)
1042                                         ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tmp->chan->name);
1043                                 ast_hangup(tmp->chan);
1044                                 tmp->chan = NULL;
1045                                 cause = AST_CAUSE_CONGESTION;
1046                         }
1047                         if (!tmp->chan) {
1048                                 HANDLE_CAUSE(cause, chan);
1049                                 cur = rest;
1050                                 continue;
1051                         }
1052                 }
1053
1054                 /* Inherit specially named variables from parent channel */
1055                 ast_channel_inherit_variables(chan, tmp->chan);
1056
1057                 tmp->chan->appl = "AppDial";
1058                 tmp->chan->data = "(Outgoing Line)";
1059                 tmp->chan->whentohangup = 0;
1060                 if (tmp->chan->cid.cid_num)
1061                         free(tmp->chan->cid.cid_num);
1062                 tmp->chan->cid.cid_num = NULL;
1063                 if (tmp->chan->cid.cid_name)
1064                         free(tmp->chan->cid.cid_name);
1065                 tmp->chan->cid.cid_name = NULL;
1066                 if (tmp->chan->cid.cid_ani)
1067                         free(tmp->chan->cid.cid_ani);
1068                 tmp->chan->cid.cid_ani = NULL;
1069
1070                 if (chan->cid.cid_num) 
1071                         tmp->chan->cid.cid_num = strdup(chan->cid.cid_num);
1072                 if (chan->cid.cid_name) 
1073                         tmp->chan->cid.cid_name = strdup(chan->cid.cid_name);
1074                 if (chan->cid.cid_ani) 
1075                         tmp->chan->cid.cid_ani = strdup(chan->cid.cid_ani);
1076                 
1077                 /* Copy language from incoming to outgoing */
1078                 ast_copy_string(tmp->chan->language, chan->language, sizeof(tmp->chan->language));
1079                 ast_copy_string(tmp->chan->accountcode, chan->accountcode, sizeof(tmp->chan->accountcode));
1080                 tmp->chan->cdrflags = chan->cdrflags;
1081                 if (ast_strlen_zero(tmp->chan->musicclass))
1082                         ast_copy_string(tmp->chan->musicclass, chan->musicclass, sizeof(tmp->chan->musicclass));
1083                 if (chan->cid.cid_rdnis)
1084                         tmp->chan->cid.cid_rdnis = strdup(chan->cid.cid_rdnis);
1085                 /* Pass callingpres setting */
1086                 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
1087                 /* Pass type of number */
1088                 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
1089                 /* Pass type of tns */
1090                 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
1091                 /* Presense of ADSI CPE on outgoing channel follows ours */
1092                 tmp->chan->adsicpe = chan->adsicpe;
1093                 /* Pass the transfer capability */
1094                 tmp->chan->transfercapability = chan->transfercapability;
1095
1096                 /* If we have an outbound group, set this peer channel to it */
1097                 if (outbound_group)
1098                         ast_app_group_set_channel(tmp->chan, outbound_group);
1099
1100                 /* Place the call, but don't wait on the answer */
1101                 res = ast_call(tmp->chan, numsubst, 0);
1102
1103                 /* Save the info in cdr's that we called them */
1104                 if (chan->cdr)
1105                         ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
1106
1107                 /* check the results of ast_call */
1108                 if (res) {
1109                         /* Again, keep going even if there's an error */
1110                         if (option_debug)
1111                                 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
1112                         else if (option_verbose > 2)
1113                                 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
1114                         ast_hangup(tmp->chan);
1115                         tmp->chan = NULL;
1116                         cur = rest;
1117                         continue;
1118                 } else {
1119                         senddialevent(chan, tmp->chan);
1120                         if (option_verbose > 2)
1121                                 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
1122                         if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
1123                                 ast_set_callerid(tmp->chan, ast_strlen_zero(chan->macroexten) ? chan->exten : chan->macroexten, get_cid_name(cidname, sizeof(cidname), chan), NULL);
1124                 }
1125                 /* Put them in the list of outgoing thingies...  We're ready now. 
1126                    XXX If we're forcibly removed, these outgoing calls won't get
1127                    hung up XXX */
1128                 ast_set_flag(tmp, DIAL_STILLGOING);     
1129                 tmp->next = outgoing;
1130                 outgoing = tmp;
1131                 /* If this line is up, don't try anybody else */
1132                 if (outgoing->chan->_state == AST_STATE_UP)
1133                         break;
1134                 cur = rest;
1135         } while (cur);
1136         
1137         if (!ast_strlen_zero(args.timeout)) {
1138                 to = atoi(args.timeout);
1139                 if (to > 0)
1140                         to *= 1000;
1141                 else
1142                         ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1143         } else
1144                 to = -1;
1145
1146         if (outgoing) {
1147                 /* Our status will at least be NOANSWER */
1148                 strcpy(status, "NOANSWER");
1149                 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
1150                         moh=1;
1151                         ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK]);
1152                 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
1153                         ast_indicate(chan, AST_CONTROL_RINGING);
1154                         sentringing++;
1155                 }
1156         } else
1157                 strcpy(status, "CHANUNAVAIL");
1158
1159         time(&start_time);
1160         peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
1161         
1162         if (!peer) {
1163                 if (result) {
1164                         res = result;
1165                 } else if (to) 
1166                         /* Musta gotten hung up */
1167                         res = -1;
1168                 else 
1169                         /* Nobody answered, next please? */
1170                         res = 0;
1171                 
1172                 goto out;
1173         }
1174         if (peer) {
1175                 time(&answer_time);
1176 #ifdef OSP_SUPPORT
1177                 /* Once call is answered, ditch the OSP Handle */
1178                 pbx_builtin_setvar_helper(chan, "_OSPHANDLE", "");
1179 #endif
1180                 strcpy(status, "ANSWER");
1181                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
1182                    we will always return with -1 so that it is hung up properly after the 
1183                    conversation.  */
1184                 hanguptree(outgoing, peer);
1185                 outgoing = NULL;
1186                 /* If appropriate, log that we have a destination channel */
1187                 if (chan->cdr)
1188                         ast_cdr_setdestchan(chan->cdr, peer->name);
1189                 if (peer->name)
1190                         pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1191
1192                 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1193                 if (!number)
1194                         number = numsubst;
1195                 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1196                 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1197                         ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
1198                         ast_channel_sendurl( peer, args.url );
1199                 }
1200                 if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
1201                         int res2;
1202                         int loopcount = 0;
1203                         if( privdb_val == AST_PRIVACY_UNKNOWN ) {
1204
1205                                 /* Get the user's intro, store it in priv-callerintros/$CID, 
1206                                    unless it is already there-- this should be done before the 
1207                                    call is actually dialed  */
1208
1209                                 /* all ring indications and moh for the caller has been halted as soon as the 
1210                                    target extension was picked up. We are going to have to kill some
1211                                    time and make the caller believe the peer hasn't picked up yet */
1212
1213                                 if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1214                                         ast_indicate(chan, -1);
1215                                         ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK]);
1216                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1217                                         ast_indicate(chan, AST_CONTROL_RINGING);
1218                                         sentringing++;
1219                                 }
1220
1221                                 /* Start autoservice on the other chan ?? */
1222                                 res2 = ast_autoservice_start(chan);
1223                                 /* Now Stream the File */
1224                                 if (!res2) {
1225                                         do {
1226                                                 if (!res2)
1227                                                         res2 = ast_play_and_wait(peer,"priv-callpending");
1228                                                 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! */
1229                                                         res2 = 0;
1230                                                 
1231                                                 /* priv-callpending script: 
1232                                                    "I have a caller waiting, who introduces themselves as:"
1233                                                 */
1234                                                 if (!res2)
1235                                                         res2 = ast_play_and_wait(peer,privintro);
1236                                                 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! */
1237                                                         res2 = 0;
1238                                                 /* now get input from the called party, as to their choice */
1239                                                 if( !res2 ) {
1240                                                         if( ast_test_flag(&opts, OPT_PRIVACY) )
1241                                                                 res2 = ast_play_and_wait(peer,"priv-callee-options");
1242                                                         if( ast_test_flag(&opts, OPT_SCREENING) )
1243                                                                 res2 = ast_play_and_wait(peer,"screen-callee-options");
1244                                                 }
1245                                                 /* priv-callee-options script:
1246                                                         "Dial 1 if you wish this caller to reach you directly in the future,
1247                                                                 and immediately connect to their incoming call
1248                                                          Dial 2 if you wish to send this caller to voicemail now and 
1249                                                                 forevermore.
1250                                                          Dial 3 to send this callerr to the torture menus, now and forevermore.
1251                                                          Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1252                                                          Dial 5 to allow this caller to come straight thru to you in the future,
1253                                                 but right now, just this once, send them to voicemail."
1254                                                 */
1255                                 
1256                                                 /* screen-callee-options script:
1257                                                         "Dial 1 if you wish to immediately connect to the incoming call
1258                                                          Dial 2 if you wish to send this caller to voicemail.
1259                                                          Dial 3 to send this callerr to the torture menus.
1260                                                          Dial 4 to send this caller to a simple "go away" menu.
1261                                                 */
1262                                                 if( !res2 || res2 < '1' || (ast_test_flag(&opts, OPT_PRIVACY) && res2 > '5') || (ast_test_flag(&opts, OPT_SCREENING) && res2 > '4') ) {
1263                                                         /* invalid option */
1264                                                         res2 = ast_play_and_wait(peer,"vm-sorry");
1265                                                 }
1266                                                 loopcount++; /* give the callee a couple chances to make a choice */
1267                                         } while( (!res2 || res2 < '1' || (ast_test_flag(&opts, OPT_PRIVACY) && res2 > '5') || (ast_test_flag(&opts, OPT_SCREENING) && res2 > '4')) && loopcount < 2 );
1268                                 }
1269
1270                                 switch(res2) {
1271                                 case '1':
1272                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1273                                                 if (option_verbose > 2)
1274                                                         ast_verbose( VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1275                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1276                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1277                                         }
1278                                         break;
1279                                 case '2':
1280                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1281                                                 if (option_verbose > 2)
1282                                                         ast_verbose( VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
1283                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1284                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
1285                                         }
1286                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1287                                                 ast_moh_stop(chan);
1288                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1289                                                 ast_indicate(chan, -1);
1290                                                 sentringing=0;
1291                                         }
1292                                         res2 = ast_autoservice_stop(chan);
1293                                         ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1294                                         res=0;
1295                                         goto out;
1296                                 case '3':
1297                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1298                                                 if (option_verbose > 2)
1299                                                         ast_verbose( VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
1300                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1301                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
1302                                         }
1303                                         ast_copy_string(status, "TORTURE", sizeof(status));
1304                                         
1305                                         res = 0;
1306                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1307                                                 ast_moh_stop(chan);
1308                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1309                                                 ast_indicate(chan, -1);
1310                                                 sentringing=0;
1311                                         }
1312                                         res2 = ast_autoservice_stop(chan);
1313                                         ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1314                                         goto out; /* Is this right? */
1315                                 case '4':
1316                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1317                                                 if (option_verbose > 2)
1318                                                         ast_verbose( VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
1319                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1320                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
1321                                         }
1322
1323                                         ast_copy_string(status, "DONTCALL", sizeof(status));
1324                                         res = 0;
1325                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1326                                                 ast_moh_stop(chan);
1327                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1328                                                 ast_indicate(chan, -1);
1329                                                 sentringing=0;
1330                                         }
1331                                         res2 = ast_autoservice_stop(chan);
1332                                         ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1333                                         goto out; /* Is this right? */
1334                                 case '5':
1335                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1336                                                 if (option_verbose > 2)
1337                                                         ast_verbose( VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1338                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1339                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1340                                                 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1341                                                         ast_moh_stop(chan);
1342                                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1343                                                         ast_indicate(chan, -1);
1344                                                         sentringing=0;
1345                                                 }
1346                                                 res2 = ast_autoservice_stop(chan);
1347                                                 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1348                                                 res=0;
1349                                                 goto out;
1350                                         } /* if not privacy, then 5 is the same as "default" case */
1351                                 default:
1352                                         /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do?  */
1353                                         /* well, there seems basically two choices. Just patch the caller thru immediately,
1354                                                   or,... put 'em thru to voicemail. */
1355                                         /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1356                                         if (option_verbose > 2)
1357                                                 ast_log(LOG_NOTICE,"privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1358                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1359                                                 ast_moh_stop(chan);
1360                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1361                                                 ast_indicate(chan, -1);
1362                                                 sentringing=0;
1363                                         }
1364                                         res2 = ast_autoservice_stop(chan);
1365                                         ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1366                                         res=0;
1367                                         goto out;
1368                                 }
1369                                 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1370                                         ast_moh_stop(chan);
1371                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1372                                         ast_indicate(chan, -1);
1373                                         sentringing=0;
1374                                 }
1375                                 res2 = ast_autoservice_stop(chan);
1376                                 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll 
1377                                    just clog things up, and it's not useful information, not being tied to a CID */
1378                                 if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
1379                                         ast_filedelete(privintro, NULL);
1380                                         if( ast_fileexists(privintro,NULL,NULL ) > 0 )
1381                                                 ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", privintro);
1382                                         else if (option_verbose > 2)
1383                                                 ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1384                                 }
1385                         }
1386                 }
1387                 if (ast_test_flag(&opts, OPT_ANNOUNCE) && !ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1388                         /* Start autoservice on the other chan */
1389                         res = ast_autoservice_start(chan);
1390                         /* Now Stream the File */
1391                         if (!res)
1392                                 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1393                         if (!res) {
1394                                 digit = ast_waitstream(peer, AST_DIGIT_ANY); 
1395                         }
1396                         /* Ok, done. stop autoservice */
1397                         res = ast_autoservice_stop(chan);
1398                         if (digit > 0 && !res)
1399                                 res = ast_senddigit(chan, digit); 
1400                         else
1401                                 res = digit;
1402
1403                 } else
1404                         res = 0;
1405
1406                 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1407                         char *ch;
1408
1409                         for (ch = opt_args[OPT_ARG_GOTO]; *ch; ch++) {
1410                                 if (*ch == '^')
1411                                         *ch = '|';
1412                         }
1413                         ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1414                         ast_parseable_goto(peer, opt_args[OPT_ARG_GOTO]);
1415                         peer->priority++;
1416                         ast_pbx_start(peer);
1417                         hanguptree(outgoing, NULL);
1418                         LOCAL_USER_REMOVE(u);
1419                         return 0;
1420                 }
1421
1422                 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1423                         char *ch;
1424
1425                         res = ast_autoservice_start(chan);
1426                         if (res) {
1427                                 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1428                                 res = -1;
1429                         }
1430
1431                         app = pbx_findapp("Macro");
1432
1433                         if (app && !res) {
1434                                 for (ch = opt_args[OPT_ARG_CALLEE_MACRO]; *ch; ch++) {
1435                                         if (*ch == '^')
1436                                                 *ch = '|';
1437                                 }
1438                                 res = pbx_exec(peer, app, opt_args[OPT_ARG_CALLEE_MACRO], 1);
1439                                 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
1440                                 res = 0;
1441                         } else {
1442                                 ast_log(LOG_ERROR, "Could not find application Macro\n");
1443                                 res = -1;
1444                         }
1445
1446                         if (ast_autoservice_stop(chan) < 0) {
1447                                 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1448                                 res = -1;
1449                         }
1450
1451                         if (!res) {
1452                                 if ((macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1453                                         if (!strcasecmp(macro_result, "BUSY")) {
1454                                                 ast_copy_string(status, macro_result, sizeof(status));
1455                                                 if (option_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1456                                                         if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
1457                                                                 ast_set_flag(peerflags, OPT_GO_ON);
1458                                                         }
1459                                                 } else
1460                                                         ast_set_flag(peerflags, OPT_GO_ON);
1461                                                 res = -1;
1462                                         }
1463                                         else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1464                                                 ast_copy_string(status, macro_result, sizeof(status));
1465                                                 ast_set_flag(peerflags, OPT_GO_ON);     
1466                                                 res = -1;
1467                                         }
1468                                         else if (!strcasecmp(macro_result, "CONTINUE")) {
1469                                                 /* hangup peer and keep chan alive assuming the macro has changed 
1470                                                    the context / exten / priority or perhaps 
1471                                                    the next priority in the current exten is desired.
1472                                                 */
1473                                                 ast_set_flag(peerflags, OPT_GO_ON);     
1474                                                 res = -1;
1475                                         } else if (!strcasecmp(macro_result, "ABORT")) {
1476                                                 /* Hangup both ends unless the caller has the g flag */
1477                                                 res = -1;
1478                                         } else if (!strncasecmp(macro_result, "GOTO:",5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1479                                                 res = -1;
1480                                                 /* perform a transfer to a new extension */
1481                                                 if (strchr(macro_transfer_dest,'^')) { /* context^exten^priority*/
1482                                                         /* no brainer mode... substitute ^ with | and feed it to builtin goto */
1483                                                         for (res=0;res<strlen(macro_transfer_dest);res++)
1484                                                                 if (macro_transfer_dest[res] == '^')
1485                                                                         macro_transfer_dest[res] = '|';
1486
1487                                                         if (!ast_parseable_goto(chan, macro_transfer_dest))
1488                                                                 ast_set_flag(peerflags, OPT_GO_ON);
1489
1490                                                 }
1491                                         }
1492                                 }
1493                         }
1494                 }
1495
1496                 if (!res) {
1497                         if (calldurationlimit > 0) {
1498                                 time_t now;
1499
1500                                 time(&now);
1501                                 chan->whentohangup = now + calldurationlimit;
1502                         }
1503                         if (!ast_strlen_zero(dtmfcalled)) { 
1504                                 if (option_verbose > 2)
1505                                         ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n",dtmfcalled);
1506                                 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1507                         }
1508                         if (!ast_strlen_zero(dtmfcalling)) {
1509                                 if (option_verbose > 2)
1510                                         ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n",dtmfcalling);
1511                                 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1512                         }
1513                 }
1514                 
1515                 if (!res) {
1516                         char toast[80];
1517
1518                         memset(&config,0,sizeof(struct ast_bridge_config));
1519                         if (play_to_caller)
1520                                 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
1521                         if (play_to_callee)
1522                                 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
1523                         if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
1524                                 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1525                         if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
1526                                 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1527                         if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
1528                                 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1529                         if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
1530                                 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1531                         if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
1532                                 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1533                         if (ast_test_flag(peerflags, OPT_CALLER_MONITOR)) 
1534                                 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1535
1536                         config.timelimit = timelimit;
1537                         config.play_warning = play_warning;
1538                         config.warning_freq = warning_freq;
1539                         config.warning_sound = warning_sound;
1540                         config.end_sound = end_sound;
1541                         config.start_sound = start_sound;
1542                         if (moh) {
1543                                 moh = 0;
1544                                 ast_moh_stop(chan);
1545                         } else if (sentringing) {
1546                                 sentringing = 0;
1547                                 ast_indicate(chan, -1);
1548                         }
1549                         /* Be sure no generators are left on it */
1550                         ast_deactivate_generator(chan);
1551                         /* Make sure channels are compatible */
1552                         res = ast_channel_make_compatible(chan, peer);
1553                         if (res < 0) {
1554                                 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1555                                 ast_hangup(peer);
1556                                 LOCAL_USER_REMOVE(u);
1557                                 return -1;
1558                         }
1559                         res = ast_bridge_call(chan,peer,&config);
1560                         time(&end_time);
1561                         snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1562                         pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1563                         snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1564                         pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1565                         
1566                 } else 
1567                         res = -1;
1568                 
1569                 if (res != AST_PBX_NO_HANGUP_PEER) {
1570                         if (!chan->_softhangup)
1571                                 chan->hangupcause = peer->hangupcause;
1572                         ast_hangup(peer);
1573                 }
1574         }       
1575 out:
1576         if (moh) {
1577                 moh = 0;
1578                 ast_moh_stop(chan);
1579         } else if (sentringing) {
1580                 sentringing = 0;
1581                 ast_indicate(chan, -1);
1582         }
1583         hanguptree(outgoing, NULL);
1584         pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
1585         ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
1586         
1587         if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE))
1588                 res=0;
1589         
1590         LOCAL_USER_REMOVE(u);    
1591         
1592         return res;
1593 }
1594
1595 static int dial_exec(struct ast_channel *chan, void *data)
1596 {
1597         struct ast_flags peerflags;
1598         memset(&peerflags, 0, sizeof(peerflags));
1599         return dial_exec_full(chan, data, &peerflags);
1600 }
1601
1602 static int retrydial_exec(struct ast_channel *chan, void *data)
1603 {
1604         char *announce = NULL, *context = NULL, *dialdata = NULL;
1605         int sleep = 0, loops = 0, res = 0;
1606         struct localuser *u;
1607         struct ast_flags peerflags;
1608         
1609         if (ast_strlen_zero(data)) {
1610                 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1611                 return -1;
1612         }       
1613
1614         LOCAL_USER_ADD(u);
1615
1616         announce = ast_strdupa(data);   
1617         if (!announce) {        
1618                 ast_log(LOG_ERROR, "Out of memory!\n");
1619                 LOCAL_USER_REMOVE(u);
1620                 return -1;
1621         }
1622         
1623         memset(&peerflags, 0, sizeof(peerflags));
1624
1625         if ((dialdata = strchr(announce, '|'))) {
1626                 *dialdata = '\0';
1627                 dialdata++;
1628                 if ((sleep = atoi(dialdata))) {
1629                         sleep *= 1000;
1630                 } else {
1631                         ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1632                         LOCAL_USER_REMOVE(u);
1633                         return -1;
1634                 }
1635                 if ((dialdata = strchr(dialdata, '|'))) {
1636                         *dialdata = '\0';
1637                         dialdata++;
1638                         if (!(loops = atoi(dialdata))) {
1639                                 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1640                                 LOCAL_USER_REMOVE(u);
1641                                 return -1;
1642                         }
1643                 }
1644         }
1645         
1646         if ((dialdata = strchr(dialdata, '|'))) {
1647                 *dialdata = '\0';
1648                 dialdata++;
1649         } else {
1650                 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1651                 LOCAL_USER_REMOVE(u);
1652                 return -1;
1653         }
1654                 
1655         if (sleep < 1000)
1656                 sleep = 10000;
1657         
1658         if (!loops)
1659                 loops = -1;
1660         
1661         context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1662         
1663         while (loops) {
1664                 chan->data = "Retrying";
1665                 if (ast_test_flag(chan, AST_FLAG_MOH))
1666                         ast_moh_stop(chan);
1667
1668                 if ((res = dial_exec_full(chan, dialdata, &peerflags)) == 0) {
1669                         if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
1670                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1671                                         res = ast_waitstream(chan, AST_DIGIT_ANY);
1672                                 if (!res && sleep) {
1673                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1674                                                 ast_moh_start(chan, NULL);
1675                                         res = ast_waitfordigit(chan, sleep);
1676                                 }
1677                         } else {
1678                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1679                                         res = ast_waitstream(chan, "");
1680                                 if (sleep) {
1681                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1682                                                 ast_moh_start(chan, NULL);
1683                                         if (!res) 
1684                                                 res = ast_waitfordigit(chan, sleep);
1685                                 }
1686                         }
1687                 }
1688
1689                 if (res < 0)
1690                         break;
1691                 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1692                         if (onedigit_goto(chan, context, (char) res, 1)) {
1693                                 res = 0;
1694                                 break;
1695                         }
1696                 }
1697                 loops--;
1698         }
1699         
1700         if (ast_test_flag(chan, AST_FLAG_MOH))
1701                 ast_moh_stop(chan);
1702
1703         LOCAL_USER_REMOVE(u);
1704         return loops ? res : 0;
1705
1706 }
1707
1708 int unload_module(void)
1709 {
1710         int res;
1711
1712         res = ast_unregister_application(app);
1713         res |= ast_unregister_application(rapp);
1714
1715         STANDARD_HANGUP_LOCALUSERS;
1716         
1717         return res;
1718 }
1719
1720 int load_module(void)
1721 {
1722         int res;
1723
1724         res = ast_register_application(app, dial_exec, synopsis, descrip);
1725         res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1726         
1727         return res;
1728 }
1729
1730 char *description(void)
1731 {
1732         return tdesc;
1733 }
1734
1735 int usecount(void)
1736 {
1737         int res;
1738         STANDARD_USECOUNT(res);
1739         return res;
1740 }
1741
1742 char *key()
1743 {
1744         return ASTERISK_GPL_KEY;
1745 }