bd09b720dff97914d5c8f3d3fd91f18d270e5ce0
[asterisk/asterisk.git] / pbx.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Core PBX routines.
5  * 
6  * Copyright (C) 1999, Mark Spencer
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <asterisk/lock.h>
15 #include <asterisk/cli.h>
16 #include <asterisk/pbx.h>
17 #include <asterisk/channel.h>
18 #include <asterisk/options.h>
19 #include <asterisk/logger.h>
20 #include <asterisk/file.h>
21 #include <asterisk/callerid.h>
22 #include <asterisk/cdr.h>
23 #include <asterisk/term.h>
24 #include <asterisk/manager.h>
25 #include <asterisk/ast_expr.h>
26 #include <asterisk/channel_pvt.h>
27 #include <asterisk/linkedlists.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <setjmp.h>
33 #include <ctype.h>
34 #include <errno.h>
35 #include "asterisk.h"
36
37 /*
38  * I M P O R T A N T :
39  *
40  *              The speed of extension handling will likely be among the most important
41  * aspects of this PBX.  The switching scheme as it exists right now isn't
42  * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
43  * of priorities, but a constant search time here would be great ;-) 
44  *
45  */
46
47
48 struct ast_context;
49
50 struct ast_pbx {
51         int dtimeout;                                   /* Timeout between digits (seconds) */
52         int rtimeout;                                   /* Timeout for response (seconds) */
53 };
54
55 /* An extension */
56 struct ast_exten {
57         char exten[AST_MAX_EXTENSION];
58         int matchcid;
59         char cidmatch[AST_MAX_EXTENSION];
60         int priority;
61         /* An extension */
62         struct ast_context *parent;
63         /* Application to execute */
64         char app[AST_MAX_EXTENSION];
65         /* Data to use */
66         void *data;
67         /* Data destructor */
68         void (*datad)(void *);
69         /* Next higher priority with our extension */
70         struct ast_exten *peer;
71         /* Registrar */
72         char *registrar;
73         /* Extension with a greater ID */
74         struct ast_exten *next;
75 };
76
77 struct ast_include {
78         char name[AST_MAX_EXTENSION];
79         char rname[AST_MAX_EXTENSION];
80         char *registrar;
81         int hastime;
82         unsigned int monthmask;
83         unsigned int daymask;
84         unsigned int dowmask;
85         unsigned int minmask[24];
86         struct ast_include *next;
87 };
88
89 struct ast_sw {
90         char name[AST_MAX_EXTENSION];
91         char *registrar;
92         char data[AST_MAX_EXTENSION];
93         struct ast_sw *next;
94 };
95
96 struct ast_ignorepat {
97         char pattern[AST_MAX_EXTENSION];
98         char *registrar;
99         struct ast_ignorepat *next;
100 };
101
102 /* An extension context */
103 struct ast_context {
104         /* Name of the context */
105         char name[AST_MAX_EXTENSION];
106         /* A lock to prevent multiple threads from clobbering the context */
107         pthread_mutex_t lock;
108         /* The root of the list of extensions */
109         struct ast_exten *root;
110         /* Link them together */
111         struct ast_context *next;
112         /* Include other contexts */
113         struct ast_include *includes;
114         /* Patterns for which to continue playing dialtone */
115         struct ast_ignorepat *ignorepats;
116         /* Registrar */
117         char *registrar;
118         /* Alternative switches */
119         struct ast_sw *alts;
120 };
121
122
123 /* An application */
124 struct ast_app {
125         /* Name of the application */
126         char name[AST_MAX_APP];
127         int (*execute)(struct ast_channel *chan, void *data);
128         char *synopsis;
129         char *description;
130         struct ast_app *next;
131 };
132
133 static int pbx_builtin_prefix(struct ast_channel *, void *);
134 static int pbx_builtin_stripmsd(struct ast_channel *, void *);
135 static int pbx_builtin_answer(struct ast_channel *, void *);
136 static int pbx_builtin_goto(struct ast_channel *, void *);
137 static int pbx_builtin_hangup(struct ast_channel *, void *);
138 static int pbx_builtin_background(struct ast_channel *, void *);
139 static int pbx_builtin_dtimeout(struct ast_channel *, void *);
140 static int pbx_builtin_rtimeout(struct ast_channel *, void *);
141 static int pbx_builtin_atimeout(struct ast_channel *, void *);
142 static int pbx_builtin_wait(struct ast_channel *, void *);
143 static int pbx_builtin_setlanguage(struct ast_channel *, void *);
144 static int pbx_builtin_ringing(struct ast_channel *, void *);
145 static int pbx_builtin_congestion(struct ast_channel *, void *);
146 static int pbx_builtin_busy(struct ast_channel *, void *);
147 static int pbx_builtin_setvar(struct ast_channel *, void *);
148 static int pbx_builtin_setglobalvar(struct ast_channel *, void *);
149 static int pbx_builtin_noop(struct ast_channel *, void *);
150 static int pbx_builtin_gotoif(struct ast_channel *, void *);
151 void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value);
152 char *pbx_builtin_getvar_helper(struct ast_channel *chan, char *name);
153
154 static struct varshead globals = AST_LIST_HEAD_INITIALIZER(varshead);
155
156 static struct pbx_builtin {
157         char name[AST_MAX_APP];
158         int (*execute)(struct ast_channel *chan, void *data);
159         char *synopsis;
160         char *description;
161 } builtins[] = 
162 {
163         /* These applications are built into the PBX core and do not
164            need separate modules */
165         { "Answer", pbx_builtin_answer, 
166 "Answer a channel if ringing", 
167 "  Answer(): If the channel is ringing, answer it, otherwise do nothing. \n"
168 "Returns 0 unless it tries to answer the channel and fails.\n"   },
169
170         { "Goto", pbx_builtin_goto, 
171 "Goto a particular priority, extension, or context",
172 "  Goto([[context|]extension|]priority):  Set the  priority to the specified\n"
173 "value, optionally setting the extension and optionally the context as well.\n"
174 "The extension BYEXTENSION is special in that it uses the current extension,\n"
175 "thus  permitting  you  to go to a different  context, without  specifying a\n"
176 "specific extension. Always returns 0, even if the given context, extension,\n"
177 "or priority is invalid.\n" },
178
179         { "Hangup", pbx_builtin_hangup,
180 "Unconditional hangup",
181 "  Hangup(): Unconditionally hangs up a given channel by returning -1 always.\n" },
182
183         { "DigitTimeout", pbx_builtin_dtimeout,
184 "Set maximum timeout between digits",
185 "  DigitTimeout(seconds): Set the  maximum  amount of time permitted between\n"
186 "digits when the user is typing in an extension.  When this timeout expires,\n"
187 "after the user has started to  type  in an extension, the extension will be\n"
188 "considered  complete, and  will be interpreted.  Note that if an  extension\n"
189 "typed in is valid, it will not have to timeout to be tested,  so  typically\n"
190 "at  the  expiry of  this timeout, the  extension will be considered invalid\n"
191 "(and  thus  control  would be passed to the 'i' extension, or if it doesn't\n"
192 "exist the call would be terminated).  Always returns 0.\n" },
193
194         { "ResponseTimeout", pbx_builtin_rtimeout,
195 "Set maximum timeout awaiting response",
196 "  ResponseTimeout(seconds): Set the maximum amount of time permitted after\n"
197 "falling through a series of priorities for a channel in which the user may\n"
198 "begin typing an extension.  If the user does not type an extension in this\n"
199 "amount of time, control will pass to the 't' extension if  it  exists, and\n"
200 "if not the call would be terminated.  Always returns 0.\n"  },
201
202         { "AbsoluteTimeout", pbx_builtin_atimeout,
203 "Set absolute maximum time of call",
204 "  AbsoluteTimeout(seconds): Set the absolute maximum amount of time permitted\n"
205 "for a call.  A setting of 0 disables the timeout.  Always returns 0.\n" },
206
207         { "BackGround", pbx_builtin_background,
208 "Play a file while awaiting extension",
209 "  Background(filename): Plays a given file, while simultaneously waiting for\n"
210 "the user to begin typing an extension. The  timeouts  do not count until the\n"
211 "last BackGround application as ended. Always returns 0.\n" },
212
213         { "Wait", pbx_builtin_wait, 
214 "Waits for some time", 
215 "  Wait(seconds): Waits for a specified number of seconds, then returns 0.\n" },
216
217         { "StripMSD", pbx_builtin_stripmsd,
218 "Strip leading digits",
219 "  StripMSD(count): Strips the leading  'count'  digits  from  the  channel's\n"
220 "associated extension. For example, the  number  5551212 when stripped with a\n"
221 "count of 3 would be changed to 1212.  This app always returns 0, and the PBX\n"
222 "will continue processing at the next priority for the *new* extension.\n"
223 "  So, for  example, if  priority 3 of 5551212  is  StripMSD 3, the next step\n"
224 "executed will be priority 4 of 1212.  If you switch into an  extension which\n"
225 "has no first step, the PBX will treat it as though the user dialed an\n"
226 "invalid extension.\n" },
227
228         { "Prefix", pbx_builtin_prefix, 
229 "Prepend leading digits",
230 "  Prefix(digits): Prepends the  digit  string  specified  by  digits to the\n"
231 "channel's associated extension. For example, the number 1212 when  prefixed\n"
232 "with '555' will become 5551212. This app always returns 0, and the PBX will\n"
233 "continue processing at the next priority for the *new* extension.\n"
234 "  So, for example, if priority  3  of 1212 is  Prefix  555, the  next  step\n"
235 "executed will be priority 4 of 5551212. If  you  switch  into an  extension\n"
236 "which has no first step, the PBX will treat it as though the user dialed an\n"
237 "invalid extension.\n" },
238
239         { "SetLanguage", pbx_builtin_setlanguage,
240 "Sets user language",
241 "  SetLanguage(language):  Set  the  channel  language to 'language'.  This\n"
242 "information is used for the generation of numbers, and to select a natural\n"
243 "language file when available.  For example, if language is set to 'fr' and\n"
244 "the file 'demo-congrats' is requested  to  be  played,  if the file 'demo-\n"
245 "congrats-fr' exists, then it will play that file, and if not will play the\n"
246 "normal 'demo-congrats'. Always returns 0.\n"  },
247
248         { "Ringing", pbx_builtin_ringing,
249 "Indicate ringing tone",
250 "  Ringing(): Request that the channel indicate ringing tone to the user.\n"
251 "Always returns 0.\n" },
252
253         { "Congestion", pbx_builtin_congestion,
254 "Indicate congestion and stop",
255 "  Congestion(): Requests that the channel indicate congestion and then\n"
256 "waits for the user to hang up.  Always returns -1." },
257
258         { "Busy", pbx_builtin_busy,
259 "Indicate busy condition and stop",
260 "  Busy(): Requests that the channel indicate busy condition and then waits\n"
261 "for the user to hang up.  Always returns -1." },
262
263         { "SetVar", pbx_builtin_setvar,
264 "Set variable to value",
265 "  Setvar(#n=value): Sets variable n to value" },
266
267         { "SetGlobalVar", pbx_builtin_setglobalvar,
268 "Set variable to value",
269 "  Setvar(#n=value): Sets global variable n to value" },
270
271         { "NoOp", pbx_builtin_noop,
272 "No operation",
273 "  NoOp(): No-operation; Does nothing." },
274
275         { "GotoIf", pbx_builtin_gotoif,
276 "Conditional goto",
277 "  GotoIf(Condition?label1:label2): Go to label 1 if condition is\n"
278 "true, to label2 if condition is false. Either label1 or label2 may be\n"
279 "omitted (in that case, we just don't take the particular branch) but not\n"
280 "both.  Look for the condition syntax in examples or documentation." },
281
282 };
283
284 /* Lock for the application list */
285 static pthread_mutex_t applock = AST_MUTEX_INITIALIZER;
286 static struct ast_context *contexts = NULL;
287 /* Lock for the ast_context list */
288 static pthread_mutex_t conlock = AST_MUTEX_INITIALIZER;
289 static struct ast_app *apps = NULL;
290
291 /* Lock for switches */
292 static pthread_mutex_t switchlock = AST_MUTEX_INITIALIZER;
293 struct ast_switch *switches = NULL;
294
295 int pbx_exec(struct ast_channel *c, /* Channel */
296                                         struct ast_app *app,
297                                         void *data,                             /* Data for execution */
298                                         int newstack)                   /* Force stack increment */
299 {
300         /* This function is special.  It saves the stack so that no matter
301            how many times it is called, it returns to the same place */
302         int res;
303         int stack = c->stack;
304         int (*execute)(struct ast_channel *chan, void *data) = app->execute; 
305         if (newstack && stack > AST_CHANNEL_MAX_STACK - 2) {
306                 /* Don't allow us to go over the max number of stacks we
307                    permit saving. */
308                 ast_log(LOG_WARNING, "Stack overflow, cannot create another stack\n");
309                 return -1;
310         }
311         if (newstack && (res = setjmp(c->jmp[++c->stack]))) {
312                 /* Okay, here's where it gets weird.  If newstack is non-zero, 
313                    then we increase the stack increment, but setjmp is not going
314                    to return until longjmp is called -- when the application
315                    exec'd is finished running. */
316                 if (res == 1)
317                         res = 0;
318                 if (c->stack != stack + 1) 
319                         ast_log(LOG_WARNING, "Stack returned to an unexpected place!\n");
320                 else if (c->app[c->stack])
321                         ast_log(LOG_WARNING, "Application may have forgotten to free its memory\n");
322                 c->stack = stack;
323                 return res;
324         } else {
325                 if (c->cdr)
326                         ast_cdr_setapp(c->cdr, app->name, data);
327                 c->appl = app->name;
328                 c->data = data;         
329                 res = execute(c, data);
330                 c->appl = NULL;
331                 c->data = NULL;         
332                 /* Any application that returns, we longjmp back, just in case. */
333                 if (c->stack != stack + 1)
334                         ast_log(LOG_WARNING, "Stack is not at expected value\n");
335                 longjmp(c->jmp[stack+1], res);
336                 /* Never returns */
337         }
338 }
339
340
341 /* Go no deeper than this through includes (not counting loops) */
342 #define AST_PBX_MAX_STACK       64
343
344 #define HELPER_EXISTS 0
345 #define HELPER_SPAWN 1
346 #define HELPER_EXEC 2
347 #define HELPER_CANMATCH 3
348 #define HELPER_MATCHMORE 4
349
350 struct ast_app *pbx_findapp(char *app) 
351 {
352         struct ast_app *tmp;
353         if (ast_pthread_mutex_lock(&applock)) {
354                 ast_log(LOG_WARNING, "Unable to obtain application lock\n");
355                 return NULL;
356         }
357         tmp = apps;
358         while(tmp) {
359                 if (!strcasecmp(tmp->name, app))
360                         break;
361                 tmp = tmp->next;
362         }
363         ast_pthread_mutex_unlock(&applock);
364         return tmp;
365 }
366
367 static struct ast_switch *pbx_findswitch(char *sw)
368 {
369         struct ast_switch *asw;
370         if (ast_pthread_mutex_lock(&switchlock)) {
371                 ast_log(LOG_WARNING, "Unable to obtain application lock\n");
372                 return NULL;
373         }
374         asw = switches;
375         while(asw) {
376                 if (!strcasecmp(asw->name, sw))
377                         break;
378                 asw = asw->next;
379         }
380         ast_pthread_mutex_unlock(&switchlock);
381         return asw;
382 }
383
384 static inline int include_valid(struct ast_include *i)
385 {
386         struct tm *tm;
387         time_t t;
388         if (!i->hastime)
389                 return 1;
390         time(&t);
391         tm = localtime(&t);
392         if (!tm) {
393                 ast_log(LOG_WARNING, "Failed to get local time\n");
394                 return 0;
395         }
396
397         /* If it's not the right month, return */
398         if (!(i->monthmask & (1 << tm->tm_mon))) {
399                 return 0;
400         }
401
402         /* If it's not that time of the month.... */
403         /* Warning, tm_mday has range 1..31! */
404         if (!(i->daymask & (1 << (tm->tm_mday-1))))
405                 return 0;
406
407         /* If it's not the right day of the week */
408         if (!(i->dowmask & (1 << tm->tm_wday)))
409                 return 0;
410
411         /* Sanity check the hour just to be safe */
412         if ((tm->tm_hour < 0) || (tm->tm_hour > 23)) {
413                 ast_log(LOG_WARNING, "Insane time...\n");
414                 return 0;
415         }
416
417         /* Now the tough part, we calculate if it fits
418            in the right time based on min/hour */
419         if (!(i->minmask[tm->tm_hour] & (1 << (tm->tm_min / 2))))
420                 return 0;
421
422         /* If we got this far, then we're good */
423         return 1;
424 }
425
426 static void pbx_destroy(struct ast_pbx *p)
427 {
428         free(p);
429 }
430
431 #define EXTENSION_MATCH_CORE(data,pattern,match) {\
432         /* All patterns begin with _ */\
433         if (pattern[0] != '_') \
434                 return 0;\
435         /* Start optimistic */\
436         match=1;\
437         pattern++;\
438         while(match && *data && *pattern && (*pattern != '/')) {\
439                 switch(toupper(*pattern)) {\
440                 case '[': \
441                 {\
442                         int i,border=0;\
443                         char *where;\
444                         match=0;\
445                         pattern++;\
446                         where=strchr(pattern,']');\
447                         if (where)\
448                                 border=(int)(where-pattern);\
449                         if (!where || border > strlen(pattern)) {\
450                                 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");\
451                                 return match;\
452                         }\
453                         for (i=0; i<border; i++) {\
454                                 int res=0;\
455                                 if (i+2<border)\
456                                         if (pattern[i+1]=='-') {\
457                                                 if (*data >= pattern[i] && *data <= pattern[i+2]) {\
458                                                         res=1;\
459                                                 } else {\
460                                                         i+=2;\
461                                                         continue;\
462                                                 }\
463                                         }\
464                                 if (res==1 || *data==pattern[i]) {\
465                                         match = 1;\
466                                         break;\
467                                 }\
468                         }\
469                         pattern+=border;\
470                         break;\
471                 }\
472                 case 'N':\
473                         if ((*data < '2') || (*data > '9'))\
474                                 match=0;\
475                         break;\
476                 case 'X':\
477                         if ((*data < '0') || (*data > '9'))\
478                                 match = 0;\
479                         break;\
480                 case 'Z':\
481                         if ((*data < '1') || (*data > '9'))\
482                                 match = 0;\
483                         break;\
484                 case '.':\
485                         /* Must match */\
486                         return 1;\
487                 case ' ':\
488                 case '-':\
489                         /* Ignore these characters */\
490                         data--;\
491                         break;\
492                 default:\
493                         if (*data != *pattern)\
494                                 match =0;\
495                 }\
496                 data++;\
497                 pattern++;\
498         }\
499 }
500
501 int ast_extension_match(char *pattern, char *data)
502 {
503         int match;
504         /* If they're the same return */
505         if (!strcasecmp(pattern, data))
506                 return 1;
507         EXTENSION_MATCH_CORE(data,pattern,match);
508         /* Must be at the end of both */
509         if (*data || (*pattern && (*pattern != '/')))
510                 match = 0;
511         return match;
512 }
513
514 static int extension_close(char *pattern, char *data, int needmore)
515 {
516         int match;
517         /* If "data" is longer, it can'be a subset of pattern unless
518            pattern is a pattern match */
519         if ((strlen(pattern) < strlen(data)) && (pattern[0] != '_'))
520                 return 0;
521         
522         if ((!strlen((char *)data) || !strncasecmp(pattern, data, strlen(data))) && 
523                 (!needmore || (strlen(pattern) > strlen(data)))) {
524                 return 1;
525         }
526         EXTENSION_MATCH_CORE(data,pattern,match);
527         /* If there's more or we don't care about more, return non-zero, otlherwise it's a miss */
528         if (!needmore || *pattern) {
529                 return match;
530         } else
531                 return 0;
532 }
533
534 struct ast_context *ast_context_find(char *name)
535 {
536         struct ast_context *tmp;
537         ast_pthread_mutex_lock(&conlock);
538         if (name) {
539                 tmp = contexts;
540                 while(tmp) {
541                         if (!strcasecmp(name, tmp->name))
542                                 break;
543                         tmp = tmp->next;
544                 }
545         } else
546                 tmp = contexts;
547         ast_pthread_mutex_unlock(&conlock);
548         return tmp;
549 }
550
551 #define STATUS_NO_CONTEXT   1
552 #define STATUS_NO_EXTENSION 2
553 #define STATUS_NO_PRIORITY  3
554 #define STATUS_SUCCESS      4
555
556 static int matchcid(char *cidpattern, char *callerid)
557 {
558         char tmp[AST_MAX_EXTENSION];
559         int failresult;
560         char *name, *num;
561         
562         /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
563            failing to get a number should count as a match, otherwise not */
564
565
566         if (strlen(cidpattern))
567                 failresult = 0;
568         else
569                 failresult = 1;
570
571         if (!callerid)
572                 return failresult;
573
574         /* Copy original Caller*ID */
575         strncpy(tmp, callerid, sizeof(tmp)-1);
576         /* Parse Number */
577         if (ast_callerid_parse(tmp, &name, &num)) 
578                 return failresult;
579         if (!num)
580                 return failresult;
581         ast_shrink_phone_number(num);
582         return ast_extension_match(cidpattern, num);
583 }
584
585 static struct ast_exten *pbx_find_extension(struct ast_channel *chan, char *context, char *exten, int priority, char *callerid, int action, char *incstack[], int *stacklen, int *status, struct ast_switch **swo, char **data)
586 {
587         int x, res;
588         struct ast_context *tmp;
589         struct ast_exten *e, *eroot;
590         struct ast_include *i;
591         struct ast_sw *sw;
592         struct ast_switch *asw;
593         /* Initialize status if appropriate */
594         if (!*stacklen) {
595                 *status = STATUS_NO_CONTEXT;
596                 *swo = NULL;
597                 *data = NULL;
598         }
599         /* Check for stack overflow */
600         if (*stacklen >= AST_PBX_MAX_STACK) {
601                 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
602                 return NULL;
603         }
604         /* Check first to see if we've already been checked */
605         for (x=0;x<*stacklen;x++) {
606                 if (!strcasecmp(incstack[x], context))
607                         return NULL;
608         }
609         tmp = contexts;
610         while(tmp) {
611                 /* Match context */
612                 if (!strcasecmp(tmp->name, context)) {
613                         if (*status < STATUS_NO_EXTENSION)
614                                 *status = STATUS_NO_EXTENSION;
615                         eroot = tmp->root;
616                         while(eroot) {
617                                 /* Match extension */
618                                 if ((((action != HELPER_MATCHMORE) && ast_extension_match(eroot->exten, exten)) ||
619                                                 ((action == HELPER_CANMATCH) && (extension_close(eroot->exten, exten, 0))) ||
620                                                 ((action == HELPER_MATCHMORE) && (extension_close(eroot->exten, exten, 1)))) &&
621                                                 (!eroot->matchcid || matchcid(eroot->cidmatch, callerid))) {
622                                                 e = eroot;
623                                                 if (*status < STATUS_NO_PRIORITY)
624                                                         *status = STATUS_NO_PRIORITY;
625                                                 while(e) {
626                                                         /* Match priority */
627                                                         if (e->priority == priority) {
628                                                                 *status = STATUS_SUCCESS;
629                                                                 return e;
630                                                         }
631                                                         e = e->peer;
632                                                 }
633                                 }
634                                 eroot = eroot->next;
635                         }
636                         /* Check alternative switches */
637                         sw = tmp->alts;
638                         while(sw) {
639                                 if ((asw = pbx_findswitch(sw->name))) {
640                                         if (action == HELPER_CANMATCH)
641                                                 res = asw->canmatch ? asw->canmatch(chan, context, exten, priority, callerid, sw->data) : 0;
642                                         else if (action == HELPER_MATCHMORE)
643                                                 res = asw->matchmore ? asw->matchmore(chan, context, exten, priority, callerid, sw->data) : 0;
644                                         else
645                                                 res = asw->exists ? asw->exists(chan, context, exten, priority, callerid, sw->data) : 0;
646                                         if (res) {
647                                                 /* Got a match */
648                                                 *swo = asw;
649                                                 *data = sw->data;
650                                                 return NULL;
651                                         }
652                                 } else {
653                                         ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
654                                 }
655                                 sw = sw->next;
656                         }
657                         /* Setup the stack */
658                         incstack[*stacklen] = tmp->name;
659                         (*stacklen)++;
660                         /* Now try any includes we have in this context */
661                         i = tmp->includes;
662                         while(i) {
663                                 if (include_valid(i)) {
664                                         if ((e = pbx_find_extension(chan, i->rname, exten, priority, callerid, action, incstack, stacklen, status, swo, data))) 
665                                                 return e;
666                                         if (*swo) 
667                                                 return NULL;
668                                 }
669                                 i = i->next;
670                         }
671                 }
672                 tmp = tmp->next;
673         }
674         return NULL;
675 }
676
677 static void pbx_substitute_variables_temp(struct ast_channel *c,char *cp3,char **cp4)
678 {
679         int offset;
680         struct ast_var_t *variables;
681         char *name, *num; /* for callerid name + num variables */
682         struct varshead *headp;
683         char pri[80];
684         headp=&c->varshead;
685         *cp4=NULL;
686                                 /* Now we have the variable name on cp3 */
687                                 if (!strcmp(cp3, "CALLERIDNUM")) {
688                                                 char cid[256] = "";
689                                                 if (c->callerid)
690                                                         strncpy(cid, c->callerid, sizeof(cid) - 1);
691                                                 ast_callerid_parse(cid, &name, &num);
692                                                 if (num) {
693                                                         ast_shrink_phone_number(num);
694                                                         *cp4 = num;
695                                                 } else
696                                                         *cp4 = "";
697                                         } else if (!strcmp(cp3, "CALLERIDNAME")) {
698                                                 char cid[256] = "";
699                                                 if (c->callerid)
700                                                         strncpy(cid, c->callerid, sizeof(cid) - 1);
701                                                 ast_callerid_parse(cid, &name, &num);
702                                                 if (name)
703                                                         *cp4 = name;
704                                                 else
705                                                         *cp4 = "";
706                                         } else if (!strcmp(cp3, "CALLERID")) {
707                                                 *cp4 = c->callerid;
708                                                 if (!(*cp4))
709                                                         *cp4 = "";
710                                         } else if (!strcmp(cp3, "EXTEN")) {
711                                                 *cp4 = c->exten;
712                                         } else if (!strncmp(cp3, "EXTEN-", strlen("EXTEN-")) && 
713                                                 (sscanf(cp3 + strlen("EXTEN-"), "%d", &offset) == 1)) {
714                                                 if (offset < 0)
715                                                         offset=0;
716                                                 if (offset > strlen(c->exten))
717                                                         offset = strlen(c->exten);
718                                                 *cp4 = c->exten + offset;
719                                         } else if (!strcmp(cp3, "RDNIS")) {
720                                                 *cp4 = c->rdnis;
721                                                 if (!(*cp4))
722                                                         *cp4 = "";
723                                         } else if (!strcmp(cp3, "CONTEXT")) {
724                                                 *cp4 = c->context;
725                                         } else if (!strcmp(cp3, "PRIORITY")) {
726                                                 snprintf(pri, sizeof(pri), "%d", c->priority);
727                                                 *cp4 = pri;
728                                         } else {
729                                         AST_LIST_TRAVERSE(headp,variables,entries) {
730 //                                              ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",cp3,ast_var_name(variables));
731                                                         if (strncasecmp(ast_var_name(variables),cp3,strlen(cp3))==0)
732                                                                 *cp4=ast_var_value(variables);
733                                                 }
734                                                 if (!(*cp4)) {
735                                                         /* Try globals */
736                                                 AST_LIST_TRAVERSE(&globals,variables,entries) {
737 //                                                      ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",cp3,ast_var_name(variables));
738                                                                 if (strncasecmp(ast_var_name(variables),cp3,strlen(cp3))==0)
739                                                                         *cp4=ast_var_value(variables);
740                                                         }
741                                                 }
742                                         }
743 }
744
745 static void pbx_substitute_variables_helper(struct ast_channel *c,char *cp1,char **ecp2)
746 {
747         char *cp4,*cp2;
748         char *tmp,*wherearewe,*finish;
749         int length;
750
751         wherearewe=tmp=cp1;
752         cp2=*ecp2;
753         *cp2='\0';
754         do {
755                 if (!(*wherearewe)) break;
756                 if ((tmp=strstr(wherearewe,"${"))) {
757                         length=(int)(tmp-wherearewe);
758                         strncat(cp2,wherearewe,length);
759                         wherearewe=tmp;
760                         if (!strncmp(tmp+2,"${",2)) {
761                                 char *ltmp,*lval;
762                                 ltmp=malloc(sizeof(char)*256);
763                                 finish=strchr(tmp+2,'}');
764                                 /* get the one before the last closing bracket */
765                                 do {
766                                         if (strlen(finish)<2)
767                                                 break;
768                                         if (finish[1]=='}' && finish[2]=='}')
769                                                 finish++;
770                                         else break;
771                                 } while (1);
772                                 
773                                 if (!finish) {
774                                         ast_log(LOG_WARNING, "Something went wrong with ${VARIABLE}\n");
775                                         *ecp2="";
776                                         break;
777                                 }
778                                 length=(int)(finish-tmp-1);
779                                 wherearewe+=length+3;
780                                 lval=strndup(tmp+2,length);
781                                 pbx_substitute_variables_helper(c,lval,&ltmp);
782                                 free(lval);
783                                 pbx_substitute_variables_temp(c,ltmp,&cp4);
784                                 if (cp4) {
785                                         length=strlen(cp4);
786                                         strncat(cp2,cp4,length);
787                                 }
788                         } else {
789                                 char value[256];
790                                 finish=strchr(tmp+2,'}');
791                                 if (!finish) {
792                                         ast_log(LOG_WARNING, "Something went wrong with ${VARIABLE}\n");
793                                         *ecp2="";
794                                         break;                                  
795                                 }
796                                 length=(int)(finish-tmp)-2;
797                                 wherearewe+=length+3;
798                                 strncpy(value,tmp+2,length);
799                                 value[length]='\0';
800                                 pbx_substitute_variables_temp(c,value,&cp4);
801                                 if (cp4) {
802                                         length=strlen(cp4);
803                                         strncat(cp2,cp4,length);
804                                 }
805                         }
806                 } else {
807                         if (*wherearewe) {
808                                 length=strlen(wherearewe);
809                                 strncat(cp2,wherearewe,length);
810                         }
811                         strcat(cp2,"\0");
812                         break;
813                 }
814         } while(1);
815 }
816
817 static void *pbx_substitute_variables(struct ast_channel *c, struct ast_exten *e) {
818         char *cp1,*cp3,*cp4,*cp5;
819         char *cp2;
820         char c1,c2;
821         int m,mve,origlen,quoted,dolsign,docopy;
822         
823         /* No variables or expressions in e->data, so why scan it? */
824         if (!strstr(e->data,"${") && !strstr(e->data,"$[")) {
825                 return strndup(e->data,strlen(e->data)+1);
826         }
827         
828         cp1=e->data;
829         cp2=malloc(sizeof(char)*256);
830         pbx_substitute_variables_helper(c,cp1,(char **)&cp2);
831
832         /* Second stage, expression evaluation */
833         if ((strstr(cp2,"$[")==NULL)) {
834                 /* No expressions in cp2, return it */
835                 return(cp2);
836         }
837         /* else, do expression evaluation */
838         
839         dolsign=0;
840         docopy=1;
841         origlen=strlen(cp2)+1;
842         
843         cp5=malloc(origlen);
844         memset(cp5,0,origlen);
845         cp4=NULL;
846         cp1=cp2;
847         quoted=0;
848         
849         do {
850                 c1=*cp1;
851                 mve=0;
852                 switch (c1) {
853                         case '$' : 
854                                 dolsign=1;
855                                 docopy=0;
856                                 break;
857                         case '[' :
858                                 if (dolsign==0) {
859                                         docopy=1;
860                                         dolsign=0;
861                                         break;
862                                 }
863                                 dolsign=0;
864                                 docopy=0;
865                                 m=0;
866                                 mve=1;
867                                 cp1++;
868                                 
869                                 while (((c2=*(cp1+m))!=']') && (c2!='\0')) {
870                                         m++;
871                                 }
872                                 cp3=malloc(m+2);
873                                 strncpy(cp3,cp1,m);
874                                 cp3[m]='\0';
875                                 cp1+=m;
876                                 /* Now we have the expression to evaluate on cp3 */
877                                 cp4=ast_expr(cp3);
878                                 free(cp3);
879                                 break;
880                         default :
881                                 if (dolsign==1) {
882                                         strncat((char *)cp5,"$",1);
883                                 }
884                                 dolsign=0;
885                                 docopy=1;
886                                 mve=0;
887                                 break;
888                 }
889                 if (cp1!='\0') {
890                         if (mve==0) {
891                                 if (docopy==1) {
892                                         strncat((char *)cp5,&c1,1);
893                                 }
894                         } else {
895                                 if (cp4!=NULL) {
896                                         cp5=realloc(cp5,origlen+strlen(cp4)+1);
897                                         strncat((char *)cp5,cp4,strlen(cp4));
898                                         free(cp4);
899                                 } else {
900                                         ast_log(LOG_WARNING,"mve!=0 and cp4=NULL, something gone astray\n");
901                                 }
902                         }
903                 }
904                         
905         } while (*cp1++!='\0');
906         free(cp2);
907         return(cp5);
908 }
909                                 
910                         
911                                                                 
912
913 static int pbx_extension_helper(struct ast_channel *c, char *context, char *exten, int priority, char *callerid, int action) 
914 {
915         struct ast_exten *e;
916         struct ast_app *app;
917         struct ast_switch *sw;
918         char *data;
919         char *newdata;
920         int newstack = 0;
921         int res;
922         int status = 0;
923         char *incstack[AST_PBX_MAX_STACK];
924         int stacklen = 0;
925         char tmp[80];
926         char tmp2[80];
927         char tmp3[256];
928         if (ast_pthread_mutex_lock(&conlock)) {
929                 ast_log(LOG_WARNING, "Unable to obtain lock\n");
930                 if ((action == HELPER_EXISTS) || (action == HELPER_CANMATCH) || (action == HELPER_MATCHMORE))
931                         return 0;
932                 else
933                         return -1;
934         }
935         e = pbx_find_extension(c, context, exten, priority, callerid, action, incstack, &stacklen, &status, &sw, &data);
936         if (e) {
937                 switch(action) {
938                 case HELPER_CANMATCH:
939                         pthread_mutex_unlock(&conlock);
940                         return -1;
941                 case HELPER_EXISTS:
942                         pthread_mutex_unlock(&conlock);
943                         return -1;
944                 case HELPER_MATCHMORE:
945                         pthread_mutex_unlock(&conlock);
946                         return -1;
947                 case HELPER_SPAWN:
948                         newstack++;
949                         /* Fall through */
950                 case HELPER_EXEC:
951                         app = pbx_findapp(e->app);
952                         pthread_mutex_unlock(&conlock);
953                         if (app) {
954                                 strncpy(c->context, context, sizeof(c->context-1));
955                                 strncpy(c->exten, exten, sizeof(c->exten)-1);
956                                 c->priority = priority;
957                                 newdata=pbx_substitute_variables(c,e);
958                                 if (option_debug)
959                                                 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
960                                 else if (option_verbose > 2)
961                                                 ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n", 
962                                                                 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
963                                                                 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
964                                                                 term_color(tmp3, (newdata ? (char *)newdata : NULL), COLOR_BRMAGENTA, 0, sizeof(tmp3)),
965                                                                 (newstack ? "in new stack" : "in same stack"));
966                                 res = pbx_exec(c, app, newdata, newstack);
967                                 free(newdata);
968                                 return res;
969                         } else {
970                                 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
971                                 return -1;
972                         }
973                 default:
974                         ast_log(LOG_WARNING, "Huh (%d)?\n", action);                    return -1;
975                 }
976         } else if (sw) {
977                 switch(action) {
978                 case HELPER_CANMATCH:
979                         pthread_mutex_unlock(&conlock);
980                         return -1;
981                 case HELPER_EXISTS:
982                         pthread_mutex_unlock(&conlock);
983                         return -1;
984                 case HELPER_MATCHMORE:
985                         pthread_mutex_unlock(&conlock);
986                         return -1;
987                 case HELPER_SPAWN:
988                         newstack++;
989                         /* Fall through */
990                 case HELPER_EXEC:
991                         pthread_mutex_unlock(&conlock);
992                         if (sw->exec)
993                                 res = sw->exec(c, context, exten, priority, callerid, newstack, data);
994                         else {
995                                 ast_log(LOG_WARNING, "No execution engine for switch %s\n", sw->name);
996                                 res = -1;
997                         }
998                         return res;
999                 default:
1000                         ast_log(LOG_WARNING, "Huh (%d)?\n", action);
1001                         return -1;
1002                 }
1003         } else {
1004                 pthread_mutex_unlock(&conlock);
1005                 switch(status) {
1006                 case STATUS_NO_CONTEXT:
1007                         if ((action != HELPER_EXISTS) && (action != HELPER_MATCHMORE))
1008                                 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
1009                         break;
1010                 case STATUS_NO_EXTENSION:
1011                         if ((action != HELPER_EXISTS) && (action !=  HELPER_CANMATCH) && (action != HELPER_MATCHMORE))
1012                                 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
1013                         break;
1014                 case STATUS_NO_PRIORITY:
1015                         if ((action != HELPER_EXISTS) && (action !=  HELPER_CANMATCH) && (action != HELPER_MATCHMORE))
1016                                 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
1017                         break;
1018                 default:
1019                         ast_log(LOG_DEBUG, "Shouldn't happen!\n");
1020                 }
1021                 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE))
1022                         return -1;
1023                 else
1024                         return 0;
1025         }
1026
1027 }
1028
1029 int ast_exists_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid) 
1030 {
1031         return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_EXISTS);
1032 }
1033
1034 int ast_canmatch_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid)
1035 {
1036         return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_CANMATCH);
1037 }
1038
1039 int ast_matchmore_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid)
1040 {
1041         return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_MATCHMORE);
1042 }
1043
1044 int ast_spawn_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid) 
1045 {
1046         return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_SPAWN);
1047 }
1048
1049 int ast_pbx_run(struct ast_channel *c)
1050 {
1051         int firstpass = 1;
1052         char digit;
1053         char exten[256];
1054         int pos;
1055         int waittime;
1056         int res=0;
1057
1058         /* A little initial setup here */
1059         if (c->pbx)
1060                 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
1061         c->pbx = malloc(sizeof(struct ast_pbx));
1062         if (!c->pbx) {
1063                 ast_log(LOG_WARNING, "Out of memory\n");
1064                 return -1;
1065         }
1066         if (c->amaflags) {
1067                 if (c->cdr) {
1068                         ast_log(LOG_WARNING, "%s already has a call record??\n", c->name);
1069                 } else {
1070                         c->cdr = ast_cdr_alloc();
1071                         if (!c->cdr) {
1072                                 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
1073                                 free(c->pbx);
1074                                 return -1;
1075                         }
1076                         ast_cdr_init(c->cdr, c);
1077                 }
1078         }
1079         memset(c->pbx, 0, sizeof(struct ast_pbx));
1080         /* Set reasonable defaults */
1081         c->pbx->rtimeout = 10;
1082         c->pbx->dtimeout = 5;
1083
1084         if (option_debug)
1085                 ast_log(LOG_DEBUG, "PBX_THREAD(%s)\n", c->name);
1086         else if (option_verbose > 1) {
1087                 if (c->callerid)
1088                         ast_verbose( VERBOSE_PREFIX_2 "Accepting call on '%s' (%s)\n", c->name, c->callerid);
1089                 else
1090                         ast_verbose( VERBOSE_PREFIX_2 "Accepting call on '%s'\n", c->name);
1091         }
1092                 
1093         /* Start by trying whatever the channel is set to */
1094         if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
1095                 /* JK02: If not successfull fall back to 's' */
1096                 strncpy(c->exten, "s", sizeof(c->exten)-1);
1097                 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
1098                         /* JK02: And finally back to default if everything else failed */
1099                         strncpy(c->context, "default", sizeof(c->context)-1);
1100                 }
1101                 c->priority = 1;
1102         }
1103         if (c->cdr)
1104                 ast_cdr_start(c->cdr);
1105         for(;;) {
1106                 pos = 0;
1107                 digit = 0;
1108                 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
1109                         memset(exten, 0, sizeof(exten));
1110                         manager_event(EVENT_FLAG_CALL, "Newexten", 
1111                                 "Channel: %s\r\n"
1112                                 "Context: %s\r\n"
1113                                 "Extension: %s\r\n"
1114                                 "Priority: %d\r\n",
1115                                 c->name, c->context, c->exten, c->priority);                    
1116                         if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->callerid))) {
1117                                 /* Something bad happened, or a hangup has been requested. */
1118                                 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F'))) {
1119                                         ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
1120                                         exten[pos++] = digit = res;
1121                                         break;
1122                                 }
1123                                 switch(res) {
1124                                 case AST_PBX_KEEPALIVE:
1125                                         if (option_debug)
1126                                                 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
1127                                         else if (option_verbose > 1)
1128                                                 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
1129                                         goto out;
1130                                         break;
1131                                 default:
1132                                         if (option_debug)
1133                                                 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
1134                                         else if (option_verbose > 1)
1135                                                 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
1136                                         if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
1137                                                 c->_softhangup =0;
1138                                                 break;
1139                                         }
1140                                         goto out;
1141                                 }
1142                         }
1143                         if (c->_softhangup) {
1144                                 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
1145                                         c->exten, c->priority);
1146                                 goto out;
1147                         }
1148                         firstpass = 0;
1149                         c->priority++;
1150                 }
1151                 if (!ast_exists_extension(c, c->context, c->exten, 1, c->callerid)) {
1152                         /* It's not a valid extension anymore */
1153                         if (ast_exists_extension(c, c->context, "i", 1, c->callerid)) {
1154                                 if (option_verbose > 2)
1155                                         ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
1156                                 strncpy(c->exten, "i", sizeof(c->exten)-1);
1157                                 c->priority = 1;
1158                         } else {
1159                                 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
1160                                         c->name, c->exten, c->context);
1161                                 goto out;
1162                         }
1163                 } else {
1164                         /* Done, wait for an extension */
1165                         if (digit)
1166                                 waittime = c->pbx->dtimeout;
1167                         else
1168                                 waittime = c->pbx->rtimeout;
1169                         while (ast_matchmore_extension(c, c->context, exten, 1, c->callerid)) {
1170                                 /* As long as we're willing to wait, and as long as it's not defined, 
1171                                    keep reading digits until we can't possibly get a right answer anymore.  */
1172                                 digit = ast_waitfordigit(c, waittime * 1000);
1173                                 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
1174                                         c->_softhangup = 0;
1175                                 } else {
1176                                         if (!digit)
1177                                                 /* No entry */
1178                                                 break;
1179                                         if (digit < 0)
1180                                                 /* Error, maybe a  hangup */
1181                                                 goto out;
1182                                         exten[pos++] = digit;
1183                                         waittime = c->pbx->dtimeout;
1184                                 }
1185                         }
1186                         if (ast_exists_extension(c, c->context, exten, 1, c->callerid)) {
1187                                 /* Prepare the next cycle */
1188                                 strncpy(c->exten, exten, sizeof(c->exten)-1);
1189                                 c->priority = 1;
1190                         } else {
1191                                 /* No such extension */
1192                                 if (strlen(exten)) {
1193                                         /* An invalid extension */
1194                                         if (ast_exists_extension(c, c->context, "i", 1, c->callerid)) {
1195                                                 if (option_verbose > 2)
1196                                                         ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name);
1197                                                 strncpy(c->exten, "i", sizeof(c->exten)-1);
1198                                                 c->priority = 1;
1199                                         } else {
1200                                                 ast_log(LOG_WARNING, "Invalid extension, but no rule 'i' in context '%s'\n", c->context);
1201                                                 goto out;
1202                                         }
1203                                 } else {
1204                                         /* A simple timeout */
1205                                         if (ast_exists_extension(c, c->context, "t", 1, c->callerid)) {
1206                                                 if (option_verbose > 2)
1207                                                         ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
1208                                                 strncpy(c->exten, "t", sizeof(c->exten)-1);
1209                                                 c->priority = 1;
1210                                         } else {
1211                                                 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
1212                                                 goto out;
1213                                         }
1214                                 }       
1215                         }
1216                 }
1217         }
1218         if (firstpass) 
1219                 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
1220 out:
1221         if (ast_exists_extension(c, c->context, "h", 1, c->callerid)) {
1222                 strcpy(c->exten, "h");
1223                 c->priority = 1;
1224                 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
1225                         if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->callerid))) {
1226                                 /* Something bad happened, or a hangup has been requested. */
1227                                 if (option_debug)
1228                                         ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
1229                                 else if (option_verbose > 1)
1230                                         ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
1231                                 break;
1232                         }
1233                         c->priority++;
1234                 }
1235         }
1236
1237         pbx_destroy(c->pbx);
1238         c->pbx = NULL;
1239         if (res != AST_PBX_KEEPALIVE)
1240                 ast_hangup(c);
1241         return 0;
1242 }
1243
1244 static void *pbx_thread(void *data)
1245 {
1246         /* Oh joyeous kernel, we're a new thread, with nothing to do but
1247            answer this channel and get it going.  The setjmp stuff is fairly
1248            confusing, but necessary to get smooth transitions between
1249            the execution of different applications (without the use of
1250            additional threads) */
1251         struct ast_channel *c = data;
1252         ast_pbx_run(c);
1253         pthread_exit(NULL);
1254         return NULL;
1255 }
1256
1257 int ast_pbx_start(struct ast_channel *c)
1258 {
1259         pthread_t t;
1260         pthread_attr_t attr;
1261         if (!c) {
1262                 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
1263                 return -1;
1264         }
1265            
1266         /* Start a new thread, and get something handling this channel. */
1267         pthread_attr_init(&attr);
1268         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1269         if (pthread_create(&t, &attr, pbx_thread, c)) {
1270                 ast_log(LOG_WARNING, "Failed to create new channel thread\n");
1271                 return -1;
1272         }
1273         return 0;
1274 }
1275
1276 /*
1277  * This function locks contexts list by &conlist, search for the rigt context
1278  * structure, leave context list locked and call ast_context_remove_include2
1279  * which removes include, unlock contexts list and return ...
1280  */
1281 int ast_context_remove_include(char *context, char *include, char *registrar)
1282 {
1283         struct ast_context *c;
1284
1285         if (ast_lock_contexts()) return -1;
1286
1287         /* walk contexts and search for the right one ...*/
1288         c = ast_walk_contexts(NULL);
1289         while (c) {
1290                 /* we found one ... */
1291                 if (!strcmp(ast_get_context_name(c), context)) {
1292                         int ret;
1293                         /* remove include from this context ... */      
1294                         ret = ast_context_remove_include2(c, include, registrar);
1295
1296                         ast_unlock_contexts();
1297
1298                         /* ... return results */
1299                         return ret;
1300                 }
1301                 c = ast_walk_contexts(c);
1302         }
1303
1304         /* we can't find the right one context */
1305         ast_unlock_contexts();
1306         return -1;
1307 }
1308
1309 /*
1310  * When we call this function, &conlock lock must be locked, because when
1311  * we giving *con argument, some process can remove/change this context
1312  * and after that there can be segfault.
1313  *
1314  * This function locks given context, removes include, unlock context and
1315  * return.
1316  */
1317 int ast_context_remove_include2(struct ast_context *con, char *include, char *registrar)
1318 {
1319         struct ast_include *i, *pi = NULL;
1320
1321         if (ast_pthread_mutex_lock(&con->lock)) return -1;
1322
1323         /* walk includes */
1324         i = con->includes;
1325         while (i) {
1326                 /* find our include */
1327                 if (!strcmp(i->name, include) && 
1328                         (!strcmp(i->registrar, registrar) || !registrar)) {
1329                         /* remove from list */
1330                         if (pi)
1331                                 pi->next = i->next;
1332                         else
1333                                 con->includes = i->next;
1334                         /* free include and return */
1335                         free(i);
1336                         ast_pthread_mutex_unlock(&con->lock);
1337                         return 0;
1338                 }
1339                 pi = i;
1340                 i = i->next;
1341         }
1342
1343         /* we can't find the right include */
1344         ast_pthread_mutex_unlock(&con->lock);
1345         return -1;
1346 }
1347
1348 /*
1349  * This function locks contexts list by &conlist, search for the rigt context
1350  * structure, leave context list locked and call ast_context_remove_switch2
1351  * which removes switch, unlock contexts list and return ...
1352  */
1353 int ast_context_remove_switch(char *context, char *sw, char *data, char *registrar)
1354 {
1355         struct ast_context *c;
1356
1357         if (ast_lock_contexts()) return -1;
1358
1359         /* walk contexts and search for the right one ...*/
1360         c = ast_walk_contexts(NULL);
1361         while (c) {
1362                 /* we found one ... */
1363                 if (!strcmp(ast_get_context_name(c), context)) {
1364                         int ret;
1365                         /* remove switch from this context ... */       
1366                         ret = ast_context_remove_switch2(c, sw, data, registrar);
1367
1368                         ast_unlock_contexts();
1369
1370                         /* ... return results */
1371                         return ret;
1372                 }
1373                 c = ast_walk_contexts(c);
1374         }
1375
1376         /* we can't find the right one context */
1377         ast_unlock_contexts();
1378         return -1;
1379 }
1380
1381 /*
1382  * When we call this function, &conlock lock must be locked, because when
1383  * we giving *con argument, some process can remove/change this context
1384  * and after that there can be segfault.
1385  *
1386  * This function locks given context, removes switch, unlock context and
1387  * return.
1388  */
1389 int ast_context_remove_switch2(struct ast_context *con, char *sw, char *data, char *registrar)
1390 {
1391         struct ast_sw *i, *pi = NULL;
1392
1393         if (ast_pthread_mutex_lock(&con->lock)) return -1;
1394
1395         /* walk switchs */
1396         i = con->alts;
1397         while (i) {
1398                 /* find our switch */
1399                 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 
1400                         (!strcmp(i->registrar, registrar) || !registrar)) {
1401                         /* remove from list */
1402                         if (pi)
1403                                 pi->next = i->next;
1404                         else
1405                                 con->alts = i->next;
1406                         /* free switch and return */
1407                         free(i);
1408                         ast_pthread_mutex_unlock(&con->lock);
1409                         return 0;
1410                 }
1411                 pi = i;
1412                 i = i->next;
1413         }
1414
1415         /* we can't find the right switch */
1416         ast_pthread_mutex_unlock(&con->lock);
1417         return -1;
1418 }
1419
1420 /*
1421  * This functions lock contexts list, search for the right context,
1422  * call ast_context_remove_extension2, unlock contexts list and return.
1423  * In this function we are using
1424  */
1425 int ast_context_remove_extension(char *context, char *extension, int priority, char *registrar)
1426 {
1427         struct ast_context *c;
1428
1429         if (ast_lock_contexts()) return -1;
1430
1431         /* walk contexts ... */
1432         c = ast_walk_contexts(NULL);
1433         while (c) {
1434                 /* ... search for the right one ... */
1435                 if (!strcmp(ast_get_context_name(c), context)) {
1436                         /* ... remove extension ... */
1437                         int ret = ast_context_remove_extension2(c, extension, priority,
1438                                 registrar);
1439                         /* ... unlock contexts list and return */
1440                         ast_unlock_contexts();
1441                         return ret;
1442                 }
1443                 c = ast_walk_contexts(c);
1444         }
1445
1446         /* we can't find the right context */
1447         ast_unlock_contexts();
1448         return -1;
1449 }
1450
1451 /*
1452  * When do you want to call this function, make sure that &conlock is locked,
1453  * because some process can handle with your *con context before you lock
1454  * it.
1455  *
1456  * This functionc locks given context, search for the right extension and
1457  * fires out all peer in this extensions with given priority. If priority
1458  * is set to 0, all peers are removed. After that, unlock context and
1459  * return.
1460  */
1461 int ast_context_remove_extension2(struct ast_context *con, char *extension, int priority, char *registrar)
1462 {
1463         struct ast_exten *exten, *prev_exten = NULL;
1464
1465         if (ast_pthread_mutex_lock(&con->lock)) return -1;
1466
1467         /* go through all extensions in context and search the right one ... */
1468         exten = con->root;
1469         while (exten) {
1470
1471                 /* look for right extension */
1472                 if (!strcmp(exten->exten, extension) &&
1473                         (!strcmp(exten->registrar, registrar) || !registrar)) {
1474                         struct ast_exten *peer;
1475
1476                         /* should we free all peers in this extension? (priority == 0)? */
1477                         if (priority == 0) {
1478                                 /* remove this extension from context list */
1479                                 if (prev_exten)
1480                                         prev_exten->next = exten->next;
1481                                 else
1482                                         con->root = exten->next;
1483
1484                                 /* fire out all peers */
1485                                 peer = exten; 
1486                                 while (peer) {
1487                                         exten = peer->peer;
1488
1489                                         peer->datad(peer->data);
1490                                         free(peer);
1491
1492                                         peer = exten;
1493                                 }
1494
1495                                 ast_pthread_mutex_unlock(&con->lock);
1496                                 return 0;
1497                         } else {
1498                                 /* remove only extension with exten->priority == priority */
1499                                 struct ast_exten *previous_peer = NULL;
1500
1501                                 peer = exten;
1502                                 while (peer) {
1503                                         /* is this our extension? */
1504                                         if (peer->priority == priority &&
1505                                                 (!strcmp(peer->registrar, registrar) || !registrar)) {
1506                                                 /* we are first priority extension? */
1507                                                 if (!previous_peer) {
1508                                                         /* exists previous extension here? */
1509                                                         if (prev_exten) {
1510                                                                 /* yes, so we must change next pointer in
1511                                                                  * previous connection to next peer
1512                                                                  */
1513                                                                 if (peer->peer) {
1514                                                                         prev_exten->next = peer->peer;
1515                                                                         peer->peer->next = exten->next;
1516                                                                 } else
1517                                                                         prev_exten->next = exten->next;
1518                                                         } else {
1519                                                                 /* no previous extension, we are first
1520                                                                  * extension, so change con->root ...
1521                                                                  */
1522                                                                 if (peer->peer)
1523                                                                         con->root = peer->peer;
1524                                                                 else
1525                                                                         con->root = exten->next; 
1526                                                         }
1527                                                 } else {
1528                                                         /* we are not first priority in extension */
1529                                                         previous_peer->peer = peer->peer;
1530                                                 }
1531
1532                                                 /* now, free whole priority extension */
1533                                                 peer->datad(peer->data);
1534                                                 free(peer);
1535
1536                                                 ast_pthread_mutex_unlock(&con->lock);
1537                                                 return 0;
1538                                         } else {
1539                                                 /* this is not right extension, skip to next peer */
1540                                                 previous_peer = peer;
1541                                                 peer = peer->peer;
1542                                         }
1543                                 }
1544
1545                                 ast_pthread_mutex_unlock(&con->lock);
1546                                 return -1;
1547                         }
1548                 }
1549
1550                 prev_exten = exten;
1551                 exten = exten->next;
1552         }
1553
1554         /* we can't find right extension */
1555         ast_pthread_mutex_unlock(&con->lock);
1556         return -1;
1557 }
1558
1559
1560 int ast_register_application(char *app, int (*execute)(struct ast_channel *, void *), char *synopsis, char *description)
1561 {
1562         struct ast_app *tmp;
1563         char tmps[80];
1564         if (ast_pthread_mutex_lock(&applock)) {
1565                 ast_log(LOG_ERROR, "Unable to lock application list\n");
1566                 return -1;
1567         }
1568         tmp = apps;
1569         while(tmp) {
1570                 if (!strcasecmp(app, tmp->name)) {
1571                         ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
1572                         ast_pthread_mutex_unlock(&applock);
1573                         return -1;
1574                 }
1575                 tmp = tmp->next;
1576         }
1577         tmp = malloc(sizeof(struct ast_app));
1578         if (tmp) {
1579                 memset(tmp, 0, sizeof(struct ast_app));
1580                 strncpy(tmp->name, app, sizeof(tmp->name)-1);
1581                 tmp->execute = execute;
1582                 tmp->synopsis = synopsis;
1583                 tmp->description = description;
1584                 tmp->next = apps;
1585                 apps = tmp;
1586         } else {
1587                 ast_log(LOG_WARNING, "Out of memory\n");
1588                 ast_pthread_mutex_unlock(&applock);
1589                 return -1;
1590         }
1591         if (option_verbose > 1)
1592                 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
1593         ast_pthread_mutex_unlock(&applock);
1594         return 0;
1595 }
1596
1597 int ast_register_switch(struct ast_switch *sw)
1598 {
1599         struct ast_switch *tmp, *prev=NULL;
1600         if (ast_pthread_mutex_lock(&switchlock)) {
1601                 ast_log(LOG_ERROR, "Unable to lock switch lock\n");
1602                 return -1;
1603         }
1604         tmp = switches;
1605         while(tmp) {
1606                 if (!strcasecmp(tmp->name, sw->name))
1607                         break;
1608                 prev = tmp;
1609                 tmp = tmp->next;
1610         }
1611         if (tmp) {      
1612                 ast_pthread_mutex_unlock(&switchlock);
1613                 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
1614                 return -1;
1615         }
1616         sw->next = NULL;
1617         if (prev) 
1618                 prev->next = sw;
1619         else
1620                 switches = sw;
1621         ast_pthread_mutex_unlock(&switchlock);
1622         return 0;
1623 }
1624
1625 void ast_unregister_switch(struct ast_switch *sw)
1626 {
1627         struct ast_switch *tmp, *prev=NULL;
1628         if (ast_pthread_mutex_lock(&switchlock)) {
1629                 ast_log(LOG_ERROR, "Unable to lock switch lock\n");
1630                 return;
1631         }
1632         tmp = switches;
1633         while(tmp) {
1634                 if (tmp == sw) {
1635                         if (prev)
1636                                 prev->next = tmp->next;
1637                         else
1638                                 switches = tmp->next;
1639                         tmp->next = NULL;
1640                         break;                  
1641                 }
1642                 prev = tmp;
1643                 tmp = tmp->next;
1644         }
1645         ast_pthread_mutex_unlock(&switchlock);
1646 }
1647
1648 /*
1649  * Help for CLI commands ...
1650  */
1651 static char show_application_help[] = 
1652 "Usage: show application <application> [<application> [<application> [...]]]\n"
1653 "       Describes a particular application.\n";
1654
1655 static char show_applications_help[] =
1656 "Usage: show applications\n"
1657 "       List applications which are currently available.\n";
1658
1659 static char show_dialplan_help[] =
1660 "Usage: show dialplan [exten@][context]\n"
1661 "       Show dialplan\n";
1662
1663 static char show_switches_help[] = 
1664 "Usage: show switches\n"
1665 "       Show registered switches\n";
1666
1667 /*
1668  * IMPLEMENTATION OF CLI FUNCTIONS IS IN THE SAME ORDER AS COMMANDS HELPS
1669  *
1670  */
1671
1672 /*
1673  * 'show application' CLI command implementation functions ...
1674  */
1675
1676 /*
1677  * There is a possibility to show informations about more than one
1678  * application at one time. You can type 'show application Dial Echo' and
1679  * you will see informations about these two applications ...
1680  */
1681 static char *complete_show_application(char *line, char *word,
1682         int pos, int state)
1683 {
1684         struct ast_app *a;
1685         int which = 0;
1686
1687         /* try to lock applications list ... */
1688         if (ast_pthread_mutex_lock(&applock)) {
1689                 ast_log(LOG_ERROR, "Unable to lock application list\n");
1690                 return NULL;
1691         }
1692
1693         /* ... walk all applications ... */
1694         a = apps; 
1695         while (a) {
1696                 /* ... check if word matches this application ... */
1697                 if (!strncasecmp(word, a->name, strlen(word))) {
1698                         /* ... if this is right app serve it ... */
1699                         if (++which > state) {
1700                                 char *ret = strdup(a->name);
1701                                 ast_pthread_mutex_unlock(&applock);
1702                                 return ret;
1703                         }
1704                 }
1705                 a = a->next; 
1706         }
1707
1708         /* no application match */
1709         ast_pthread_mutex_unlock(&applock);
1710         return NULL; 
1711 }
1712
1713 static int handle_show_application(int fd, int argc, char *argv[])
1714 {
1715         struct ast_app *a;
1716         char buf[2048];
1717         int app, no_registered_app = 1;
1718
1719         if (argc < 3) return RESULT_SHOWUSAGE;
1720
1721         /* try to lock applications list ... */
1722         if (ast_pthread_mutex_lock(&applock)) {
1723                 ast_log(LOG_ERROR, "Unable to lock application list\n");
1724                 return -1;
1725         }
1726
1727         /* ... go through all applications ... */
1728         a = apps; 
1729         while (a) {
1730                 /* ... compare this application name with all arguments given
1731                  * to 'show application' command ... */
1732                 for (app = 2; app < argc; app++) {
1733                         if (!strcasecmp(a->name, argv[app])) {
1734                                 no_registered_app = 0;
1735
1736                                 /* ... one of our applications, show info ...*/
1737                                 snprintf(buf, sizeof(buf),
1738                                         "\n  -= Info about application '%s' =- \n\n"
1739                                         "[Synopsis]:\n  %s\n\n"
1740                                         "[Description]:\n%s\n",
1741                                         a->name,
1742                                         a->synopsis ? a->synopsis : "Not available",
1743                                         a->description ? a-> description : "Not available");
1744                                 ast_cli(fd, buf);
1745                         }
1746                 }
1747                 a = a->next; 
1748         }
1749
1750         ast_pthread_mutex_unlock(&applock);
1751
1752         /* we found at least one app? no? */
1753         if (no_registered_app) {
1754                 ast_cli(fd, "Your application(s) is (are) not registered\n");
1755                 return RESULT_FAILURE;
1756         }
1757
1758         return RESULT_SUCCESS;
1759 }
1760
1761 static int handle_show_switches(int fd, int argc, char *argv[])
1762 {
1763         struct ast_switch *sw;
1764         if (!switches) {
1765                 ast_cli(fd, "There are no registered alternative switches\n");
1766                 return RESULT_SUCCESS;
1767         }
1768         /* ... we have applications ... */
1769         ast_cli(fd, "\n    -= Registered Asterisk Alternative Switches =-\n");
1770         if (ast_pthread_mutex_lock(&switchlock)) {
1771                 ast_log(LOG_ERROR, "Unable to lock switches\n");
1772                 return -1;
1773         }
1774         sw = switches;
1775         while (sw) {
1776                 ast_cli(fd, "%s: %s\n", sw->name, sw->description);
1777                 sw = sw->next;
1778         }
1779         ast_pthread_mutex_unlock(&switchlock);
1780         return RESULT_SUCCESS;
1781 }
1782
1783 /*
1784  * 'show applications' CLI command implementation functions ...
1785  */
1786 static int handle_show_applications(int fd, int argc, char *argv[])
1787 {
1788         struct ast_app *a;
1789
1790         /* try to lock applications list ... */
1791         if (ast_pthread_mutex_lock(&applock)) {
1792                 ast_log(LOG_ERROR, "Unable to lock application list\n");
1793                 return -1;
1794         }
1795
1796         /* ... go to first application ... */
1797         a = apps; 
1798
1799         /* ... have we got at least one application (first)? no? */
1800         if (!a) {
1801                 ast_cli(fd, "There is no registered applications\n");
1802                 ast_pthread_mutex_unlock(&applock);
1803                 return -1;
1804         }
1805
1806         /* ... we have applications ... */
1807         ast_cli(fd, "\n    -= Registered Asterisk Applications =-\n");
1808
1809         /* ... go through all applications ... */
1810         while (a) {
1811                 /* ... show informations about applications ... */
1812                 ast_cli(fd,"  %15s: %s\n",
1813                         a->name,
1814                         a->synopsis ? a->synopsis : "<Synopsis not available>");
1815                 a = a->next; 
1816         }
1817
1818         /* ... unlock and return */
1819         ast_pthread_mutex_unlock(&applock);
1820
1821         return RESULT_SUCCESS;
1822 }
1823
1824 /*
1825  * 'show dialplan' CLI command implementation functions ...
1826  */
1827 static char *complete_show_dialplan_context(char *line, char *word, int pos,
1828         int state)
1829 {
1830         struct ast_context *c;
1831         int which = 0;
1832
1833         /* we are do completion of [exten@]context on second postion only */
1834         if (pos != 2) return NULL;
1835
1836         /* try to lock contexts list ... */
1837         if (ast_lock_contexts()) {
1838                 ast_log(LOG_ERROR, "Unable to lock context list\n");
1839                 return NULL;
1840         }
1841
1842         /* ... walk through all contexts ... */
1843         c = ast_walk_contexts(NULL);
1844         while(c) {
1845                 /* ... word matches context name? yes? ... */
1846                 if (!strncasecmp(word, ast_get_context_name(c), strlen(word))) {
1847                         /* ... for serve? ... */
1848                         if (++which > state) {
1849                                 /* ... yes, serve this context name ... */
1850                                 char *ret = strdup(ast_get_context_name(c));
1851                                 ast_unlock_contexts();
1852                                 return ret;
1853                         }
1854                 }
1855                 c = ast_walk_contexts(c);
1856         }
1857
1858         /* ... unlock and return */
1859         ast_unlock_contexts();
1860         return NULL;
1861 }
1862
1863 static int handle_show_dialplan(int fd, int argc, char *argv[])
1864 {
1865         struct ast_context *c;
1866         char *exten = NULL, *context = NULL;
1867         int context_existence = 0, extension_existence = 0;
1868
1869         if (argc != 3 && argc != 2) return -1;
1870
1871         /* we obtain [exten@]context? if yes, split them ... */
1872         if (argc == 3) {
1873                 char *splitter = argv[2];
1874                 /* is there a '@' character? */
1875                 if (strchr(argv[2], '@')) {
1876                         /* yes, split into exten & context ... */
1877                         exten   = strsep(&splitter, "@");
1878                         context = splitter;
1879
1880                         /* check for length and change to NULL if !strlen() */
1881                         if (!strlen(exten))   exten = NULL;
1882                         if (!strlen(context)) context = NULL;
1883                 } else
1884                 {
1885                         /* no '@' char, only context given */
1886                         context = argv[2];
1887                         if (!strlen(context)) context = NULL;
1888                 }
1889         }
1890
1891         /* try to lock contexts */
1892         if (ast_lock_contexts()) {
1893                 ast_cli(LOG_WARNING, "Failed to lock contexts list\n");
1894                 return RESULT_FAILURE;
1895         }
1896
1897         /* walk all contexts ... */
1898         c = ast_walk_contexts(NULL);
1899         while (c) {
1900                 /* show this context? */
1901                 if (!context ||
1902                         !strcmp(ast_get_context_name(c), context)) {
1903                         context_existence = 1;
1904
1905                         /* try to lock context before walking in ... */
1906                         if (!ast_lock_context(c)) {
1907                                 struct ast_exten *e;
1908                                 struct ast_include *i;
1909                                 struct ast_ignorepat *ip;
1910                                 struct ast_sw *sw;
1911                                 char buf[256], buf2[256];
1912                                 int context_info_printed = 0;
1913
1914                                 /* are we looking for exten too? if yes, we print context
1915                                  * if we our extension only
1916                                  */
1917                                 if (!exten) {
1918                                         ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
1919                                                 ast_get_context_name(c), ast_get_context_registrar(c));
1920                                         context_info_printed = 1;
1921                                 }
1922
1923                                 /* walk extensions ... */
1924                                 e = ast_walk_context_extensions(c, NULL);
1925                                 while (e) {
1926                                         struct ast_exten *p;
1927
1928                                         /* looking for extension? is this our extension? */
1929                                         if (exten &&
1930                                                 strcmp(ast_get_extension_name(e), exten))
1931                                         {
1932                                                 /* we are looking for extension and it's not our
1933                                                  * extension, so skip to next extension */
1934                                                 e = ast_walk_context_extensions(c, e);
1935                                                 continue;
1936                                         }
1937
1938                                         extension_existence = 1;
1939
1940                                         /* may we print context info? */        
1941                                         if (!context_info_printed) {
1942                                                 ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
1943                                                         ast_get_context_name(c),
1944                                                         ast_get_context_registrar(c));
1945                                                 context_info_printed = 1;
1946                                         }
1947
1948                                         /* write extension name and first peer */       
1949                                         bzero(buf, sizeof(buf));                
1950                                         snprintf(buf, sizeof(buf), "'%s' =>",
1951                                                 ast_get_extension_name(e));
1952
1953                                         snprintf(buf2, sizeof(buf2),
1954                                                 "%d. %s(%s)",
1955                                                 ast_get_extension_priority(e),
1956                                                 ast_get_extension_app(e),
1957                                                 (char *)ast_get_extension_app_data(e));
1958
1959                                         ast_cli(fd, "  %-17s %-45s [%s]\n", buf, buf2,
1960                                                 ast_get_extension_registrar(e));
1961
1962                                         /* walk next extension peers */
1963                                         p = ast_walk_extension_priorities(e, e);
1964                                         while (p) {
1965                                                 bzero((void *)buf2, sizeof(buf2));
1966
1967                                                 snprintf(buf2, sizeof(buf2),
1968                                                         "%d. %s(%s)",
1969                                                         ast_get_extension_priority(p),
1970                                                         ast_get_extension_app(p),
1971                                                         (char *)ast_get_extension_app_data(p));
1972
1973                                                 ast_cli(fd,"  %-17s %-45s [%s]\n",
1974                                                         "", buf2,
1975                                                         ast_get_extension_registrar(p));        
1976
1977                                                 p = ast_walk_extension_priorities(e, p);
1978                                         }
1979                                         e = ast_walk_context_extensions(c, e);
1980                                 }
1981
1982                                 /* include & ignorepat we all printing if we are not
1983                                  * looking for exact extension
1984                                  */
1985                                 if (!exten) {
1986                                         if (ast_walk_context_extensions(c, NULL))
1987                                                 ast_cli(fd, "\n");
1988
1989                                         /* walk included and write info ... */
1990                                         i = ast_walk_context_includes(c, NULL);
1991                                         while (i) {
1992                                                 bzero(buf, sizeof(buf));
1993                                                 snprintf(buf, sizeof(buf), "'%s'",
1994                                                         ast_get_include_name(i));
1995                                                 ast_cli(fd, "  Include =>        %-45s [%s]\n",
1996                                                         buf, ast_get_include_registrar(i));
1997                                                 i = ast_walk_context_includes(c, i);
1998                                         }
1999
2000                                         /* walk ignore patterns and write info ... */
2001                                         ip = ast_walk_context_ignorepats(c, NULL);
2002                                         while (ip) {
2003                                                 bzero(buf, sizeof(buf));
2004                                                 snprintf(buf, sizeof(buf), "'%s'",
2005                                                         ast_get_ignorepat_name(ip));
2006                                                 ast_cli(fd, "  Ignore pattern => %-45s [%s]\n",
2007                                                         buf, ast_get_ignorepat_registrar(ip));  
2008                                                 ip = ast_walk_context_ignorepats(c, ip);
2009                                         }
2010                                         sw = ast_walk_context_switches(c, NULL);
2011                                         while(sw) {
2012                                                 bzero(buf, sizeof(buf));
2013                                                 snprintf(buf, sizeof(buf), "'%s/%s'",
2014                                                         ast_get_switch_name(sw),
2015                                                         ast_get_switch_data(sw));
2016                                                 ast_cli(fd, "  Alt. Switch =>    %-45s [%s]\n",
2017                                                         buf, ast_get_switch_registrar(sw));     
2018                                                 sw = ast_walk_context_switches(c, sw);
2019                                         }
2020                                 }
2021         
2022                                 ast_unlock_context(c);
2023
2024                                 /* if we print something in context, make an empty line */
2025                                 if (context_info_printed) ast_cli(fd, "\n");
2026                         }
2027                 }
2028                 c = ast_walk_contexts(c);
2029         }
2030         ast_unlock_contexts();
2031
2032         /* check for input failure and throw some error messages */
2033         if (context && !context_existence) {
2034                 ast_cli(fd, "There is no existence of '%s' context\n",
2035                         context);
2036                 return RESULT_FAILURE;
2037         }
2038
2039         if (exten && !extension_existence) {
2040                 if (context)
2041                         ast_cli(fd, "There is no existence of %s@%s extension\n",
2042                                 exten, context);
2043                 else
2044                         ast_cli(fd,
2045                                 "There is no existence of '%s' extension in all contexts\n",
2046                                 exten);
2047                 return RESULT_FAILURE;
2048         }
2049
2050         /* everything ok */
2051         return RESULT_SUCCESS;
2052 }
2053
2054 /*
2055  * CLI entries for upper commands ...
2056  */
2057 static struct ast_cli_entry show_applications_cli = 
2058         { { "show", "applications", NULL }, 
2059         handle_show_applications, "Shows registered applications",
2060         show_applications_help };
2061
2062 static struct ast_cli_entry show_application_cli =
2063         { { "show", "application", NULL }, 
2064         handle_show_application, "Describe a specific application",
2065         show_application_help, complete_show_application };
2066
2067 static struct ast_cli_entry show_dialplan_cli =
2068         { { "show", "dialplan", NULL },
2069                 handle_show_dialplan, "Show dialplan",
2070                 show_dialplan_help, complete_show_dialplan_context };
2071
2072 static struct ast_cli_entry show_switches_cli =
2073         { { "show", "switches", NULL },
2074                 handle_show_switches, "Show alternative switches",
2075                 show_switches_help, NULL };
2076
2077 int ast_unregister_application(char *app) {
2078         struct ast_app *tmp, *tmpl = NULL;
2079         if (ast_pthread_mutex_lock(&applock)) {
2080                 ast_log(LOG_ERROR, "Unable to lock application list\n");
2081                 return -1;
2082         }
2083         tmp = apps;
2084         while(tmp) {
2085                 if (!strcasecmp(app, tmp->name)) {
2086                         if (tmpl)
2087                                 tmpl->next = tmp->next;
2088                         else
2089                                 apps = tmp->next;
2090                         if (option_verbose > 1)
2091                                 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
2092                         ast_pthread_mutex_unlock(&applock);
2093                         return 0;
2094                 }
2095                 tmpl = tmp;
2096                 tmp = tmp->next;
2097         }
2098         ast_pthread_mutex_unlock(&applock);
2099         return -1;
2100 }
2101
2102 struct ast_context *ast_context_create(char *name, char *registrar)
2103 {
2104         struct ast_context *tmp;
2105         
2106         ast_pthread_mutex_lock(&conlock);
2107         tmp = contexts;
2108         while(tmp) {
2109                 if (!strcasecmp(tmp->name, name)) {
2110                         ast_pthread_mutex_unlock(&conlock);
2111                         ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
2112                         return NULL;
2113                 }
2114                 tmp = tmp->next;
2115         }
2116         tmp = malloc(sizeof(struct ast_context));
2117         if (tmp) {
2118                 memset(tmp, 0, sizeof(struct ast_context));
2119                 ast_pthread_mutex_init(&tmp->lock);
2120                 strncpy(tmp->name, name, sizeof(tmp->name)-1);
2121                 tmp->root = NULL;
2122                 tmp->registrar = registrar;
2123                 tmp->next = contexts;
2124                 tmp->includes = NULL;
2125                 tmp->ignorepats = NULL;
2126                 contexts = tmp;
2127                 if (option_debug)
2128                         ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
2129                 else if (option_verbose > 2)
2130                         ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
2131         } else
2132                 ast_log(LOG_WARNING, "Out of memory\n");
2133         
2134         ast_pthread_mutex_unlock(&conlock);
2135         return tmp;
2136 }
2137
2138 /*
2139  * errno values
2140  *  EBUSY  - can't lock
2141  *  ENODATA - no existence of context
2142  */
2143 int ast_context_add_include(char *context, char *include, char *registrar)
2144 {
2145         struct ast_context *c;
2146
2147         if (ast_lock_contexts()) {
2148                 errno = EBUSY;
2149                 return -1;
2150         }
2151
2152         /* walk contexts ... */
2153         c = ast_walk_contexts(NULL);
2154         while (c) {
2155                 /* ... search for the right one ... */
2156                 if (!strcmp(ast_get_context_name(c), context)) {
2157                         int ret = ast_context_add_include2(c, include, registrar);
2158                         /* ... unlock contexts list and return */
2159                         ast_unlock_contexts();
2160                         return ret;
2161                 }
2162                 c = ast_walk_contexts(c);
2163         }
2164
2165         /* we can't find the right context */
2166         ast_unlock_contexts();
2167         errno = ENODATA;
2168         return -1;
2169 }
2170
2171 #define FIND_NEXT \
2172 do { \
2173         c = info; \
2174         while(*c && (*c != '|')) c++; \
2175         if (*c) { *c = '\0'; c++; } else c = NULL; \
2176 } while(0)
2177
2178 static void get_timerange(struct ast_include *i, char *times)
2179 {
2180         char *e;
2181         int x;
2182         int s1, s2;
2183         int e1, e2;
2184         /* Star is all times */
2185         if (!strlen(times) || !strcmp(times, "*")) {
2186                 for (x=0;x<24;x++)
2187                         i->minmask[x] = (1 << 30) - 1;
2188                 return;
2189         }
2190         /* Otherwise expect a range */
2191         e = strchr(times, '-');
2192         if (!e) {
2193                 ast_log(LOG_WARNING, "Time range is not valid. Assuming no time.\n");
2194                 return;
2195         }
2196         *e = '\0';
2197         e++;
2198         while(*e && !isdigit(*e)) e++;
2199         if (!*e) {
2200                 ast_log(LOG_WARNING, "Invalid time range.  Assuming no time.\n");
2201                 return;
2202         }
2203         if (sscanf(times, "%d:%d", &s1, &s2) != 2) {
2204                 ast_log(LOG_WARNING, "%s isn't a time.  Assuming no time.\n", times);
2205                 return;
2206         }
2207         if (sscanf(e, "%d:%d", &e1, &e2) != 2) {
2208                 ast_log(LOG_WARNING, "%s isn't a time.  Assuming no time.\n", e);
2209                 return;
2210         }
2211         s1 = s1 * 30 + s2/2;
2212         if ((s1 < 0) || (s1 >= 24*30)) {
2213                 ast_log(LOG_WARNING, "%s isn't a valid star time. Assuming no time.\n", times);
2214                 return;
2215         }
2216         e1 = e1 * 30 + e2/2;
2217         if ((e1 < 0) || (e2 >= 24*30)) {
2218                 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times);
2219                 return;
2220         }
2221         /* Go through the time and enable each appropriate bit */
2222         for (x=s1;x != e1;x = (x + 1) % (24 * 30)) {
2223                 i->minmask[x/30] |= (1 << (x % 30));
2224         }
2225         /* Do the last one */
2226         i->minmask[x/30] |= (1 << (x % 30));
2227         /* All done */
2228 }
2229
2230 static char *days[] =
2231 {
2232         "sun",
2233         "mon",
2234         "tue",
2235         "wed",
2236         "thu",
2237         "fri",
2238         "sat",
2239 };
2240
2241 static unsigned int get_dow(char *dow)
2242 {
2243         char *c;
2244         /* The following line is coincidence, really! */
2245         int s, e, x;
2246         unsigned int mask;
2247         /* Check for all days */
2248         if (!strlen(dow) || !strcmp(dow, "*"))
2249                 return (1 << 7) - 1;
2250         /* Get start and ending days */
2251         c = strchr(dow, '-');
2252         if (c) {
2253                 *c = '\0';
2254                 c++;
2255         } else
2256                 c = NULL;
2257         /* Find the start */
2258         s = 0;
2259         while((s < 7) && strcasecmp(dow, days[s])) s++;
2260         if (s >= 7) {
2261                 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", dow);
2262                 return 0;
2263         }
2264         if (c) {
2265                 e = 0;
2266                 while((e < 7) && strcasecmp(c, days[e])) e++;
2267                 if (e >= 7) {
2268                         ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c);
2269                         return 0;
2270                 }
2271         } else
2272                 e = s;
2273         mask = 0;
2274         for (x=s;x!=e;x = (x + 1) % 7) {
2275                 mask |= (1 << x);
2276         }
2277         /* One last one */
2278         mask |= (1 << x);
2279         return mask;
2280 }
2281
2282 static unsigned int get_day(char *day)
2283 {
2284         char *c;
2285         /* The following line is coincidence, really! */
2286         int s, e, x;
2287         unsigned int mask;
2288         /* Check for all days */
2289         if (!strlen(day) || !strcmp(day, "*")) {
2290                 mask = (1 << 30)  + ((1 << 30) - 1);
2291                 return mask;
2292         }
2293         /* Get start and ending days */
2294         c = strchr(day, '-');
2295         if (c) {
2296                 *c = '\0';
2297                 c++;
2298         }
2299         /* Find the start */
2300         if (sscanf(day, "%d", &s) != 1) {
2301                 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day);
2302                 return 0;
2303         }
2304         if ((s < 1) || (s > 31)) {
2305                 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day);
2306                 return 0;
2307         }
2308         s--;
2309         if (c) {
2310                 if (sscanf(c, "%d", &e) != 1) {
2311                         ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c);
2312                         return 0;
2313                 }
2314                 if ((e < 1) || (e > 31)) {
2315                         ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c);
2316                         return 0;
2317                 }
2318                 e--;
2319         } else
2320                 e = s;
2321         mask = 0;
2322         for (x=s;x!=e;x = (x + 1) % 31) {
2323                 mask |= (1 << x);
2324         }
2325         mask |= (1 << x);
2326         return mask;
2327 }
2328
2329 static char *months[] =
2330 {
2331         "jan",
2332         "feb",
2333         "mar",
2334         "apr",
2335         "may",
2336         "jun",
2337         "jul",
2338         "aug",
2339         "sep",
2340         "oct",
2341         "nov",
2342         "dec",
2343 };
2344
2345 static unsigned int get_month(char *mon)
2346 {
2347         char *c;
2348         /* The following line is coincidence, really! */
2349         int s, e, x;
2350         unsigned int mask;
2351         /* Check for all days */
2352         if (!strlen(mon) || !strcmp(mon, "*")) 
2353                 return (1 << 12) - 1;
2354         /* Get start and ending days */
2355         c = strchr(mon, '-');
2356         if (c) {
2357                 *c = '\0';
2358                 c++;
2359         }
2360         /* Find the start */
2361         s = 0;
2362         while((s < 12) && strcasecmp(mon, months[s])) s++;
2363         if (s >= 12) {
2364                 ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", mon);
2365                 return 0;
2366         }
2367         if (c) {
2368                 e = 0;
2369                 while((e < 12) && strcasecmp(mon, months[e])) e++;
2370                 if (e >= 12) {
2371                         ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", c);
2372                         return 0;
2373                 }
2374         } else
2375                 e = s;
2376         mask = 0;
2377         for (x=s;x!=e;x = (x + 1) % 12) {
2378                 mask |= (1 << x);
2379         }
2380         /* One last one */
2381         mask |= (1 << x);
2382         return mask;
2383 }
2384
2385 static void build_timing(struct ast_include *i, char *info)
2386 {
2387         char *c;
2388         /* Check for empty just in case */
2389         if (!strlen(info))
2390                 return;
2391         i->hastime = 1;
2392         /* Assume everything except time */
2393         i->monthmask = (1 << 12) - 1;
2394         i->daymask = (1 << 30) - 1 + (1 << 30);
2395         i->dowmask = (1 << 7) - 1;
2396         /* Avoid using str tok */
2397         FIND_NEXT;
2398         /* Info has the time range, start with that */
2399         get_timerange(i, info);
2400         info = c;
2401         if (!info)
2402                 return;
2403         FIND_NEXT;
2404         /* Now check for day of week */
2405         i->dowmask = get_dow(info);
2406
2407         info = c;
2408         if (!info)
2409                 return;
2410         FIND_NEXT;
2411         /* Now check for the day of the month */
2412         i->daymask = get_day(info);
2413         info = c;
2414         if (!info)
2415                 return;
2416         FIND_NEXT;
2417         /* And finally go for the month */
2418         i->monthmask = get_month(info);
2419 }
2420
2421 /*
2422  * errno values
2423  *  ENOMEM - out of memory
2424  *  EBUSY  - can't lock
2425  *  EEXIST - already included
2426  *  EINVAL - there is no existence of context for inclusion
2427  */
2428 int ast_context_add_include2(struct ast_context *con, char *value,
2429         char *registrar)
2430 {
2431         struct ast_include *new_include;
2432         char *c;
2433         struct ast_include *i, *il = NULL; /* include, include_last */
2434
2435         /* allocate new include structure ... */
2436         if (!(new_include = malloc(sizeof(struct ast_include)))) {
2437                 ast_log(LOG_WARNING, "Out of memory\n");
2438                 errno = ENOMEM;
2439                 return -1;
2440         }
2441         
2442         /* ... fill in this structure ... */
2443         memset(new_include, 0, sizeof(struct ast_include));
2444         strncpy(new_include->name, value, sizeof(new_include->name)-1);
2445         strncpy(new_include->rname, value, sizeof(new_include->rname)-1);
2446         c = new_include->rname;
2447         /* Strip off timing info */
2448         while(*c && (*c != '|')) c++; 
2449         /* Process if it's there */
2450         if (*c) {
2451                 build_timing(new_include, c+1);
2452                 *c = '\0';
2453         }
2454         new_include->next      = NULL;
2455         new_include->registrar = registrar;
2456
2457         /* ... try to lock this context ... */
2458         if (ast_pthread_mutex_lock(&con->lock)) {
2459                 free(new_include);
2460                 errno = EBUSY;
2461                 return -1;
2462         }
2463
2464         /* ... go to last include and check if context is already included too... */
2465         i = con->includes;
2466         while (i) {
2467                 if (!strcasecmp(i->name, new_include->name)) {
2468                         free(new_include);
2469                         ast_pthread_mutex_unlock(&con->lock);
2470                         errno = EEXIST;
2471                         return -1;
2472                 }
2473                 il = i;
2474                 i = i->next;
2475         }
2476
2477         /* ... include new context into context list, unlock, return */
2478         if (il)
2479                 il->next = new_include;
2480         else
2481                 con->includes = new_include;
2482         if (option_verbose > 2)
2483                 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 
2484         ast_pthread_mutex_unlock(&con->lock);
2485
2486         return 0;
2487 }
2488
2489 /*
2490  * errno values
2491  *  EBUSY  - can't lock
2492  *  ENODATA - no existence of context
2493  */
2494 int ast_context_add_switch(char *context, char *sw, char *data, char *registrar)
2495 {
2496         struct ast_context *c;
2497
2498         if (ast_lock_contexts()) {
2499                 errno = EBUSY;
2500                 return -1;
2501         }
2502
2503         /* walk contexts ... */
2504         c = ast_walk_contexts(NULL);
2505         while (c) {
2506                 /* ... search for the right one ... */
2507                 if (!strcmp(ast_get_context_name(c), context)) {
2508                         int ret = ast_context_add_switch2(c, sw, data, registrar);
2509                         /* ... unlock contexts list and return */
2510                         ast_unlock_contexts();
2511                         return ret;
2512                 }
2513                 c = ast_walk_contexts(c);
2514         }
2515
2516         /* we can't find the right context */
2517         ast_unlock_contexts();
2518         errno = ENODATA;
2519         return -1;
2520 }
2521
2522 /*
2523  * errno values
2524  *  ENOMEM - out of memory
2525  *  EBUSY  - can't lock
2526  *  EEXIST - already included
2527  *  EINVAL - there is no existence of context for inclusion
2528  */
2529 int ast_context_add_switch2(struct ast_context *con, char *value,
2530         char *data, char *registrar)
2531 {
2532         struct ast_sw *new_sw;
2533         struct ast_sw *i, *il = NULL; /* sw, sw_last */
2534
2535         /* allocate new sw structure ... */
2536         if (!(new_sw = malloc(sizeof(struct ast_sw)))) {
2537                 ast_log(LOG_WARNING, "Out of memory\n");
2538                 errno = ENOMEM;
2539                 return -1;
2540         }
2541         
2542         /* ... fill in this structure ... */
2543         memset(new_sw, 0, sizeof(struct ast_sw));
2544         strncpy(new_sw->name, value, sizeof(new_sw->name)-1);
2545         if (data)
2546                 strncpy(new_sw->data, data, sizeof(new_sw->data)-1);
2547         else
2548                 strncpy(new_sw->data, "", sizeof(new_sw->data)-1);
2549         new_sw->next      = NULL;
2550         new_sw->registrar = registrar;
2551
2552         /* ... try to lock this context ... */
2553         if (ast_pthread_mutex_lock(&con->lock)) {
2554                 free(new_sw);
2555                 errno = EBUSY;
2556                 return -1;
2557         }
2558
2559         /* ... go to last sw and check if context is already swd too... */
2560         i = con->alts;
2561         while (i) {
2562                 if (!strcasecmp(i->name, new_sw->name)) {
2563                         free(new_sw);
2564                         ast_pthread_mutex_unlock(&con->lock);
2565                         errno = EEXIST;
2566                         return -1;
2567                 }
2568                 il = i;
2569                 i = i->next;
2570         }
2571
2572         /* ... sw new context into context list, unlock, return */
2573         if (il)
2574                 il->next = new_sw;
2575         else
2576                 con->alts = new_sw;
2577         if (option_verbose > 2)
2578                 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 
2579         ast_pthread_mutex_unlock(&con->lock);
2580
2581         return 0;
2582 }
2583
2584 /*
2585  * EBUSY  - can't lock
2586  * ENODATA - there is not context existence
2587  */
2588 int ast_context_remove_ignorepat(char *context, char *ignorepat, char *registrar)
2589 {
2590         struct ast_context *c;
2591
2592         if (ast_lock_contexts()) {
2593                 errno = EBUSY;
2594                 return -1;
2595         }
2596
2597         c = ast_walk_contexts(NULL);
2598         while (c) {
2599                 if (!strcmp(ast_get_context_name(c), context)) {
2600                         int ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
2601                         ast_unlock_contexts();
2602                         return ret;
2603                 }
2604                 c = ast_walk_contexts(c);
2605         }
2606
2607         ast_unlock_contexts();
2608         errno = ENODATA;
2609         return -1;
2610 }
2611
2612 int ast_context_remove_ignorepat2(struct ast_context *con, char *ignorepat, char *registrar)
2613 {
2614         struct ast_ignorepat *ip, *ipl = NULL;
2615
2616         if (ast_pthread_mutex_lock(&con->lock)) {
2617                 errno = EBUSY;
2618                 return -1;
2619         }
2620
2621         ip = con->ignorepats;
2622         while (ip) {
2623                 if (!strcmp(ip->pattern, ignorepat) &&
2624                         (registrar == ip->registrar || !registrar)) {
2625                         if (ipl) {
2626                                 ipl->next = ip->next;
2627                                 free(ip);
2628                         } else {
2629                                 con->ignorepats = ip->next;
2630                                 free(ip);
2631                         }
2632                         ast_pthread_mutex_unlock(&con->lock);
2633                         return 0;
2634                 }
2635                 ipl = ip; ip = ip->next;
2636         }
2637
2638         ast_pthread_mutex_unlock(&con->lock);
2639         errno = EINVAL;
2640         return -1;
2641 }
2642
2643 /*
2644  * EBUSY - can't lock
2645  * ENODATA - there is no existence of context
2646  */
2647 int ast_context_add_ignorepat(char *con, char *value, char *registrar)
2648 {
2649         struct ast_context *c;
2650
2651         if (ast_lock_contexts()) {
2652                 errno = EBUSY;
2653                 return -1;
2654         }
2655
2656         c = ast_walk_contexts(NULL);
2657         while (c) {
2658                 if (!strcmp(ast_get_context_name(c), con)) {
2659                         int ret = ast_context_add_ignorepat2(c, value, registrar);
2660                         ast_unlock_contexts();
2661                         return ret;
2662                 } 
2663                 c = ast_walk_contexts(c);
2664         }
2665
2666         ast_unlock_contexts();
2667         errno = ENODATA;
2668         return -1;
2669 }
2670
2671 int ast_context_add_ignorepat2(struct ast_context *con, char *value, char *registrar)
2672 {
2673         struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
2674         ignorepat = malloc(sizeof(struct ast_ignorepat));
2675         if (!ignorepat) {
2676                 ast_log(LOG_WARNING, "Out of memory\n");
2677                 errno = ENOMEM;
2678                 return -1;
2679         }
2680         memset(ignorepat, 0, sizeof(struct ast_ignorepat));
2681         strncpy(ignorepat->pattern, value, sizeof(ignorepat->pattern)-1);
2682         ignorepat->next = NULL;
2683         ignorepat->registrar = registrar;
2684         ast_pthread_mutex_lock(&con->lock);
2685         ignorepatc = con->ignorepats;
2686         while(ignorepatc) {
2687                 ignorepatl = ignorepatc;
2688                 if (!strcasecmp(ignorepatc->pattern, value)) {
2689                         /* Already there */
2690                         pthread_mutex_unlock(&con->lock);
2691                         errno = EEXIST;
2692                         return -1;
2693                 }
2694                 ignorepatc = ignorepatc->next;
2695         }
2696         if (ignorepatl) 
2697                 ignorepatl->next = ignorepat;
2698         else
2699                 con->ignorepats = ignorepat;
2700         pthread_mutex_unlock(&con->lock);
2701         return 0;
2702         
2703 }
2704
2705 int ast_ignore_pattern(char *context, char *pattern)
2706 {
2707         struct ast_context *con;
2708         struct ast_ignorepat *pat;
2709         con = ast_context_find(context);
2710         if (con) {
2711                 pat = con->ignorepats;
2712                 while (pat) {
2713                         if (ast_extension_match(pat->pattern, pattern))
2714                                 return 1;
2715                         pat = pat->next;
2716                 }
2717         } 
2718         return 0;
2719 }
2720
2721 /*
2722  * EBUSY   - can't lock
2723  * ENODATA  - no existence of context
2724  *
2725  */
2726 int ast_add_extension(char *context, int replace, char *extension, int priority, char *callerid,
2727         char *application, void *data, void (*datad)(void *), char *registrar)
2728 {
2729         struct ast_context *c;
2730
2731         if (ast_lock_contexts()) {
2732                 errno = EBUSY;
2733                 return -1;
2734         }
2735
2736         c = ast_walk_contexts(NULL);
2737         while (c) {
2738                 if (!strcmp(context, ast_get_context_name(c))) {
2739                         int ret = ast_add_extension2(c, replace, extension, priority, callerid,
2740                                 application, data, datad, registrar);
2741                         ast_unlock_contexts();
2742                         return ret;
2743                 }
2744                 c = ast_walk_contexts(c);
2745         }
2746
2747         ast_unlock_contexts();
2748         errno = ENODATA;
2749         return -1;
2750 }
2751
2752 int ast_async_goto(struct ast_channel *chan, char *context, char *exten, int priority, int needlock)
2753 {
2754         int res = 0;
2755         if (needlock)
2756                 ast_pthread_mutex_lock(&chan->lock);
2757         if (chan->pbx) {
2758                 /* This channel is currently in the PBX */
2759                 if (context && strlen(context))
2760                         strncpy(chan->context, context, sizeof(chan->context) - 1);
2761                 if (exten && strlen(exten))
2762                         strncpy(chan->exten, exten, sizeof(chan->context) - 1);
2763                 if (priority)
2764                         chan->priority = priority - 1;
2765                 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
2766                 if (needlock)
2767                         ast_pthread_mutex_unlock(&chan->lock);
2768         } else {
2769                 /* In order to do it when the channel doesn't really exist within
2770                    the PBX, we have to make a new channel, masquerade, and start the PBX
2771                    at the new location */
2772                 struct ast_channel *tmpchan;
2773                 struct ast_frame *f;
2774                 tmpchan = ast_channel_alloc(0);
2775                 if (tmpchan) {
2776                         ast_setstate(tmpchan, chan->_state);
2777                         snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name);
2778                         /* Make formats okay */
2779                         tmpchan->readformat = chan->readformat;
2780                         tmpchan->writeformat = chan->writeformat;
2781                         /* Setup proper location */
2782                         if (context && strlen(context))
2783                                 strncpy(tmpchan->context, context, sizeof(tmpchan->context) - 1);
2784                         else
2785                                 strncpy(tmpchan->context, chan->context, sizeof(tmpchan->context) - 1);
2786                         if (exten && strlen(exten))
2787                                 strncpy(tmpchan->exten, exten, sizeof(tmpchan->exten) - 1);
2788                         else
2789                                 strncpy(tmpchan->exten, chan->exten, sizeof(tmpchan->exten) - 1);
2790                         if (priority)
2791                                 tmpchan->priority = priority;
2792                         else
2793                                 tmpchan->priority = chan->priority;
2794                         if (needlock)
2795                                 ast_pthread_mutex_unlock(&chan->lock);
2796                         
2797                         /* Masquerade into temp channel */
2798                         ast_channel_masquerade(tmpchan, chan);
2799                         
2800                         /* Make the masquerade happen by reading a frame from the tmp channel */
2801                         f = ast_read(tmpchan);
2802                         if (f)
2803                                 ast_frfree(f);
2804                         /* Start the PBX going on our stolen channel */
2805                         if (ast_pbx_start(tmpchan)) {
2806                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
2807                                 ast_hangup(tmpchan);
2808                                 res = -1;
2809                         }
2810                 } else {
2811                         res = -1;
2812                         if (needlock)
2813                                 ast_pthread_mutex_unlock(&chan->lock);
2814                 }
2815         }
2816         return res;
2817 }
2818
2819 int ast_async_goto_by_name(char *channame, char *context, char *exten, int priority)
2820 {
2821         struct ast_channel *chan;
2822         chan = ast_channel_walk(NULL);
2823         while(chan) {
2824                 if (!strcasecmp(channame, chan->name))
2825                         break;
2826                 chan = ast_channel_walk(chan);
2827         }
2828         if (chan)
2829                 return ast_async_goto(chan, context, exten, priority, 1);
2830         return -1;
2831 }
2832
2833 static void ext_strncpy(char *dst, char *src, int len)
2834 {
2835         int count=0;
2836         while(*src && (count < len - 1)) {
2837                 switch(*src) {
2838                 case ' ':
2839 //otherwise exten => [a-b],1,... doesn't work
2840 //              case '-':
2841                         /* Ignore */
2842                         break;
2843                 default:
2844                         *dst = *src;
2845                         dst++;
2846                 }
2847                 src++;
2848                 count++;
2849         }
2850         *dst = '\0';
2851 }
2852
2853 /*
2854  * EBUSY - can't lock
2855  * EEXIST - extension with the same priority exist and no replace is set
2856  *
2857  */
2858 int ast_add_extension2(struct ast_context *con,
2859                                           int replace, char *extension, int priority, char *callerid,
2860                                           char *application, void *data, void (*datad)(void *),
2861                                           char *registrar)
2862 {
2863
2864 #define LOG do {        if (option_debug) {\
2865                 if (tmp->matchcid) { \
2866                         ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \
2867                 } else { \
2868                         ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
2869                 } \
2870         } else if (option_verbose > 2) { \
2871                 if (tmp->matchcid) { \
2872                         ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \
2873                 } else {  \
2874                         ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
2875                 } \
2876         } } while(0)
2877
2878         /*
2879          * This is a fairly complex routine.  Different extensions are kept
2880          * in order by the extension number.  Then, extensions of different
2881          * priorities (same extension) are kept in a list, according to the
2882          * peer pointer.
2883          */
2884         struct ast_exten *tmp, *e, *el = NULL, *ep = NULL;
2885         int res;
2886         /* Be optimistic:  Build the extension structure first */
2887         tmp = malloc(sizeof(struct ast_exten));
2888         if (tmp) {
2889                 memset(tmp, 0, sizeof(struct ast_exten));
2890                 ext_strncpy(tmp->exten, extension, sizeof(tmp->exten));
2891                 tmp->priority = priority;
2892                 if (callerid) {
2893                         ext_strncpy(tmp->cidmatch, callerid, sizeof(tmp->cidmatch));
2894                         tmp->matchcid = 1;
2895                 } else {
2896                         strcpy(tmp->cidmatch, "");
2897                         tmp->matchcid = 0;
2898                 }
2899                 strncpy(tmp->app, application, sizeof(tmp->app)-1);
2900                 tmp->data = data;
2901                 tmp->datad = datad;
2902                 tmp->registrar = registrar;
2903                 tmp->peer = NULL;
2904                 tmp->next =  NULL;
2905         } else {
2906                 ast_log(LOG_WARNING, "Out of memory\n");
2907                 errno = ENOMEM;
2908                 return -1;
2909         }
2910         if (ast_pthread_mutex_lock(&con->lock)) {
2911                 free(tmp);
2912                 /* And properly destroy the data */
2913                 datad(data);
2914                 ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name);
2915                 errno = EBUSY;
2916                 return -1;
2917         }
2918         e = con->root;
2919         while(e) {
2920                 res= strcasecmp(e->exten, extension);
2921                 if (!res) {
2922                         if (!e->matchcid && !tmp->matchcid)
2923                                 res = 0;
2924                         else if (tmp->matchcid && !e->matchcid)
2925                                 res = 1;
2926                         else if (e->matchcid && !tmp->matchcid)
2927                                 res = -1;
2928                         else
2929                                 res = strcasecmp(e->cidmatch, tmp->cidmatch);
2930                 }
2931                 if (res == 0) {
2932                         /* We have an exact match, now we find where we are
2933                            and be sure there's no duplicates */
2934                         while(e) {
2935                                 if (e->priority == tmp->priority) {
2936                                         /* Can't have something exactly the same.  Is this a
2937                                            replacement?  If so, replace, otherwise, bonk. */
2938                                         if (replace) {
2939                                                 if (ep) {
2940                                                         /* We're in the peer list, insert ourselves */
2941                                                         ep->peer = tmp;
2942                                                         tmp->peer = e->peer;
2943                                                 } else if (el) {
2944                                                         /* We're the first extension. Take over e's functions */
2945                                                         el->next = tmp;
2946                                                         tmp->next = e->next;
2947                                                         tmp->peer = e->peer;
2948                                                 } else {
2949                                                         /* We're the very first extension.  */
2950                                                         con->root = tmp;
2951                                                         tmp->next = e->next;
2952                                                         tmp->peer = e->peer;
2953                                                 }
2954                                                 /* Destroy the old one */
2955                                                 e->datad(e->data);
2956                                                 free(e);
2957                                                 ast_pthread_mutex_unlock(&con->lock);
2958                                                 /* And immediately return success. */
2959                                                 LOG;
2960                                                 return 0;
2961                                         } else {
2962                                                 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name);
2963                                                 tmp->datad(tmp->data);
2964                                                 free(tmp);
2965                                                 ast_pthread_mutex_unlock(&con->lock);
2966                                                 errno = EEXIST;
2967                                                 return -1;
2968                                         }
2969                                 } else if (e->priority > tmp->priority) {
2970                                         /* Slip ourselves in just before e */
2971                                         if (ep) {
2972                                                 /* Easy enough, we're just in the peer list */
2973                                                 ep->peer = tmp;
2974                                                 tmp->peer = e;
2975                                         } else if (el) {
2976                                                 /* We're the first extension in this peer list */
2977                                                 el->next = tmp;
2978                                                 tmp->next = e->next;
2979                                                 e->next = NULL;
2980                                                 tmp->peer = e;
2981                                         } else {
2982                                                 /* We're the very first extension altogether */
2983                                                 tmp->next = con->root;
2984                                                 /* Con->root must always exist or we couldn't get here */
2985                                                 tmp->peer = con->root->peer;
2986                                                 con->root = tmp;
2987                                         }
2988                                         ast_pthread_mutex_unlock(&con->lock);
2989                                         /* And immediately return success. */
2990                                         LOG;
2991                                         return 0;
2992                                 }
2993                                 ep = e;
2994                                 e = e->peer;
2995                         }
2996                         /* If we make it here, then it's time for us to go at the very end.
2997                            ep *must* be defined or we couldn't have gotten here. */
2998                         ep->peer = tmp;
2999                         ast_pthread_mutex_unlock(&con->lock);
3000                         /* And immediately return success. */
3001                         LOG;
3002                         return 0;
3003                                 
3004                 } else if (res > 0) {
3005                         /* Insert ourselves just before 'e'.  We're the first extension of
3006                            this kind */
3007                         tmp->next = e;
3008                         if (el) {
3009                                 /* We're in the list somewhere */
3010                                 el->next = tmp;
3011                         } else {
3012                                 /* We're at the top of the list */
3013                                 con->root = tmp;
3014                         }
3015                         ast_pthread_mutex_unlock(&con->lock);
3016                         /* And immediately return success. */
3017                         LOG;
3018                         return 0;
3019                 }                       
3020                         
3021                 el = e;
3022                 e = e->next;
3023         }
3024         /* If we fall all the way through to here, then we need to be on the end. */
3025         if (el)
3026                 el->next = tmp;
3027         else
3028                 con->root = tmp;
3029         ast_pthread_mutex_unlock(&con->lock);
3030         LOG;
3031         return 0;       
3032 }
3033
3034 struct async_stat {
3035         pthread_t p;
3036         struct ast_channel *chan;
3037         char context[AST_MAX_EXTENSION];
3038         char exten[AST_MAX_EXTENSION];
3039         int priority;
3040         int timeout;
3041         char app[AST_MAX_EXTENSION];
3042         char appdata[1024];
3043 };
3044
3045 static void *async_wait(void *data) 
3046 {
3047         struct async_stat *as = data;
3048         struct ast_channel *chan = as->chan;
3049         int timeout = as->timeout;
3050         int res;
3051         struct ast_frame *f;
3052         struct ast_app *app;
3053         
3054         while(timeout && (chan->_state != AST_STATE_UP)) {
3055                 res = ast_waitfor(chan, timeout);
3056                 if (res < 1) 
3057                         break;
3058                 if (timeout > -1)
3059                         timeout = res;
3060                 f = ast_read(chan);
3061                 if (!f)
3062                         break;
3063                 if (f->frametype == AST_FRAME_CONTROL) {
3064                         if ((f->subclass == AST_CONTROL_BUSY)  ||
3065                                 (f->subclass == AST_CONTROL_CONGESTION) )
3066                                         break;
3067                 }
3068                 ast_frfree(f);
3069         }
3070         if (chan->_state == AST_STATE_UP) {
3071                 if (strlen(as->app)) {
3072                         app = pbx_findapp(as->app);
3073                         if (app) {
3074                                 if (option_verbose > 2)
3075                                         ast_verbose(VERBOSE_PREFIX_3 "Lauching %s(%s) on %s\n", as->app, as->appdata, chan->name);
3076                                 pbx_exec(chan, app, as->appdata, 1);
3077                         } else
3078                                 ast_log(LOG_WARNING, "No such application '%s'\n", as->app);
3079                 } else {
3080                         if (strlen(as->context))
3081                                 strncpy(chan->context, as->context, sizeof(chan->context) - 1);
3082                         if (strlen(as->exten))
3083                                 strncpy(chan->exten, as->exten, sizeof(chan->exten) - 1);
3084                         if (as->priority > 0)
3085                                 chan->priority = as->priority;
3086                         /* Run the PBX */
3087                         if (ast_pbx_run(chan)) {
3088                                 ast_log(LOG_WARNING, "Failed to start PBX on %s\n", chan->name);
3089                         } else {
3090                                 /* PBX will have taken care of this */
3091                                 chan = NULL;
3092                         }
3093                 }
3094                         
3095         }
3096         free(as);
3097         if (chan)
3098                 ast_hangup(chan);
3099         return NULL;
3100 }
3101
3102 int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, char *callerid, char *variable )
3103 {
3104         struct ast_channel *chan;
3105         struct async_stat *as;
3106         int res = -1;
3107         char *var, *tmp;
3108         if (sync) {
3109                 chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
3110                 if (chan) {
3111                         /* JDG chanvar */
3112                         tmp = variable;
3113                         /* FIXME replace this call with strsep  NOT*/
3114                         while( (var = strtok_r(NULL, "|", &tmp)) ) {
3115                                 pbx_builtin_setvar( chan, var );
3116                         } /* /JDG */
3117                         if (chan->_state == AST_STATE_UP) {
3118                                 res = 0;
3119                                 if (option_verbose > 3)
3120                                         ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
3121                                 if (context && strlen(context))
3122                                         strncpy(chan->context, context, sizeof(chan->context) - 1);
3123                                 if (exten && strlen(exten))
3124                                         strncpy(chan->exten, exten, sizeof(chan->exten) - 1);
3125                                 if (priority > 0)
3126                                         chan->priority = priority;
3127                                 if (sync > 1) {
3128                                         if (ast_pbx_run(chan)) {
3129                                                 ast_log(LOG_WARNING, "Unable to run PBX on %s\n", chan->name);
3130                                                 ast_hangup(chan);
3131                                                 res = -1;
3132                                         }
3133                                 } else {
3134                                         if (ast_pbx_start(chan)) {
3135                                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", chan->name);
3136                                                 ast_hangup(chan);
3137                                                 res = -1;
3138                                         } 
3139                                 }
3140                         } else {
3141                                 if (option_verbose > 3)
3142                                         ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
3143                                 ast_hangup(chan);
3144                         }
3145                 }
3146         } else {
3147                 as = malloc(sizeof(struct async_stat));
3148                 if (!as)
3149                         return -1;
3150                 memset(as, 0, sizeof(struct async_stat));
3151                 chan = ast_request_and_dial(type, format, data, 0, reason, callerid);
3152                 if (!chan) {
3153                         free(as);
3154                         return -1;
3155                 }
3156                 as->chan = chan;
3157                 strncpy(as->context, context, sizeof(as->context) - 1);
3158                 strncpy(as->exten,  exten, sizeof(as->exten) - 1);
3159                 as->priority = priority;
3160                 as->timeout = timeout;
3161                 if (pthread_create(&as->p, NULL, async_wait, as)) {
3162                         ast_log(LOG_WARNING, "Failed to start async wait\n");
3163                         free(as);
3164                         ast_hangup(chan);
3165                         return -1;
3166                 }
3167                 res = 0;
3168         }
3169         return res;
3170 }
3171
3172 struct app_tmp {
3173         char app[256];
3174         char data[256];
3175         struct ast_channel *chan;
3176         pthread_t t;
3177 };
3178
3179 static void *ast_pbx_run_app(void *data)
3180 {
3181         struct app_tmp *tmp = data;
3182         struct ast_app *app;
3183         app = pbx_findapp(tmp->app);
3184         if (app) {
3185                 if (option_verbose > 3)
3186                         ast_verbose(VERBOSE_PREFIX_4 "Lauching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name);
3187                 pbx_exec(tmp->chan, app, tmp->data, 1);
3188         } else
3189                 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app);
3190         ast_hangup(tmp->chan);
3191         free(tmp);
3192         return NULL;
3193 }
3194
3195 int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *callerid)
3196 {
3197         struct ast_channel *chan;
3198         struct async_stat *as;
3199         struct app_tmp *tmp;
3200         int res = -1;
3201         if (!app || !strlen(app))
3202                 return -1;
3203         if (sync) {
3204                 chan = ast_request_and_dial(type, format, data, timeout, reason, callerid);
3205                 if (chan) {
3206                         if (chan->_state == AST_STATE_UP) {
3207                                 res = 0;
3208                                 if (option_verbose > 3)
3209                                         ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
3210                                 tmp = malloc(sizeof(struct app_tmp));
3211                                 if (tmp) {
3212                                         memset(tmp, 0, sizeof(struct app_tmp));
3213                                         strncpy(tmp->app, app, sizeof(tmp->app) - 1);
3214                                         strncpy(tmp->data, appdata, sizeof(tmp->data) - 1);
3215                                         tmp->chan = chan;
3216                                         if (sync > 1) {
3217                                                 ast_pbx_run_app(tmp);
3218                                         } else {
3219                                                 if (pthread_create(&tmp->t, NULL, ast_pbx_run_app, tmp)) {
3220                                                         ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
3221                                                         free(tmp);
3222                                                         ast_hangup(chan);
3223                                                         res = -1;
3224                                                 }
3225                                         }
3226                                 } else {
3227                                         ast_log(LOG_WARNING, "Out of memory :(\n");
3228                                         res = -1;
3229                                 }
3230                         } else {
3231                                 if (option_verbose > 3)
3232                                         ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
3233                                 ast_hangup(chan);
3234                         }
3235                 }
3236         } else {
3237                 as = malloc(sizeof(struct async_stat));
3238                 if (!as)
3239                         return -1;
3240                 memset(as, 0, sizeof(struct async_stat));
3241                 chan = ast_request_and_dial(type, format, data, 0, reason, callerid);
3242                 if (!chan) {
3243                         free(as);
3244                         return -1;
3245                 }
3246                 as->chan = chan;
3247                 strncpy(as->app, app, sizeof(as->app) - 1);
3248                 if (appdata)
3249                         strncpy(as->appdata,  appdata, sizeof(as->appdata) - 1);
3250                 as->timeout = timeout;
3251                 if (pthread_create(&as->p, NULL, async_wait, as)) {
3252                         ast_log(LOG_WARNING, "Failed to start async wait\n");
3253                         free(as);
3254                         ast_hangup(chan);
3255                         return -1;
3256                 }
3257                 res = 0;
3258         }
3259         return res;
3260 }
3261
3262 void ast_context_destroy(struct ast_context *con, char *registrar)
3263 {
3264         struct ast_context *tmp, *tmpl=NULL;
3265         struct ast_include *tmpi, *tmpil= NULL;
3266         struct ast_sw *sw, *swl= NULL;
3267         ast_pthread_mutex_lock(&conlock);
3268         tmp = contexts;
3269         while(tmp) {
3270                 if (((tmp == con) || !con) &&
3271                     (!registrar || !strcasecmp(registrar, tmp->registrar))) {
3272                         /* Okay, let's lock the structure to be sure nobody else
3273                            is searching through it. */
3274                         if (ast_pthread_mutex_lock(&tmp->lock)) {
3275                                 ast_log(LOG_WARNING, "Unable to lock context lock\n");
3276                                 return;
3277                         }
3278                         if (tmpl)
3279                                 tmpl->next = tmp->next;
3280                         else
3281                                 contexts = tmp->next;
3282                         /* Okay, now we're safe to let it go -- in a sense, we were
3283                            ready to let it go as soon as we locked it. */
3284                         ast_pthread_mutex_unlock(&tmp->lock);
3285                         for (tmpi = tmp->includes; tmpi; ) {
3286                                 /* Free includes */
3287                                 tmpil = tmpi;
3288                                 tmpi = tmpi->next;
3289                                 free(tmpil);
3290                                 tmpil = tmpi;
3291                         }
3292                         for (sw = tmp->alts; sw; ) {
3293                                 swl = sw;
3294                                 sw = sw->next;
3295                                 free(swl);
3296                                 swl = sw;
3297                         }
3298                         free(tmp);
3299                         if (!con) {
3300                                 /* Might need to get another one -- restart */
3301                                 tmp = contexts;
3302                                 tmpl = NULL;
3303                                 tmpil = NULL;
3304                                 continue;
3305                         }
3306                         ast_pthread_mutex_unlock(&conlock);
3307                         return;
3308                 }
3309                 tmpl = tmp;
3310                 tmp = tmp->next;
3311         }
3312         ast_pthread_mutex_unlock(&conlock);
3313 }
3314
3315 static void wait_for_hangup(struct ast_channel *chan)
3316 {
3317         int res;
3318         struct ast_frame *f;
3319         do {
3320                 res = ast_waitfor(chan, -1);
3321                 if (res < 0)
3322                         return;
3323                 f = ast_read(chan);
3324                 if (f)
3325                         ast_frfree(f);
3326         } while(f);
3327 }
3328
3329 static int pbx_builtin_ringing(struct ast_channel *chan, void *data)
3330 {
3331         ast_indicate(chan, AST_CONTROL_RINGING);
3332         return 0;
3333 }
3334
3335 static int pbx_builtin_busy(struct ast_channel *chan, void *data)
3336 {
3337         ast_indicate(chan, AST_CONTROL_BUSY);           
3338         wait_for_hangup(chan);
3339         return -1;
3340 }
3341
3342 static int pbx_builtin_congestion(struct ast_channel *chan, void *data)
3343 {
3344         ast_indicate(chan, AST_CONTROL_CONGESTION);
3345         wait_for_hangup(chan);
3346         return -1;
3347 }
3348
3349 static int pbx_builtin_answer(struct ast_channel *chan, void *data)
3350 {
3351         return ast_answer(chan);
3352 }
3353
3354 static int pbx_builtin_setlanguage(struct ast_channel *chan, void *data)
3355 {
3356         /* Copy the language as specified */
3357         strncpy(chan->language, (char *)data, sizeof(chan->language)-1);
3358         return 0;
3359 }
3360
3361 static int pbx_builtin_hangup(struct ast_channel *chan, void *data)
3362 {
3363         /* Just return non-zero and it will hang up */
3364         return -1;
3365 }
3366
3367 static int pbx_builtin_stripmsd(struct ast_channel *chan, void *data)
3368 {
3369         char newexten[AST_MAX_EXTENSION] = "";
3370         if (!data || !atoi(data)) {
3371                 ast_log(LOG_DEBUG, "Ignoring, since number of digits to strip is 0\n");
3372                 return 0;
3373         }
3374         if (strlen(chan->exten) > atoi(data)) {
3375                 strncpy(newexten, chan->exten + atoi(data), sizeof(newexten)-1);
3376         }
3377         strncpy(chan->exten, newexten, sizeof(chan->exten)-1);
3378         return 0;
3379 }
3380
3381 static int pbx_builtin_prefix(struct ast_channel *chan, void *data)
3382 {
3383         char newexten[AST_MAX_EXTENSION] = "";
3384         if (!data || !strlen(data)) {
3385                 ast_log(LOG_DEBUG, "Ignoring, since there is no prefix to add\n");
3386                 return 0;
3387         }
3388         snprintf(newexten, sizeof(newexten), "%s%s", (char *)data, chan->exten);
3389         strncpy(chan->exten, newexten, sizeof(chan->exten)-1);
3390         if (option_verbose > 2)
3391                 ast_verbose(VERBOSE_PREFIX_3 "Prepended prefix, new extension is %s\n", chan->exten);
3392         return 0;
3393 }
3394
3395 static int pbx_builtin_wait(struct ast_channel *chan, void *data)
3396 {
3397         int ms;
3398         /* Wait for "n" seconds */
3399         if (data && atoi((char *)data)) {
3400                 ms = atoi((char *)data) * 1000;
3401                 return ast_safe_sleep(chan, ms);
3402         }
3403         return 0;
3404 }
3405
3406 static int pbx_builtin_background(struct ast_channel *chan, void *data)
3407 {
3408         int res;
3409         /* Answer if need be */
3410         if (chan->_state != AST_STATE_UP)
3411                 if (ast_answer(chan))
3412                         return -1;
3413         /* Stop anything playing */
3414         ast_stopstream(chan);
3415         /* Stream a file */
3416         res = ast_streamfile(chan, (char *)data, chan->language);
3417         if (!res) {
3418                 res = ast_waitstream(chan, AST_DIGIT_ANY);
3419                 ast_stopstream(chan);
3420         }
3421         return res;
3422 }
3423
3424 static int pbx_builtin_atimeout(struct ast_channel *chan, void *data)
3425 {
3426         int x = atoi((char *) data);
3427         /* Set the timeout for how long to wait between digits */
3428         ast_channel_setwhentohangup(chan,x);
3429         if (option_verbose > 2)
3430                 ast_verbose( VERBOSE_PREFIX_3 "Set Absolute Timeout to %d\n", x);
3431         return 0;
3432 }
3433
3434 static int pbx_builtin_rtimeout(struct ast_channel *chan, void *data)
3435 {
3436         /* Set the timeout for how long to wait between digits */
3437         chan->pbx->rtimeout = atoi((char *)data);
3438         if (option_verbose > 2)
3439                 ast_verbose( VERBOSE_PREFIX_3 "Set Response Timeout to %d\n", chan->pbx->rtimeout);
3440         return 0;
3441 }
3442
3443 static int pbx_builtin_dtimeout(struct ast_channel *chan, void *data)
3444 {
3445         /* Set the timeout for how long to wait between digits */
3446         chan->pbx->dtimeout = atoi((char *)data);
3447         if (option_verbose > 2)
3448                 ast_verbose( VERBOSE_PREFIX_3 "Set Digit Timeout to %d\n", chan->pbx->dtimeout);
3449         return 0;
3450 }
3451
3452 static int pbx_builtin_goto(struct ast_channel *chan, void *data)
3453 {
3454         char *s;
3455         char *exten, *pri, *context;
3456         char *stringp=NULL;
3457         if (!data || !strlen(data)) {
3458                 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
3459                 return -1;
3460         }
3461         s = strdup((void *) data);
3462         stringp=s;
3463         context = strsep(&stringp, "|");
3464         exten = strsep(&stringp, "|");
3465         if (!exten) {
3466                 /* Only a priority in this one */
3467                 pri = context;
3468                 exten = NULL;
3469                 context = NULL;
3470         } else {
3471                 pri = strsep(&stringp, "|");
3472                 if (!pri) {
3473                         /* Only an extension and priority in this one */
3474                         pri = exten;
3475                         exten = context;
3476                         context = NULL;
3477                 }
3478         }
3479         if (atoi(pri) < 0) {
3480                 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", pri);
3481                 free(s);
3482                 return -1;
3483         }