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