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