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