add MD5 and CHECK_MD5 functions, deprecate MD5 and MD5Check apps (bug #4123)
[asterisk/asterisk.git] / pbx.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Core PBX routines.
5  * 
6  * Copyright (C) 1999 - 2005, Digium, Inc.
7  *
8  * Mark Spencer <markster@digium.com>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <sys/types.h>
15 #include <regex.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <setjmp.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <time.h>
24 #include <sys/time.h>
25
26 #include "asterisk/lock.h"
27 #include "asterisk/cli.h"
28 #include "asterisk/pbx.h"
29 #include "asterisk/channel.h"
30 #include "asterisk/options.h"
31 #include "asterisk/logger.h"
32 #include "asterisk/file.h"
33 #include "asterisk/callerid.h"
34 #include "asterisk/cdr.h"
35 #include "asterisk/config.h"
36 #include "asterisk/term.h"
37 #include "asterisk/manager.h"
38 #include "asterisk/ast_expr.h"
39 #include "asterisk/linkedlists.h"
40 #include "asterisk/say.h"
41 #include "asterisk/utils.h"
42 #include "asterisk/causes.h"
43 #include "asterisk/musiconhold.h"
44 #include "asterisk/app.h"
45 #include "asterisk.h"
46
47 /*
48  * I M P O R T A N T :
49  *
50  *              The speed of extension handling will likely be among the most important
51  * aspects of this PBX.  The switching scheme as it exists right now isn't
52  * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
53  * of priorities, but a constant search time here would be great ;-) 
54  *
55  */
56
57 #ifdef LOW_MEMORY
58 #define EXT_DATA_SIZE 256
59 #else
60 #define EXT_DATA_SIZE 8192
61 #endif
62
63 #define SWITCH_DATA_LENGTH 256
64
65
66 #define VAR_NORMAL              1
67 #define VAR_SOFTTRAN    2
68 #define VAR_HARDTRAN    3
69
70 #define BACKGROUND_SKIP         (1 << 0)
71 #define BACKGROUND_NOANSWER     (1 << 1)
72
73 AST_DECLARE_OPTIONS(background_opts,{
74         ['s'] = { BACKGROUND_SKIP },
75         ['n'] = { BACKGROUND_NOANSWER },
76 });
77
78 #define WAITEXTEN_MOH           (1 << 0)
79
80 AST_DECLARE_OPTIONS(waitexten_opts,{
81         ['m'] = { WAITEXTEN_MOH, 1 },
82 });
83
84 struct ast_context;
85
86 /* ast_exten: An extension */
87 struct ast_exten {
88         char *exten;                    /* Extension name */
89         int matchcid;                   /* Match caller id ? */
90         char *cidmatch;                 /* Caller id to match for this extension */
91         int priority;                   /* Priority */
92         char *label;                    /* Label */
93         struct ast_context *parent;     /* The context this extension belongs to  */
94         char *app;                      /* Application to execute */
95         void *data;                     /* Data to use (arguments) */
96         void (*datad)(void *);          /* Data destructor */
97         struct ast_exten *peer;         /* Next higher priority with our extension */
98         const char *registrar;          /* Registrar */
99         struct ast_exten *next;         /* Extension with a greater ID */
100         char stuff[0];
101 };
102
103 /* ast_include: include= support in extensions.conf */
104 struct ast_include {
105         char *name;             
106         char *rname;            /* Context to include */
107         const char *registrar;                  /* Registrar */
108         int hastime;                            /* If time construct exists */
109         struct ast_timing timing;               /* time construct */
110         struct ast_include *next;               /* Link them together */
111         char stuff[0];
112 };
113
114 /* ast_sw: Switch statement in extensions.conf */
115 struct ast_sw {
116         char *name;
117         const char *registrar;                  /* Registrar */
118         char *data;                             /* Data load */
119         int eval;
120         struct ast_sw *next;                    /* Link them together */
121         char *tmpdata;
122         char stuff[0];
123 };
124
125 struct ast_ignorepat {
126         const char *registrar;
127         struct ast_ignorepat *next;
128         char pattern[0];
129 };
130
131 /* ast_context: An extension context */
132 struct ast_context {
133         ast_mutex_t lock;                       /* A lock to prevent multiple threads from clobbering the context */
134         struct ast_exten *root;                 /* The root of the list of extensions */
135         struct ast_context *next;               /* Link them together */
136         struct ast_include *includes;           /* Include other contexts */
137         struct ast_ignorepat *ignorepats;       /* Patterns for which to continue playing dialtone */
138         const char *registrar;                  /* Registrar */
139         struct ast_sw *alts;                    /* Alternative switches */
140         char name[0];                           /* Name of the context */
141 };
142
143
144 /* ast_app: An application */
145 struct ast_app {
146         int (*execute)(struct ast_channel *chan, void *data);
147         const char *synopsis;                   /* Synopsis text for 'show applications' */
148         const char *description;                /* Description (help text) for 'show application <name>' */
149         struct ast_app *next;                   /* Next app in list */
150         char name[0];                           /* Name of the application */
151 };
152
153 /* ast_state_cb: An extension state notify */
154 struct ast_state_cb {
155         int id;
156         void *data;
157         ast_state_cb_type callback;
158         struct ast_state_cb *next;
159 };
160             
161 /* ast_devstate_cb: An extension state notify */
162 struct ast_devstate_cb {
163         void *data;
164         ast_devstate_cb_type callback;
165         struct ast_devstate_cb *next;
166 };
167
168 static struct ast_devstate_cb *devcbs;
169
170 /* Hints are pointers from an extension in the dialplan to one or more devices (tech/name) */
171 struct ast_hint {
172         struct ast_exten *exten;        /* Extension */
173         int laststate;                  /* Last known state */
174         struct ast_state_cb *callbacks; /* Callback list for this extension */
175         struct ast_hint *next;          /* Pointer to next hint in list */
176 };
177
178 int ast_pbx_outgoing_cdr_failed(void);
179
180 static int pbx_builtin_prefix(struct ast_channel *, void *);
181 static int pbx_builtin_suffix(struct ast_channel *, void *);
182 static int pbx_builtin_stripmsd(struct ast_channel *, void *);
183 static int pbx_builtin_answer(struct ast_channel *, void *);
184 static int pbx_builtin_goto(struct ast_channel *, void *);
185 static int pbx_builtin_hangup(struct ast_channel *, void *);
186 static int pbx_builtin_background(struct ast_channel *, void *);
187 static int pbx_builtin_dtimeout(struct ast_channel *, void *);
188 static int pbx_builtin_rtimeout(struct ast_channel *, void *);
189 static int pbx_builtin_atimeout(struct ast_channel *, void *);
190 static int pbx_builtin_wait(struct ast_channel *, void *);
191 static int pbx_builtin_waitexten(struct ast_channel *, void *);
192 static int pbx_builtin_setlanguage(struct ast_channel *, void *);
193 static int pbx_builtin_resetcdr(struct ast_channel *, void *);
194 static int pbx_builtin_setaccount(struct ast_channel *, void *);
195 static int pbx_builtin_setamaflags(struct ast_channel *, void *);
196 static int pbx_builtin_ringing(struct ast_channel *, void *);
197 static int pbx_builtin_progress(struct ast_channel *, void *);
198 static int pbx_builtin_congestion(struct ast_channel *, void *);
199 static int pbx_builtin_busy(struct ast_channel *, void *);
200 static int pbx_builtin_setglobalvar(struct ast_channel *, void *);
201 static int pbx_builtin_noop(struct ast_channel *, void *);
202 static int pbx_builtin_gotoif(struct ast_channel *, void *);
203 static int pbx_builtin_gotoiftime(struct ast_channel *, void *);
204 static int pbx_builtin_execiftime(struct ast_channel *, void *);
205 static int pbx_builtin_saynumber(struct ast_channel *, void *);
206 static int pbx_builtin_saydigits(struct ast_channel *, void *);
207 static int pbx_builtin_saycharacters(struct ast_channel *, void *);
208 static int pbx_builtin_sayphonetic(struct ast_channel *, void *);
209 int pbx_builtin_setvar(struct ast_channel *, void *);
210 static int pbx_builtin_importvar(struct ast_channel *, void *);
211 static char *ast_func_read(struct ast_channel *chan, const char *in, char *workspace, size_t len);
212 static void ast_func_write(struct ast_channel *chan, const char *in, const char *value);
213
214 static struct varshead globals;
215
216 static int autofallthrough = 0;
217
218 static struct ast_custom_function_obj *acf_root = NULL;
219
220 static struct pbx_builtin {
221         char name[AST_MAX_APP];
222         int (*execute)(struct ast_channel *chan, void *data);
223         char *synopsis;
224         char *description;
225 } builtins[] = 
226 {
227         /* These applications are built into the PBX core and do not
228            need separate modules
229            
230             */
231
232         { "AbsoluteTimeout", pbx_builtin_atimeout,
233         "Set absolute maximum time of call",
234         "  AbsoluteTimeout(seconds): Set the absolute maximum amount of time permitted\n"
235         "for a call.  A setting of 0 disables the timeout.  Always returns 0.\n" 
236         },
237
238         { "Answer", pbx_builtin_answer, 
239         "Answer a channel if ringing", 
240         "  Answer([delay]): If the channel is ringing, answer it, otherwise do nothing. \n"
241         "If delay is specified, asterisk will pause execution for the specified amount\n"
242         "of milliseconds if an answer is required, in order to give audio a chance to\n"
243         "become ready. Returns 0 unless it tries to answer the channel and fails.\n"   
244         },
245
246         { "BackGround", pbx_builtin_background,
247         "Play a file while awaiting extension",
248         "  Background(filename1[&filename2...][|options[|langoverride]]): Plays\n"
249         "given files, while simultaneously waiting for the user to begin typing\n"
250         "an extension. The timeouts do not count until the last BackGround\n"
251         "application has ended. Options may also be included following a pipe \n"
252         "symbol. The 'langoverride' may be a language to use for playing the prompt\n"
253         "which differs from the current language of the channel. Returns -1 if \n"
254         "the channel was hung up, or if the file does not exist. Returns 0 otherwise.\n\n"
255         "  Options:\n"
256         "    's' - causes the playback of the message to be skipped\n"
257         "          if the channel is not in the 'up' state (i.e. it\n"
258         "          hasn't been answered yet.) If this happens, the\n"
259         "          application will return immediately.\n"
260         "    'n' - don't answer the channel before playing the files\n"
261         },
262
263         { "Busy", pbx_builtin_busy,
264         "Indicate busy condition and stop",
265         "  Busy([timeout]): Requests that the channel indicate busy condition and\n"
266         "then waits for the user to hang up or the optional timeout to expire.\n"
267         "Always returns -1." 
268         },
269
270         { "Congestion", pbx_builtin_congestion,
271         "Indicate congestion and stop",
272         "  Congestion([timeout]): Requests that the channel indicate congestion\n"
273         "and then waits for the user to hang up or for the optional timeout to\n"
274         "expire.  Always returns -1." 
275         },
276
277         { "DigitTimeout", pbx_builtin_dtimeout,
278         "Set maximum timeout between digits",
279         "  DigitTimeout(seconds): Set the maximum amount of time permitted between\n"
280         "digits when the user is typing in an extension. When this timeout expires,\n"
281         "after the user has started to type in an extension, the extension will be\n"
282         "considered complete, and will be interpreted. Note that if an extension\n"
283         "typed in is valid, it will not have to timeout to be tested, so typically\n"
284         "at the expiry of this timeout, the extension will be considered invalid\n"
285         "(and thus control would be passed to the 'i' extension, or if it doesn't\n"
286         "exist the call would be terminated). The default timeout is 5 seconds.\n"
287         "Always returns 0.\n" 
288         },
289
290         { "Goto", pbx_builtin_goto, 
291         "Goto a particular priority, extension, or context",
292         "  Goto([[context|]extension|]priority):  Set the  priority to the specified\n"
293         "value, optionally setting the extension and optionally the context as well.\n"
294         "The extension BYEXTENSION is special in that it uses the current extension,\n"
295         "thus  permitting you to go to a different context, without specifying a\n"
296         "specific extension. Always returns 0, even if the given context, extension,\n"
297         "or priority is invalid.\n" 
298         },
299
300         { "GotoIf", pbx_builtin_gotoif,
301         "Conditional goto",
302         "  GotoIf(Condition?label1:label2): Go to label 1 if condition is\n"
303         "true, to label2 if condition is false. Either label1 or label2 may be\n"
304         "omitted (in that case, we just don't take the particular branch) but not\n"
305         "both. Look for the condition syntax in examples or documentation." 
306         },
307
308         { "GotoIfTime", pbx_builtin_gotoiftime,
309         "Conditional goto on current time",
310         "  GotoIfTime(<times>|<weekdays>|<mdays>|<months>?[[context|]extension|]pri):\n"
311         "If the current time matches the specified time, then branch to the specified\n"
312         "extension. Each of the elements may be specified either as '*' (for always)\n"
313         "or as a range. See the 'include' syntax for details." 
314         },
315
316         { "ExecIfTime", pbx_builtin_execiftime,
317         "Conditional application execution on current time",
318         "  ExecIfTime(<times>|<weekdays>|<mdays>|<months>?<appname>[|<appdata>]):\n"
319         "If the current time matches the specified time, then execute the specified\n"
320         "application. Each of the elements may be specified either as '*' (for always)\n"
321         "or as a range. See the 'include' syntax for details. It will return whatever\n"
322         "<appname> returns, or a non-zero value if the application is not found.\n"
323         },
324         
325         { "Hangup", pbx_builtin_hangup,
326         "Unconditional hangup",
327         "  Hangup(): Unconditionally hangs up a given channel by returning -1 always.\n" 
328         },
329
330         { "NoOp", pbx_builtin_noop,
331         "No operation",
332         "  NoOp(): No-operation; Does nothing." 
333         },
334
335         { "Prefix", pbx_builtin_prefix, 
336         "Prepend leading digits",
337         "  Prefix(digits): Prepends the digit string specified by digits to the\n"
338         "channel's associated extension. For example, the number 1212 when prefixed\n"
339         "with '555' will become 5551212. This app always returns 0, and the PBX will\n"
340         "continue processing at the next priority for the *new* extension.\n"
341         "  So, for example, if priority  3  of 1212 is  Prefix  555, the next step\n"
342         "executed will be priority 4 of 5551212. If you switch into an extension\n"
343         "which has no first step, the PBX will treat it as though the user dialed an\n"
344         "invalid extension.\n" 
345         },
346
347         { "Progress", pbx_builtin_progress,
348         "Indicate progress",
349         "  Progress(): Request that the channel indicate in-band progress is \n"
350         "available to the user.\nAlways returns 0.\n" 
351         },
352
353         { "ResetCDR", pbx_builtin_resetcdr,
354         "Resets the Call Data Record",
355         "  ResetCDR([options]):  Causes the Call Data Record to be reset, optionally\n"
356         "storing the current CDR before zeroing it out\b"
357         " - if 'w' option is specified record will be stored.\n"
358         " - if 'a' option is specified any stacked records will be stored.\n"
359         " - if 'v' option is specified any variables will be saved.\n"
360         "Always returns 0.\n"  
361         },
362
363         { "ResponseTimeout", pbx_builtin_rtimeout,
364         "Set maximum timeout awaiting response",
365         "  ResponseTimeout(seconds): Set the maximum amount of time permitted after\n"
366         "falling through a series of priorities for a channel in which the user may\n"
367         "begin typing an extension. If the user does not type an extension in this\n"
368         "amount of time, control will pass to the 't' extension if it exists, and\n"
369         "if not the call would be terminated. The default timeout is 10 seconds.\n"
370         "Always returns 0.\n"  
371         },
372
373         { "Ringing", pbx_builtin_ringing,
374         "Indicate ringing tone",
375         "  Ringing(): Request that the channel indicate ringing tone to the user.\n"
376         "Always returns 0.\n" 
377         },
378
379         { "SayNumber", pbx_builtin_saynumber,
380         "Say Number",
381         "  SayNumber(digits[,gender]): Says the passed number. SayNumber is using\n" 
382         "the current language setting for the channel. (See app SetLanguage).\n"
383         },
384
385         { "SayDigits", pbx_builtin_saydigits,
386         "Say Digits",
387         "  SayDigits(digits): Says the passed digits. SayDigits is using the\n" 
388         "current language setting for the channel. (See app setLanguage)\n"
389         },
390
391         { "SayAlpha", pbx_builtin_saycharacters,
392         "Say Alpha",
393         "  SayAlpha(string): Spells the passed string\n" 
394         },
395
396         { "SayPhonetic", pbx_builtin_sayphonetic,
397         "Say Phonetic",
398         "  SayPhonetic(string): Spells the passed string with phonetic alphabet\n" 
399         },
400
401         { "SetAccount", pbx_builtin_setaccount,
402         "Sets account code",
403         "  SetAccount([account]): Set the channel account code for billing\n"
404         "purposes. Always returns 0.\n"
405         },
406
407         { "SetAMAFlags", pbx_builtin_setamaflags,
408         "Sets AMA Flags",
409         "  SetAMAFlags([flag]): Set the channel AMA Flags for billing\n"
410         "purposes. Always returns 0.\n"
411         },
412
413         { "SetGlobalVar", pbx_builtin_setglobalvar,
414         "Set global variable to value",
415         "  SetGlobalVar(#n=value): Sets global variable n to value. Global\n" 
416         "variable are available across channels.\n"
417         },
418
419         { "SetLanguage", pbx_builtin_setlanguage,
420         "Sets channel language",
421         "  SetLanguage(language): Set the channel language to 'language'. This\n"
422         "information is used for the syntax in generation of numbers, and to choose\n"
423         "a natural language file when available.\n"
424         "  For example, if language is set to 'fr' and the file 'demo-congrats' is \n"
425         "requested to be played, if the file 'fr/demo-congrats' exists, then\n"
426         "it will play that file, and if not will play the normal 'demo-congrats'.\n"
427         "For some language codes, SetLanguage also changes the syntax of some\n"
428         "Asterisk functions, like SayNumber.\n"
429         "Always returns 0.\n"
430         },
431
432         { "SetVar", pbx_builtin_setvar,
433         "Set channel variable to value",
434         "  SetVar(#n1=value|#n2=value|..[|options]) \n"
435         "You can specify an endless list of name / value pairs to be set as channel variables.\n"
436         "  #n=value: Sets variable n to value. If prefixed with _, single\n"
437         "inheritance assumed. If prefixed with __, infinite inheritance is assumed.\n" 
438         "The last arg (if it doesn't contain an '=' ) is intrepreted as a string of\n"
439         "options. Valid Options:\n"
440         "  - c - CDR, if set set the var as a CDR variable also.\n"
441         "  - r - Recursive CDR, if there are any stacked CDRs, also apply to all as a cdr var.\n"
442         "  - g - Set a global variable not a channel variable.\n"
443         },
444
445         { "ImportVar", pbx_builtin_importvar,
446         "Set variable to value",
447         "  ImportVar(#n=channel|variable): Sets variable n to variable as evaluated on\n"
448         "the specified channel (instead of current). If prefixed with _, single\n"
449         "inheritance assumed. If prefixed with __, infinite inheritance is assumed.\n" },
450
451         { "StripMSD", pbx_builtin_stripmsd,
452         "Strip leading digits",
453         "  StripMSD(count): Strips the leading 'count' digits from the channel's\n"
454         "associated extension. For example, the number 5551212 when stripped with a\n"
455         "count of 3 would be changed to 1212. This app always returns 0, and the PBX\n"
456         "will continue processing at the next priority for the *new* extension.\n"
457         "  So, for example, if priority 3 of 5551212 is StripMSD 3, the next step\n"
458         "executed will be priority 4 of 1212. If you switch into an extension which\n"
459         "has no first step, the PBX will treat it as though the user dialed an\n"
460         "invalid extension.\n" 
461         },
462
463         { "Suffix", pbx_builtin_suffix, 
464         "Append trailing digits",
465         "  Suffix(digits): Appends the digit string specified by digits to the\n"
466         "channel's associated extension. For example, the number 555 when suffixed\n"
467         "with '1212' will become 5551212. This app always returns 0, and the PBX will\n"
468         "continue processing at the next priority for the *new* extension.\n"
469         "  So, for example, if priority 3 of 555 is Suffix 1212, the next step\n"
470         "executed will be priority 4 of 5551212. If you switch into an extension\n"
471         "which has no first step, the PBX will treat it as though the user dialed an\n"
472         "invalid extension.\n" 
473         },
474
475         { "Wait", pbx_builtin_wait, 
476         "Waits for some time", 
477         "  Wait(seconds): Waits for a specified number of seconds, then returns 0.\n"
478         "seconds can be passed with fractions of a second. (eg: 1.5 = 1.5 seconds)\n" 
479         },
480
481         { "WaitExten", pbx_builtin_waitexten, 
482         "Waits for an extension to be entered", 
483         "  WaitExten([seconds][|options]): Waits for the user to enter a new extension for the \n"
484         "specified number of seconds, then returns 0. Seconds can be passed with\n"
485         "fractions of a seconds (eg: 1.5 = 1.5 seconds) or if unspecified the\n"
486         "default extension timeout will be used.\n"
487         "  Options:\n"
488         "    'm[(x)]' - Provide music on hold to the caller while waiting for an extension.\n"
489         "               Optionally, specify the class for music on hold within parenthesis.\n"
490         },
491
492 };
493
494 static struct ast_context *contexts = NULL;
495 AST_MUTEX_DEFINE_STATIC(conlock);               /* Lock for the ast_context list */
496 static struct ast_app *apps = NULL;
497 AST_MUTEX_DEFINE_STATIC(applock);               /* Lock for the application list */
498
499 struct ast_switch *switches = NULL;
500 AST_MUTEX_DEFINE_STATIC(switchlock);            /* Lock for switches */
501
502 AST_MUTEX_DEFINE_STATIC(hintlock);              /* Lock for extension state notifys */
503 static int stateid = 1;
504 struct ast_hint *hints = NULL;
505 struct ast_state_cb *statecbs = NULL;
506
507 int pbx_exec(struct ast_channel *c,             /* Channel */
508                 struct ast_app *app,            /* Application */
509                 void *data,                     /* Data for execution */
510                 int newstack)                   /* Force stack increment */
511 {
512         /* This function is special. It saves the stack so that no matter
513            how many times it is called, it returns to the same place */
514         int res;
515         
516         char *saved_c_appl;
517         char *saved_c_data;
518         
519         int (*execute)(struct ast_channel *chan, void *data) = app->execute; 
520
521         if (newstack) {
522                 if (c->cdr)
523                         ast_cdr_setapp(c->cdr, app->name, data);
524
525                 /* save channel values */
526                 saved_c_appl= c->appl;
527                 saved_c_data= c->data;
528
529                 c->appl = app->name;
530                 c->data = data;         
531                 res = execute(c, data);
532                 /* restore channel values */
533                 c->appl= saved_c_appl;
534                 c->data= saved_c_data;
535                 return res;
536         } else
537                 ast_log(LOG_WARNING, "You really didn't want to call this function with newstack set to 0\n");
538         return -1;
539 }
540
541
542 /* Go no deeper than this through includes (not counting loops) */
543 #define AST_PBX_MAX_STACK       128
544
545 #define HELPER_EXISTS 0
546 #define HELPER_SPAWN 1
547 #define HELPER_EXEC 2
548 #define HELPER_CANMATCH 3
549 #define HELPER_MATCHMORE 4
550 #define HELPER_FINDLABEL 5
551
552 struct ast_app *pbx_findapp(const char *app) 
553 {
554         struct ast_app *tmp;
555
556         if (ast_mutex_lock(&applock)) {
557                 ast_log(LOG_WARNING, "Unable to obtain application lock\n");
558                 return NULL;
559         }
560         tmp = apps;
561         while(tmp) {
562                 if (!strcasecmp(tmp->name, app))
563                         break;
564                 tmp = tmp->next;
565         }
566         ast_mutex_unlock(&applock);
567         return tmp;
568 }
569
570 static struct ast_switch *pbx_findswitch(const char *sw)
571 {
572         struct ast_switch *asw;
573
574         if (ast_mutex_lock(&switchlock)) {
575                 ast_log(LOG_WARNING, "Unable to obtain application lock\n");
576                 return NULL;
577         }
578         asw = switches;
579         while(asw) {
580                 if (!strcasecmp(asw->name, sw))
581                         break;
582                 asw = asw->next;
583         }
584         ast_mutex_unlock(&switchlock);
585         return asw;
586 }
587
588 static inline int include_valid(struct ast_include *i)
589 {
590         if (!i->hastime)
591                 return 1;
592
593         return ast_check_timing(&(i->timing));
594 }
595
596 static void pbx_destroy(struct ast_pbx *p)
597 {
598         free(p);
599 }
600
601 #define EXTENSION_MATCH_CORE(data,pattern,match) {\
602         /* All patterns begin with _ */\
603         if (pattern[0] != '_') \
604                 return 0;\
605         /* Start optimistic */\
606         match=1;\
607         pattern++;\
608         while(match && *data && *pattern && (*pattern != '/')) {\
609                 while (*data == '-' && (*(data+1) != '\0')) data++;\
610                 switch(toupper(*pattern)) {\
611                 case '[': \
612                 {\
613                         int i,border=0;\
614                         char *where;\
615                         match=0;\
616                         pattern++;\
617                         where=strchr(pattern,']');\
618                         if (where)\
619                                 border=(int)(where-pattern);\
620                         if (!where || border > strlen(pattern)) {\
621                                 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");\
622                                 return match;\
623                         }\
624                         for (i=0; i<border; i++) {\
625                                 int res=0;\
626                                 if (i+2<border)\
627                                         if (pattern[i+1]=='-') {\
628                                                 if (*data >= pattern[i] && *data <= pattern[i+2]) {\
629                                                         res=1;\
630                                                 } else {\
631                                                         i+=2;\
632                                                         continue;\
633                                                 }\
634                                         }\
635                                 if (res==1 || *data==pattern[i]) {\
636                                         match = 1;\
637                                         break;\
638                                 }\
639                         }\
640                         pattern+=border;\
641                         break;\
642                 }\
643                 case 'N':\
644                         if ((*data < '2') || (*data > '9'))\
645                                 match=0;\
646                         break;\
647                 case 'X':\
648                         if ((*data < '0') || (*data > '9'))\
649                                 match = 0;\
650                         break;\
651                 case 'Z':\
652                         if ((*data < '1') || (*data > '9'))\
653                                 match = 0;\
654                         break;\
655                 case '.':\
656                         /* Must match */\
657                         return 1;\
658                 case '!':\
659                         /* Early match */\
660                         return 2;\
661                 case ' ':\
662                 case '-':\
663                         /* Ignore these characters */\
664                         data--;\
665                         break;\
666                 default:\
667                         if (*data != *pattern)\
668                                 match =0;\
669                 }\
670                 data++;\
671                 pattern++;\
672         }\
673         /* If we ran off the end of the data and the pattern ends in '!', match */\
674         if (match && !*data && (*pattern == '!'))\
675                 return 2;\
676 }
677
678 int ast_extension_match(const char *pattern, const char *data)
679 {
680         int match;
681         /* If they're the same return */
682         if (!strcmp(pattern, data))
683                 return 1;
684         EXTENSION_MATCH_CORE(data,pattern,match);
685         /* Must be at the end of both */
686         if (*data || (*pattern && (*pattern != '/')))
687                 match = 0;
688         return match;
689 }
690
691 int ast_extension_close(const char *pattern, const char *data, int needmore)
692 {
693         int match;
694         /* If "data" is longer, it can'be a subset of pattern unless
695            pattern is a pattern match */
696         if ((strlen(pattern) < strlen(data)) && (pattern[0] != '_'))
697                 return 0;
698         
699         if ((ast_strlen_zero((char *)data) || !strncasecmp(pattern, data, strlen(data))) && 
700                 (!needmore || (strlen(pattern) > strlen(data)))) {
701                 return 1;
702         }
703         EXTENSION_MATCH_CORE(data,pattern,match);
704         /* If there's more or we don't care about more, or if it's a possible early match, 
705            return non-zero; otherwise it's a miss */
706         if (!needmore || *pattern || match == 2) {
707                 return match;
708         } else
709                 return 0;
710 }
711
712 struct ast_context *ast_context_find(const char *name)
713 {
714         struct ast_context *tmp;
715         ast_mutex_lock(&conlock);
716         if (name) {
717                 tmp = contexts;
718                 while(tmp) {
719                         if (!strcasecmp(name, tmp->name))
720                                 break;
721                         tmp = tmp->next;
722                 }
723         } else
724                 tmp = contexts;
725         ast_mutex_unlock(&conlock);
726         return tmp;
727 }
728
729 #define STATUS_NO_CONTEXT   1
730 #define STATUS_NO_EXTENSION 2
731 #define STATUS_NO_PRIORITY  3
732 #define STATUS_NO_LABEL         4
733 #define STATUS_SUCCESS      5
734
735 static int matchcid(const char *cidpattern, const char *callerid)
736 {
737         int failresult;
738         
739         /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
740            failing to get a number should count as a match, otherwise not */
741
742
743         if (!ast_strlen_zero(cidpattern))
744                 failresult = 0;
745         else
746                 failresult = 1;
747
748         if (!callerid)
749                 return failresult;
750
751         return ast_extension_match(cidpattern, callerid);
752 }
753
754 static struct ast_exten *pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, const char *context, const char *exten, int priority, const char *label, const char *callerid, int action, char *incstack[], int *stacklen, int *status, struct ast_switch **swo, char **data, const char **foundcontext)
755 {
756         int x, res;
757         struct ast_context *tmp;
758         struct ast_exten *e, *eroot;
759         struct ast_include *i;
760         struct ast_sw *sw;
761         struct ast_switch *asw;
762
763         /* Initialize status if appropriate */
764         if (!*stacklen) {
765                 *status = STATUS_NO_CONTEXT;
766                 *swo = NULL;
767                 *data = NULL;
768         }
769         /* Check for stack overflow */
770         if (*stacklen >= AST_PBX_MAX_STACK) {
771                 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
772                 return NULL;
773         }
774         /* Check first to see if we've already been checked */
775         for (x=0; x<*stacklen; x++) {
776                 if (!strcasecmp(incstack[x], context))
777                         return NULL;
778         }
779         if (bypass)
780                 tmp = bypass;
781         else
782                 tmp = contexts;
783         while(tmp) {
784                 /* Match context */
785                 if (bypass || !strcmp(tmp->name, context)) {
786                         struct ast_exten *earlymatch = NULL;
787
788                         if (*status < STATUS_NO_EXTENSION)
789                                 *status = STATUS_NO_EXTENSION;
790                         for (eroot = tmp->root; eroot; eroot=eroot->next) {
791                                 int match = 0;
792                                 /* Match extension */
793                                 if ((((action != HELPER_MATCHMORE) && ast_extension_match(eroot->exten, exten)) ||
794                                      ((action == HELPER_CANMATCH) && (ast_extension_close(eroot->exten, exten, 0))) ||
795                                      ((action == HELPER_MATCHMORE) && (match = ast_extension_close(eroot->exten, exten, 1)))) &&
796                                     (!eroot->matchcid || matchcid(eroot->cidmatch, callerid))) {
797
798                                         if (action == HELPER_MATCHMORE && match == 2 && !earlymatch) {
799                                                 /* It matched an extension ending in a '!' wildcard
800                                                    So ignore it for now, unless there's a better match */
801                                                 earlymatch = eroot;
802                                         } else {
803                                                 e = eroot;
804                                                 if (*status < STATUS_NO_PRIORITY)
805                                                         *status = STATUS_NO_PRIORITY;
806                                                 while(e) {
807                                                         /* Match priority */
808                                                         if (action == HELPER_FINDLABEL) {
809                                                                 if (*status < STATUS_NO_LABEL)
810                                                                         *status = STATUS_NO_LABEL;
811                                                                 if (label && e->label && !strcmp(label, e->label)) {
812                                                                         *status = STATUS_SUCCESS;
813                                                                         *foundcontext = context;
814                                                                         return e;
815                                                                 }
816                                                         } else if (e->priority == priority) {
817                                                                 *status = STATUS_SUCCESS;
818                                                                 *foundcontext = context;
819                                                                 return e;
820                                                         }
821                                                         e = e->peer;
822                                                 }
823                                         }
824                                 }
825                         }
826                         if (earlymatch) {
827                                 /* Bizarre logic for HELPER_MATCHMORE. We return zero to break out 
828                                    of the loop waiting for more digits, and _then_ match (normally)
829                                    the extension we ended up with. We got an early-matching wildcard
830                                    pattern, so return NULL to break out of the loop. */
831                                 return NULL;
832                         }
833                         /* Check alternative switches */
834                         sw = tmp->alts;
835                         while(sw) {
836                                 if ((asw = pbx_findswitch(sw->name))) {
837                                         /* Substitute variables now */
838                                         if (sw->eval) 
839                                                 pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1);
840                                         if (action == HELPER_CANMATCH)
841                                                 res = asw->canmatch ? asw->canmatch(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0;
842                                         else if (action == HELPER_MATCHMORE)
843                                                 res = asw->matchmore ? asw->matchmore(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0;
844                                         else
845                                                 res = asw->exists ? asw->exists(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0;
846                                         if (res) {
847                                                 /* Got a match */
848                                                 *swo = asw;
849                                                 *data = sw->eval ? sw->tmpdata : sw->data;
850                                                 *foundcontext = context;
851                                                 return NULL;
852                                         }
853                                 } else {
854                                         ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
855                                 }
856                                 sw = sw->next;
857                         }
858                         /* Setup the stack */
859                         incstack[*stacklen] = tmp->name;
860                         (*stacklen)++;
861                         /* Now try any includes we have in this context */
862                         i = tmp->includes;
863                         while(i) {
864                                 if (include_valid(i)) {
865                                         if ((e = pbx_find_extension(chan, bypass, i->rname, exten, priority, label, callerid, action, incstack, stacklen, status, swo, data, foundcontext))) 
866                                                 return e;
867                                         if (*swo) 
868                                                 return NULL;
869                                 }
870                                 i = i->next;
871                         }
872                         break;
873                 }
874                 tmp = tmp->next;
875         }
876         return NULL;
877 }
878
879 /*--- pbx_retrieve_variable: Support for Asterisk built-in variables and
880       functions in the dialplan
881   ---*/
882 void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
883 {
884         char *first,*second;
885         char tmpvar[80] = "";
886         time_t thistime;
887         struct tm brokentime;
888         int offset,offset2;
889         struct ast_var_t *variables;
890
891         if (c) 
892                 headp=&c->varshead;
893         *ret=NULL;
894         if ((first=strchr(var,':'))) {  /* : Remove characters counting from end or start of string */
895                 strncpy(tmpvar, var, sizeof(tmpvar) - 1);
896                 first = strchr(tmpvar, ':');
897                 if (!first)
898                         first = tmpvar + strlen(tmpvar);
899                 *first='\0';
900                 pbx_retrieve_variable(c,tmpvar,ret,workspace,workspacelen - 1, headp);
901                 if (!(*ret)) 
902                         return;
903                 offset=atoi(first+1);   /* The number of characters, 
904                                            positive: remove # of chars from start
905                                            negative: keep # of chars from end */
906                                                 
907                 if ((second=strchr(first+1,':'))) {     
908                         *second='\0';
909                         offset2 = atoi(second+1);               /* Number of chars to copy */
910                 } else if (offset >= 0) {
911                         offset2 = strlen(*ret)-offset;  /* Rest of string */
912                 } else {
913                         offset2 = abs(offset);
914                 }
915
916                 if (abs(offset) > strlen(*ret)) {       /* Offset beyond string */
917                         if (offset >= 0) 
918                                 offset=strlen(*ret);
919                         else 
920                                 offset=-strlen(*ret);   
921                 }
922                 if ((offset < 0 && offset2 > -offset) || (offset >= 0 && offset+offset2 > strlen(*ret))) {
923                         if (offset >= 0) 
924                                 offset2=strlen(*ret)-offset;
925                         else 
926                                 offset2=strlen(*ret)+offset;
927                 }
928                 if (offset >= 0)
929                         *ret += offset;
930                 else
931                         *ret += strlen(*ret)+offset;
932                 (*ret)[offset2] = '\0';         /* Cut at offset2 position */
933         } else if (c && !strncmp(var, "CALL", 4)) {
934                 if (!strncmp(var + 4, "ER", 2)) {
935                         if (!strncmp(var + 6, "ID", 2)) {
936                                 if (!var[8]) {                  /* CALLERID */
937                                         if (c->cid.cid_num) {
938                                                 if (c->cid.cid_name) {
939                                                         snprintf(workspace, workspacelen, "\"%s\" <%s>", c->cid.cid_name, c->cid.cid_num);
940                                                 } else {
941                                                         strncpy(workspace, c->cid.cid_num, workspacelen - 1);
942                                                 }
943                                                 *ret = workspace;
944                                         } else if (c->cid.cid_name) {
945                                                 strncpy(workspace, c->cid.cid_name, workspacelen - 1);
946                                                 *ret = workspace;
947                                         } else
948                                                 *ret = NULL;
949                                 } else if (!strcmp(var + 8, "NUM")) {
950                                         /* CALLERIDNUM */
951                                         if (c->cid.cid_num) {
952                                                 strncpy(workspace, c->cid.cid_num, workspacelen - 1);
953                                                 *ret = workspace;
954                                         } else
955                                                 *ret = NULL;
956                                 } else if (!strcmp(var + 8, "NAME")) {
957                                         /* CALLERIDNAME */
958                                         if (c->cid.cid_name) {
959                                                 strncpy(workspace, c->cid.cid_name, workspacelen - 1);
960                                                 *ret = workspace;
961                                         } else
962                                                 *ret = NULL;
963                                 }
964                         } else if (!strcmp(var + 6, "ANI")) {
965                                 /* CALLERANI */
966                                 if (c->cid.cid_ani) {
967                                         strncpy(workspace, c->cid.cid_ani, workspacelen - 1);
968                                         *ret = workspace;
969                                 } else
970                                         *ret = NULL;
971                         } else
972                                 goto icky;
973                 } else if (!strncmp(var + 4, "ING", 3)) {
974                         if (!strcmp(var + 7, "PRES")) {
975                                 /* CALLINGPRES */
976                                 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
977                                 *ret = workspace;
978                         } else if (!strcmp(var + 7, "ANI2")) {
979                                 /* CALLINGANI2 */
980                                 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
981                                 *ret = workspace;
982                         } else if (!strcmp(var + 7, "TON")) {
983                                 /* CALLINGTON */
984                                 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
985                                 *ret = workspace;
986                         } else if (!strcmp(var + 7, "TNS")) {
987                                 /* CALLINGTNS */
988                                 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
989                                 *ret = workspace;
990                         } else
991                                 goto icky;
992                 } else
993                         goto icky;
994         } else if (c && !strcmp(var, "DNID")) {
995                 if (c->cid.cid_dnid) {
996                         strncpy(workspace, c->cid.cid_dnid, workspacelen - 1);
997                         *ret = workspace;
998                 } else
999                         *ret = NULL;
1000         } else if (c && !strcmp(var, "HINT")) {
1001                 if (!ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten))
1002                         *ret = NULL;
1003                 else
1004                         *ret = workspace;
1005         } else if (c && !strcmp(var, "HINTNAME")) {
1006                 if (!ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten))
1007                         *ret = NULL;
1008                 else
1009                         *ret = workspace;
1010         } else if (c && !strcmp(var, "EXTEN")) {
1011                 strncpy(workspace, c->exten, workspacelen - 1);
1012                 *ret = workspace;
1013         } else if (c && !strcmp(var, "RDNIS")) {
1014                 if (c->cid.cid_rdnis) {
1015                         strncpy(workspace, c->cid.cid_rdnis, workspacelen - 1);
1016                         *ret = workspace;
1017                 } else
1018                         *ret = NULL;
1019         } else if (c && !strcmp(var, "CONTEXT")) {
1020                 strncpy(workspace, c->context, workspacelen - 1);
1021                 *ret = workspace;
1022         } else if (c && !strcmp(var, "PRIORITY")) {
1023                 snprintf(workspace, workspacelen, "%d", c->priority);
1024                 *ret = workspace;
1025         } else if (c && !strcmp(var, "CHANNEL")) {
1026                 strncpy(workspace, c->name, workspacelen - 1);
1027                 *ret = workspace;
1028         } else if (!strcmp(var, "EPOCH")) {
1029                 snprintf(workspace, workspacelen, "%u",(int)time(NULL));
1030                 *ret = workspace;
1031         } else if (!strcmp(var, "DATETIME")) {
1032                 thistime=time(NULL);
1033                 localtime_r(&thistime, &brokentime);
1034                 snprintf(workspace, workspacelen, "%02d%02d%04d-%02d:%02d:%02d",
1035                         brokentime.tm_mday,
1036                         brokentime.tm_mon+1,
1037                         brokentime.tm_year+1900,
1038                         brokentime.tm_hour,
1039                         brokentime.tm_min,
1040                         brokentime.tm_sec
1041                 );
1042                 *ret = workspace;
1043         } else if (!strcmp(var, "TIMESTAMP")) {
1044                 thistime=time(NULL);
1045                 localtime_r(&thistime, &brokentime);
1046                 /* 20031130-150612 */
1047                 snprintf(workspace, workspacelen, "%04d%02d%02d-%02d%02d%02d",
1048                         brokentime.tm_year+1900,
1049                         brokentime.tm_mon+1,
1050                         brokentime.tm_mday,
1051                         brokentime.tm_hour,
1052                         brokentime.tm_min,
1053                         brokentime.tm_sec
1054                 );
1055                 *ret = workspace;
1056         } else if (c && !strcmp(var, "UNIQUEID")) {
1057                 snprintf(workspace, workspacelen, "%s", c->uniqueid);
1058                 *ret = workspace;
1059         } else if (c && !strcmp(var, "HANGUPCAUSE")) {
1060                 snprintf(workspace, workspacelen, "%d", c->hangupcause);
1061                 *ret = workspace;
1062         } else if (c && !strcmp(var, "ACCOUNTCODE")) {
1063                 strncpy(workspace, c->accountcode, workspacelen - 1);
1064                 *ret = workspace;
1065         } else if (c && !strcmp(var, "LANGUAGE")) {
1066                 strncpy(workspace, c->language, workspacelen - 1);
1067                 *ret = workspace;
1068         } else {
1069 icky:
1070                 if (headp) {
1071                         AST_LIST_TRAVERSE(headp,variables,entries) {
1072 #if 0
1073                                 ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",var,ast_var_name(variables));
1074 #endif
1075                                 if (strcasecmp(ast_var_name(variables),var)==0) {
1076                                         *ret=ast_var_value(variables);
1077                                         if (*ret) {
1078                                                 strncpy(workspace, *ret, workspacelen - 1);
1079                                                 *ret = workspace;
1080                                         }
1081                                         break;
1082                                 }
1083                         }
1084                 }
1085                 if (!(*ret)) {
1086                         /* Try globals */
1087                         AST_LIST_TRAVERSE(&globals,variables,entries) {
1088 #if 0
1089                                 ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",var,ast_var_name(variables));
1090 #endif
1091                                 if (strcasecmp(ast_var_name(variables),var)==0) {
1092                                         *ret=ast_var_value(variables);
1093                                         if (*ret) {
1094                                                 strncpy(workspace, *ret, workspacelen - 1);
1095                                                 *ret = workspace;
1096                                         }
1097                                 }
1098                         }
1099                 }
1100         }
1101 }
1102
1103 static int handle_show_functions(int fd, int argc, char *argv[])
1104 {
1105         struct ast_custom_function_obj *acfptr;
1106
1107         ast_cli(fd, "Installed Custom Functions:\n--------------------------------------------------------------------------------\n");
1108         for (acfptr = acf_root ; acfptr ; acfptr = acfptr->next) {
1109                 ast_cli(fd, "%s\t(%s)\t[%s]\n", acfptr->name, acfptr->desc, acfptr->syntax);
1110         }
1111         ast_cli(fd, "\n");
1112         return 0;
1113 }
1114
1115 struct ast_custom_function_obj* ast_custom_function_find_obj(char *name) 
1116 {
1117         struct ast_custom_function_obj *acfptr;
1118
1119         for (acfptr = acf_root ; acfptr ; acfptr = acfptr->next) {
1120                 if (!strcmp(name, acfptr->name)) {
1121                         break;
1122                 }
1123         }       
1124         
1125         return acfptr;
1126 }
1127
1128 int ast_custom_function_unregister(struct ast_custom_function_obj *acf) 
1129 {
1130         struct ast_custom_function_obj *acfptr, *lastacf = NULL;
1131
1132         if (acf) {
1133                 for (acfptr = acf_root ; acfptr ; acfptr = acfptr->next) {
1134                         if (acfptr == acf) {
1135                                 if (lastacf) {
1136                                         lastacf->next = acf->next;
1137                                 } else {
1138                                         acf_root = acf->next;
1139                                 }
1140                                 if (option_verbose > 1)
1141                                         ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
1142                                 return 0;
1143                         }
1144                         lastacf = acfptr;
1145                 }
1146         }
1147         return -1;
1148 }
1149
1150 int ast_custom_function_register(struct ast_custom_function_obj *acf) 
1151 {
1152         struct ast_custom_function_obj *acfptr;
1153
1154         if (acf) {
1155                 if((acfptr = ast_custom_function_find_obj(acf->name))) {
1156                         ast_log(LOG_ERROR, "Function %s already in use.\n", acf->name);
1157                         return -1;
1158                 }
1159                 acf->next = acf_root;
1160                 acf_root = acf;
1161                 if (option_verbose > 1)
1162                         ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
1163                 return 0;
1164         }
1165
1166         return -1;
1167 }
1168
1169 char *ast_func_read(struct ast_channel *chan, const char *in, char *workspace, size_t len)
1170 {
1171         char *args = NULL, *function, *p;
1172         char *ret = "0";
1173         struct ast_custom_function_obj *acfptr;
1174
1175         function = ast_strdupa(in);
1176         if (function) {
1177                 if ((args = strchr(function, '('))) {
1178                         *args = '\0';
1179                         args++;
1180                         if ((p = strrchr(args, ')'))) {
1181                                 *p = '\0';
1182                         } else {
1183                                 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
1184                         }
1185                 } else {
1186                         ast_log(LOG_WARNING, "Function doesn't contain parentheses.  Assuming null argument.\n");
1187                 }
1188
1189                 if ((acfptr = ast_custom_function_find_obj(function))) {
1190                         /* run the custom function */
1191                         if (acfptr->read) {
1192                                 return acfptr->read(chan, function, args, workspace, len);
1193                         } else {
1194                                 ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
1195                         }
1196                 } else {
1197                         ast_log(LOG_ERROR, "Function %s not registered\n", function);
1198                 }
1199         } else {
1200                 ast_log(LOG_ERROR, "Out of memory\n");
1201         }
1202         return ret;
1203 }
1204
1205 static void ast_func_write(struct ast_channel *chan, const char *in, const char *value)
1206 {
1207         char *args = NULL, *function, *p;
1208         struct ast_custom_function_obj *acfptr;
1209
1210         function = ast_strdupa(in);
1211         if (function) {
1212                 if ((args = strchr(function, '('))) {
1213                         *args = '\0';
1214                         args++;
1215                         if ((p = strrchr(args, ')'))) {
1216                                 *p = '\0';
1217                         } else {
1218                                 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
1219                         }
1220                 } else {
1221                         ast_log(LOG_WARNING, "Function doesn't contain parentheses.  Assuming null argument.\n");
1222                 }
1223
1224                 if ((acfptr = ast_custom_function_find_obj(function))) {
1225                         /* run the custom function */
1226                         if (acfptr->write) {
1227                                 acfptr->write(chan, function, args, value);
1228                         } else {
1229                                 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function);
1230                         }
1231                 } else {
1232                         ast_log(LOG_ERROR, "Function %s not registered\n", function);
1233                 }
1234         } else {
1235                 ast_log(LOG_ERROR, "Out of memory\n");
1236         }
1237 }
1238
1239 static char *builtin_function_isnull(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
1240 {
1241         char *ret_true = "1", *ret_false = "0";
1242         return data && *data ? ret_false : ret_true;
1243 }
1244
1245 static char *builtin_function_exists(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
1246 {
1247         char *ret_true = "1", *ret_false = "0";
1248         return data && *data ? ret_true : ret_false;
1249 }
1250
1251 static char *builtin_function_if(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
1252 {
1253         char *ret = NULL;
1254         char *mydata = NULL;
1255         char *expr = NULL;
1256         char *iftrue = NULL;
1257         char *iffalse = NULL;
1258
1259         if((mydata = ast_strdupa(data))) {
1260                 expr = mydata;
1261                 if ((iftrue = strchr(mydata, '?'))) {
1262                         *iftrue = '\0';
1263                         iftrue++;
1264                         if ((iffalse = strchr(iftrue, ':'))) {
1265                                 *iffalse = '\0';
1266                                 iffalse++;
1267                         }
1268                 } else 
1269                         iffalse = "";
1270                 if (expr && iftrue) {
1271                         ret = ast_true(expr) ? iftrue : iffalse;
1272                         strncpy(buf, ret, len);
1273                         ret = buf;
1274                 } else {
1275                         ast_log(LOG_WARNING, "Syntax $(if <expr>?[<truecond>][:<falsecond>])\n");
1276                         ret = NULL;
1277                 }
1278         } else {
1279                 ast_log(LOG_WARNING, "Memory Error!\n");
1280                 ret = NULL;
1281         }
1282
1283         return ret;
1284 }
1285
1286 static char *builtin_function_env_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
1287 {
1288         char *ret = "";
1289         if (data) {
1290                 ret = getenv(data);
1291                 if (!ret)
1292                         ret = "";
1293         }
1294         strncpy(buf, ret, len);
1295         buf[len - 1] = '\0';
1296         return buf;
1297 }
1298
1299 static void builtin_function_env_write(struct ast_channel *chan, char *cmd, char *data, const char *value) 
1300 {
1301         if (data && !ast_strlen_zero(data)) {
1302                 if (value && !ast_strlen_zero(value)) {
1303                         setenv(data, value, 1);
1304                 } else {
1305                         unsetenv(data);
1306                 }
1307         }
1308 }
1309
1310 static char *builtin_function_len(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
1311 {
1312         int length = 0;
1313         if (data) {
1314                 length = strlen(data);
1315         }
1316         snprintf(buf, len, "%d", length);
1317         return buf;
1318 }
1319
1320 static char *builtin_function_cdr_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
1321 {
1322         char *ret;
1323         if (chan && chan->cdr && data) {
1324                 ast_cdr_getvar(chan->cdr, data, &ret, buf, len, 1);
1325         }
1326         return ret;
1327 }
1328
1329 static void builtin_function_cdr_write(struct ast_channel *chan, char *cmd, char *data, const char *value) 
1330 {
1331         if (chan && chan->cdr && data) {
1332                 ast_cdr_setvar(chan->cdr, data, value, 1);
1333         }
1334 }
1335
1336 static char *builtin_function_regex(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
1337 {
1338         char *ret_true = "1", *ret_false = "0", *ret;
1339         char *arg, *earg, *tmp, errstr[256] = "";
1340         int errcode;
1341         regex_t regexbuf;
1342
1343         ret = ret_false; /* convince me otherwise */
1344         tmp = ast_strdupa(data);
1345         if (tmp) {
1346                 /* Regex in quotes */
1347                 arg = strchr(tmp, '"');
1348                 if (arg) {
1349                         arg++;
1350                         earg = strrchr(arg, '"');
1351                         if (earg) {
1352                                 *earg = '\0';
1353                         }
1354                 } else {
1355                         arg = tmp;
1356                 }
1357
1358                 if ((errcode = regcomp(&regexbuf, arg, REG_EXTENDED | REG_NOSUB))) {
1359                         regerror(errcode, &regexbuf, errstr, sizeof(errstr));
1360                         ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, data, errstr);
1361                         ret = NULL;
1362                 } else {
1363                         ret = regexec(&regexbuf, data, 0, NULL, 0) ? ret_false : ret_true;
1364                 }
1365                 regfree(&regexbuf);
1366         } else {
1367                 ast_log(LOG_ERROR, "Out of memory in %s(%s)\n", cmd, data);
1368         }
1369
1370         return ret;
1371 }
1372
1373 static char *builtin_function_md5(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
1374 {
1375         char md5[33];
1376
1377         if (!data || ast_strlen_zero(data)) {
1378                 ast_log(LOG_WARNING, "Syntax: MD5(<data>) - missing argument!\n");
1379                 return NULL;
1380         }
1381
1382         ast_md5_hash(md5, data);
1383         ast_copy_string(buf, md5, len);
1384         
1385         return buf;
1386 }
1387
1388 static char *builtin_function_checkmd5(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
1389 {
1390         int argc;
1391         char *argv[2];
1392         char *args;
1393         char newmd5[33];
1394
1395         if (!data || ast_strlen_zero(data)) {
1396                 ast_log(LOG_WARNING, "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
1397                 return NULL;
1398         }
1399
1400         args = ast_strdupa(data);       
1401         argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / sizeof(argv[0]));
1402
1403         if (argc < 2) {
1404                 ast_log(LOG_WARNING, "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
1405                 return NULL;
1406         }
1407
1408         ast_md5_hash(newmd5, argv[1]);
1409
1410         if (!strcasecmp(newmd5, argv[0]))       /* they match */
1411                 ast_copy_string(buf, "1", len);
1412         else
1413                 ast_copy_string(buf, "0", len);
1414         
1415         return buf;
1416 }
1417
1418 static void pbx_substitute_variables_helper_full(struct ast_channel *c, const char *cp1, char *cp2, int count, struct varshead *headp)
1419 {
1420         char *cp4;
1421         const char *tmp, *whereweare;
1422         int length;
1423         char workspace[4096];
1424         char ltmp[4096], var[4096];
1425         char *nextvar, *nextexp, *nextthing;
1426         char *vars, *vare;
1427         int pos, brackets, needsub, len;
1428         
1429         /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be
1430            zero-filled */
1431         whereweare=tmp=cp1;
1432         while(!ast_strlen_zero(whereweare) && count) {
1433                 /* Assume we're copying the whole remaining string */
1434                 pos = strlen(whereweare);
1435                 nextvar = NULL;
1436                 nextexp = NULL;
1437                 nextthing = strchr(whereweare, '$');
1438                 if (nextthing) {
1439                         switch(nextthing[1]) {
1440                         case '{':
1441                                 nextvar = nextthing;
1442                                 break;
1443                         case '[':
1444                                 nextexp = nextthing;
1445                                 break;
1446                         }
1447                 }
1448                 /* If there is one, we only go that far */
1449                 if (nextvar)
1450                         pos = nextvar - whereweare;
1451                 else if (nextexp)
1452                         pos = nextexp - whereweare;
1453
1454                 /* Can't copy more than 'count' bytes */
1455                 if (pos > count)
1456                         pos = count;
1457
1458                 /* Copy that many bytes */
1459                 memcpy(cp2, whereweare, pos);
1460
1461                 count -= pos;
1462                 cp2 += pos;
1463                 whereweare += pos;
1464                 
1465                 if (nextvar) {
1466                         /* We have a variable.  Find the start and end, and determine
1467                            if we are going to have to recursively call ourselves on the
1468                            contents */
1469                         vars = vare = nextvar + 2;
1470                         brackets = 1;
1471                         needsub = 0;
1472
1473                         /* Find the end of it */
1474                         while(brackets && *vare) {
1475                                 if ((vare[0] == '$') && (vare[1] == '{')) {
1476                                         needsub++;
1477                                         brackets++;
1478                                 } else if (vare[0] == '}') {
1479                                         brackets--;
1480                                 } else if ((vare[0] == '$') && (vare[1] == '['))
1481                                         needsub++;
1482                                 vare++;
1483                         }
1484                         if (brackets)
1485                                 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n");
1486                         len = vare - vars - 1;
1487
1488                         /* Skip totally over variable name */
1489                         whereweare += ( len + 3);
1490
1491                         /* Store variable name (and truncate) */
1492                         memset(var, 0, sizeof(var));
1493                         strncpy(var, vars, sizeof(var) - 1);
1494                         var[len] = '\0';
1495
1496                         /* Substitute if necessary */
1497                         if (needsub) {
1498                                 memset(ltmp, 0, sizeof(ltmp));
1499                                 pbx_substitute_variables_helper(c, var, ltmp, sizeof(ltmp) - 1);
1500                                 vars = ltmp;
1501                         } else {
1502                                 vars = var;
1503                         }
1504
1505                         workspace[0] = '\0';
1506
1507                         if (var[len - 1] == ')') {
1508                                 /* Evaluate function */
1509                                 cp4 = ast_func_read(c, vars, workspace, sizeof(workspace));
1510
1511                                 ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)");
1512                         } else {
1513                                 /* Retrieve variable value */
1514                                 pbx_retrieve_variable(c, vars, &cp4, workspace, sizeof(workspace), headp);
1515                         }
1516                         if (cp4) {
1517                                 length = strlen(cp4);
1518                                 if (length > count)
1519                                         length = count;
1520                                 memcpy(cp2, cp4, length);
1521                                 count -= length;
1522                                 cp2 += length;
1523                         }
1524                 } else if (nextexp) {
1525                         /* We have an expression.  Find the start and end, and determine
1526                            if we are going to have to recursively call ourselves on the
1527                            contents */
1528                         vars = vare = nextexp + 2;
1529                         brackets = 1;
1530                         needsub = 0;
1531
1532                         /* Find the end of it */
1533                         while(brackets && *vare) {
1534                                 if ((vare[0] == '$') && (vare[1] == '[')) {
1535                                         needsub++;
1536                                         brackets++;
1537                                         vare++;
1538                                 } else if (vare[0] == '[') {
1539                                         brackets++;
1540                                 } else if (vare[0] == ']') {
1541                                         brackets--;
1542                                 } else if ((vare[0] == '$') && (vare[1] == '{')) {
1543                                         needsub++;
1544                                         vare++;
1545                                 }
1546                                 vare++;
1547                         }
1548                         if (brackets)
1549                                 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
1550                         len = vare - vars - 1;
1551                         
1552                         /* Skip totally over variable name */
1553                         whereweare += ( len + 3);
1554                         
1555                         /* Store variable name (and truncate) */
1556                         memset(var, 0, sizeof(var));
1557                         strncpy(var, vars, sizeof(var) - 1);
1558                         var[len] = '\0';
1559                         
1560                         /* Substitute if necessary */
1561                         if (needsub) {
1562                                 memset(ltmp, 0, sizeof(ltmp));
1563                                 pbx_substitute_variables_helper(c, var, ltmp, sizeof(ltmp) - 1);
1564                                 vars = ltmp;
1565                         } else {
1566                                 vars = var;
1567                         }
1568
1569                         /* Evaluate expression */                       
1570                         cp4 = ast_expr(vars);
1571                         
1572                         ast_log(LOG_DEBUG, "Expression is '%s'\n", cp4);
1573                         
1574                         if (cp4) {
1575                                 length = strlen(cp4);
1576                                 if (length > count)
1577                                         length = count;
1578                                 memcpy(cp2, cp4, length);
1579                                 count -= length;
1580                                 cp2 += length;
1581                                 free(cp4);
1582                         }
1583                 } else
1584                         break;
1585         }
1586 }
1587
1588 void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
1589 {
1590         pbx_substitute_variables_helper_full(c, cp1, cp2, count, NULL);
1591 }
1592
1593 void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count)
1594 {
1595         pbx_substitute_variables_helper_full(NULL, cp1, cp2, count, headp);
1596 }
1597
1598 static void pbx_substitute_variables(char *passdata, int datalen, struct ast_channel *c, struct ast_exten *e)
1599 {
1600         memset(passdata, 0, datalen);
1601                 
1602         /* No variables or expressions in e->data, so why scan it? */
1603         if (!strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) {
1604                 strncpy(passdata, e->data, datalen - 1);
1605                 passdata[datalen-1] = '\0';
1606                 return;
1607         }
1608         
1609         pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1);
1610 }                                                               
1611
1612 static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, int action) 
1613 {
1614         struct ast_exten *e;
1615         struct ast_app *app;
1616         struct ast_switch *sw;
1617         char *data;
1618         const char *foundcontext=NULL;
1619         int newstack = 0;
1620         int res;
1621         int status = 0;
1622         char *incstack[AST_PBX_MAX_STACK];
1623         char passdata[EXT_DATA_SIZE];
1624         int stacklen = 0;
1625         char tmp[80];
1626         char tmp2[80];
1627         char tmp3[EXT_DATA_SIZE];
1628         char atmp[80];
1629         char atmp2[EXT_DATA_SIZE+100];
1630
1631         if (ast_mutex_lock(&conlock)) {
1632                 ast_log(LOG_WARNING, "Unable to obtain lock\n");
1633                 if ((action == HELPER_EXISTS) || (action == HELPER_CANMATCH) || (action == HELPER_MATCHMORE))
1634                         return 0;
1635                 else
1636                         return -1;
1637         }
1638         e = pbx_find_extension(c, con, context, exten, priority, label, callerid, action, incstack, &stacklen, &status, &sw, &data, &foundcontext);
1639         if (e) {
1640                 switch(action) {
1641                 case HELPER_CANMATCH:
1642                         ast_mutex_unlock(&conlock);
1643                         return -1;
1644                 case HELPER_EXISTS:
1645                         ast_mutex_unlock(&conlock);
1646                         return -1;
1647                 case HELPER_FINDLABEL:
1648                         res = e->priority;
1649                         ast_mutex_unlock(&conlock);
1650                         return res;
1651                 case HELPER_MATCHMORE:
1652                         ast_mutex_unlock(&conlock);
1653                         return -1;
1654                 case HELPER_SPAWN:
1655                         newstack++;
1656                         /* Fall through */
1657                 case HELPER_EXEC:
1658                         app = pbx_findapp(e->app);
1659                         ast_mutex_unlock(&conlock);
1660                         if (app) {
1661                                 if (c->context != context)
1662                                         strncpy(c->context, context, sizeof(c->context)-1);
1663                                 if (c->exten != exten)
1664                                         strncpy(c->exten, exten, sizeof(c->exten)-1);
1665                                 c->priority = priority;
1666                                 pbx_substitute_variables(passdata, sizeof(passdata), c, e);
1667                                 if (option_debug) {
1668                                                 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
1669                                                 snprintf(atmp, 80, "STACK-%s-%s-%d", context, exten, priority);
1670                                                 snprintf(atmp2, EXT_DATA_SIZE+100, "%s(\"%s\", \"%s\") %s", app->name, c->name, (!ast_strlen_zero(passdata) ? (char *)passdata : ""), (newstack ? "in new stack" : "in same stack"));
1671                                                 pbx_builtin_setvar_helper(c, atmp, atmp2);
1672                                 }
1673                                 if (option_verbose > 2)
1674                                                 ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n", 
1675                                                                 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
1676                                                                 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
1677                                                                 term_color(tmp3, (!ast_strlen_zero(passdata) ? (char *)passdata : ""), COLOR_BRMAGENTA, 0, sizeof(tmp3)),
1678                                                                 (newstack ? "in new stack" : "in same stack"));
1679                                 manager_event(EVENT_FLAG_CALL, "Newexten", 
1680                                         "Channel: %s\r\n"
1681                                         "Context: %s\r\n"
1682                                         "Extension: %s\r\n"
1683                                         "Priority: %d\r\n"
1684                                         "Application: %s\r\n"
1685                                         "AppData: %s\r\n"
1686                                         "Uniqueid: %s\r\n",
1687                                         c->name, c->context, c->exten, c->priority, app->name, passdata ? passdata : "(NULL)", c->uniqueid);
1688                                 res = pbx_exec(c, app, passdata, newstack);
1689                                 return res;
1690                         } else {
1691                                 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
1692                                 return -1;
1693                         }
1694                 default:
1695                         ast_log(LOG_WARNING, "Huh (%d)?\n", action);                    return -1;
1696                 }
1697         } else if (sw) {
1698                 switch(action) {
1699                 case HELPER_CANMATCH:
1700                         ast_mutex_unlock(&conlock);
1701                         return -1;
1702                 case HELPER_EXISTS:
1703                         ast_mutex_unlock(&conlock);
1704                         return -1;
1705                 case HELPER_MATCHMORE:
1706                         ast_mutex_unlock(&conlock);
1707                         return -1;
1708                 case HELPER_FINDLABEL:
1709                         ast_mutex_unlock(&conlock);
1710                         return -1;
1711                 case HELPER_SPAWN:
1712                         newstack++;
1713                         /* Fall through */
1714                 case HELPER_EXEC:
1715                         ast_mutex_unlock(&conlock);
1716                         if (sw->exec)
1717                                 res = sw->exec(c, foundcontext ? foundcontext : context, exten, priority, callerid, newstack, data);
1718                         else {
1719                                 ast_log(LOG_WARNING, "No execution engine for switch %s\n", sw->name);
1720                                 res = -1;
1721                         }
1722                         return res;
1723                 default:
1724                         ast_log(LOG_WARNING, "Huh (%d)?\n", action);
1725                         return -1;
1726                 }
1727         } else {
1728                 ast_mutex_unlock(&conlock);
1729                 switch(status) {
1730                 case STATUS_NO_CONTEXT:
1731                         if ((action != HELPER_EXISTS) && (action != HELPER_MATCHMORE))
1732                                 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
1733                         break;
1734                 case STATUS_NO_EXTENSION:
1735                         if ((action != HELPER_EXISTS) && (action !=  HELPER_CANMATCH) && (action != HELPER_MATCHMORE))
1736                                 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
1737                         break;
1738                 case STATUS_NO_PRIORITY:
1739                         if ((action != HELPER_EXISTS) && (action !=  HELPER_CANMATCH) && (action != HELPER_MATCHMORE))
1740                                 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
1741                         break;
1742                 case STATUS_NO_LABEL:
1743                         if (context)
1744                                 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context);
1745                         break;
1746                 default:
1747                         ast_log(LOG_DEBUG, "Shouldn't happen!\n");
1748                 }
1749                 
1750                 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE))
1751                         return -1;
1752                 else
1753                         return 0;
1754         }
1755
1756 }
1757
1758 /*--- ast_hint_extension: Find hint for given extension in context */
1759 static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
1760 {
1761         struct ast_exten *e;
1762         struct ast_switch *sw;
1763         char *data;
1764         const char *foundcontext = NULL;
1765         int status = 0;
1766         char *incstack[AST_PBX_MAX_STACK];
1767         int stacklen = 0;
1768
1769         if (ast_mutex_lock(&conlock)) {
1770                 ast_log(LOG_WARNING, "Unable to obtain lock\n");
1771                 return NULL;
1772         }
1773         e = pbx_find_extension(c, NULL, context, exten, PRIORITY_HINT, NULL, "", HELPER_EXISTS, incstack, &stacklen, &status, &sw, &data, &foundcontext);
1774         ast_mutex_unlock(&conlock);     
1775         return e;
1776 }
1777
1778 /*--- ast_extensions_state2: Check state of extension by using hints */
1779 static int ast_extension_state2(struct ast_exten *e)
1780 {
1781         char hint[AST_MAX_EXTENSION] = "";    
1782         char *cur, *rest;
1783         int res = -1;
1784         int allunavailable = 1, allbusy = 1, allfree = 1;
1785         int busy = 0;
1786
1787         if (!e)
1788                 return -1;
1789
1790         strncpy(hint, ast_get_extension_app(e), sizeof(hint)-1);
1791
1792         cur = hint;     /* On or more devices separated with a & character */
1793         do {
1794                 rest = strchr(cur, '&');
1795                 if (rest) {
1796                         *rest = 0;
1797                         rest++;
1798                 }
1799         
1800                 res = ast_device_state(cur);
1801                 switch (res) {
1802                 case AST_DEVICE_NOT_INUSE:
1803                         allunavailable = 0;
1804                         allbusy = 0;
1805                         break;
1806                 case AST_DEVICE_INUSE:
1807                         return AST_EXTENSION_INUSE;
1808                 case AST_DEVICE_BUSY:
1809                         allunavailable = 0;
1810                         allfree = 0;
1811                         busy = 1;
1812                         break;
1813                 case AST_DEVICE_UNAVAILABLE:
1814                 case AST_DEVICE_INVALID:
1815                         allbusy = 0;
1816                         allfree = 0;
1817                         break;
1818                 default:
1819                         allunavailable = 0;
1820                         allbusy = 0;
1821                         allfree = 0;
1822                 }
1823                 cur = rest;
1824         } while (cur);
1825
1826         if (allfree)                    
1827                 return AST_EXTENSION_NOT_INUSE;
1828         if (allbusy)            
1829                 return AST_EXTENSION_BUSY;
1830         if (allunavailable)
1831                 return AST_EXTENSION_UNAVAILABLE;
1832         if (busy) 
1833                 return AST_EXTENSION_INUSE;
1834         
1835         return AST_EXTENSION_NOT_INUSE;
1836 }
1837
1838
1839 /*--- ast_extension_state: Check extension state for an extension by using hint */
1840 int ast_extension_state(struct ast_channel *c, char *context, char *exten)
1841 {
1842         struct ast_exten *e;
1843
1844         e = ast_hint_extension(c, context, exten);      /* Do we have a hint for this extension ? */ 
1845         if (!e) 
1846                 return -1;                              /* No hint, return -1 */
1847
1848         return ast_extension_state2(e);                 /* Check all devices in the hint */
1849 }
1850
1851 /*--- ast_device_state_changed: If device state in cblist is changed  - then notify callback function */
1852 int ast_device_state_changed(const char *fmt, ...) 
1853 {
1854         struct ast_hint *list;
1855         struct ast_state_cb *cblist;
1856         struct ast_devstate_cb *devcb;
1857         char hint[AST_MAX_EXTENSION] = "";
1858         char device[AST_MAX_EXTENSION];
1859
1860         char *cur, *rest;
1861         int state;
1862
1863         va_list ap;
1864
1865         va_start(ap, fmt);
1866         vsnprintf(device, sizeof(device), fmt, ap);
1867         va_end(ap);
1868
1869         rest = strchr(device, '-');
1870         if (rest) {
1871                 *rest = 0;
1872         }
1873
1874
1875         state = ast_device_state(device);
1876         if (option_debug > 2)
1877                 ast_log(LOG_DEBUG, "Changing state for %s - state %d\n", device, state);
1878
1879         ast_mutex_lock(&hintlock);
1880
1881         /* First check device callbacks */
1882         devcb = devcbs;
1883         while(devcb) {
1884                 if (devcb->callback)
1885                         devcb->callback(device, state, devcb->data);
1886                 devcb = devcb->next;
1887         }
1888
1889         /* Then check callbacks in hints */
1890         list = hints;
1891
1892         while (list) {
1893
1894                 strncpy(hint, ast_get_extension_app(list->exten), sizeof(hint) - 1);
1895                 cur = hint;
1896                 do {
1897                         rest = strchr(cur, '&');
1898                         if (rest) {
1899                                 *rest = 0;
1900                                 rest++;
1901                         }
1902                         
1903                         if (!strcmp(cur, device)) {     /* Is this device referred to in this hint? */
1904
1905                                 /* Get device state for this hint */
1906                                 state = ast_extension_state2(list->exten);
1907
1908                                 if ((state != -1) && (state != list->laststate)) {
1909                                         /* Device state changed since last check - notify the watcher */
1910
1911                                         /* For general callbacks */
1912                                         cblist = statecbs;
1913                                         while (cblist) {
1914                                                 cblist->callback(list->exten->parent->name, list->exten->exten, state, cblist->data);
1915                                                 cblist = cblist->next;
1916                                         }
1917
1918                                         /* For extension callbacks */
1919                                         cblist = list->callbacks;
1920                                         while (cblist) {
1921                                                 cblist->callback(list->exten->parent->name, list->exten->exten, state, cblist->data);
1922                                                 cblist = cblist->next;
1923                                         }
1924                         
1925                                         list->laststate = state;
1926                                 }
1927                                 break;
1928                         }
1929                         cur = rest;
1930                 } while (cur);
1931                 list = list->next;
1932         }
1933         ast_mutex_unlock(&hintlock);
1934         return 1;
1935 }
1936                         
1937 /*--- ast_devstate_add: Add device state watcher */
1938 int ast_devstate_add(ast_devstate_cb_type callback, void *data)
1939 {
1940         struct ast_devstate_cb *devcb;
1941         devcb = malloc(sizeof(struct ast_devstate_cb));
1942         if (devcb) {
1943                 memset(devcb, 0, sizeof(struct ast_devstate_cb));
1944                 ast_mutex_lock(&hintlock);
1945                 devcb->data = data;
1946                 devcb->callback = callback;
1947                 devcb->next = devcbs;
1948                 devcbs = devcb;
1949                 ast_mutex_unlock(&hintlock);
1950         }
1951         return 0;
1952 }
1953
1954 /*--- ast_devstate_del: Remove device state watcher */
1955 void ast_devstate_del(ast_devstate_cb_type callback, void *data)
1956 {
1957         struct ast_devstate_cb *devcb, *prev = NULL, *next;
1958         ast_mutex_lock(&hintlock);
1959         devcb = devcbs;
1960         while(devcb) {
1961                 next = devcb->next;
1962                 if ((devcb->data == data) && (devcb->callback == callback)) {
1963                         if (prev)
1964                                 prev->next = next;
1965                         else
1966                                 devcbs = next;
1967                         free(devcb);
1968                 } else
1969                         prev = devcb;
1970                 devcb = next;
1971         }
1972         ast_mutex_unlock(&hintlock);
1973 }
1974
1975 /*--- ast_extension_state_add: Add watcher for extension states */
1976 int ast_extension_state_add(const char *context, const char *exten, 
1977                             ast_state_cb_type callback, void *data)
1978 {
1979         struct ast_hint *list;
1980         struct ast_state_cb *cblist;
1981         struct ast_exten *e;
1982
1983         /* If there's no context and extension:  add callback to statecbs list */
1984         if (!context && !exten) {
1985                 ast_mutex_lock(&hintlock);
1986
1987                 cblist = statecbs;
1988                 while (cblist) {
1989                         if (cblist->callback == callback) {
1990                                 cblist->data = data;
1991                                 ast_mutex_unlock(&hintlock);
1992                         }
1993                         cblist = cblist->next;
1994                 }
1995         
1996                 /* Now inserts the callback */
1997                 cblist = malloc(sizeof(struct ast_state_cb));
1998                 if (!cblist) {
1999                         ast_mutex_unlock(&hintlock);
2000                         return -1;
2001                 }
2002                 memset(cblist, 0, sizeof(struct ast_state_cb));
2003                 cblist->id = 0;
2004                 cblist->callback = callback;
2005                 cblist->data = data;
2006         
2007                 cblist->next = statecbs;
2008                 statecbs = cblist;
2009
2010                 ast_mutex_unlock(&hintlock);
2011                 return 0;
2012         }
2013
2014         if (!context || !exten)
2015                 return -1;
2016
2017         /* This callback type is for only one hint, so get the hint */
2018         e = ast_hint_extension(NULL, context, exten);    
2019         if (!e) {
2020                 return -1;
2021         }
2022
2023         /* Find the hint in the list of hints */
2024         ast_mutex_lock(&hintlock);
2025         list = hints;        
2026
2027         while (list) {
2028                 if (list->exten == e)
2029                         break;      
2030                 list = list->next;    
2031         }
2032
2033         if (!list) {
2034                 /* We have no hint, sorry */
2035                 ast_mutex_unlock(&hintlock);
2036                 return -1;
2037         }
2038
2039         /* Now insert the callback in the callback list  */
2040         cblist = malloc(sizeof(struct ast_state_cb));
2041         if (!cblist) {
2042                 ast_mutex_unlock(&hintlock);
2043                 return -1;
2044         }
2045         memset(cblist, 0, sizeof(struct ast_state_cb));
2046         cblist->id = stateid++;         /* Unique ID for this callback */
2047         cblist->callback = callback;    /* Pointer to callback routine */
2048         cblist->data = data;            /* Data for the callback */
2049
2050         cblist->next = list->callbacks;
2051         list->callbacks = cblist;
2052
2053         ast_mutex_unlock(&hintlock);
2054         return cblist->id;
2055 }
2056
2057 /*--- ast_extension_state_del: Remove a watcher from the callback list */
2058 int ast_extension_state_del(int id, ast_state_cb_type callback)
2059 {
2060         struct ast_hint *list;
2061         struct ast_state_cb *cblist, *cbprev;
2062
2063         if (!id && !callback)
2064                 return -1;
2065
2066         ast_mutex_lock(&hintlock);
2067
2068         /* id is zero is a callback without extension */
2069         if (!id) {
2070                 cbprev = NULL;
2071                 cblist = statecbs;
2072                 while (cblist) {
2073                         if (cblist->callback == callback) {
2074                                 if (!cbprev)
2075                                         statecbs = cblist->next;
2076                                 else
2077                                         cbprev->next = cblist->next;
2078
2079                                 free(cblist);
2080
2081                                 ast_mutex_unlock(&hintlock);
2082                                 return 0;
2083                         }
2084                         cbprev = cblist;
2085                         cblist = cblist->next;
2086                 }
2087
2088                 ast_mutex_lock(&hintlock);
2089                 return -1;
2090         }
2091
2092         /* id greater than zero is a callback with extension */
2093         /* Find the callback based on ID */
2094         list = hints;
2095         while (list) {
2096                 cblist = list->callbacks;
2097                 cbprev = NULL;
2098                 while (cblist) {
2099                         if (cblist->id==id) {
2100                                 if (!cbprev)
2101                                         list->callbacks = cblist->next;         
2102                                 else
2103                                         cbprev->next = cblist->next;
2104                 
2105                                 free(cblist);
2106                 
2107                                 ast_mutex_unlock(&hintlock);
2108                                 return 0;               
2109                         }               
2110                         cbprev = cblist;                                
2111                         cblist = cblist->next;
2112                 }
2113                 list = list->next;
2114         }
2115
2116         ast_mutex_unlock(&hintlock);
2117         return -1;
2118 }
2119
2120 /*--- ast_add_hint: Add hint to hint list, check initial extension state */
2121 static int ast_add_hint(struct ast_exten *e)
2122 {
2123         struct ast_hint *list;
2124
2125         if (!e) 
2126                 return -1;
2127
2128         ast_mutex_lock(&hintlock);
2129         list = hints;        
2130
2131         /* Search if hint exists, do nothing */
2132         while (list) {
2133                 if (list->exten == e) {
2134                         ast_mutex_unlock(&hintlock);
2135                         if (option_debug > 1)
2136                                 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
2137                         return -1;
2138                 }
2139                 list = list->next;    
2140         }
2141
2142         if (option_debug > 1)
2143                 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
2144
2145         list = malloc(sizeof(struct ast_hint));
2146         if (!list) {
2147                 ast_mutex_unlock(&hintlock);
2148                 if (option_debug > 1)
2149                         ast_log(LOG_DEBUG, "HINTS: Out of memory...\n");
2150                 return -1;
2151         }
2152         /* Initialize and insert new item at the top */
2153         memset(list, 0, sizeof(struct ast_hint));
2154         list->exten = e;
2155         list->laststate = ast_extension_state2(e);
2156         list->next = hints;
2157         hints = list;
2158
2159         ast_mutex_unlock(&hintlock);
2160         return 0;
2161 }
2162
2163 /*--- ast_change_hint: Change hint for an extension */
2164 static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
2165
2166         struct ast_hint *list;
2167
2168         ast_mutex_lock(&hintlock);
2169         list = hints;
2170
2171         while(list) {
2172                 if (list->exten == oe) {
2173                         list->exten = ne;
2174                         ast_mutex_unlock(&hintlock);    
2175                         return 0;
2176                 }
2177                 list = list->next;
2178         }
2179         ast_mutex_unlock(&hintlock);
2180
2181         return -1;
2182 }
2183
2184 /*--- ast_remove_hint: Remove hint from extension */
2185 static int ast_remove_hint(struct ast_exten *e)
2186 {
2187         /* Cleanup the Notifys if hint is removed */
2188         struct ast_hint *list, *prev = NULL;
2189         struct ast_state_cb *cblist, *cbprev;
2190
2191         if (!e) 
2192                 return -1;
2193
2194         ast_mutex_lock(&hintlock);
2195
2196         list = hints;    
2197         while(list) {
2198                 if (list->exten==e) {
2199                         cbprev = NULL;
2200                         cblist = list->callbacks;
2201                         while (cblist) {
2202                                 /* Notify with -1 and remove all callbacks */
2203                                 cbprev = cblist;            
2204                                 cblist = cblist->next;
2205                                 cbprev->callback(list->exten->parent->name, list->exten->exten, -1, cbprev->data);
2206                                 free(cbprev);
2207                         }
2208                         list->callbacks = NULL;
2209
2210                         if (!prev)
2211                                 hints = list->next;
2212                         else
2213                                 prev->next = list->next;
2214                         free(list);
2215             
2216                         ast_mutex_unlock(&hintlock);
2217                         return 0;
2218                 } else {
2219                         prev = list;
2220                         list = list->next;    
2221                 }
2222         }
2223
2224         ast_mutex_unlock(&hintlock);
2225         return -1;
2226 }
2227
2228
2229 /*--- ast_get_hint: Get hint for channel */
2230 int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
2231 {
2232         struct ast_exten *e;
2233         void *tmp;
2234         e = ast_hint_extension(c, context, exten);
2235         if (e) {
2236                 if (hint) 
2237                     strncpy(hint, ast_get_extension_app(e), hintsize - 1);
2238                 if (name) {
2239                         tmp = ast_get_extension_app_data(e);
2240                         if (tmp)
2241                                 strncpy(name, (char *)tmp, namesize - 1);
2242                 }
2243             return -1;
2244         }
2245         return 0;       
2246 }
2247
2248 int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) 
2249 {
2250         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXISTS);
2251 }
2252
2253 int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) 
2254 {
2255         return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, HELPER_FINDLABEL);
2256 }
2257
2258 int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) 
2259 {
2260         return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, HELPER_FINDLABEL);
2261 }
2262
2263 int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
2264 {
2265         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_CANMATCH);
2266 }
2267
2268 int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
2269 {
2270         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_MATCHMORE);
2271 }
2272
2273 int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) 
2274 {
2275         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_SPAWN);
2276 }
2277
2278 int ast_exec_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) 
2279 {
2280         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXEC);
2281 }
2282
2283 int ast_pbx_run(struct ast_channel *c)
2284 {
2285         int firstpass = 1;
2286         char digit;
2287         char exten[256];
2288         int pos;
2289         int waittime;
2290         int res=0;
2291         int autoloopflag;
2292
2293         /* A little initial setup here */
2294         if (c->pbx)
2295                 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
2296         c->pbx = malloc(sizeof(struct ast_pbx));
2297         if (!c->pbx) {
2298                 ast_log(LOG_ERROR, "Out of memory\n");
2299                 return -1;
2300         }
2301         if (c->amaflags) {
2302                 if (!c->cdr) {
2303                         c->cdr = ast_cdr_alloc();
2304                         if (!c->cdr) {
2305                                 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
2306                                 free(c->pbx);
2307                                 return -1;
2308                         }
2309                         ast_cdr_init(c->cdr, c);
2310                 }
2311         }
2312         memset(c->pbx, 0, sizeof(struct ast_pbx));
2313         /* Set reasonable defaults */
2314         c->pbx->rtimeout = 10;
2315         c->pbx->dtimeout = 5;
2316
2317         autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP);
2318         ast_set_flag(c, AST_FLAG_IN_AUTOLOOP);
2319
2320         /* Start by trying whatever the channel is set to */
2321         if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
2322                 /* If not successful fall back to 's' */
2323                 if (option_verbose > 1)
2324                         ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
2325                 strncpy(c->exten, "s", sizeof(c->exten)-1);
2326                 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
2327                         /* JK02: And finally back to default if everything else failed */
2328                         if (option_verbose > 1)
2329                                 ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
2330                         strncpy(c->context, "default", sizeof(c->context)-1);
2331                 }
2332                 c->priority = 1;
2333         }
2334         if (c->cdr && !c->cdr->start.tv_sec && !c->cdr->start.tv_usec)
2335                 ast_cdr_start(c->cdr);
2336         for(;;) {
2337                 pos = 0;
2338                 digit = 0;
2339                 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
2340                         memset(exten, 0, sizeof(exten));
2341                         if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
2342                                 /* Something bad happened, or a hangup has been requested. */
2343                                 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
2344                                         (res == '*') || (res == '#')) {
2345                                         ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
2346                                         memset(exten, 0, sizeof(exten));
2347                                         pos = 0;
2348                                         exten[pos++] = digit = res;
2349                                         break;
2350                                 }
2351                                 switch(res) {
2352                                 case AST_PBX_KEEPALIVE:
2353                                         if (option_debug)
2354                                                 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
2355                                         else if (option_verbose > 1)
2356                                                 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
2357                                         goto out;
2358                                         break;
2359                                 default:
2360                                         if (option_debug)
2361                                                 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2362                                         else if (option_verbose > 1)
2363                                                 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2364                                         if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
2365                                                 c->_softhangup =0;
2366                                                 break;
2367                                         }
2368                                         /* atimeout */
2369                                         if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
2370                                                 break;
2371                                         }
2372
2373                                         if (c->cdr) {
2374                                                 ast_cdr_update(c);
2375                                         }
2376                                         goto out;
2377                                 }
2378                         }
2379                         if ((c->_softhangup == AST_SOFTHANGUP_TIMEOUT) && (ast_exists_extension(c,c->context,"T",1,c->cid.cid_num))) {
2380                                 strncpy(c->exten,"T",sizeof(c->exten) - 1);
2381                                 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
2382                                 c->whentohangup = 0;
2383                                 c->priority = 0;
2384                                 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
2385                         } else if (c->_softhangup) {
2386                                 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
2387                                         c->exten, c->priority);
2388                                 goto out;
2389                         }
2390                         firstpass = 0;
2391                         c->priority++;
2392                 }
2393                 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
2394                         /* It's not a valid extension anymore */
2395                         if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
2396                                 if (option_verbose > 2)
2397                                         ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
2398                                 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
2399                                 strncpy(c->exten, "i", sizeof(c->exten)-1);
2400                                 c->priority = 1;
2401                         } else {
2402                                 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
2403                                         c->name, c->exten, c->context);
2404                                 goto out;
2405                         }
2406                 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
2407                         /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
2408                         c->_softhangup = 0;
2409                 } else {
2410                         /* Done, wait for an extension */
2411                         waittime = 0;
2412                         if (digit)
2413                                 waittime = c->pbx->dtimeout;
2414                         else if (!autofallthrough)
2415                                 waittime = c->pbx->rtimeout;
2416                         if (waittime) {
2417                                 while (ast_matchmore_extension(c, c->context, exten, 1, c->cid.cid_num)) {
2418                                         /* As long as we're willing to wait, and as long as it's not defined, 
2419                                            keep reading digits until we can't possibly get a right answer anymore.  */
2420                                         digit = ast_waitfordigit(c, waittime * 1000);
2421                                         if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
2422                                                 c->_softhangup = 0;
2423                                         } else {
2424                                                 if (!digit)
2425                                                         /* No entry */
2426                                                         break;
2427                                                 if (digit < 0)
2428                                                         /* Error, maybe a  hangup */
2429                                                         goto out;
2430                                                 exten[pos++] = digit;
2431                                                 waittime = c->pbx->dtimeout;
2432                                         }
2433                                 }
2434                                 if (ast_exists_extension(c, c->context, exten, 1, c->cid.cid_num)) {
2435                                         /* Prepare the next cycle */
2436                                         strncpy(c->exten, exten, sizeof(c->exten)-1);
2437                                         c->priority = 1;
2438                                 } else {
2439                                         /* No such extension */
2440                                         if (!ast_strlen_zero(exten)) {
2441                                                 /* An invalid extension */
2442                                                 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
2443                                                         if (option_verbose > 2)
2444                                                                 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name);
2445                                                         pbx_builtin_setvar_helper(c, "INVALID_EXTEN", exten);
2446                                                         strncpy(c->exten, "i", sizeof(c->exten)-1);
2447                                                         c->priority = 1;
2448                                                 } else {
2449                                                         ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", exten, c->context);
2450                                                         goto out;
2451                                                 }
2452                                         } else {
2453                                                 /* A simple timeout */
2454                                                 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) {
2455                                                         if (option_verbose > 2)
2456                                                                 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
2457                                                         strncpy(c->exten, "t", sizeof(c->exten)-1);
2458                                                         c->priority = 1;
2459                                                 } else {
2460                                                         ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
2461                                                         goto out;
2462                                                 }
2463                                         }       
2464                                 }
2465                                 if (c->cdr) {
2466                                         if (option_verbose > 2)
2467                                                 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name);    
2468                                         ast_cdr_update(c);
2469                             }
2470                         } else {
2471                                 char *status;
2472
2473                                 status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
2474                                 if (!status)
2475                                         status = "UNKNOWN";
2476                                 if (option_verbose > 2)
2477                                         ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status);
2478                                 if (!strcasecmp(status, "CONGESTION"))
2479                                         res = pbx_builtin_congestion(c, "10");
2480                                 else if (!strcasecmp(status, "CHANUNAVAIL"))
2481                                         res = pbx_builtin_congestion(c, "10");
2482                                 else if (!strcasecmp(status, "BUSY"))
2483                                         res = pbx_builtin_busy(c, "10");
2484                                 goto out;
2485                         }
2486                 }
2487         }
2488         if (firstpass) 
2489                 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
2490 out:
2491         if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
2492                 c->exten[0] = 'h';
2493                 c->exten[1] = '\0';
2494                 c->priority = 1;
2495                 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
2496                         if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
2497                                 /* Something bad happened, or a hangup has been requested. */
2498                                 if (option_debug)
2499                                         ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2500                                 else if (option_verbose > 1)
2501                                         ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2502                                 break;
2503                         }
2504                         c->priority++;
2505                 }
2506         }
2507         ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP);
2508
2509         pbx_destroy(c->pbx);
2510         c->pbx = NULL;
2511         if (res != AST_PBX_KEEPALIVE)
2512                 ast_hangup(c);
2513         return 0;
2514 }
2515
2516 static void *pbx_thread(void *data)
2517 {
2518         /* Oh joyeous kernel, we're a new thread, with nothing to do but
2519            answer this channel and get it going.  The setjmp stuff is fairly
2520            confusing, but necessary to get smooth transitions between
2521            the execution of different applications (without the use of
2522            additional threads) */
2523         struct ast_channel *c = data;
2524         ast_pbx_run(c);
2525         pthread_exit(NULL);
2526         return NULL;
2527 }
2528
2529 int ast_pbx_start(struct ast_channel *c)
2530 {
2531         pthread_t t;
2532         pthread_attr_t attr;
2533         if (!c) {
2534                 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
2535                 return -1;
2536         }
2537            
2538         /* Start a new thread, and get something handling this channel. */
2539         pthread_attr_init(&attr);
2540         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2541         if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
2542                 ast_log(LOG_WARNING, "Failed to create new channel thread\n");
2543                 return -1;
2544         }
2545         return 0;
2546 }
2547
2548 int pbx_set_autofallthrough(int newval)
2549 {
2550         int oldval;
2551         oldval = autofallthrough;
2552         if (oldval != newval)
2553                 autofallthrough = newval;
2554         return oldval;
2555 }
2556
2557 /*
2558  * This function locks contexts list by &conlist, search for the right context
2559  * structure, leave context list locked and call ast_context_remove_include2
2560  * which removes include, unlock contexts list and return ...
2561  */
2562 int ast_context_remove_include(const char *context, const char *include, const char *registrar)
2563 {
2564         struct ast_context *c;
2565
2566         if (ast_lock_contexts()) return -1;
2567
2568         /* walk contexts and search for the right one ...*/
2569         c = ast_walk_contexts(NULL);
2570         while (c) {
2571                 /* we found one ... */
2572                 if (!strcmp(ast_get_context_name(c), context)) {
2573                         int ret;
2574                         /* remove include from this context ... */      
2575                         ret = ast_context_remove_include2(c, include, registrar);
2576
2577                         ast_unlock_contexts();
2578
2579                         /* ... return results */
2580                         return ret;
2581                 }
2582                 c = ast_walk_contexts(c);
2583         }
2584
2585         /* we can't find the right one context */
2586         ast_unlock_contexts();
2587         return -1;
2588 }
2589
2590 /*
2591  * When we call this function, &conlock lock must be locked, because when
2592  * we giving *con argument, some process can remove/change this context
2593  * and after that there can be segfault.
2594  *
2595  * This function locks given context, removes include, unlock context and
2596  * return.
2597  */
2598 int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
2599 {
2600         struct ast_include *i, *pi = NULL;
2601
2602         if (ast_mutex_lock(&con->lock)) return -1;
2603
2604         /* walk includes */
2605         i = con->includes;
2606         while (i) {
2607                 /* find our include */
2608                 if (!strcmp(i->name, include) && 
2609                         (!registrar || !strcmp(i->registrar, registrar))) {
2610                         /* remove from list */
2611                         if (pi)
2612                                 pi->next = i->next;
2613                         else
2614                                 con->includes = i->next;
2615                         /* free include and return */
2616                         free(i);
2617                         ast_mutex_unlock(&con->lock);
2618                         return 0;
2619                 }
2620                 pi = i;
2621                 i = i->next;
2622         }
2623
2624         /* we can't find the right include */
2625         ast_mutex_unlock(&con->lock);
2626         return -1;
2627 }
2628
2629 /*
2630  * This function locks contexts list by &conlist, search for the rigt context
2631  * structure, leave context list locked and call ast_context_remove_switch2
2632  * which removes switch, unlock contexts list and return ...
2633  */
2634 int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar)
2635 {
2636         struct ast_context *c;
2637
2638         if (ast_lock_contexts()) return -1;
2639
2640         /* walk contexts and search for the right one ...*/
2641         c = ast_walk_contexts(NULL);
2642         while (c) {
2643                 /* we found one ... */
2644                 if (!strcmp(ast_get_context_name(c), context)) {
2645                         int ret;
2646                         /* remove switch from this context ... */       
2647                         ret = ast_context_remove_switch2(c, sw, data, registrar);
2648
2649                         ast_unlock_contexts();
2650
2651                         /* ... return results */
2652                         return ret;
2653                 }
2654                 c = ast_walk_contexts(c);
2655         }
2656
2657         /* we can't find the right one context */
2658         ast_unlock_contexts();
2659         return -1;
2660 }
2661
2662 /*
2663  * When we call this function, &conlock lock must be locked, because when
2664  * we giving *con argument, some process can remove/change this context
2665  * and after that there can be segfault.
2666  *
2667  * This function locks given context, removes switch, unlock context and
2668  * return.
2669  */
2670 int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
2671 {
2672         struct ast_sw *i, *pi = NULL;
2673
2674         if (ast_mutex_lock(&con->lock)) return -1;
2675
2676         /* walk switchs */
2677         i = con->alts;
2678         while (i) {
2679                 /* find our switch */
2680                 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 
2681                         (!registrar || !strcmp(i->registrar, registrar))) {
2682                         /* remove from list */
2683                         if (pi)
2684                                 pi->next = i->next;
2685                         else
2686                                 con->alts = i->next;
2687                         /* free switch and return */
2688                         free(i);
2689                         ast_mutex_unlock(&con->lock);
2690                         return 0;
2691                 }
2692                 pi = i;
2693                 i = i->next;
2694         }
2695
2696         /* we can't find the right switch */
2697         ast_mutex_unlock(&con->lock);
2698         return -1;
2699 }
2700
2701 /*
2702  * This functions lock contexts list, search for the right context,
2703  * call ast_context_remove_extension2, unlock contexts list and return.
2704  * In this function we are using
2705  */
2706 int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
2707 {
2708         struct ast_context *c;
2709
2710         if (ast_lock_contexts()) return -1;
2711
2712         /* walk contexts ... */
2713         c = ast_walk_contexts(NULL);
2714         while (c) {
2715                 /* ... search for the right one ... */
2716                 if (!strcmp(ast_get_context_name(c), context)) {
2717                         /* ... remove extension ... */
2718                         int ret = ast_context_remove_extension2(c, extension, priority,
2719                                 registrar);
2720                         /* ... unlock contexts list and return */
2721                         ast_unlock_contexts();
2722                         return ret;
2723                 }
2724                 c = ast_walk_contexts(c);
2725         }
2726
2727         /* we can't find the right context */
2728         ast_unlock_contexts();
2729         return -1;
2730 }
2731
2732 /*
2733  * When do you want to call this function, make sure that &conlock is locked,
2734  * because some process can handle with your *con context before you lock
2735  * it.
2736  *
2737  * This functionc locks given context, search for the right extension and
2738  * fires out all peer in this extensions with given priority. If priority
2739  * is set to 0, all peers are removed. After that, unlock context and
2740  * return.
2741  */
2742 int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar)
2743 {
2744         struct ast_exten *exten, *prev_exten = NULL;
2745
2746         if (ast_mutex_lock(&con->lock)) return -1;
2747
2748         /* go through all extensions in context and search the right one ... */
2749         exten = con->root;
2750         while (exten) {
2751
2752                 /* look for right extension */
2753                 if (!strcmp(exten->exten, extension) &&
2754                         (!registrar || !strcmp(exten->registrar, registrar))) {
2755                         struct ast_exten *peer;
2756
2757                         /* should we free all peers in this extension? (priority == 0)? */
2758                         if (priority == 0) {
2759                                 /* remove this extension from context list */
2760                                 if (prev_exten)
2761                                         prev_exten->next = exten->next;
2762                                 else
2763                                         con->root = exten->next;
2764
2765                                 /* fire out all peers */
2766                                 peer = exten; 
2767                                 while (peer) {
2768                                         exten = peer->peer;
2769                                         
2770                                         if (!peer->priority==PRIORITY_HINT) 
2771                                             ast_remove_hint(peer);
2772
2773                                         peer->datad(peer->data);
2774                                         free(peer);
2775
2776                                         peer = exten;
2777                                 }
2778
2779                                 ast_mutex_unlock(&con->lock);
2780                                 return 0;
2781                         } else {
2782                                 /* remove only extension with exten->priority == priority */
2783                                 struct ast_exten *previous_peer = NULL;
2784
2785                                 peer = exten;
2786                                 while (peer) {
2787                                         /* is this our extension? */
2788                                         if (peer->priority == priority &&
2789                                                 (!registrar || !strcmp(peer->registrar, registrar) )) {
2790                                                 /* we are first priority extension? */
2791                                                 if (!previous_peer) {
2792                                                         /* exists previous extension here? */
2793                                                         if (prev_exten) {
2794                                                                 /* yes, so we must change next pointer in
2795                                                                  * previous connection to next peer
2796                                                                  */
2797                                                                 if (peer->peer) {
2798                                                                         prev_exten->next = peer->peer;
2799                                                                         peer->peer->next = exten->next;
2800                                                                 } else
2801                                                                         prev_exten->next = exten->next;
2802                                                         } else {
2803                                                                 /* no previous extension, we are first
2804                                                                  * extension, so change con->root ...
2805                                                                  */
2806                                                                 if (peer->peer)
2807                                                                         con->root = peer->peer;
2808                                                                 else
2809                                                                         con->root = exten->next; 
2810                                                         }
2811                                                 } else {
2812                                                         /* we are not first priority in extension */
2813                                                         previous_peer->peer = peer->peer;
2814                                                 }
2815
2816                                                 /* now, free whole priority extension */
2817                                                 if (peer->priority==PRIORITY_HINT)
2818                                                     ast_remove_hint(peer);
2819                                                 peer->datad(peer->data);
2820                                                 free(peer);
2821
2822                                                 ast_mutex_unlock(&con->lock);
2823                                                 return 0;
2824                                         } else {
2825                                                 /* this is not right extension, skip to next peer */
2826                                                 previous_peer = peer;
2827                                                 peer = peer->peer;
2828                                         }
2829                                 }
2830
2831                                 ast_mutex_unlock(&con->lock);
2832                                 return -1;
2833                         }
2834                 }
2835
2836                 prev_exten = exten;
2837                 exten = exten->next;
2838         }
2839
2840         /* we can't find right extension */
2841         ast_mutex_unlock(&con->lock);
2842         return -1;
2843 }
2844
2845
2846 int ast_register_application(const char *app, int (*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
2847 {
2848         struct ast_app *tmp, *prev, *cur;
2849         char tmps[80];
2850         int length;
2851         length = sizeof(struct ast_app);
2852         length += strlen(app) + 1;
2853         if (ast_mutex_lock(&applock)) {
2854                 ast_log(LOG_ERROR, "Unable to lock application list\n");
2855                 return -1;
2856         }
2857         tmp = apps;
2858         while(tmp) {
2859                 if (!strcasecmp(app, tmp->name)) {
2860                         ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
2861                         ast_mutex_unlock(&applock);
2862                         return -1;
2863                 }
2864                 tmp = tmp->next;
2865         }
2866         tmp = malloc(length);
2867         if (tmp) {
2868                 memset(tmp, 0, length);
2869                 strcpy(tmp->name, app);
2870                 tmp->execute = execute;
2871                 tmp->synopsis = synopsis;
2872                 tmp->description = description;
2873                 /* Store in alphabetical order */
2874                 cur = apps;
2875                 prev = NULL;
2876                 while(cur) {
2877                         if (strcasecmp(tmp->name, cur->name) < 0)
2878                                 break;
2879                         prev = cur;
2880                         cur = cur->next;
2881                 }
2882                 if (prev) {
2883                         tmp->next = prev->next;
2884                         prev->next = tmp;
2885                 } else {
2886                         tmp->next = apps;
2887                         apps = tmp;
2888                 }
2889         } else {
2890                 ast_log(LOG_ERROR, "Out of memory\n");
2891                 ast_mutex_unlock(&applock);
2892                 return -1;
2893         }
2894         if (option_verbose > 1)
2895                 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
2896         ast_mutex_unlock(&applock);
2897         return 0;
2898 }
2899
2900 int ast_register_switch(struct ast_switch *sw)
2901 {
2902         struct ast_switch *tmp, *prev=NULL;
2903         if (ast_mutex_lock(&switchlock)) {
2904                 ast_log(LOG_ERROR, "Unable to lock switch lock\n");
2905                 return -1;
2906         }
2907         tmp = switches;
2908         while(tmp) {
2909                 if (!strcasecmp(tmp->name, sw->name))
2910                         break;
2911                 prev = tmp;
2912                 tmp = tmp->next;
2913         }
2914         if (tmp) {      
2915                 ast_mutex_unlock(&switchlock);
2916                 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
2917                 return -1;
2918         }
2919         sw->next = NULL;
2920         if (prev) 
2921                 prev->next = sw;
2922         else
2923                 switches = sw;
2924         ast_mutex_unlock(&switchlock);
2925         return 0;
2926 }
2927
2928 void ast_unregister_switch(struct ast_switch *sw)
2929 {
2930         struct ast_switch *tmp, *prev=NULL;
2931         if (ast_mutex_lock(&switchlock)) {
2932                 ast_log(LOG_ERROR, "Unable to lock switch lock\n");
2933                 return;
2934         }
2935         tmp = switches;
2936         while(tmp) {
2937                 if (tmp == sw) {
2938                         if (prev)
2939                                 prev->next = tmp->next;
2940                         else
2941                                 switches = tmp->next;
2942                         tmp->next = NULL;
2943                         break;                  
2944                 }
2945                 prev = tmp;
2946                 tmp = tmp->next;
2947         }
2948         ast_mutex_unlock(&switchlock);
2949 }
2950
2951 /*
2952  * Help for CLI commands ...
2953  */
2954 static char show_application_help[] = 
2955 "Usage: show application <application> [<application> [<application> [...]]]\n"
2956 "       Describes a particular application.\n";
2957
2958 static char show_functions_help[] =
2959 "Usage: show functions\n"
2960 "       List builtin functions accessable as $(function args)";
2961
2962 static char show_applications_help[] =
2963 "Usage: show applications [{like|describing} <text>]\n"
2964 "       List applications which are currently available.\n"
2965 "       If 'like', <text> will be a substring of the app name\n"
2966 "       If 'describing', <text> will be a substring of the description\n";
2967
2968 static char show_dialplan_help[] =
2969 "Usage: show dialplan [exten@][context]\n"
2970 "       Show dialplan\n";
2971
2972 static char show_switches_help[] = 
2973 "Usage: show switches\n"
2974 "       Show registered switches\n";
2975
2976 static char show_hints_help[] = 
2977 "Usage: show hints\n"
2978 "       Show registered hints\n";
2979
2980
2981 /*
2982  * IMPLEMENTATION OF CLI FUNCTIONS IS IN THE SAME ORDER AS COMMANDS HELPS
2983  *
2984  */
2985
2986 /*
2987  * 'show application' CLI command implementation functions ...
2988  */
2989
2990 /*
2991  * There is a possibility to show informations about more than one
2992  * application at one time. You can type 'show application Dial Echo' and
2993  * you will see informations about these two applications ...
2994  */
2995 static char *complete_show_application(char *line, char *word,
2996         int pos, int state)
2997 {
2998         struct ast_app *a;
2999         int which = 0;
3000
3001         /* try to lock applications list ... */
3002         if (ast_mutex_lock(&applock)) {
3003                 ast_log(LOG_ERROR, "Unable to lock application list\n");
3004                 return NULL;
3005         }
3006
3007         /* ... walk all applications ... */
3008         a = apps; 
3009         while (a) {
3010                 /* ... check if word matches this application ... */
3011                 if (!strncasecmp(word, a->name, strlen(word))) {
3012                         /* ... if this is right app serve it ... */
3013                         if (++which > state) {
3014                                 char *ret = strdup(a->name);
3015                                 ast_mutex_unlock(&applock);
3016                                 return ret;
3017                         }
3018                 }
3019                 a = a->next; 
3020         }
3021
3022         /* no application match */
3023         ast_mutex_unlock(&applock);
3024         return NULL; 
3025 }
3026
3027 static int handle_show_application(int fd, int argc, char *argv[])
3028 {
3029         struct ast_app *a;