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