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