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