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