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