Additional TDD changes (preparing for SIP changes - adding TDD support to SIP)
[asterisk/asterisk.git] / main / pbx.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 Core PBX routines.
22  *
23  * \author Mark Spencer <markster@digium.com>
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include <sys/types.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <ctype.h>
36 #include <errno.h>
37 #include <time.h>
38 #include <sys/time.h>
39 #include <limits.h>
40 #if defined(HAVE_SYSINFO)
41 #include <sys/sysinfo.h>
42 #endif
43 #if defined(SOLARIS)
44 #include <sys/loadavg.h>
45 #endif
46
47 #include "asterisk/lock.h"
48 #include "asterisk/cli.h"
49 #include "asterisk/pbx.h"
50 #include "asterisk/channel.h"
51 #include "asterisk/options.h"
52 #include "asterisk/logger.h"
53 #include "asterisk/file.h"
54 #include "asterisk/callerid.h"
55 #include "asterisk/cdr.h"
56 #include "asterisk/config.h"
57 #include "asterisk/term.h"
58 #include "asterisk/manager.h"
59 #include "asterisk/ast_expr.h"
60 #include "asterisk/linkedlists.h"
61 #define SAY_STUBS       /* generate declarations and stubs for say methods */
62 #include "asterisk/say.h"
63 #include "asterisk/utils.h"
64 #include "asterisk/causes.h"
65 #include "asterisk/musiconhold.h"
66 #include "asterisk/app.h"
67 #include "asterisk/devicestate.h"
68 #include "asterisk/stringfields.h"
69 #include "asterisk/event.h"
70 #include "asterisk/module.h"
71 #include "asterisk/indications.h"
72
73 /*!
74  * \note I M P O R T A N T :
75  *
76  *              The speed of extension handling will likely be among the most important
77  * aspects of this PBX.  The switching scheme as it exists right now isn't
78  * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
79  * of priorities, but a constant search time here would be great ;-)
80  *
81  */
82
83 #ifdef LOW_MEMORY
84 #define EXT_DATA_SIZE 256
85 #else
86 #define EXT_DATA_SIZE 8192
87 #endif
88
89 #define SWITCH_DATA_LENGTH 256
90
91 #define VAR_BUF_SIZE 4096
92
93 #define VAR_NORMAL              1
94 #define VAR_SOFTTRAN    2
95 #define VAR_HARDTRAN    3
96
97 #define BACKGROUND_SKIP         (1 << 0)
98 #define BACKGROUND_NOANSWER     (1 << 1)
99 #define BACKGROUND_MATCHEXTEN   (1 << 2)
100 #define BACKGROUND_PLAYBACK     (1 << 3)
101
102 AST_APP_OPTIONS(background_opts, {
103         AST_APP_OPTION('s', BACKGROUND_SKIP),
104         AST_APP_OPTION('n', BACKGROUND_NOANSWER),
105         AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN),
106         AST_APP_OPTION('p', BACKGROUND_PLAYBACK),
107 });
108
109 #define WAITEXTEN_MOH           (1 << 0)
110 #define WAITEXTEN_DIALTONE      (1 << 1)
111
112 AST_APP_OPTIONS(waitexten_opts, {
113         AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 0),
114         AST_APP_OPTION_ARG('d', WAITEXTEN_DIALTONE, 0),
115 });
116
117 struct ast_context;
118 struct ast_app;
119
120 /*!
121    \brief ast_exten: An extension
122         The dialplan is saved as a linked list with each context
123         having it's own linked list of extensions - one item per
124         priority.
125 */
126 struct ast_exten {
127         char *exten;                    /*!< Extension name */
128         int matchcid;                   /*!< Match caller id ? */
129         const char *cidmatch;           /*!< Caller id to match for this extension */
130         int priority;                   /*!< Priority */
131         const char *label;              /*!< Label */
132         struct ast_context *parent;     /*!< The context this extension belongs to  */
133         const char *app;                /*!< Application to execute */
134         struct ast_app *cached_app;     /*!< Cached location of application */
135         void *data;                     /*!< Data to use (arguments) */
136         void (*datad)(void *);          /*!< Data destructor */
137         struct ast_exten *peer;         /*!< Next higher priority with our extension */
138         const char *registrar;          /*!< Registrar */
139         struct ast_exten *next;         /*!< Extension with a greater ID */
140         char stuff[0];
141 };
142
143 /*! \brief ast_include: include= support in extensions.conf */
144 struct ast_include {
145         const char *name;
146         const char *rname;                      /*!< Context to include */
147         const char *registrar;                  /*!< Registrar */
148         int hastime;                            /*!< If time construct exists */
149         struct ast_timing timing;               /*!< time construct */
150         struct ast_include *next;               /*!< Link them together */
151         char stuff[0];
152 };
153
154 /*! \brief ast_sw: Switch statement in extensions.conf */
155 struct ast_sw {
156         char *name;
157         const char *registrar;                  /*!< Registrar */
158         char *data;                             /*!< Data load */
159         int eval;
160         AST_LIST_ENTRY(ast_sw) list;
161         char *tmpdata;
162         char stuff[0];
163 };
164
165 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
166 struct ast_ignorepat {
167         const char *registrar;
168         struct ast_ignorepat *next;
169         const char pattern[0];
170 };
171
172 /*! \brief ast_context: An extension context */
173 struct ast_context {
174         ast_rwlock_t lock;                      /*!< A lock to prevent multiple threads from clobbering the context */
175         struct ast_exten *root;                 /*!< The root of the list of extensions */
176         struct ast_context *next;               /*!< Link them together */
177         struct ast_include *includes;           /*!< Include other contexts */
178         struct ast_ignorepat *ignorepats;       /*!< Patterns for which to continue playing dialtone */
179         const char *registrar;                  /*!< Registrar */
180         AST_LIST_HEAD_NOLOCK(, ast_sw) alts;    /*!< Alternative switches */
181         ast_mutex_t macrolock;                  /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
182         char name[0];                           /*!< Name of the context */
183 };
184
185
186 /*! \brief ast_app: A registered application */
187 struct ast_app {
188         int (*execute)(struct ast_channel *chan, void *data);
189         const char *synopsis;                   /*!< Synopsis text for 'show applications' */
190         const char *description;                /*!< Description (help text) for 'show application &lt;name&gt;' */
191         AST_RWLIST_ENTRY(ast_app) list;         /*!< Next app in list */
192         struct ast_module *module;              /*!< Module this app belongs to */
193         char name[0];                           /*!< Name of the application */
194 };
195
196 /*! \brief ast_state_cb: An extension state notify register item */
197 struct ast_state_cb {
198         int id;
199         void *data;
200         ast_state_cb_type callback;
201         struct ast_state_cb *next;
202 };
203
204 /*! \brief Structure for dial plan hints
205
206   \note Hints are pointers from an extension in the dialplan to one or
207   more devices (tech/name) 
208         - See \ref AstExtState
209 */
210 struct ast_hint {
211         struct ast_exten *exten;        /*!< Extension */
212         int laststate;                  /*!< Last known state */
213         struct ast_state_cb *callbacks; /*!< Callback list for this extension */
214         AST_RWLIST_ENTRY(ast_hint) list;/*!< Pointer to next hint in list */
215 };
216
217 static const struct cfextension_states {
218         int extension_state;
219         const char * const text;
220 } extension_states[] = {
221         { AST_EXTENSION_NOT_INUSE,                     "Idle" },
222         { AST_EXTENSION_INUSE,                         "InUse" },
223         { AST_EXTENSION_BUSY,                          "Busy" },
224         { AST_EXTENSION_UNAVAILABLE,                   "Unavailable" },
225         { AST_EXTENSION_RINGING,                       "Ringing" },
226         { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
227         { AST_EXTENSION_ONHOLD,                        "Hold" },
228         { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD,  "InUse&Hold" }
229 };
230
231 struct statechange {
232         AST_LIST_ENTRY(statechange) entry;
233         char dev[0];
234 };
235
236 /*!
237  * \brief Data used by the device state thread
238  */
239 static struct {
240         /*! Set to 1 to stop the thread */
241         unsigned int stop:1;
242         /*! The device state monitoring thread */
243         pthread_t thread;
244         /*! Lock for the state change queue */
245         ast_mutex_t lock;
246         /*! Condition for the state change queue */
247         ast_cond_t cond;
248         /*! Queue of state changes */
249         AST_LIST_HEAD_NOLOCK(, statechange) state_change_q;
250 } device_state = {
251         .thread = AST_PTHREADT_NULL,
252 };
253
254 struct pbx_exception {
255         AST_DECLARE_STRING_FIELDS(
256                 AST_STRING_FIELD(context);      /*!< Context associated with this exception */
257                 AST_STRING_FIELD(exten);        /*!< Exten associated with this exception */
258                 AST_STRING_FIELD(reason);               /*!< The exception reason */
259         );
260
261         int priority;                           /*!< Priority associated with this exception */
262 };
263
264 static int pbx_builtin_answer(struct ast_channel *, void *);
265 static int pbx_builtin_goto(struct ast_channel *, void *);
266 static int pbx_builtin_hangup(struct ast_channel *, void *);
267 static int pbx_builtin_background(struct ast_channel *, void *);
268 static int pbx_builtin_wait(struct ast_channel *, void *);
269 static int pbx_builtin_waitexten(struct ast_channel *, void *);
270 static int pbx_builtin_keepalive(struct ast_channel *, void *);
271 static int pbx_builtin_resetcdr(struct ast_channel *, void *);
272 static int pbx_builtin_setamaflags(struct ast_channel *, void *);
273 static int pbx_builtin_ringing(struct ast_channel *, void *);
274 static int pbx_builtin_progress(struct ast_channel *, void *);
275 static int pbx_builtin_congestion(struct ast_channel *, void *);
276 static int pbx_builtin_busy(struct ast_channel *, void *);
277 static int pbx_builtin_noop(struct ast_channel *, void *);
278 static int pbx_builtin_gotoif(struct ast_channel *, void *);
279 static int pbx_builtin_gotoiftime(struct ast_channel *, void *);
280 static int pbx_builtin_execiftime(struct ast_channel *, void *);
281 static int pbx_builtin_saynumber(struct ast_channel *, void *);
282 static int pbx_builtin_saydigits(struct ast_channel *, void *);
283 static int pbx_builtin_saycharacters(struct ast_channel *, void *);
284 static int pbx_builtin_sayphonetic(struct ast_channel *, void *);
285 int pbx_builtin_setvar(struct ast_channel *, void *);
286 static int pbx_builtin_setvar_multiple(struct ast_channel *, void *);
287 static int pbx_builtin_importvar(struct ast_channel *, void *);
288 static void set_ext_pri(struct ast_channel *c, const char *exten, int pri);
289
290 AST_RWLOCK_DEFINE_STATIC(globalslock);
291 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
292
293 static int autofallthrough = 1;
294
295 /*! \brief Subscription for device state change events */
296 static struct ast_event_sub *device_state_sub;
297
298 AST_MUTEX_DEFINE_STATIC(maxcalllock);
299 static int countcalls;
300
301 static AST_RWLIST_HEAD_STATIC(acf_root, ast_custom_function);
302
303 /*! \brief Declaration of builtin applications */
304 static struct pbx_builtin {
305         char name[AST_MAX_APP];
306         int (*execute)(struct ast_channel *chan, void *data);
307         char *synopsis;
308         char *description;
309 } builtins[] =
310 {
311         /* These applications are built into the PBX core and do not
312            need separate modules */
313
314         { "Answer", pbx_builtin_answer,
315         "Answer a channel if ringing",
316         "  Answer([delay]): If the call has not been answered, this application will\n"
317         "answer it. Otherwise, it has no effect on the call. If a delay is specified,\n"
318         "Asterisk will wait this number of milliseconds before returning to\n"
319         "the dialplan after answering the call.\n"
320         },
321
322         { "BackGround", pbx_builtin_background,
323         "Play an audio file while waiting for digits of an extension to go to.",
324         "  Background(filename1[&filename2...][,options[,langoverride][,context]]):\n"
325         "This application will play the given list of files while waiting for an\n"
326         "extension to be dialed by the calling channel. To continue waiting for digits\n"
327         "after this application has finished playing files, the WaitExten application\n"
328         "should be used. The 'langoverride' option explicitly specifies which language\n"
329         "to attempt to use for the requested sound files. If a 'context' is specified,\n"
330         "this is the dialplan context that this application will use when exiting to a\n"
331         "dialed extension."
332         "  If one of the requested sound files does not exist, call processing will be\n"
333         "terminated.\n"
334         "  Options:\n"
335         "    s - Causes the playback of the message to be skipped\n"
336         "          if the channel is not in the 'up' state (i.e. it\n"
337         "          hasn't been answered yet). If this happens, the\n"
338         "          application will return immediately.\n"
339         "    n - Don't answer the channel before playing the files.\n"
340         "    m - Only break if a digit hit matches a one digit\n"
341         "          extension in the destination context.\n"
342         "This application sets the following channel variable upon completion:\n"
343         " BACKGROUNDSTATUS    The status of the background attempt as a text string, one of\n"
344         "               SUCCESS | FAILED\n"
345         },
346
347         { "Busy", pbx_builtin_busy,
348         "Indicate the Busy condition",
349         "  Busy([timeout]): This application will indicate the busy condition to\n"
350         "the calling channel. If the optional timeout is specified, the calling channel\n"
351         "will be hung up after the specified number of seconds. Otherwise, this\n"
352         "application will wait until the calling channel hangs up.\n"
353         },
354
355         { "Congestion", pbx_builtin_congestion,
356         "Indicate the Congestion condition",
357         "  Congestion([timeout]): This application will indicate the congestion\n"
358         "condition to the calling channel. If the optional timeout is specified, the\n"
359         "calling channel will be hung up after the specified number of seconds.\n"
360         "Otherwise, this application will wait until the calling channel hangs up.\n"
361         },
362
363         { "ExecIfTime", pbx_builtin_execiftime,
364         "Conditional application execution based on the current time",
365         "  ExecIfTime(<times>,<weekdays>,<mdays>,<months>?appname[(appargs)]):\n"
366         "This application will execute the specified dialplan application, with optional\n"
367         "arguments, if the current time matches the given time specification.\n"
368         },
369
370         { "Goto", pbx_builtin_goto,
371         "Jump to a particular priority, extension, or context",
372         "  Goto([[context,]extension,]priority): This application will set the current\n"
373         "context, extension, and priority in the channel structure. After it completes, the\n"
374         "pbx engine will continue dialplan execution at the specified location.\n"
375         "If no specific extension, or extension and context, are specified, then this\n"
376         "application will just set the specified priority of the current extension.\n"
377         "  At least a priority is required as an argument, or the goto will return a -1,\n"
378         "and the channel and call will be terminated.\n"
379         "  If the location that is put into the channel information is bogus, and asterisk cannot\n"
380         "find that location in the dialplan,\n"
381         "then the execution engine will try to find and execute the code in the 'i' (invalid)\n"
382         "extension in the current context. If that does not exist, it will try to execute the\n"
383         "'h' extension. If either or neither the 'h' or 'i' extensions have been defined, the\n"
384         "channel is hung up, and the execution of instructions on the channel is terminated.\n"
385         "What this means is that, for example, you specify a context that does not exist, then\n"
386         "it will not be possible to find the 'h' or 'i' extensions, and the call will terminate!\n"
387         },
388
389         { "GotoIf", pbx_builtin_gotoif,
390         "Conditional goto",
391         "  GotoIf(condition?[labeliftrue]:[labeliffalse]): This application will set the current\n"
392         "context, extension, and priority in the channel structure based on the evaluation of\n"
393         "the given condition. After this application completes, the\n"
394         "pbx engine will continue dialplan execution at the specified location in the dialplan.\n"
395         "The channel will continue at\n"
396         "'labeliftrue' if the condition is true, or 'labeliffalse' if the condition is\n"
397         "false. The labels are specified with the same syntax as used within the Goto\n"
398         "application.  If the label chosen by the condition is omitted, no jump is\n"
399         "performed, and the execution passes to the next instruction.\n"
400         "If the target location is bogus, and does not exist, the execution engine will try \n"
401         "to find and execute the code in the 'i' (invalid)\n"
402         "extension in the current context. If that does not exist, it will try to execute the\n"
403         "'h' extension. If either or neither the 'h' or 'i' extensions have been defined, the\n"
404         "channel is hung up, and the execution of instructions on the channel is terminated.\n"
405         "Remember that this command can set the current context, and if the context specified\n"
406         "does not exist, then it will not be able to find any 'h' or 'i' extensions there, and\n"
407         "the channel and call will both be terminated!\n"
408         },
409
410         { "GotoIfTime", pbx_builtin_gotoiftime,
411         "Conditional Goto based on the current time",
412         "  GotoIfTime(<times>,<weekdays>,<mdays>,<months>?[[context,]exten,]priority):\n"
413         "This application will set the context, extension, and priority in the channel structure\n"
414         "if the current time matches the given time specification. Otherwise, nothing is done.\n"
415         "Further information on the time specification can be found in examples\n"
416         "illustrating how to do time-based context includes in the dialplan.\n" 
417         "If the target jump location is bogus, the same actions would be taken as for Goto.\n"
418         },
419
420         { "ImportVar", pbx_builtin_importvar,
421         "Import a variable from a channel into a new variable",
422         "  ImportVar(newvar=channelname,variable): This application imports a variable\n"
423         "from the specified channel (as opposed to the current one) and stores it as\n"
424         "a variable in the current channel (the channel that is calling this\n"
425         "application). Variables created by this application have the same inheritance\n"
426         "properties as those created with the Set application. See the documentation for\n"
427         "Set for more information.\n"
428         },
429
430         { "Hangup", pbx_builtin_hangup,
431         "Hang up the calling channel",
432         "  Hangup([causecode]): This application will hang up the calling channel.\n"
433         "If a causecode is given the channel's hangup cause will be set to the given\n"
434         "value.\n"
435         },
436
437         { "NoOp", pbx_builtin_noop,
438         "Do Nothing (No Operation)",
439         "  NoOp(): This application does nothing. However, it is useful for debugging\n"
440         "purposes. Any text that is provided as arguments to this application can be\n"
441         "viewed at the Asterisk CLI. This method can be used to see the evaluations of\n"
442         "variables or functions without having any effect. Alternatively, see the\n"
443   "Verbose() application for finer grain control of output at custom verbose levels.\n"
444         },
445
446         { "Progress", pbx_builtin_progress,
447         "Indicate progress",
448         "  Progress(): This application will request that in-band progress information\n"
449         "be provided to the calling channel.\n"
450         },
451
452         { "RaiseException", pbx_builtin_raise_exception,
453         "Handle an exceptional condition",
454         "  RaiseException(<reason>): This application will jump to the \"e\" extension\n"
455         "in the current context, setting the dialplan function EXCEPTION(). If the \"e\"\n"
456         "extension does not exist, the call will hangup.\n"
457         },
458
459         { "ResetCDR", pbx_builtin_resetcdr,
460         "Resets the Call Data Record",
461         "  ResetCDR([options]):  This application causes the Call Data Record to be\n"
462         "reset.\n"
463         "  Options:\n"
464         "    w -- Store the current CDR record before resetting it.\n"
465         "    a -- Store any stacked records.\n"
466         "    v -- Save CDR variables.\n"
467         },
468
469         { "Ringing", pbx_builtin_ringing,
470         "Indicate ringing tone",
471         "  Ringing(): This application will request that the channel indicate a ringing\n"
472         "tone to the user.\n"
473         },
474
475         { "SayAlpha", pbx_builtin_saycharacters,
476         "Say Alpha",
477         "  SayAlpha(string): This application will play the sounds that correspond to\n"
478         "the letters of the given string.\n"
479         },
480
481         { "SayDigits", pbx_builtin_saydigits,
482         "Say Digits",
483         "  SayDigits(digits): This application will play the sounds that correspond\n"
484         "to the digits of the given number. This will use the language that is currently\n"
485         "set for the channel. See the LANGUAGE function for more information on setting\n"
486         "the language for the channel.\n"
487         },
488
489         { "SayNumber", pbx_builtin_saynumber,
490         "Say Number",
491         "  SayNumber(digits[,gender]): This application will play the sounds that\n"
492         "correspond to the given number. Optionally, a gender may be specified.\n"
493         "This will use the language that is currently set for the channel. See the\n"
494         "LANGUAGE function for more information on setting the language for the channel.\n"
495         },
496
497         { "SayPhonetic", pbx_builtin_sayphonetic,
498         "Say Phonetic",
499         "  SayPhonetic(string): This application will play the sounds from the phonetic\n"
500         "alphabet that correspond to the letters in the given string.\n"
501         },
502
503         { "Set", pbx_builtin_setvar,
504         "Set channel variable or function value",
505         "  Set(name=value)\n"
506         "This function can be used to set the value of channel variables or dialplan\n"
507         "functions. When setting variables, if the variable name is prefixed with _,\n"
508         "the variable will be inherited into channels created from the current\n"
509         "channel. If the variable name is prefixed with __, the variable will be\n"
510         "inherited into channels created from the current channel and all children\n"
511         "channels.\n"
512         },
513
514         { "MSet", pbx_builtin_setvar_multiple,
515         "Set channel variable(s) or function value(s)",
516         "  MSet(name1=value1,name2=value2,...)\n"
517         "This function can be used to set the value of channel variables or dialplan\n"
518         "functions. When setting variables, if the variable name is prefixed with _,\n"
519         "the variable will be inherited into channels created from the current\n"
520         "channel. If the variable name is prefixed with __, the variable will be\n"
521         "inherited into channels created from the current channel and all children\n"
522         "channels.\n\n"
523         "MSet behaves in a similar fashion to the way Set worked in 1.2/1.4 and is thus\n"
524         "prone to doing things that you may not expect.  Avoid its use if possible.\n"
525         },
526
527         { "SetAMAFlags", pbx_builtin_setamaflags,
528         "Set the AMA Flags",
529         "  SetAMAFlags([flag]): This application will set the channel's AMA Flags for\n"
530         "  billing purposes.\n"
531         },
532
533         { "Wait", pbx_builtin_wait,
534         "Waits for some time",
535         "  Wait(seconds): This application waits for a specified number of seconds.\n"
536         "Then, dialplan execution will continue at the next priority.\n"
537         "  Note that the seconds can be passed with fractions of a second. For example,\n"
538         "'1.5' will ask the application to wait for 1.5 seconds.\n"
539         },
540
541         { "WaitExten", pbx_builtin_waitexten,
542         "Waits for an extension to be entered",
543         "  WaitExten([seconds][,options]): This application waits for the user to enter\n"
544         "a new extension for a specified number of seconds.\n"
545         "  Note that the seconds can be passed with fractions of a second. For example,\n"
546         "'1.5' will ask the application to wait for 1.5 seconds.\n"
547         "  Options:\n"
548         "    m[(x)] - Provide music on hold to the caller while waiting for an extension.\n"
549         "               Optionally, specify the class for music on hold within parenthesis.\n"
550         },
551
552         { "KeepAlive", pbx_builtin_keepalive,
553         "returns AST_PBX_KEEPALIVE value",
554         "  KeepAlive(): This application is chiefly meant for internal use with Gosubs.\n"
555         "Please do not run it alone from the dialplan!\n"
556         },
557
558 };
559
560 static struct ast_context *contexts;
561 AST_RWLOCK_DEFINE_STATIC(conlock);              /*!< Lock for the ast_context list */
562
563 static AST_RWLIST_HEAD_STATIC(apps, ast_app);
564
565 static AST_RWLIST_HEAD_STATIC(switches, ast_switch);
566
567 static int stateid = 1;
568 /* WARNING:
569    When holding this list's lock, do _not_ do anything that will cause conlock
570    to be taken, unless you _already_ hold it. The ast_merge_contexts_and_delete
571    function will take the locks in conlock/hints order, so any other
572    paths that require both locks must also take them in that order.
573 */
574 static AST_RWLIST_HEAD_STATIC(hints, ast_hint);
575 struct ast_state_cb *statecbs;
576
577 /*
578    \note This function is special. It saves the stack so that no matter
579    how many times it is called, it returns to the same place */
580 int pbx_exec(struct ast_channel *c,             /*!< Channel */
581              struct ast_app *app,               /*!< Application */
582              void *data)                        /*!< Data for execution */
583 {
584         int res;
585         struct ast_module_user *u = NULL;
586         const char *saved_c_appl;
587         const char *saved_c_data;
588
589         if (c->cdr &&  !ast_check_hangup(c))
590                 ast_cdr_setapp(c->cdr, app->name, data);
591
592         /* save channel values */
593         saved_c_appl= c->appl;
594         saved_c_data= c->data;
595
596         c->appl = app->name;
597         c->data = data;
598         if (app->module)
599                 u = __ast_module_user_add(app->module, c);
600         res = app->execute(c, data);
601         if (app->module && u)
602                 __ast_module_user_remove(app->module, u);
603         /* restore channel values */
604         c->appl = saved_c_appl;
605         c->data = saved_c_data;
606         return res;
607 }
608
609
610 /*! Go no deeper than this through includes (not counting loops) */
611 #define AST_PBX_MAX_STACK       128
612
613 /*! \brief Find application handle in linked list
614  */
615 struct ast_app *pbx_findapp(const char *app)
616 {
617         struct ast_app *tmp;
618
619         AST_RWLIST_RDLOCK(&apps);
620         AST_RWLIST_TRAVERSE(&apps, tmp, list) {
621                 if (!strcasecmp(tmp->name, app))
622                         break;
623         }
624         AST_RWLIST_UNLOCK(&apps);
625
626         return tmp;
627 }
628
629 static struct ast_switch *pbx_findswitch(const char *sw)
630 {
631         struct ast_switch *asw;
632
633         AST_RWLIST_RDLOCK(&switches);
634         AST_RWLIST_TRAVERSE(&switches, asw, list) {
635                 if (!strcasecmp(asw->name, sw))
636                         break;
637         }
638         AST_RWLIST_UNLOCK(&switches);
639
640         return asw;
641 }
642
643 static inline int include_valid(struct ast_include *i)
644 {
645         if (!i->hastime)
646                 return 1;
647
648         return ast_check_timing(&(i->timing));
649 }
650
651 static void pbx_destroy(struct ast_pbx *p)
652 {
653         ast_free(p);
654 }
655
656 /*
657  * Special characters used in patterns:
658  *      '_'     underscore is the leading character of a pattern.
659  *              In other position it is treated as a regular char.
660  *      ' ' '-' space and '-' are separator and ignored.
661  *      .       one or more of any character. Only allowed at the end of
662  *              a pattern.
663  *      !       zero or more of anything. Also impacts the result of CANMATCH
664  *              and MATCHMORE. Only allowed at the end of a pattern.
665  *              In the core routine, ! causes a match with a return code of 2.
666  *              In turn, depending on the search mode: (XXX check if it is implemented)
667  *              - E_MATCH retuns 1 (does match)
668  *              - E_MATCHMORE returns 0 (no match)
669  *              - E_CANMATCH returns 1 (does match)
670  *
671  *      /       should not appear as it is considered the separator of the CID info.
672  *              XXX at the moment we may stop on this char.
673  *
674  *      X Z N   match ranges 0-9, 1-9, 2-9 respectively.
675  *      [       denotes the start of a set of character. Everything inside
676  *              is considered literally. We can have ranges a-d and individual
677  *              characters. A '[' and '-' can be considered literally if they
678  *              are just before ']'.
679  *              XXX currently there is no way to specify ']' in a range, nor \ is
680  *              considered specially.
681  *
682  * When we compare a pattern with a specific extension, all characters in the extension
683  * itself are considered literally with the only exception of '-' which is considered
684  * as a separator and thus ignored.
685  * XXX do we want to consider space as a separator as well ?
686  * XXX do we want to consider the separators in non-patterns as well ?
687  */
688
689 /*!
690  * \brief helper functions to sort extensions and patterns in the desired way,
691  * so that more specific patterns appear first.
692  *
693  * ext_cmp1 compares individual characters (or sets of), returning
694  * an int where bits 0-7 are the ASCII code of the first char in the set,
695  * while bit 8-15 are the cardinality of the set minus 1.
696  * This way more specific patterns (smaller cardinality) appear first.
697  * Wildcards have a special value, so that we can directly compare them to
698  * sets by subtracting the two values. In particular:
699  *      0x000xx         one character, xx
700  *      0x0yyxx         yy character set starting with xx
701  *      0x10000         '.' (one or more of anything)
702  *      0x20000         '!' (zero or more of anything)
703  *      0x30000         NUL (end of string)
704  *      0x40000         error in set.
705  * The pointer to the string is advanced according to needs.
706  * NOTES:
707  *      1. the empty set is equivalent to NUL.
708  *      2. given that a full set has always 0 as the first element,
709  *         we could encode the special cases as 0xffXX where XX
710  *         is 1, 2, 3, 4 as used above.
711  */
712 static int ext_cmp1(const char **p)
713 {
714         uint32_t chars[8];
715         int c, cmin = 0xff, count = 0;
716         const char *end;
717
718         /* load, sign extend and advance pointer until we find
719          * a valid character.
720          */
721         while ( (c = *(*p)++) && (c == ' ' || c == '-') )
722                 ;       /* ignore some characters */
723
724         /* always return unless we have a set of chars */
725         switch (c) {
726         default:        /* ordinary character */
727                 return 0x0000 | (c & 0xff);
728
729         case 'N':       /* 2..9 */
730                 return 0x0700 | '2' ;
731
732         case 'X':       /* 0..9 */
733                 return 0x0900 | '0';
734
735         case 'Z':       /* 1..9 */
736                 return 0x0800 | '1';
737
738         case '.':       /* wildcard */
739                 return 0x10000;
740
741         case '!':       /* earlymatch */
742                 return 0x20000; /* less specific than NULL */
743
744         case '\0':      /* empty string */
745                 *p = NULL;
746                 return 0x30000;
747
748         case '[':       /* pattern */
749                 break;
750         }
751         /* locate end of set */
752         end = strchr(*p, ']');  
753
754         if (end == NULL) {
755                 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
756                 return 0x40000; /* XXX make this entry go last... */
757         }
758
759         bzero(chars, sizeof(chars));    /* clear all chars in the set */
760         for (; *p < end  ; (*p)++) {
761                 unsigned char c1, c2;   /* first-last char in range */
762                 c1 = (unsigned char)((*p)[0]);
763                 if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
764                         c2 = (unsigned char)((*p)[2]);
765                         *p += 2;        /* skip a total of 3 chars */
766                 } else                  /* individual character */
767                         c2 = c1;
768                 if (c1 < cmin)
769                         cmin = c1;
770                 for (; c1 <= c2; c1++) {
771                         uint32_t mask = 1 << (c1 % 32);
772                         if ( (chars[ c1 / 32 ] & mask) == 0)
773                                 count += 0x100;
774                         chars[ c1 / 32 ] |= mask;
775                 }
776         }
777         (*p)++;
778         return count == 0 ? 0x30000 : (count | cmin);
779 }
780
781 /*!
782  * \brief the full routine to compare extensions in rules.
783  */
784 static int ext_cmp(const char *a, const char *b)
785 {
786         /* make sure non-patterns come first.
787          * If a is not a pattern, it either comes first or
788          * we use strcmp to compare the strings.
789          */
790         int ret = 0;
791
792         if (a[0] != '_')
793                 return (b[0] == '_') ? -1 : strcmp(a, b);
794
795         /* Now we know a is a pattern; if b is not, a comes first */
796         if (b[0] != '_')
797                 return 1;
798 #if 0   /* old mode for ext matching */
799         return strcmp(a, b);
800 #endif
801         /* ok we need full pattern sorting routine */
802         while (!ret && a && b)
803                 ret = ext_cmp1(&a) - ext_cmp1(&b);
804         if (ret == 0)
805                 return 0;
806         else
807                 return (ret > 0) ? 1 : -1;
808 }
809
810 int ast_extension_cmp(const char *a, const char *b)
811 {
812         return ext_cmp(a, b);
813 }
814
815 /*!
816  * \internal
817  * \brief used ast_extension_{match|close}
818  * mode is as follows:
819  *      E_MATCH         success only on exact match
820  *      E_MATCHMORE     success only on partial match (i.e. leftover digits in pattern)
821  *      E_CANMATCH      either of the above.
822  * \retval 0 on no-match
823  * \retval 1 on match
824  * \retval 2 on early match.
825  */
826
827 static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
828 {
829         mode &= E_MATCH_MASK;   /* only consider the relevant bits */
830
831         if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */
832                 return 1;
833
834         if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
835                 int ld = strlen(data), lp = strlen(pattern);
836
837                 if (lp < ld)            /* pattern too short, cannot match */
838                         return 0;
839                 /* depending on the mode, accept full or partial match or both */
840                 if (mode == E_MATCH)
841                         return !strcmp(pattern, data); /* 1 on match, 0 on fail */
842                 if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */
843                         return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
844                 else
845                         return 0;
846         }
847         pattern++; /* skip leading _ */
848         /*
849          * XXX below we stop at '/' which is a separator for the CID info. However we should
850          * not store '/' in the pattern at all. When we insure it, we can remove the checks.
851          */
852         while (*data && *pattern && *pattern != '/') {
853                 const char *end;
854
855                 if (*data == '-') { /* skip '-' in data (just a separator) */
856                         data++;
857                         continue;
858                 }
859                 switch (toupper(*pattern)) {
860                 case '[':       /* a range */
861                         end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */
862                         if (end == NULL) {
863                                 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
864                                 return 0;       /* unconditional failure */
865                         }
866                         for (pattern++; pattern != end; pattern++) {
867                                 if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
868                                         if (*data >= pattern[0] && *data <= pattern[2])
869                                                 break;  /* match found */
870                                         else {
871                                                 pattern += 2; /* skip a total of 3 chars */
872                                                 continue;
873                                         }
874                                 } else if (*data == pattern[0])
875                                         break;  /* match found */
876                         }
877                         if (pattern == end)
878                                 return 0;
879                         pattern = end;  /* skip and continue */
880                         break;
881                 case 'N':
882                         if (*data < '2' || *data > '9')
883                                 return 0;
884                         break;
885                 case 'X':
886                         if (*data < '0' || *data > '9')
887                                 return 0;
888                         break;
889                 case 'Z':
890                         if (*data < '1' || *data > '9')
891                                 return 0;
892                         break;
893                 case '.':       /* Must match, even with more digits */
894                         return 1;
895                 case '!':       /* Early match */
896                         return 2;
897                 case ' ':
898                 case '-':       /* Ignore these in patterns */
899                         data--; /* compensate the final data++ */
900                         break;
901                 default:
902                         if (*data != *pattern)
903                                 return 0;
904                 }
905                 data++;
906                 pattern++;
907         }
908         if (*data)                      /* data longer than pattern, no match */
909                 return 0;
910         /*
911          * match so far, but ran off the end of the data.
912          * Depending on what is next, determine match or not.
913          */
914         if (*pattern == '\0' || *pattern == '/')        /* exact match */
915                 return (mode == E_MATCHMORE) ? 0 : 1;   /* this is a failure for E_MATCHMORE */
916         else if (*pattern == '!')                       /* early match */
917                 return 2;
918         else                                            /* partial match */
919                 return (mode == E_MATCH) ? 0 : 1;       /* this is a failure for E_MATCH */
920 }
921
922 /*
923  * Wrapper around _extension_match_core() to do performance measurement
924  * using the profiling code.
925  */
926 static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
927 {
928         int i;
929         static int prof_id = -2;        /* marker for 'unallocated' id */
930         if (prof_id == -2)
931                 prof_id = ast_add_profile("ext_match", 0);
932         ast_mark(prof_id, 1);
933         i = _extension_match_core(pattern, data, mode);
934         ast_mark(prof_id, 0);
935         return i;
936 }
937
938 int ast_extension_match(const char *pattern, const char *data)
939 {
940         return extension_match_core(pattern, data, E_MATCH);
941 }
942
943 int ast_extension_close(const char *pattern, const char *data, int needmore)
944 {
945         if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
946                 ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
947         return extension_match_core(pattern, data, needmore);
948 }
949
950 struct ast_context *ast_context_find(const char *name)
951 {
952         struct ast_context *tmp = NULL;
953         ast_rdlock_contexts();
954         while ( (tmp = ast_walk_contexts(tmp)) ) {
955                 if (!name || !strcasecmp(name, tmp->name))
956                         break;
957         }
958         ast_unlock_contexts();
959         return tmp;
960 }
961
962 #define STATUS_NO_CONTEXT       1
963 #define STATUS_NO_EXTENSION     2
964 #define STATUS_NO_PRIORITY      3
965 #define STATUS_NO_LABEL         4
966 #define STATUS_SUCCESS          5
967
968 static int matchcid(const char *cidpattern, const char *callerid)
969 {
970         /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
971            failing to get a number should count as a match, otherwise not */
972
973         if (ast_strlen_zero(callerid))
974                 return ast_strlen_zero(cidpattern) ? 1 : 0;
975
976         return ast_extension_match(cidpattern, callerid);
977 }
978
979 struct ast_exten *pbx_find_extension(struct ast_channel *chan,
980         struct ast_context *bypass, struct pbx_find_info *q,
981         const char *context, const char *exten, int priority,
982         const char *label, const char *callerid, enum ext_match_t action)
983 {
984         int x, res;
985         struct ast_context *tmp;
986         struct ast_exten *e, *eroot;
987         struct ast_include *i;
988         struct ast_sw *sw;
989
990         /* Initialize status if appropriate */
991         if (q->stacklen == 0) {
992                 q->status = STATUS_NO_CONTEXT;
993                 q->swo = NULL;
994                 q->data = NULL;
995                 q->foundcontext = NULL;
996         } else if (q->stacklen >= AST_PBX_MAX_STACK) {
997                 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
998                 return NULL;
999         }
1000
1001         /* Check first to see if we've already been checked */
1002         for (x = 0; x < q->stacklen; x++) {
1003                 if (!strcasecmp(q->incstack[x], context))
1004                         return NULL;
1005         }
1006
1007         if (bypass)     /* bypass means we only look there */
1008                 tmp = bypass;
1009         else {  /* look in contexts */
1010                 tmp = NULL;
1011                 while ((tmp = ast_walk_contexts(tmp)) ) {
1012                         if (!strcmp(tmp->name, context))
1013                                 break;
1014                 }
1015                 if (!tmp)
1016                         return NULL;
1017         }
1018
1019         if (q->status < STATUS_NO_EXTENSION)
1020                 q->status = STATUS_NO_EXTENSION;
1021
1022         /* scan the list trying to match extension and CID */
1023         eroot = NULL;
1024         while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
1025                 int match = extension_match_core(eroot->exten, exten, action);
1026                 /* 0 on fail, 1 on match, 2 on earlymatch */
1027
1028                 if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
1029                         continue;       /* keep trying */
1030                 if (match == 2 && action == E_MATCHMORE) {
1031                         /* We match an extension ending in '!'.
1032                          * The decision in this case is final and is NULL (no match).
1033                          */
1034                         return NULL;
1035                 }
1036                 /* found entry, now look for the right priority */
1037                 if (q->status < STATUS_NO_PRIORITY)
1038                         q->status = STATUS_NO_PRIORITY;
1039                 e = NULL;
1040                 while ( (e = ast_walk_extension_priorities(eroot, e)) ) {
1041                         /* Match label or priority */
1042                         if (action == E_FINDLABEL) {
1043                                 if (q->status < STATUS_NO_LABEL)
1044                                         q->status = STATUS_NO_LABEL;
1045                                 if (label && e->label && !strcmp(label, e->label))
1046                                         break;  /* found it */
1047                         } else if (e->priority == priority) {
1048                                 break;  /* found it */
1049                         } /* else keep searching */
1050                 }
1051                 if (e) {        /* found a valid match */
1052                         q->status = STATUS_SUCCESS;
1053                         q->foundcontext = context;
1054                         return e;
1055                 }
1056         }
1057         /* Check alternative switches */
1058         AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
1059                 struct ast_switch *asw = pbx_findswitch(sw->name);
1060                 ast_switch_f *aswf = NULL;
1061                 char *datap;
1062
1063                 if (!asw) {
1064                         ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
1065                         continue;
1066                 }
1067                 /* Substitute variables now */
1068                 if (sw->eval)
1069                         pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1);
1070
1071                 /* equivalent of extension_match_core() at the switch level */
1072                 if (action == E_CANMATCH)
1073                         aswf = asw->canmatch;
1074                 else if (action == E_MATCHMORE)
1075                         aswf = asw->matchmore;
1076                 else /* action == E_MATCH */
1077                         aswf = asw->exists;
1078                 datap = sw->eval ? sw->tmpdata : sw->data;
1079                 res = !aswf ? 0 : aswf(chan, context, exten, priority, callerid, datap);
1080                 if (res) {      /* Got a match */
1081                         q->swo = asw;
1082                         q->data = datap;
1083                         q->foundcontext = context;
1084                         /* XXX keep status = STATUS_NO_CONTEXT ? */
1085                         return NULL;
1086                 }
1087         }
1088         q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
1089         /* Now try any includes we have in this context */
1090         for (i = tmp->includes; i; i = i->next) {
1091                 if (include_valid(i)) {
1092                         if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action)))
1093                                 return e;
1094                         if (q->swo)
1095                                 return NULL;
1096                 }
1097         }
1098         return NULL;
1099 }
1100
1101 /*! 
1102  * \brief extract offset:length from variable name.
1103  * \return 1 if there is a offset:length part, which is
1104  * trimmed off (values go into variables)
1105  */
1106 static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
1107 {
1108         int parens=0;
1109
1110         *offset = 0;
1111         *length = INT_MAX;
1112         *isfunc = 0;
1113         for (; *var; var++) {
1114                 if (*var == '(') {
1115                         (*isfunc)++;
1116                         parens++;
1117                 } else if (*var == ')') {
1118                         parens--;
1119                 } else if (*var == ':' && parens == 0) {
1120                         *var++ = '\0';
1121                         sscanf(var, "%d:%d", offset, length);
1122                         return 1; /* offset:length valid */
1123                 }
1124         }
1125         return 0;
1126 }
1127
1128 /*! 
1129  *\brief takes a substring. It is ok to call with value == workspace.
1130  * \param value
1131  * \param offset < 0 means start from the end of the string and set the beginning
1132  *   to be that many characters back.
1133  * \param length is the length of the substring, a value less than 0 means to leave
1134  * that many off the end.
1135  * \param workspace
1136  * \param workspace_len
1137  * Always return a copy in workspace.
1138  */
1139 static char *substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
1140 {
1141         char *ret = workspace;
1142         int lr; /* length of the input string after the copy */
1143
1144         ast_copy_string(workspace, value, workspace_len); /* always make a copy */
1145
1146         lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
1147
1148         /* Quick check if no need to do anything */
1149         if (offset == 0 && length >= lr)        /* take the whole string */
1150                 return ret;
1151
1152         if (offset < 0) {       /* translate negative offset into positive ones */
1153                 offset = lr + offset;
1154                 if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
1155                         offset = 0;
1156         }
1157
1158         /* too large offset result in empty string so we know what to return */
1159         if (offset >= lr)
1160                 return ret + lr;        /* the final '\0' */
1161
1162         ret += offset;          /* move to the start position */
1163         if (length >= 0 && length < lr - offset)        /* truncate if necessary */
1164                 ret[length] = '\0';
1165         else if (length < 0) {
1166                 if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */
1167                         ret[lr + length - offset] = '\0';
1168                 else
1169                         ret[0] = '\0';
1170         }
1171
1172         return ret;
1173 }
1174
1175 /*! \brief  Support for Asterisk built-in variables in the dialplan
1176
1177 \note   See also
1178         - \ref AstVar   Channel variables
1179         - \ref AstCauses The HANGUPCAUSE variable
1180  */
1181 void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
1182 {
1183         const char not_found = '\0';
1184         char *tmpvar;
1185         const char *s;  /* the result */
1186         int offset, length;
1187         int i, need_substring;
1188         struct varshead *places[2] = { headp, &globals };       /* list of places where we may look */
1189
1190         if (c) {
1191                 ast_channel_lock(c);
1192                 places[0] = &c->varshead;
1193         }
1194         /*
1195          * Make a copy of var because parse_variable_name() modifies the string.
1196          * Then if called directly, we might need to run substring() on the result;
1197          * remember this for later in 'need_substring', 'offset' and 'length'
1198          */
1199         tmpvar = ast_strdupa(var);      /* parse_variable_name modifies the string */
1200         need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
1201
1202         /*
1203          * Look first into predefined variables, then into variable lists.
1204          * Variable 's' points to the result, according to the following rules:
1205          * s == &not_found (set at the beginning) means that we did not find a
1206          *      matching variable and need to look into more places.
1207          * If s != &not_found, s is a valid result string as follows:
1208          * s = NULL if the variable does not have a value;
1209          *      you typically do this when looking for an unset predefined variable.
1210          * s = workspace if the result has been assembled there;
1211          *      typically done when the result is built e.g. with an snprintf(),
1212          *      so we don't need to do an additional copy.
1213          * s != workspace in case we have a string, that needs to be copied
1214          *      (the ast_copy_string is done once for all at the end).
1215          *      Typically done when the result is already available in some string.
1216          */
1217         s = &not_found; /* default value */
1218         if (c) {        /* This group requires a valid channel */
1219                 /* Names with common parts are looked up a piece at a time using strncmp. */
1220                 if (!strncmp(var, "CALL", 4)) {
1221                         if (!strncmp(var + 4, "ING", 3)) {
1222                                 if (!strcmp(var + 7, "PRES")) {                 /* CALLINGPRES */
1223                                         snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
1224                                         s = workspace;
1225                                 } else if (!strcmp(var + 7, "ANI2")) {          /* CALLINGANI2 */
1226                                         snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
1227                                         s = workspace;
1228                                 } else if (!strcmp(var + 7, "TON")) {           /* CALLINGTON */
1229                                         snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
1230                                         s = workspace;
1231                                 } else if (!strcmp(var + 7, "TNS")) {           /* CALLINGTNS */
1232                                         snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
1233                                         s = workspace;
1234                                 }
1235                         }
1236                 } else if (!strcmp(var, "HINT")) {
1237                         s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
1238                 } else if (!strcmp(var, "HINTNAME")) {
1239                         s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
1240                 } else if (!strcmp(var, "EXTEN")) {
1241                         s = c->exten;
1242                 } else if (!strcmp(var, "CONTEXT")) {
1243                         s = c->context;
1244                 } else if (!strcmp(var, "PRIORITY")) {
1245                         snprintf(workspace, workspacelen, "%d", c->priority);
1246                         s = workspace;
1247                 } else if (!strcmp(var, "CHANNEL")) {
1248                         s = c->name;
1249                 } else if (!strcmp(var, "UNIQUEID")) {
1250                         s = c->uniqueid;
1251                 } else if (!strcmp(var, "HANGUPCAUSE")) {
1252                         snprintf(workspace, workspacelen, "%d", c->hangupcause);
1253                         s = workspace;
1254                 }
1255         }
1256         if (s == &not_found) { /* look for more */
1257                 if (!strcmp(var, "EPOCH")) {
1258                         snprintf(workspace, workspacelen, "%u",(int)time(NULL));
1259                         s = workspace;
1260                 } else if (!strcmp(var, "SYSTEMNAME")) {
1261                         s = ast_config_AST_SYSTEM_NAME;
1262                 }
1263         }
1264         /* if not found, look into chanvars or global vars */
1265         for (i = 0; s == &not_found && i < (sizeof(places) / sizeof(places[0])); i++) {
1266                 struct ast_var_t *variables;
1267                 if (!places[i])
1268                         continue;
1269                 if (places[i] == &globals)
1270                         ast_rwlock_rdlock(&globalslock);
1271                 AST_LIST_TRAVERSE(places[i], variables, entries) {
1272                         if (strcasecmp(ast_var_name(variables), var)==0) {
1273                                 s = ast_var_value(variables);
1274                                 break;
1275                         }
1276                 }
1277                 if (places[i] == &globals)
1278                         ast_rwlock_unlock(&globalslock);
1279         }
1280         if (s == &not_found || s == NULL)
1281                 *ret = NULL;
1282         else {
1283                 if (s != workspace)
1284                         ast_copy_string(workspace, s, workspacelen);
1285                 *ret = workspace;
1286                 if (need_substring)
1287                         *ret = substring(*ret, offset, length, workspace, workspacelen);
1288         }
1289
1290         if (c)
1291                 ast_channel_unlock(c);
1292 }
1293
1294 static void exception_store_free(void *data)
1295 {
1296         struct pbx_exception *exception = data;
1297         ast_string_field_free_memory(exception);
1298         ast_free(exception);
1299 }
1300
1301 static struct ast_datastore_info exception_store_info = {
1302         .type = "EXCEPTION",
1303         .destroy = exception_store_free,
1304 };
1305
1306 int pbx_builtin_raise_exception(struct ast_channel *chan, void *vreason)
1307 {
1308         const char *reason = vreason;
1309         struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
1310         struct pbx_exception *exception = NULL;
1311
1312         if (!ds) {
1313                 ds = ast_channel_datastore_alloc(&exception_store_info, NULL);
1314                 if (!ds)
1315                         return -1;
1316                 exception = ast_calloc(1, sizeof(struct pbx_exception));
1317                 if (!exception) {
1318                         ast_channel_datastore_free(ds);
1319                         return -1;
1320                 }
1321                 if (ast_string_field_init(exception, 128)) {
1322                         ast_free(exception);
1323                         ast_channel_datastore_free(ds);
1324                         return -1;
1325                 }
1326                 ds->data = exception;
1327                 ast_channel_datastore_add(chan, ds);
1328         } else
1329                 exception = ds->data;
1330
1331         ast_string_field_set(exception, reason, reason);
1332         ast_string_field_set(exception, context, chan->context);
1333         ast_string_field_set(exception, exten, chan->exten);
1334         exception->priority = chan->priority;
1335         set_ext_pri(chan, "e", 0);
1336         return 0;
1337 }
1338
1339 static int acf_exception_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
1340 {
1341         struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
1342         struct pbx_exception *exception = NULL;
1343         if (!ds || !ds->data)
1344                 return -1;
1345         exception = ds->data;
1346         if (!strcasecmp(data, "REASON"))
1347                 ast_copy_string(buf, exception->reason, buflen);
1348         else if (!strcasecmp(data, "CONTEXT"))
1349                 ast_copy_string(buf, exception->context, buflen);
1350         else if (!strncasecmp(data, "EXTEN", 5))
1351                 ast_copy_string(buf, exception->exten, buflen);
1352         else if (!strcasecmp(data, "PRIORITY"))
1353                 snprintf(buf, buflen, "%d", exception->priority);
1354         else
1355                 return -1;
1356         return 0;
1357 }
1358
1359 static struct ast_custom_function exception_function = {
1360         .name = "EXCEPTION",
1361         .synopsis = "Retrieve the details of the current dialplan exception",
1362         .desc =
1363 "The following fields are available for retrieval:\n"
1364 "  reason    INVALID, ERROR, RESPONSETIMEOUT, ABSOLUTETIMEOUT, or custom\n"
1365 "               value set by the RaiseException() application\n"
1366 "  context   The context executing when the exception occurred\n"
1367 "  exten     The extension executing when the exception occurred\n"
1368 "  priority  The numeric priority executing when the exception occurred\n",
1369         .syntax = "EXCEPTION(<field>)",
1370         .read = acf_exception_read,
1371 };
1372
1373 static char *handle_show_functions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1374 {
1375         struct ast_custom_function *acf;
1376         int count_acf = 0;
1377         int like = 0;
1378
1379         switch (cmd) {
1380         case CLI_INIT:
1381                 e->command = "core show functions [like]";
1382                 e->usage = 
1383                         "Usage: core show functions [like <text>]\n"
1384                         "       List builtin functions, optionally only those matching a given string\n";
1385                 return NULL;
1386         case CLI_GENERATE:
1387                 return NULL;
1388         }
1389
1390         if (a->argc == 5 && (!strcmp(a->argv[3], "like")) ) {
1391                 like = 1;
1392         } else if (a->argc != 3) {
1393                 return CLI_SHOWUSAGE;
1394         }
1395
1396         ast_cli(a->fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed");
1397
1398         AST_RWLIST_RDLOCK(&acf_root);
1399         AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
1400                 if (!like || strstr(acf->name, a->argv[4])) {
1401                         count_acf++;
1402                         ast_cli(a->fd, "%-20.20s  %-35.35s  %s\n", acf->name, acf->syntax, acf->synopsis);
1403                 }
1404         }
1405         AST_RWLIST_UNLOCK(&acf_root);
1406
1407         ast_cli(a->fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : "");
1408
1409         return CLI_SUCCESS;
1410 }
1411
1412 static char *handle_show_function(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1413 {
1414         struct ast_custom_function *acf;
1415         /* Maximum number of characters added by terminal coloring is 22 */
1416         char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
1417         char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
1418         char stxtitle[40], *syntax = NULL;
1419         int synopsis_size, description_size, syntax_size;
1420         char *ret = NULL;
1421         int which = 0;
1422         int wordlen;
1423
1424         switch (cmd) {
1425         case CLI_INIT:
1426                 e->command = "core show function";
1427                 e->usage = 
1428                         "Usage: core show function <function>\n"
1429                         "       Describe a particular dialplan function.\n";
1430                 return NULL;
1431         case CLI_GENERATE:      
1432                 wordlen = strlen(a->word);
1433                 /* case-insensitive for convenience in this 'complete' function */
1434                 AST_RWLIST_RDLOCK(&acf_root);
1435                 AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
1436                         if (!strncasecmp(a->word, acf->name, wordlen) && ++which > a->n) {
1437                                 ret = ast_strdup(acf->name);
1438                                 break;
1439                         }
1440                 }
1441                 AST_RWLIST_UNLOCK(&acf_root);
1442
1443                 return ret;
1444         }
1445
1446         if (a->argc < 4)
1447                 return CLI_SHOWUSAGE;
1448
1449         if (!(acf = ast_custom_function_find(a->argv[3]))) {
1450                 ast_cli(a->fd, "No function by that name registered.\n");
1451                 return CLI_FAILURE;
1452
1453         }
1454
1455         if (acf->synopsis)
1456                 synopsis_size = strlen(acf->synopsis) + 23;
1457         else
1458                 synopsis_size = strlen("Not available") + 23;
1459         synopsis = alloca(synopsis_size);
1460
1461         if (acf->desc)
1462                 description_size = strlen(acf->desc) + 23;
1463         else
1464                 description_size = strlen("Not available") + 23;
1465         description = alloca(description_size);
1466
1467         if (acf->syntax)
1468                 syntax_size = strlen(acf->syntax) + 23;
1469         else
1470                 syntax_size = strlen("Not available") + 23;
1471         syntax = alloca(syntax_size);
1472
1473         snprintf(info, 64 + AST_MAX_APP, "\n  -= Info about function '%s' =- \n\n", acf->name);
1474         term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
1475         term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
1476         term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
1477         term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
1478         term_color(syntax,
1479                    acf->syntax ? acf->syntax : "Not available",
1480                    COLOR_CYAN, 0, syntax_size);
1481         term_color(synopsis,
1482                    acf->synopsis ? acf->synopsis : "Not available",
1483                    COLOR_CYAN, 0, synopsis_size);
1484         term_color(description,
1485                    acf->desc ? acf->desc : "Not available",
1486                    COLOR_CYAN, 0, description_size);
1487
1488         ast_cli(a->fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description);
1489
1490         return CLI_SUCCESS;
1491 }
1492
1493 struct ast_custom_function *ast_custom_function_find(const char *name)
1494 {
1495         struct ast_custom_function *acf = NULL;
1496
1497         AST_RWLIST_RDLOCK(&acf_root);
1498         AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
1499                 if (!strcmp(name, acf->name))
1500                         break;
1501         }
1502         AST_RWLIST_UNLOCK(&acf_root);
1503
1504         return acf;
1505 }
1506
1507 int ast_custom_function_unregister(struct ast_custom_function *acf)
1508 {
1509         struct ast_custom_function *cur;
1510
1511         if (!acf)
1512                 return -1;
1513
1514         AST_RWLIST_WRLOCK(&acf_root);
1515         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
1516                 if (cur == acf) {
1517                         AST_RWLIST_REMOVE_CURRENT(&acf_root, acflist);
1518                         ast_verb(2, "Unregistered custom function %s\n", acf->name);
1519                         break;
1520                 }
1521         }
1522         AST_RWLIST_TRAVERSE_SAFE_END
1523         AST_RWLIST_UNLOCK(&acf_root);
1524
1525         return acf ? 0 : -1;
1526 }
1527
1528 int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
1529 {
1530         struct ast_custom_function *cur;
1531
1532         if (!acf)
1533                 return -1;
1534
1535         acf->mod = mod;
1536
1537         AST_RWLIST_WRLOCK(&acf_root);
1538
1539         AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) {
1540                 if (!strcmp(acf->name, cur->name)) {
1541                         ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
1542                         AST_RWLIST_UNLOCK(&acf_root);
1543                         return -1;
1544                 }
1545         }
1546
1547         /* Store in alphabetical order */
1548         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
1549                 if (strcasecmp(acf->name, cur->name) < 0) {
1550                         AST_RWLIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
1551                         break;
1552                 }
1553         }
1554         AST_RWLIST_TRAVERSE_SAFE_END
1555         if (!cur)
1556                 AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist);
1557
1558         AST_RWLIST_UNLOCK(&acf_root);
1559
1560         ast_verb(2, "Registered custom function %s\n", acf->name);
1561
1562         return 0;
1563 }
1564
1565 /*! \brief return a pointer to the arguments of the function,
1566  * and terminates the function name with '\\0'
1567  */
1568 static char *func_args(char *function)
1569 {
1570         char *args = strchr(function, '(');
1571
1572         if (!args)
1573                 ast_log(LOG_WARNING, "Function doesn't contain parentheses.  Assuming null argument.\n");
1574         else {
1575                 char *p;
1576                 *args++ = '\0';
1577                 if ((p = strrchr(args, ')')) )
1578                         *p = '\0';
1579                 else
1580                         ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
1581         }
1582         return args;
1583 }
1584
1585 int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
1586 {
1587         char *copy = ast_strdupa(function);
1588         char *args = func_args(copy);
1589         struct ast_custom_function *acfptr = ast_custom_function_find(copy);
1590
1591         if (acfptr == NULL)
1592                 ast_log(LOG_ERROR, "Function %s not registered\n", copy);
1593         else if (!acfptr->read)
1594                 ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
1595         else {
1596                 int res;
1597                 struct ast_module_user *u = NULL;
1598                 if (acfptr->mod)
1599                         u = __ast_module_user_add(acfptr->mod, chan);
1600                 res = acfptr->read(chan, copy, args, workspace, len);
1601                 if (acfptr->mod && u)
1602                         __ast_module_user_remove(acfptr->mod, u);
1603                 return res;
1604         }
1605         return -1;
1606 }
1607
1608 int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
1609 {
1610         char *copy = ast_strdupa(function);
1611         char *args = func_args(copy);
1612         struct ast_custom_function *acfptr = ast_custom_function_find(copy);
1613
1614         if (acfptr == NULL)
1615                 ast_log(LOG_ERROR, "Function %s not registered\n", copy);
1616         else if (!acfptr->write)
1617                 ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy);
1618         else {
1619                 int res;
1620                 struct ast_module_user *u = NULL;
1621                 if (acfptr->mod)
1622                         u = __ast_module_user_add(acfptr->mod, chan);
1623                 res = acfptr->write(chan, copy, args, value);
1624                 if (acfptr->mod && u)
1625                         __ast_module_user_remove(acfptr->mod, u);
1626                 return res;
1627         }
1628
1629         return -1;
1630 }
1631
1632 static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count)
1633 {
1634         /* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!!  */
1635         char *cp4;
1636         const char *tmp, *whereweare;
1637         int length, offset, offset2, isfunction;
1638         char *workspace = NULL;
1639         char *ltmp = NULL, *var = NULL;
1640         char *nextvar, *nextexp, *nextthing;
1641         char *vars, *vare;
1642         int pos, brackets, needsub, len;
1643         
1644         *cp2 = 0; /* just in case nothing ends up there */
1645         whereweare=tmp=cp1;
1646         while (!ast_strlen_zero(whereweare) && count) {
1647                 /* Assume we're copying the whole remaining string */
1648                 pos = strlen(whereweare);
1649                 nextvar = NULL;
1650                 nextexp = NULL;
1651                 nextthing = strchr(whereweare, '$');
1652                 if (nextthing) {
1653                         switch (nextthing[1]) {
1654                         case '{':
1655                                 nextvar = nextthing;
1656                                 pos = nextvar - whereweare;
1657                                 break;
1658                         case '[':
1659                                 nextexp = nextthing;
1660                                 pos = nextexp - whereweare;
1661                                 break;
1662                         default:
1663                                 pos = 1;
1664                         }
1665                 }
1666
1667                 if (pos) {
1668                         /* Can't copy more than 'count' bytes */
1669                         if (pos > count)
1670                                 pos = count;
1671
1672                         /* Copy that many bytes */
1673                         memcpy(cp2, whereweare, pos);
1674
1675                         count -= pos;
1676                         cp2 += pos;
1677                         whereweare += pos;
1678                         *cp2 = 0;
1679                 }
1680
1681                 if (nextvar) {
1682                         /* We have a variable.  Find the start and end, and determine
1683                            if we are going to have to recursively call ourselves on the
1684                            contents */
1685                         vars = vare = nextvar + 2;
1686                         brackets = 1;
1687                         needsub = 0;
1688
1689                         /* Find the end of it */
1690                         while (brackets && *vare) {
1691                                 if ((vare[0] == '$') && (vare[1] == '{')) {
1692                                         needsub++;
1693                                 } else if (vare[0] == '{') {
1694                                         brackets++;
1695                                 } else if (vare[0] == '}') {
1696                                         brackets--;
1697                                 } else if ((vare[0] == '$') && (vare[1] == '['))
1698                                         needsub++;
1699                                 vare++;
1700                         }
1701                         if (brackets)
1702                                 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n");
1703                         len = vare - vars - 1;
1704
1705                         /* Skip totally over variable string */
1706                         whereweare += (len + 3);
1707
1708                         if (!var)
1709                                 var = alloca(VAR_BUF_SIZE);
1710
1711                         /* Store variable name (and truncate) */
1712                         ast_copy_string(var, vars, len + 1);
1713
1714                         /* Substitute if necessary */
1715                         if (needsub) {
1716                                 if (!ltmp)
1717                                         ltmp = alloca(VAR_BUF_SIZE);
1718
1719                                 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
1720                                 vars = ltmp;
1721                         } else {
1722                                 vars = var;
1723                         }
1724
1725                         if (!workspace)
1726                                 workspace = alloca(VAR_BUF_SIZE);
1727
1728                         workspace[0] = '\0';
1729
1730                         parse_variable_name(vars, &offset, &offset2, &isfunction);
1731                         if (isfunction) {
1732                                 /* Evaluate function */
1733                                 if (c || !headp)
1734                                         cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
1735                                 else {
1736                                         struct varshead old;
1737                                         struct ast_channel *c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/%p", vars);
1738                                         if (c) {
1739                                                 memcpy(&old, &c->varshead, sizeof(old));
1740                                                 memcpy(&c->varshead, headp, sizeof(c->varshead));
1741                                                 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
1742                                                 /* Don't deallocate the varshead that was passed in */
1743                                                 memcpy(&c->varshead, &old, sizeof(c->varshead));
1744                                                 ast_channel_free(c);
1745                                         } else
1746                                                 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution.  Function results may be blank.\n");
1747                                 }
1748                                 ast_debug(1, "Function result is '%s'\n", cp4 ? cp4 : "(null)");
1749                         } else {
1750                                 /* Retrieve variable value */
1751                                 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);
1752                         }
1753                         if (cp4) {
1754                                 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);
1755
1756                                 length = strlen(cp4);
1757                                 if (length > count)
1758                                         length = count;
1759                                 memcpy(cp2, cp4, length);
1760                                 count -= length;
1761                                 cp2 += length;
1762                                 *cp2 = 0;
1763                         }
1764                 } else if (nextexp) {
1765                         /* We have an expression.  Find the start and end, and determine
1766                            if we are going to have to recursively call ourselves on the
1767                            contents */
1768                         vars = vare = nextexp + 2;
1769                         brackets = 1;
1770                         needsub = 0;
1771
1772                         /* Find the end of it */
1773                         while (brackets && *vare) {
1774                                 if ((vare[0] == '$') && (vare[1] == '[')) {
1775                                         needsub++;
1776                                         brackets++;
1777                                         vare++;
1778                                 } else if (vare[0] == '[') {
1779                                         brackets++;
1780                                 } else if (vare[0] == ']') {
1781                                         brackets--;
1782                                 } else if ((vare[0] == '$') && (vare[1] == '{')) {
1783                                         needsub++;
1784                                         vare++;
1785                                 }
1786                                 vare++;
1787                         }
1788                         if (brackets)
1789                                 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
1790                         len = vare - vars - 1;
1791
1792                         /* Skip totally over expression */
1793                         whereweare += (len + 3);
1794
1795                         if (!var)
1796                                 var = alloca(VAR_BUF_SIZE);
1797
1798                         /* Store variable name (and truncate) */
1799                         ast_copy_string(var, vars, len + 1);
1800
1801                         /* Substitute if necessary */
1802                         if (needsub) {
1803                                 if (!ltmp)
1804                                         ltmp = alloca(VAR_BUF_SIZE);
1805
1806                                 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
1807                                 vars = ltmp;
1808                         } else {
1809                                 vars = var;
1810                         }
1811
1812                         length = ast_expr(vars, cp2, count, c);
1813
1814                         if (length) {
1815                                 ast_debug(1, "Expression result is '%s'\n", cp2);
1816                                 count -= length;
1817                                 cp2 += length;
1818                                 *cp2 = 0;
1819                         }
1820                 }
1821         }
1822 }
1823
1824 void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
1825 {
1826         pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
1827 }
1828
1829 void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count)
1830 {
1831         pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
1832 }
1833
1834 static void pbx_substitute_variables(char *passdata, int datalen, struct ast_channel *c, struct ast_exten *e)
1835 {
1836         const char *tmp;
1837
1838         /* Nothing more to do */
1839         if (!e->data)
1840                 return;
1841
1842         /* No variables or expressions in e->data, so why scan it? */
1843         if ((!(tmp = strchr(e->data, '$'))) || (!strstr(tmp, "${") && !strstr(tmp, "$["))) {
1844                 ast_copy_string(passdata, e->data, datalen);
1845                 return;
1846         }
1847
1848         pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1);
1849 }
1850
1851 /*! \brief The return value depends on the action:
1852  *
1853  * E_MATCH, E_CANMATCH, E_MATCHMORE require a real match,
1854  *      and return 0 on failure, -1 on match;
1855  * E_FINDLABEL maps the label to a priority, and returns
1856  *      the priority on success, ... XXX
1857  * E_SPAWN, spawn an application,
1858  *      
1859  * \retval 0 on success.
1860  * \retval  -1 on failure.
1861  */
1862 static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
1863   const char *context, const char *exten, int priority,
1864   const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
1865 {
1866         struct ast_exten *e;
1867         struct ast_app *app;
1868         int res;
1869         struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
1870         char passdata[EXT_DATA_SIZE];
1871
1872         int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
1873         
1874         ast_rdlock_contexts();
1875         if (found)
1876                 *found = 0;
1877         e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
1878         if (e) {
1879                 if (found)
1880                         *found = 1;
1881                 if (matching_action) {
1882                         ast_unlock_contexts();
1883                         return -1;      /* success, we found it */
1884                 } else if (action == E_FINDLABEL) { /* map the label to a priority */
1885                         res = e->priority;
1886                         ast_unlock_contexts();
1887                         return res;     /* the priority we were looking for */
1888                 } else {        /* spawn */
1889                         if (!e->cached_app)
1890                                 e->cached_app = pbx_findapp(e->app);
1891                         app = e->cached_app;
1892                         ast_unlock_contexts();
1893                         if (!app) {
1894                                 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
1895                                 return -1;
1896                         }
1897                         if (c->context != context)
1898                                 ast_copy_string(c->context, context, sizeof(c->context));
1899                         if (c->exten != exten)
1900                                 ast_copy_string(c->exten, exten, sizeof(c->exten));
1901                         c->priority = priority;
1902                         pbx_substitute_variables(passdata, sizeof(passdata), c, e);
1903                         if (option_debug) {
1904                                 char atmp[80];
1905                                 char atmp2[EXT_DATA_SIZE+100];
1906                                 ast_debug(1, "Launching '%s'\n", app->name);
1907                                 snprintf(atmp, sizeof(atmp), "STACK-%s-%s-%d", context, exten, priority);
1908                                 snprintf(atmp2, sizeof(atmp2), "%s(\"%s\", \"%s\") %s",
1909                                         app->name, c->name, passdata, "in new stack");
1910                                 pbx_builtin_setvar_helper(c, atmp, atmp2);
1911                         }
1912                         if (option_verbose > 2) {
1913                                 char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE];
1914                                 ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n",
1915                                         exten, context, priority,
1916                                         term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
1917                                         term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
1918                                         term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)),
1919                                         "in new stack");
1920                         }
1921                         manager_event(EVENT_FLAG_CALL, "Newexten",
1922                                         "Channel: %s\r\n"
1923                                         "Context: %s\r\n"
1924                                         "Extension: %s\r\n"
1925                                         "Priority: %d\r\n"
1926                                         "Application: %s\r\n"
1927                                         "AppData: %s\r\n"
1928                                         "Uniqueid: %s\r\n",
1929                                         c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid);
1930                         return pbx_exec(c, app, passdata);      /* 0 on success, -1 on failure */
1931                 }
1932         } else if (q.swo) {     /* not found here, but in another switch */
1933                 ast_unlock_contexts();
1934                 if (matching_action)
1935                         return -1;
1936                 else {
1937                         if (!q.swo->exec) {
1938                                 ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
1939                                 res = -1;
1940                         }
1941                         return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
1942                 }
1943         } else {        /* not found anywhere, see what happened */
1944                 ast_unlock_contexts();
1945                 switch (q.status) {
1946                 case STATUS_NO_CONTEXT:
1947                         if (!matching_action && !combined_find_spawn)
1948                                 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
1949                         break;
1950                 case STATUS_NO_EXTENSION:
1951                         if (!matching_action && !combined_find_spawn)
1952                                 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
1953                         break;
1954                 case STATUS_NO_PRIORITY:
1955                         if (!matching_action && !combined_find_spawn)
1956                                 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
1957                         break;
1958                 case STATUS_NO_LABEL:
1959                         if (context && !combined_find_spawn)
1960                                 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context);
1961                         break;
1962                 default:
1963                         ast_debug(1, "Shouldn't happen!\n");
1964                 }
1965
1966                 return (matching_action) ? 0 : -1;
1967         }
1968 }
1969
1970 /*! \brief Find hint for given extension in context */
1971 static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
1972 {
1973         struct ast_exten *e;
1974         struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
1975
1976         ast_rdlock_contexts();
1977         e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH);
1978         ast_unlock_contexts();
1979
1980         return e;
1981 }
1982
1983 /*! \brief Check state of extension by using hints */
1984 static int ast_extension_state2(struct ast_exten *e)
1985 {
1986         char hint[AST_MAX_EXTENSION];
1987         char *cur, *rest;
1988         int allunavailable = 1, allbusy = 1, allfree = 1, allonhold = 1;
1989         int busy = 0, inuse = 0, ring = 0;
1990
1991         if (!e)
1992                 return -1;
1993
1994         ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint));
1995
1996         rest = hint;    /* One or more devices separated with a & character */
1997         while ( (cur = strsep(&rest, "&")) ) {
1998                 int res = ast_device_state(cur);
1999                 switch (res) {
2000                 case AST_DEVICE_NOT_INUSE:
2001                         allunavailable = 0;
2002                         allbusy = 0;
2003                         allonhold = 0;
2004                         break;
2005                 case AST_DEVICE_INUSE:
2006                         inuse = 1;
2007                         allunavailable = 0;
2008                         allfree = 0;
2009                         allonhold = 0;
2010                         break;
2011                 case AST_DEVICE_RINGING:
2012                         ring = 1;
2013                         allunavailable = 0;
2014                         allfree = 0;
2015                         allonhold = 0;
2016                         break;
2017                 case AST_DEVICE_RINGINUSE:
2018                         inuse = 1;
2019                         ring = 1;
2020                         allunavailable = 0;
2021                         allfree = 0;
2022                         allonhold = 0;
2023                         break;
2024                 case AST_DEVICE_ONHOLD:
2025                         allunavailable = 0;
2026                         allfree = 0;
2027                         break;
2028                 case AST_DEVICE_BUSY:
2029                         allunavailable = 0;
2030                         allfree = 0;
2031                         allonhold = 0;
2032                         busy = 1;
2033                         break;
2034                 case AST_DEVICE_UNAVAILABLE:
2035                 case AST_DEVICE_INVALID:
2036                         allbusy = 0;
2037                         allfree = 0;
2038                         allonhold = 0;
2039                         break;
2040                 default:
2041                         allunavailable = 0;
2042                         allbusy = 0;
2043                         allfree = 0;
2044                         allonhold = 0;
2045                 }
2046         }
2047
2048         if (!inuse && ring)
2049                 return AST_EXTENSION_RINGING;
2050         if (inuse && ring)
2051                 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
2052         if (inuse)
2053                 return AST_EXTENSION_INUSE;
2054         if (allfree)
2055                 return AST_EXTENSION_NOT_INUSE;
2056         if (allonhold)
2057                 return AST_EXTENSION_ONHOLD;
2058         if (allbusy)
2059                 return AST_EXTENSION_BUSY;
2060         if (allunavailable)
2061                 return AST_EXTENSION_UNAVAILABLE;
2062         if (busy)
2063                 return AST_EXTENSION_INUSE;
2064
2065         return AST_EXTENSION_NOT_INUSE;
2066 }
2067
2068 /*! \brief Return extension_state as string */
2069 const char *ast_extension_state2str(int extension_state)
2070 {
2071         int i;
2072
2073         for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
2074                 if (extension_states[i].extension_state == extension_state)
2075                         return extension_states[i].text;
2076         }
2077         return "Unknown";
2078 }
2079
2080 /*! \brief Check extension state for an extension by using hint */
2081 int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
2082 {
2083         struct ast_exten *e;
2084
2085         e = ast_hint_extension(c, context, exten);      /* Do we have a hint for this extension ? */
2086         if (!e)
2087                 return -1;                              /* No hint, return -1 */
2088
2089         return ast_extension_state2(e);                 /* Check all devices in the hint */
2090 }
2091
2092 static void handle_statechange(const char *device)
2093 {
2094         struct ast_hint *hint;
2095
2096         AST_RWLIST_RDLOCK(&hints);
2097
2098         AST_RWLIST_TRAVERSE(&hints, hint, list) {
2099                 struct ast_state_cb *cblist;
2100                 char buf[AST_MAX_EXTENSION];
2101                 char *parse = buf;
2102                 char *cur;
2103                 int state;
2104
2105                 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
2106                 while ( (cur = strsep(&parse, "&")) ) {
2107                         if (!strcasecmp(cur, device))
2108                                 break;
2109                 }
2110                 if (!cur)
2111                         continue;
2112
2113                 /* Get device state for this hint */
2114                 state = ast_extension_state2(hint->exten);
2115
2116                 if ((state == -1) || (state == hint->laststate))
2117                         continue;
2118
2119                 /* Device state changed since last check - notify the watchers */
2120
2121                 /* For general callbacks */
2122                 for (cblist = statecbs; cblist; cblist = cblist->next)
2123                         cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
2124
2125                 /* For extension callbacks */
2126                 for (cblist = hint->callbacks; cblist; cblist = cblist->next)
2127                         cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
2128
2129                 hint->laststate = state;        /* record we saw the change */
2130         }
2131
2132         AST_RWLIST_UNLOCK(&hints);
2133 }
2134
2135 static int statechange_queue(const char *dev)
2136 {
2137         struct statechange *sc;
2138
2139         if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
2140                 return 0;
2141
2142         strcpy(sc->dev, dev);
2143
2144         ast_mutex_lock(&device_state.lock);
2145         AST_LIST_INSERT_TAIL(&device_state.state_change_q, sc, entry);
2146         ast_cond_signal(&device_state.cond);
2147         ast_mutex_unlock(&device_state.lock);
2148
2149         return 0;
2150 }
2151
2152 static void *device_state_thread(void *data)
2153 {
2154         struct statechange *sc;
2155
2156         while (!device_state.stop) {
2157                 ast_mutex_lock(&device_state.lock);
2158                 while (!(sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry))) {
2159                         ast_cond_wait(&device_state.cond, &device_state.lock);
2160                         /* Check to see if we were woken up to see the request to stop */
2161                         if (device_state.stop) {
2162                                 ast_mutex_unlock(&device_state.lock);
2163                                 return NULL;
2164                         }
2165                 }
2166                 ast_mutex_unlock(&device_state.lock);
2167
2168                 handle_statechange(sc->dev);
2169
2170                 ast_free(sc);
2171         }
2172
2173         return NULL;
2174 }
2175
2176 /*! \brief  Add watcher for extension states */
2177 int ast_extension_state_add(const char *context, const char *exten,
2178                             ast_state_cb_type callback, void *data)
2179 {
2180         struct ast_hint *hint;
2181         struct ast_state_cb *cblist;
2182         struct ast_exten *e;
2183
2184         /* If there's no context and extension:  add callback to statecbs list */
2185         if (!context && !exten) {
2186                 AST_RWLIST_WRLOCK(&hints);
2187
2188                 for (cblist = statecbs; cblist; cblist = cblist->next) {
2189                         if (cblist->callback == callback) {
2190                                 cblist->data = data;
2191                                 AST_RWLIST_UNLOCK(&hints);
2192                                 return 0;
2193                         }
2194                 }
2195
2196                 /* Now insert the callback */
2197                 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
2198                         AST_RWLIST_UNLOCK(&hints);
2199                         return -1;
2200                 }
2201                 cblist->id = 0;
2202                 cblist->callback = callback;
2203                 cblist->data = data;
2204
2205                 cblist->next = statecbs;
2206                 statecbs = cblist;
2207
2208                 AST_RWLIST_UNLOCK(&hints);
2209                 return 0;
2210         }
2211
2212         if (!context || !exten)
2213                 return -1;
2214
2215         /* This callback type is for only one hint, so get the hint */
2216         e = ast_hint_extension(NULL, context, exten);
2217         if (!e) {
2218                 return -1;
2219         }
2220
2221         /* Find the hint in the list of hints */
2222         AST_RWLIST_WRLOCK(&hints);
2223
2224         AST_RWLIST_TRAVERSE(&hints, hint, list) {
2225                 if (hint->exten == e)
2226                         break;
2227         }
2228
2229         if (!hint) {
2230                 /* We have no hint, sorry */
2231                 AST_RWLIST_UNLOCK(&hints);
2232                 return -1;
2233         }
2234
2235         /* Now insert the callback in the callback list  */
2236         if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
2237                 AST_RWLIST_UNLOCK(&hints);
2238                 return -1;
2239         }
2240         cblist->id = stateid++;         /* Unique ID for this callback */
2241         cblist->callback = callback;    /* Pointer to callback routine */
2242         cblist->data = data;            /* Data for the callback */
2243
2244         cblist->next = hint->callbacks;
2245         hint->callbacks = cblist;
2246
2247         AST_RWLIST_UNLOCK(&hints);
2248         return cblist->id;
2249 }
2250
2251 /*! \brief Remove a watcher from the callback list */
2252 int ast_extension_state_del(int id, ast_state_cb_type callback)
2253 {
2254         struct ast_state_cb **p_cur = NULL;     /* address of pointer to us */
2255         int ret = -1;
2256
2257         if (!id && !callback)
2258                 return -1;
2259
2260         AST_RWLIST_WRLOCK(&hints);
2261
2262         if (!id) {      /* id == 0 is a callback without extension */
2263                 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
2264                         if ((*p_cur)->callback == callback)
2265                                 break;
2266                 }
2267         } else { /* callback with extension, find the callback based on ID */
2268                 struct ast_hint *hint;
2269                 AST_RWLIST_TRAVERSE(&hints, hint, list) {
2270                         for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
2271                                 if ((*p_cur)->id == id)
2272                                         break;
2273                         }
2274                         if (*p_cur)     /* found in the inner loop */
2275                                 break;
2276                 }
2277         }
2278         if (p_cur && *p_cur) {
2279                 struct ast_state_cb *cur = *p_cur;
2280                 *p_cur = cur->next;
2281                 ast_free(cur);
2282                 ret = 0;
2283         }
2284         AST_RWLIST_UNLOCK(&hints);
2285         return ret;
2286 }
2287
2288 /*! \brief Add hint to hint list, check initial extension state */
2289 static int ast_add_hint(struct ast_exten *e)
2290 {
2291         struct ast_hint *hint;
2292
2293         if (!e)
2294                 return -1;
2295
2296         AST_RWLIST_WRLOCK(&hints);
2297
2298         /* Search if hint exists, do nothing */
2299         AST_RWLIST_TRAVERSE(&hints, hint, list) {
2300                 if (hint->exten == e) {
2301                         AST_RWLIST_UNLOCK(&hints);
2302                         ast_debug(2, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
2303                         return -1;
2304                 }
2305         }
2306
2307         ast_debug(2, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
2308
2309         if (!(hint = ast_calloc(1, sizeof(*hint)))) {
2310                 AST_RWLIST_UNLOCK(&hints);
2311                 return -1;
2312         }
2313         /* Initialize and insert new item at the top */
2314         hint->exten = e;
2315         hint->laststate = ast_extension_state2(e);
2316         AST_RWLIST_INSERT_HEAD(&hints, hint, list);
2317
2318         AST_RWLIST_UNLOCK(&hints);
2319         return 0;
2320 }
2321
2322 /*! \brief Change hint for an extension */
2323 static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
2324 {
2325         struct ast_hint *hint;
2326         int res = -1;
2327
2328         AST_RWLIST_WRLOCK(&hints);
2329         AST_RWLIST_TRAVERSE(&hints, hint, list) {
2330                 if (hint->exten == oe) {
2331                         hint->exten = ne;
2332                         res = 0;
2333                         break;
2334                 }
2335         }
2336         AST_RWLIST_UNLOCK(&hints);
2337
2338         return res;
2339 }
2340
2341 /*! \brief Remove hint from extension */
2342 static int ast_remove_hint(struct ast_exten *e)
2343 {
2344         /* Cleanup the Notifys if hint is removed */
2345         struct ast_hint *hint;
2346         struct ast_state_cb *cblist, *cbprev;
2347         int res = -1;
2348
2349         if (!e)
2350                 return -1;
2351
2352         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) {
2353                 if (hint->exten == e) {
2354                         cbprev = NULL;
2355                         cblist = hint->callbacks;
2356                         while (cblist) {
2357                                 /* Notify with -1 and remove all callbacks */
2358                                 cbprev = cblist;
2359                                 cblist = cblist->next;
2360                                 cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data);
2361                                 ast_free(cbprev);
2362                         }
2363                         hint->callbacks = NULL;
2364                         AST_RWLIST_REMOVE_CURRENT(&hints, list);
2365                         ast_free(hint);
2366                         res = 0;
2367                         break;
2368                 }
2369         }
2370         AST_RWLIST_TRAVERSE_SAFE_END
2371
2372         return res;
2373 }
2374
2375
2376 /*! \brief Get hint for channel */
2377 int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
2378 {
2379         struct ast_exten *e = ast_hint_extension(c, context, exten);
2380
2381         if (e) {
2382                 if (hint)
2383                         ast_copy_string(hint, ast_get_extension_app(e), hintsize);
2384                 if (name) {
2385                         const char *tmp = ast_get_extension_app_data(e);
2386                         if (tmp)
2387                                 ast_copy_string(name, tmp, namesize);
2388                 }
2389                 return -1;
2390         }
2391         return 0;
2392 }
2393
2394 int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
2395 {
2396         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
2397 }
2398
2399 int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
2400 {
2401         return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
2402 }
2403
2404 int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
2405 {
2406         return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
2407 }
2408
2409 int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
2410 {
2411         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
2412 }
2413
2414 int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
2415 {
2416         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
2417 }
2418
2419 int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid, int *found, int combined_find_spawn)
2420 {
2421         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
2422 }
2423
2424 /*! helper function to set extension and priority */
2425 static void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
2426 {
2427         ast_copy_string(c->exten, exten, sizeof(c->exten));
2428         c->priority = pri;
2429 }
2430
2431 /*!
2432  * \brief collect digits from the channel into the buffer.
2433  * \retval 0 on timeout or done.
2434  * \retval -1 on error.
2435 */
2436 static int collect_digits(struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
2437 {
2438         int digit;
2439
2440         buf[pos] = '\0';        /* make sure it is properly terminated */
2441         while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) {
2442                 /* As long as we're willing to wait, and as long as it's not defined,
2443                    keep reading digits until we can't possibly get a right answer anymore.  */
2444                 digit = ast_waitfordigit(c, waittime * 1000);
2445                 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
2446                         c->_softhangup = 0;
2447                 } else {
2448                         if (!digit)     /* No entry */
2449                                 break;
2450                         if (digit < 0)  /* Error, maybe a  hangup */
2451                                 return -1;
2452                         if (pos < buflen - 1) { /* XXX maybe error otherwise ? */
2453                                 buf[pos++] = digit;
2454                                 buf[pos] = '\0';
2455                         }
2456                         waittime = c->pbx->dtimeout;
2457                 }
2458         }
2459         return 0;
2460 }
2461
2462 static int __ast_pbx_run(struct ast_channel *c)
2463 {
2464         int found = 0;  /* set if we find at least one match */
2465         int res = 0;
2466         int autoloopflag;
2467         int error = 0;          /* set an error conditions */
2468
2469         /* A little initial setup here */
2470         if (c->pbx) {
2471                 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
2472                 /* XXX and now what ? */
2473                 ast_free(c->pbx);
2474         }
2475         if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx))))
2476                 return -1;
2477         if (c->amaflags) {
2478                 if (!c->cdr) {
2479                         c->cdr = ast_cdr_alloc();
2480                         if (!c->cdr) {
2481                                 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
2482                                 ast_free(c->pbx);
2483                                 return -1;
2484                         }
2485                         ast_cdr_init(c->cdr, c);
2486                 }
2487         }
2488         /* Set reasonable defaults */
2489         c->pbx->rtimeout = 10;
2490         c->pbx->dtimeout = 5;
2491
2492         autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP);  /* save value to restore at the end */
2493         ast_set_flag(c, AST_FLAG_IN_AUTOLOOP);
2494
2495         /* Start by trying whatever the channel is set to */
2496         if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
2497                 /* If not successful fall back to 's' */
2498                 ast_verb(2, "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
2499                 /* XXX the original code used the existing priority in the call to
2500                  * ast_exists_extension(), and reset it to 1 afterwards.
2501                  * I believe the correct thing is to set it to 1 immediately.
2502                  */
2503                 set_ext_pri(c, "s", 1);
2504                 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
2505                         /* JK02: And finally back to default if everything else failed */
2506                         ast_verb(2, "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
2507                         ast_copy_string(c->context, "default", sizeof(c->context));
2508                 }
2509         }
2510         if (c->cdr && ast_tvzero(c->cdr->start))
2511                 ast_cdr_start(c->cdr);
2512         for (;;) {
2513                 char dst_exten[256];    /* buffer to accumulate digits */
2514                 int pos = 0;            /* XXX should check bounds */
2515                 int digit = 0;
2516
2517                 /* loop on priorities in this context/exten */
2518                 while ( !(res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found,1))) {
2519                         if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "T", 1, c->cid.cid_num)) {
2520                                 set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */
2521                                 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
2522                                 c->whentohangup = 0;
2523                                 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
2524                         } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
2525                                 pbx_builtin_raise_exception(c, "ABSOLUTETIMEOUT");
2526                                 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
2527                                 c->whentohangup = 0;
2528                                 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
2529                         } else if (ast_check_hangup(c)) {
2530                                 ast_debug(1, "Extension %s, priority %d returned normally even though call was hung up\n",
2531                                         c->exten, c->priority);
2532                                 error = 1;
2533                                 break;
2534                         }
2535                         c->priority++;
2536                 } /* end while  - from here on we can use 'break' to go out */
2537                 if (found && res) {
2538                         /* Something bad happened, or a hangup has been requested. */
2539                         if (strchr("0123456789ABCDEF*#", res)) {
2540                                 ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res);
2541                                 pos = 0;
2542                                 dst_exten[pos++] = digit = res;
2543                                 dst_exten[pos] = '\0';
2544                         }
2545                         if (res == AST_PBX_KEEPALIVE) {
2546                                 ast_debug(1, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
2547                                 ast_verb(2, "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
2548                                 error = 1;
2549                         }
2550                         ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2551                         ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2552                         
2553                         if ((res == AST_PBX_ERROR) && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
2554                                 /* if we are already on the 'e' exten, don't jump to it again */
2555                                 if (!strcmp(c->exten, "e")) {
2556                                         if (option_verbose > 1)
2557                                                 ast_verbose(VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s'\n", c->context, c->exten, c->priority, c->name);
2558                                         error = 1;
2559                                 } else {
2560                                         pbx_builtin_raise_exception(c, "ERROR");
2561                                         continue;
2562                                 }
2563                         }
2564                         
2565                         if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
2566                                 c->_softhangup = 0;
2567                         } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
2568                                 /* atimeout, nothing bad */
2569                         } else {
2570                                 if (c->cdr)
2571                                         ast_cdr_update(c);
2572                                 error = 1;
2573                                 break;
2574                         }
2575                 }
2576                 if (error)
2577                         break;
2578
2579                 /*!\note
2580                  * We get here on a failure of some kind:  non-existing extension or
2581                  * hangup.  We have options, here.  We can either catch the failure
2582                  * and continue, or we can drop out entirely. */
2583
2584                 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
2585                         /*!\note
2586                          * If there is no match at priority 1, it is not a valid extension anymore.
2587                          * Try to continue at "i" (for invalid) or "e" (for exception) or exit if
2588                          * neither exist.
2589                          */
2590                         if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
2591                                 ast_verb(3, "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
2592                                 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
2593                                 set_ext_pri(c, "i", 1);
2594                         } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
2595                                 pbx_builtin_raise_exception(c, "INVALID");
2596                         } else {
2597                                 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
2598                                         c->name, c->exten, c->context);
2599                                 error = 1; /* we know what to do with it */
2600                                 break;
2601                         }
2602                 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
2603                         /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
2604                         c->_softhangup = 0;
2605                 } else {        /* keypress received, get more digits for a full extension */
2606                         int waittime = 0;
2607                         if (digit)
2608                                 waittime = c->pbx->dtimeout;
2609                         else if (!autofallthrough)
2610                                 waittime = c->pbx->rtimeout;
2611                         if (!waittime) {
2612                                 const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
2613                                 if (!status)
2614                                         status = "UNKNOWN";
2615                                 ast_verb(3, "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status);
2616                                 if (!strcasecmp(status, "CONGESTION"))
2617                                         res = pbx_builtin_congestion(c, "10");
2618                                 else if (!strcasecmp(status, "CHANUNAVAIL"))
2619                                         res = pbx_builtin_congestion(c, "10");
2620                                 else if (!strcasecmp(status, "BUSY"))
2621                                         res = pbx_builtin_busy(c, "10");
2622                                 error = 1; /* XXX disable message */
2623                                 break;  /* exit from the 'for' loop */
2624                         }
2625
2626                         if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos))
2627                                 break;
2628                         if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */
2629                                 set_ext_pri(c, dst_exten, 1);
2630                         else {
2631                                 /* No such extension */
2632                                 if (!ast_strlen_zero(dst_exten)) {
2633                                         /* An invalid extension */
2634                                         if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
2635                                                 ast_verb(3, "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name);
2636                                                 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
2637                                                 set_ext_pri(c, "i", 1);
2638                                         } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
2639                                                 pbx_builtin_raise_exception(c, "INVALID");
2640                                         } else {
2641                                                 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context);
2642                                                 found = 1; /* XXX disable message */
2643                                                 break;
2644                                         }
2645                                 } else {
2646                                         /* A simple timeout */
2647                                         if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) {
2648                                                 ast_verb(3, "Timeout on %s\n", c->name);
2649                                                 set_ext_pri(c, "t", 1);
2650                                         } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
2651                                                 pbx_builtin_raise_exception(c, "RESPONSETIMEOUT");
2652                                         } else {
2653                                                 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
2654                                                 found = 1; /* XXX disable message */
2655                                                 break;
2656                                         }
2657                                 }
2658                         }
2659                         if (c->cdr) {
2660                                 ast_verb(2, "CDR updated on %s\n",c->name);
2661                                 ast_cdr_update(c);
2662                         }
2663                 }
2664         }
2665         if (!found && !error)
2666                 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
2667         if (res != AST_PBX_KEEPALIVE)
2668                 ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING);
2669         if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
2670                 if (c->cdr && ast_opt_end_cdr_before_h_exten)
2671                         ast_cdr_end(c->cdr);
2672                 set_ext_pri(c, "h", 1);
2673                 while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found, 1)) == 0) {
2674                         c->priority++;
2675                 }
2676                 if (found && res) {
2677                         /* Something bad happened, or a hangup has been requested. */
2678                         ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2679                         ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2680                 }
2681         }
2682         ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP);
2683
2684         pbx_destroy(c->pbx);
2685         c->pbx = NULL;
2686         if (res != AST_PBX_KEEPALIVE)
2687                 ast_hangup(c);
2688         return 0;
2689 }
2690
2691 /*! 
2692  * \brief Increase call count for channel
2693  * \retval 0 on success
2694  * \retval non-zero if a configured limit (maxcalls, maxload, minmemfree) was reached 
2695 */
2696 static int increase_call_count(const struct ast_channel *c)
2697 {
2698         int failed = 0;
2699         double curloadavg;
2700 #if defined(HAVE_SYSINFO)
2701         long curfreemem;
2702         struct sysinfo sys_info;
2703 #endif
2704
2705         ast_mutex_lock(&maxcalllock);
2706         if (option_maxcalls) {
2707                 if (countcalls >= option_maxcalls) {
2708                         ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name);
2709                         failed = -1;
2710                 }
2711         }
2712         if (option_maxload) {
2713                 getloadavg(&curloadavg, 1);
2714                 if (curloadavg >= option_maxload) {
2715                         ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg);
2716                         failed = -1;
2717                 }
2718         }
2719 #if defined(HAVE_SYSINFO)
2720         if (option_minmemfree) {
2721                 if (!sysinfo(&sys_info)) {
2722                         /* make sure that the free system memory is above the configured low watermark
2723                          * convert the amount of freeram from mem_units to MB */
2724                         curfreemem = sys_info.freeram / sys_info.mem_unit; 
2725                         curfreemem /= 1024*1024; 
2726                         if (curfreemem < option_minmemfree) {
2727                                 ast_log(LOG_WARNING, "Available system memory (~%ldMB) is below the configured low watermark (%ldMB)\n", curfreemem, option_minmemfree);
2728                                 failed = -1;
2729                         }
2730                 }
2731         }
2732 #endif
2733                 
2734         if (!failed)
2735                 countcalls++;
2736         ast_mutex_unlock(&maxcalllock);
2737
2738         return failed;
2739 }
2740
2741 static void decrease_call_count(void)
2742 {
2743         ast_mutex_lock(&maxcalllock);
2744         if (countcalls > 0)
2745                 countcalls--;
2746         ast_mutex_unlock(&maxcalllock);
2747 }
2748
2749 static void destroy_exten(struct ast_exten *e)
2750 {
2751         if (e->priority == PRIORITY_HINT)
2752                 ast_remove_hint(e);
2753
2754         if (e->datad)
2755                 e->datad(e->data);
2756         ast_free(e);
2757 }
2758
2759 static void *pbx_thread(void *data)
2760 {
2761         /* Oh joyeous kernel, we're a new thread, with nothing to do but
2762            answer this channel and get it going.
2763         */
2764         /* NOTE:
2765            The launcher of this function _MUST_ increment 'countcalls'
2766            before invoking the function; it will be decremented when the
2767            PBX has finished running on the channel
2768          */
2769         struct ast_channel *c = data;
2770
2771         __ast_pbx_run(c);
2772         decrease_call_count();
2773
2774         pthread_exit(NULL);
2775
2776         return NULL;
2777 }
2778
2779 enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
2780 {
2781         pthread_t t;
2782
2783         if (!c) {
2784                 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
2785                 return AST_PBX_FAILED;
2786         }
2787
2788         if (increase_call_count(c))
2789                 return AST_PBX_CALL_LIMIT;
2790
2791         /* Start a new thread, and get something handling this channel. */
2792         if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) {
2793                 ast_log(LOG_WARNING, "Failed to create new channel thread\n");
2794                 return AST_PBX_FAILED;
2795         }
2796
2797         return AST_PBX_SUCCESS;
2798 }
2799
2800 enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
2801 {
2802         enum ast_pbx_result res = AST_PBX_SUCCESS;
2803
2804         if (increase_call_count(c))
2805                 return AST_PBX_CALL_LIMIT;
2806
2807         res = __ast_pbx_run(c);
2808         decrease_call_count();
2809
2810         return res;
2811 }
2812
2813 int ast_active_calls(void)
2814 {
2815         return countcalls;
2816 }
2817
2818 int pbx_set_autofallthrough(int newval)
2819 {
2820         int oldval = autofallthrough;
2821         autofallthrough = newval;
2822         return oldval;
2823 }
2824
2825 /*!
2826  * \brief lookup for a context with a given name,
2827  * \retval with conlock held if found.
2828  * \retval NULL if not found.
2829 */
2830 static struct ast_context *find_context_locked(const char *context)
2831 {
2832         struct ast_context *c = NULL;
2833
2834         ast_rdlock_contexts();
2835         while ( (c = ast_walk_contexts(c)) ) {
2836                 if (!strcmp(ast_get_context_name(c), context))
2837                         return c;
2838         }
2839         ast_unlock_contexts();
2840
2841         return NULL;
2842 }
2843
2844 /*!
2845  * \brief Remove included contexts.
2846  * This function locks contexts list by &conlist, search for the right context
2847  * structure, leave context list locked and call ast_context_remove_include2
2848  * which removes include, unlock contexts list and return ...
2849 */
2850 int ast_context_remove_include(const char *context, const char *include, const char *registrar)
2851 {
2852         int ret = -1;
2853         struct ast_context *c = find_context_locked(context);
2854
2855         if (c) {
2856                 /* found, remove include from this context ... */
2857                 ret = ast_context_remove_include2(c, include, registrar);
2858                 ast_unlock_contexts();
2859         }
2860         return ret;
2861 }
2862
2863 /*!
2864  * \brief Locks context, remove included contexts, unlocks context.
2865  * When we call this function, &conlock lock must be locked, because when
2866  * we giving *con argument, some process can remove/change this context
2867  * and after that there can be segfault.
2868  *
2869  * \retval 0 on success.
2870  * \retval -1 on failure.
2871  */
2872 int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
2873 {
2874         struct ast_include *i, *pi = NULL;
2875         int ret = -1;
2876
2877         ast_wrlock_context(con);
2878
2879         /* find our include */
2880         for (i = con->includes; i; pi = i, i = i->next) {
2881                 if (!strcmp(i->name, include) &&
2882                                 (!registrar || !strcmp(i->registrar, registrar))) {
2883                         /* remove from list */
2884                         if (pi)
2885                                 pi->next = i->next;
2886                         else
2887                                 con->includes = i->next;
2888                         /* free include and return */
2889                         ast_free(i);
2890                         ret = 0;
2891                         break;
2892                 }
2893         }
2894
2895         ast_unlock_context(con);
2896
2897         return ret;
2898 }
2899
2900 /*!
2901  * \note This function locks contexts list by &conlist, search for the rigt context
2902  * structure, leave context list locked and call ast_context_remove_switch2
2903  * which removes switch, unlock contexts list and return ...
2904  */
2905 int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar)
2906 {
2907         int ret = -1; /* default error return */
2908         struct ast_context *c = find_context_locked(context);
2909
2910         if (c) {
2911                 /* remove switch from this context ... */
2912                 ret = ast_context_remove_switch2(c, sw, data, registrar);
2913                 ast_unlock_contexts();
2914         }
2915         return ret;
2916 }
2917
2918 /*!
2919  * \brief This function locks given context, removes switch, unlock context and
2920  * return.
2921  * \note When we call this function, &conlock lock must be locked, because when
2922  * we giving *con argument, some process can remove/change this context
2923  * and after that there can be segfault.
2924  *
2925  */
2926 int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
2927 {
2928         struct ast_sw *i;
2929         int ret = -1;
2930
2931         ast_wrlock_context(con);
2932
2933         /* walk switches */
2934         AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
2935                 if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
2936                         (!registrar || !strcmp(i->registrar, registrar))) {
2937                         /* found, remove from list */
2938                         AST_LIST_REMOVE_CURRENT(&con->alts, list);
2939                         ast_free(i); /* free switch and return */
2940                         ret = 0;
2941                         break;
2942                 }
2943         }
2944         AST_LIST_TRAVERSE_SAFE_END
2945
2946         ast_unlock_context(con);
2947
2948         return ret;
2949 }
2950
2951 /*
2952  * \note This functions lock contexts list, search for the right context,
2953  * call ast_context_remove_extension2, unlock contexts list and return.
2954  * In this function we are using
2955  */
2956 int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
2957 {
2958         int ret = -1; /* default error return */
2959         struct ast_context *c = find_context_locked(context);
2960
2961         if (c) { /* ... remove extension ... */
2962                 ret = ast_context_remove_extension2(c, extension, priority, registrar);
2963                 ast_unlock_contexts();
2964         }
2965         return ret;
2966 }
2967
2968 /*!
2969  * \brief This functionc locks given context, search for the right extension and
2970  * fires out all peer in this extensions with given priority. If priority
2971  * is set to 0, all peers are removed. After that, unlock context and
2972  * return.
2973  * \note When do you want to call this function, make sure that &conlock is locked,
2974  * because some process can handle with your *con context before you lock
2975  * it.
2976  *
2977  */
2978 int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar)
2979 {
2980         struct ast_exten *exten, *prev_exten = NULL;
2981         struct ast_exten *peer;
2982
2983         ast_wrlock_context(con);
2984
2985         /* scan the extension list to find matching extension-registrar */
2986         for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
2987                 if (!strcmp(exten->exten, extension) &&
2988                         (!registrar || !strcmp(exten->registrar, registrar)))
2989                         break;
2990         }
2991         if (!exten) {
2992                 /* we can't find right extension */
2993                 ast_unlock_context(con);
2994                 return -1;
2995         }
2996
2997         /* should we free all peers in this extension? (priority == 0)? */
2998         if (priority == 0) {
2999                 /* remove this extension from context list */
3000                 if (prev_exten)
3001                         prev_exten->next = exten->next;
3002                 else
3003                         con->root = exten->next;
3004
3005                 /* fire out all peers */
3006                 while ( (peer = exten) ) {
3007                         exten = peer->peer; /* prepare for next entry */
3008                         destroy_exten(peer);
3009                 }
3010         } else {
3011                 /* scan the priority list to remove extension with exten->priority == priority */
3012                 struct ast_exten *previous_peer = NULL;
3013
3014                 for (peer = exten; peer; previous_peer = peer, peer = peer->peer) {
3015                         if (peer->priority == priority &&
3016                                         (!registrar || !strcmp(peer->registrar, registrar) ))
3017                                 break; /* found our priority */
3018                 }
3019                 if (!peer) { /* not found */
3020                         ast_unlock_context(con);
3021                         return -1;
3022                 }
3023                 /* we are first priority extension? */
3024                 if (!previous_peer) {
3025                         /*
3026                          * We are first in the priority chain, so must update the extension chain.
3027                          * The next node is either the next priority or the next extension
3028                          */
3029                         struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
3030
3031                         if (!prev_exten)        /* change the root... */
3032                                 con->root = next_node;
3033                         else
3034                                 prev_exten->next = next_node; /* unlink */
3035                         if (peer->peer) /* XXX update the new head of the pri list */
3036                                 peer->peer->next = peer->next;
3037                 } else { /* easy, we are not first priority in extension */
3038                         previous_peer->peer = peer->peer;
3039                 }
3040
3041                 /* now, free whole priority extension */
3042                 destroy_exten(peer);
3043                 /* XXX should we return -1 ? */
3044         }
3045         ast_unlock_context(con);
3046         return 0;
3047 }
3048
3049
3050 /*!
3051  * \note This function locks contexts list by &conlist, searches for the right context
3052  * structure, and locks the macrolock mutex in that context.
3053  * macrolock is used to limit a macro to be executed by one call at a time.
3054  */
3055 int ast_context_lockmacro(const char *context)
3056 {
3057         struct ast_context *c = NULL;
3058         int ret = -1;
3059
3060         ast_rdlock_contexts();
3061
3062         while ((c = ast_walk_contexts(c))) {
3063                 if (!strcmp(ast_get_context_name(c), context)) {
3064                         ret = 0;
3065                         break;
3066                 }
3067         }
3068
3069         ast_unlock_contexts();
3070
3071         /* if we found context, lock macrolock */
3072         if (ret == 0) 
3073                 ret = ast_mutex_lock(&c->macrolock);
3074
3075         return ret;
3076 }
3077
3078 /*!
3079  * \note This function locks contexts list by &conlist, searches for the right context
3080  * structure, and unlocks the macrolock mutex in that context.
3081  * macrolock is used to limit a macro to be executed by one call at a time.
3082  */
3083 int ast_context_unlockmacro(const char *context)
3084 {
3085         struct ast_context *c = NULL;
3086         int ret = -1;
3087
3088         ast_rdlock_contexts();
3089
3090         while ((c = ast_walk_contexts(c))) {
3091                 if (!strcmp(ast_get_context_name(c), context)) {
3092                         ret = 0;
3093                         break;
3094                 }
3095         }
3096
3097         ast_unlock_contexts();
3098
3099         /* if we found context, unlock macrolock */
3100         if (ret == 0) 
3101                 ret = ast_mutex_unlock(&c->macrolock);
3102
3103         return ret;
3104 }
3105
3106 /*! \brief Dynamically register a new dial plan application */
3107 int ast_register_application2(const char *app, int (*execute)(struct ast_channel *, void *), const char *synopsis, const char *description, void *mod)
3108 {
3109         struct ast_app *tmp, *cur = NULL;
3110         char tmps[80];
3111         int length, res;
3112
3113         AST_RWLIST_WRLOCK(&apps);
3114         AST_RWLIST_TRAVERSE(&apps, tmp, list) {
3115                 if (!(res = strcasecmp(app, tmp->name))) {
3116                         ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
3117                         AST_RWLIST_UNLOCK(&apps);
3118                         return -1;
3119                 } else if (res < 0)
3120                         break;
3121         }
3122
3123         length = sizeof(*tmp) + strlen(app) + 1;
3124
3125         if (!(tmp = ast_calloc(1, length))) {
3126                 AST_RWLIST_UNLOCK(&apps);
3127                 return -1;
3128         }
3129
3130         strcpy(tmp->name, app);
3131         tmp->execute = execute;
3132         tmp->synopsis = synopsis;
3133         tmp->description = description;
3134         tmp->module = mod;
3135
3136         /* Store in alphabetical order */
3137         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {