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