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