Version 0.1.8 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 <pthread.h>
15 #include <asterisk/pbx.h>
16 #include <asterisk/channel.h>
17 #include <asterisk/options.h>
18 #include <asterisk/logger.h>
19 #include <asterisk/file.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <setjmp.h>
25 #include <ctype.h>
26 #include "asterisk.h"
27
28 /*
29  * I M P O R T A N T :
30  *
31  *              The speed of extension handling will likely be among the most important
32  * aspects of this PBX.  The switching scheme as it exists right now isn't
33  * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
34  * of priorities, but a constant search time here would be great ;-) 
35  *
36  */
37
38
39 struct ast_context;
40
41 struct ast_pbx {
42         int dtimeout;                                   /* Timeout between digits (seconds) */
43         int rtimeout;                                   /* Timeout for response (seconds) */
44 };
45
46 /* An extension */
47 struct ast_exten {
48         char exten[AST_MAX_EXTENSION];
49         int priority;
50         /* An extension */
51         struct ast_context *parent;
52         /* Application to execute */
53         char app[AST_MAX_EXTENSION];
54         /* Data to use */
55         void *data;
56         /* Data destructor */
57         void (*datad)(void *);
58         /* Next highest priority with our extension */
59         struct ast_exten *peer;
60         /* Extension with a greater ID */
61         struct ast_exten *next;
62 };
63
64 struct ast_include {
65         char name[AST_MAX_EXTENSION];
66         struct ast_include *next;
67 };
68
69 /* An extension context */
70 struct ast_context {
71         /* Name of the context */
72         char name[AST_MAX_EXTENSION];
73         /* A lock to prevent multiple threads from clobbering the context */
74         pthread_mutex_t lock;
75         /* The root of the list of extensions */
76         struct ast_exten *root;
77         /* Link them together */
78         struct ast_context *next;
79         /* Include other contexts */
80         struct ast_include *includes;
81 };
82
83
84 /* An application */
85 struct ast_app {
86         /* Name of the application */
87         char name[AST_MAX_APP];
88         int (*execute)(struct ast_channel *chan, void *data);
89         struct ast_app *next;
90 };
91
92 static int pbx_builtin_prefix(struct ast_channel *, void *);
93 static int pbx_builtin_stripmsd(struct ast_channel *, void *);
94 static int pbx_builtin_answer(struct ast_channel *, void *);
95 static int pbx_builtin_goto(struct ast_channel *, void *);
96 static int pbx_builtin_hangup(struct ast_channel *, void *);
97 static int pbx_builtin_background(struct ast_channel *, void *);
98 static int pbx_builtin_dtimeout(struct ast_channel *, void *);
99 static int pbx_builtin_rtimeout(struct ast_channel *, void *);
100 static int pbx_builtin_wait(struct ast_channel *, void *);
101 static int pbx_builtin_setlanguage(struct ast_channel *, void *);
102
103 static struct pbx_builtin {
104         char name[AST_MAX_APP];
105         int (*execute)(struct ast_channel *chan, void *data);
106 } builtins[] = 
107 {
108         /* These applications are built into the PBX core and do not
109            need separate modules */
110         { "Answer", pbx_builtin_answer },
111         { "Goto", pbx_builtin_goto },
112         { "Hangup", pbx_builtin_hangup },
113         { "DigitTimeout", pbx_builtin_dtimeout },
114         { "ResponseTimeout", pbx_builtin_rtimeout },
115         { "BackGround", pbx_builtin_background },
116         { "Wait", pbx_builtin_wait },
117         { "StripMSD", pbx_builtin_stripmsd },
118         { "Prefix", pbx_builtin_prefix },
119         { "SetLanguage", pbx_builtin_setlanguage },
120 };
121
122 /* Lock for the application list */
123 static pthread_mutex_t applock = PTHREAD_MUTEX_INITIALIZER;
124 static struct ast_context *contexts = NULL;
125 /* Lock for the ast_context list */
126 static pthread_mutex_t conlock = PTHREAD_MUTEX_INITIALIZER;
127 static struct ast_app *apps = NULL;
128
129 static int pbx_exec(struct ast_channel *c, /* Channel */
130                                         int (*execute)(struct ast_channel *chan, void *data), 
131                                         void *data,                             /* Data for execution */
132                                         int newstack)                   /* Force stack increment */
133 {
134         /* This function is special.  It saves the stack so that no matter
135            how many times it is called, it returns to the same place */
136         int res;
137         int stack = c->stack;
138         if (newstack && stack > AST_CHANNEL_MAX_STACK - 2) {
139                 /* Don't allow us to go over the max number of stacks we
140                    permit saving. */
141                 ast_log(LOG_WARNING, "Stack overflow, cannot create another stack\n");
142                 return -1;
143         }
144         if (newstack && (res = setjmp(c->jmp[++c->stack]))) {
145                 /* Okay, here's where it gets weird.  If newstack is non-zero, 
146                    then we increase the stack increment, but setjmp is not going
147                    to return until longjmp is called -- when the application
148                    exec'd is finished running. */
149                 if (res == 1)
150                         res = 0;
151                 if (c->stack != stack + 1) 
152                         ast_log(LOG_WARNING, "Stack returned to an unexpected place!\n");
153                 else if (c->app[c->stack])
154                         ast_log(LOG_WARNING, "Application may have forgotten to free its memory\n");
155                 c->stack = stack;
156                 return res;
157         } else {
158                 res = execute(c, data);
159                 /* Any application that returns, we longjmp back, just in case. */
160                 if (c->stack != stack + 1)
161                         ast_log(LOG_WARNING, "Stack is not at expected value\n");
162                 longjmp(c->jmp[stack+1], res);
163                 /* Never returns */
164         }
165 }
166
167
168 /* Go no deeper than this through includes (not counting loops) */
169 #define AST_PBX_MAX_STACK       64
170
171 #define HELPER_EXISTS 0
172 #define HELPER_SPAWN 1
173 #define HELPER_EXEC 2
174 #define HELPER_CANMATCH 3
175
176 static struct ast_app *pbx_findapp(char *app) 
177 {
178         struct ast_app *tmp;
179         if (pthread_mutex_lock(&applock)) {
180                 ast_log(LOG_WARNING, "Unable to obtain application lock\n");
181                 return NULL;
182         }
183         tmp = apps;
184         while(tmp) {
185                 if (!strcasecmp(tmp->name, app))
186                         break;
187                 tmp = tmp->next;
188         }
189         pthread_mutex_unlock(&applock);
190         return tmp;
191 }
192
193 static void pbx_destroy(struct ast_pbx *p)
194 {
195         free(p);
196 }
197
198 static inline int extension_match(char *pattern, char *data)
199 {
200         int match;
201         /* If they're the same return */
202         if (!strcasecmp(pattern, data))
203                 return 1;
204         /* All patterns begin with _ */
205         if (pattern[0] != '_') 
206                 return 0;
207         /* Obviously must be the same length */
208         if (strlen(pattern) != strlen(data) + 1)
209                 return 0;
210         /* Start optimistic */
211         match=1;
212         pattern++;
213         while(match && *data && *pattern) {
214                 switch(toupper(*pattern)) {
215                 case 'N':
216                         if ((*data < '2') || (*data > '9'))
217                                 match=0;
218                         break;
219                 case 'X':
220                         if ((*data < '0') || (*data > '9'))
221                                 match = 0;
222                         break;
223                 default:
224                         if (*data != *pattern)
225                                 match =0;
226                 }
227                 data++;
228                 pattern++;
229         }
230         return match;
231 }
232
233 static int extension_close(char *pattern, char *data)
234 {
235         int match;
236         /* If "data" is longer, it can'be a subset of pattern */
237         if (strlen(pattern) < strlen(data)) 
238                 return 0;
239         
240         
241         if (!strlen((char *)data) || !strncasecmp(pattern, data, strlen(data))) {
242                 return 1;
243         }
244         /* All patterns begin with _ */
245         if (pattern[0] != '_') 
246                 return 0;
247         /* Start optimistic */
248         match=1;
249         pattern++;
250         while(match && *data && *pattern) {
251                 switch(toupper(*pattern)) {
252                 case 'N':
253                         if ((*data < '2') || (*data > '9'))
254                                 match=0;
255                         break;
256                 case 'X':
257                         if ((*data < '0') || (*data > '9'))
258                                 match = 0;
259                         break;
260                 default:
261                         if (*data != *pattern)
262                                 match =0;
263                 }
264                 data++;
265                 pattern++;
266         }
267         return match;
268 }
269
270 struct ast_context *ast_context_find(char *name)
271 {
272         struct ast_context *tmp;
273         pthread_mutex_lock(&conlock);
274         tmp = contexts;
275         while(tmp) {
276                 if (!strcasecmp(name, tmp->name))
277                         break;
278                 tmp = tmp->next;
279         }
280         pthread_mutex_unlock(&conlock);
281         return tmp;
282 }
283
284 #define STATUS_NO_CONTEXT   1
285 #define STATUS_NO_EXTENSION 2
286 #define STATUS_NO_PRIORITY  3
287 #define STATUS_SUCCESS      4
288
289 static struct ast_exten *pbx_find_extension(char *context, char *exten, int priority, int action, char *incstack[], int *stacklen, int *status)
290 {
291         int x;
292         struct ast_context *tmp;
293         struct ast_exten *e, *eroot;
294         struct ast_include *i;
295         /* Initialize status if appropriate */
296         if (!*stacklen)
297                 *status = STATUS_NO_CONTEXT;
298         /* Check for stack overflow */
299         if (*stacklen >= AST_PBX_MAX_STACK) {
300                 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
301                 return NULL;
302         }
303         /* Check first to see if we've already been checked */
304         for (x=0;x<*stacklen;x++) {
305                 if (!strcasecmp(incstack[x], context))
306                         return NULL;
307         }
308         tmp = contexts;
309         while(tmp) {
310                 /* Match context */
311                 if (!strcasecmp(tmp->name, context)) {
312                         if (*status < STATUS_NO_EXTENSION)
313                                 *status = STATUS_NO_EXTENSION;
314                         eroot = tmp->root;
315                         while(eroot) {
316                                 /* Match extension */
317                                 if (extension_match(eroot->exten, exten) ||
318                                                 ((action == HELPER_CANMATCH) && (extension_close(eroot->exten, exten)))) {
319                                                 e = eroot;
320                                                 if (*status < STATUS_NO_PRIORITY)
321                                                         *status = STATUS_NO_PRIORITY;
322                                                 while(e) {
323                                                         /* Match priority */
324                                                         if (e->priority == priority) {
325                                                                 *status = STATUS_SUCCESS;
326                                                                 return e;
327                                                         }
328                                                         e = e->peer;
329                                                 }
330                                 }
331                                 eroot = eroot->next;
332                         }
333                         /* Setup the stack */
334                         incstack[*stacklen] = tmp->name;
335                         (*stacklen)++;
336                         /* Now try any includes we have in this context */
337                         i = tmp->includes;
338                         while(i) {
339                                 if ((e = pbx_find_extension(i->name, exten, priority, action, incstack, stacklen, status))) 
340                                         return e;
341                                 i = i->next;
342                         }
343                 }
344                 tmp = tmp->next;
345         }
346         return NULL;
347 }
348
349 static int pbx_extension_helper(struct ast_channel *c, char *context, char *exten, int priority, int action) 
350 {
351         struct ast_exten *e;
352         struct ast_app *app;
353         int newstack = 0;
354         int res;
355         int status = 0;
356         char *incstack[AST_PBX_MAX_STACK];
357         int stacklen = 0;
358
359
360         if (pthread_mutex_lock(&conlock)) {
361                 ast_log(LOG_WARNING, "Unable to obtain lock\n");
362                 if ((action == HELPER_EXISTS) || (action == HELPER_CANMATCH))
363                         return 0;
364                 else
365                         return -1;
366         }
367         e = pbx_find_extension(context, exten, priority, action, incstack, &stacklen, &status);
368         if (e) {
369                 switch(action) {
370                 case HELPER_CANMATCH:
371                         pthread_mutex_unlock(&conlock);
372                         return -1;
373                 case HELPER_EXISTS:
374                         pthread_mutex_unlock(&conlock);
375                         return -1;
376                 case HELPER_SPAWN:
377                         newstack++;
378                         /* Fall through */
379                 case HELPER_EXEC:
380                         app = pbx_findapp(e->app);
381                         pthread_mutex_unlock(&conlock);
382                         if (app) {
383                                 strncpy(c->context, context, sizeof(c->context));
384                                 strncpy(c->exten, exten, sizeof(c->exten));
385                                 c->priority = priority;
386                                 if (option_debug)
387                                                 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
388                                 else if (option_verbose > 2)
389                                                 ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n", 
390                                                                 app->name, c->name, (e->data ? (char *)e->data : NULL), (newstack ? "in new stack" : "in same stack"));
391                                 c->appl = app->name;
392                                 c->data = e->data;              
393                                 res = pbx_exec(c, app->execute, e->data, newstack);
394                                 c->appl = NULL;
395                                 c->data = NULL;
396                                 pthread_mutex_unlock(&conlock);
397                                 return res;
398                         } else {
399                                 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
400                                 return -1;
401                         }
402                 default:
403                         ast_log(LOG_WARNING, "Huh (%d)?\n", action);
404                         return -1;
405                 }
406         } else {
407                 pthread_mutex_unlock(&conlock);
408                 switch(status) {
409                 case STATUS_NO_CONTEXT:
410                         if (action != HELPER_EXISTS)
411                                 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
412                         break;
413                 case STATUS_NO_EXTENSION:
414                         if ((action != HELPER_EXISTS) && (action !=  HELPER_CANMATCH))
415                                 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
416                         break;
417                 case STATUS_NO_PRIORITY:
418                         if ((action != HELPER_EXISTS) && (action !=  HELPER_CANMATCH))
419                                 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
420                         break;
421                 default:
422                         ast_log(LOG_DEBUG, "Shouldn't happen!\n");
423                 }
424                 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH))
425                         return -1;
426                 else
427                         return 0;
428         }
429
430 #if 0           
431         tmp = contexts;
432         while(tmp) {
433                 if (!strcasecmp(tmp->name, context)) {
434 #if 0
435                         /* By locking tmp, not only can the state of its entries not
436                            change, but it cannot be destroyed either. */
437                         pthread_mutex_lock(&tmp->lock);
438 #endif
439                         e = tmp->root;
440                         while(e) {
441                                 if (extension_match(e->exten, exten) || 
442                                         ((action == HELPER_CANMATCH) && extension_close(e->exten, exten))) {
443                                         reale = e;
444                                         while(e) {
445                                                 if (e->priority == priority) {
446                                                         /* We have a winner! Maybe there are some races
447                                                            in here though. XXX */
448                                                         switch(action) {
449                                                         case HELPER_CANMATCH:
450                                                                 pthread_mutex_unlock(&conlock);
451                                                                 return -1;
452                                                         case HELPER_EXISTS:
453                                                                 pthread_mutex_unlock(&conlock);
454                                                                 return -1;
455                                                         case HELPER_SPAWN:
456                                                                 newstack++;
457                                                                 /* Fall through */
458                                                         case HELPER_EXEC:
459                                                                 app = pbx_findapp(e->app);
460                                                                 pthread_mutex_unlock(&conlock);
461                                                                 if (app) {
462                                                                         strncpy(c->context, context, sizeof(c->context));
463                                                                         strncpy(c->exten, exten, sizeof(c->exten));
464                                                                         c->priority = priority;
465                                                                         if (option_debug)
466                                                                                 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
467                                                                         else if (option_verbose > 2)
468                                                                                 ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n", 
469                                                                                                 app->name, c->name, (e->data ? (char *)e->data : NULL), (newstack ? "in new stack" : "in same stack"));
470                                                                         c->appl = app->name;
471                                                                         c->data = e->data;              
472                                                                         res = pbx_exec(c, app->execute, e->data, newstack);
473                                                                         c->appl = NULL;
474                                                                         c->data = NULL;
475                                                                         pthread_mutex_unlock(&conlock);
476                                                                         return res;
477                                                                 } else {
478                                                                         ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
479                                                                         return -1;
480                                                                 }
481                                                         default:
482                                                                 ast_log(LOG_WARNING, "Huh (%d)?\n", action);
483                                                         }
484                                                 }
485                                                 e = e->peer;
486                                         }
487                                         pthread_mutex_unlock(&tmp->lock);
488                                         if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH)) {
489                                                 ast_log(LOG_WARNING, "No such priority '%d' in '%s' in '%s'\n", priority, exten, context);
490                                                 pthread_mutex_unlock(&conlock);
491                                                 return -1;
492                                         } else if (action != HELPER_CANMATCH) {
493                                                 pthread_mutex_unlock(&conlock);
494                                                 return 0;
495                                         } else e = reale; /* Keep going */
496                                 }
497                                 e = e->next;
498                         }
499                         if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH)) {
500                                 pthread_mutex_unlock(&conlock);
501                                 ast_log(LOG_WARNING, "No such extension '%s' in '%s'\n", exten, context);
502                                 return -1;
503                         } else {
504                                 pthread_mutex_unlock(&conlock);
505                                 return 0;
506                         }
507                 }
508                 tmp = tmp->next;
509         }
510         pthread_mutex_unlock(&conlock);
511         if (action != HELPER_EXISTS) {
512                 ast_log(LOG_WARNING, "No such context '%s'\n", context);
513                 return -1;
514         } else
515                 return 0;
516 #endif
517 }
518
519 int ast_pbx_longest_extension(char *context) 
520 {
521         /* XXX Not include-aware XXX */
522         struct ast_context *tmp;
523         struct ast_exten *e;
524         int len = 0;
525         if (pthread_mutex_lock(&conlock)) {
526                 ast_log(LOG_WARNING, "Unable to obtain lock\n");
527                 return -1;
528         }
529         tmp = contexts;
530         while(tmp) {
531                 if (!strcasecmp(tmp->name, context)) {
532                         /* By locking tmp, not only can the state of its entries not
533                            change, but it cannot be destroyed either. */
534                         pthread_mutex_lock(&tmp->lock);
535                         /* But we can relieve the conlock, as tmp will not change */
536                         pthread_mutex_unlock(&conlock);
537                         e = tmp->root;
538                         while(e) {
539                                 if (strlen(e->exten) > len)
540                                         len = strlen(e->exten);
541                                 e = e->next;
542                         }
543                         pthread_mutex_unlock(&tmp->lock);
544                         return len;
545                 }
546                 tmp = tmp->next;
547         }
548         ast_log(LOG_WARNING, "No such context '%s'\n", context);
549         return -1;
550 }
551
552 int ast_exists_extension(struct ast_channel *c, char *context, char *exten, int priority) 
553 {
554         return pbx_extension_helper(c, context, exten, priority, HELPER_EXISTS);
555 }
556
557 int ast_canmatch_extension(struct ast_channel *c, char *context, char *exten, int priority)
558 {
559         return pbx_extension_helper(c, context, exten, priority, HELPER_CANMATCH);
560 }
561
562 int ast_spawn_extension(struct ast_channel *c, char *context, char *exten, int priority) 
563 {
564         return pbx_extension_helper(c, context, exten, priority, HELPER_SPAWN);
565 }
566
567 int ast_pbx_run(struct ast_channel *c)
568 {
569         int firstpass = 1;
570         char digit;
571         char exten[256];
572         int pos;
573         int waittime;
574         int res=0;
575
576         /* A little initial setup here */
577         if (c->pbx)
578                 ast_log(LOG_WARNING, "%s already has PBX structure??\n");
579         c->pbx = malloc(sizeof(struct ast_pbx));
580         if (!c->pbx) {
581                 ast_log(LOG_WARNING, "Out of memory\n");
582                 return -1;
583         }
584         memset(c->pbx, 0, sizeof(struct ast_pbx));
585         /* Set reasonable defaults */
586         c->pbx->rtimeout = 10;
587         c->pbx->dtimeout = 5;
588
589         if (option_debug)
590                 ast_log(LOG_DEBUG, "PBX_THREAD(%s)\n", c->name);
591         else if (option_verbose > 1) {
592                 if (c->callerid)
593                         ast_verbose( VERBOSE_PREFIX_2 "Accepting call on '%s' (%s)\n", c->name, c->callerid);
594                 else
595                         ast_verbose( VERBOSE_PREFIX_2 "Accepting call on '%s'\n", c->name);
596         }
597                 
598         
599         /* Start by trying whatever the channel is set to */
600         if (!ast_exists_extension(c, c->context, c->exten, c->priority)) {
601                 strncpy(c->context, "default", sizeof(c->context));
602                 strncpy(c->exten, "s", sizeof(c->exten));
603                 c->priority = 1;
604         }
605         for(;;) {
606                 pos = 0;
607                 digit = 0;
608                 while(ast_exists_extension(c, c->context, c->exten, c->priority)) {
609                         memset(exten, 0, sizeof(exten));
610                         if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority))) {
611                                 /* Something bad happened, or a hangup has been requested. */
612                                 switch(res) {
613                                 case AST_PBX_KEEPALIVE:
614                                         if (option_debug)
615                                                 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
616                                         else if (option_verbose > 1)
617                                                 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
618                                 break;
619                                 default:
620                                         if (option_debug)
621                                                 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
622                                         else if (option_verbose > 1)
623                                                 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
624                                 }
625                                 goto out;
626                         }
627                         /* If we're playing something in the background, wait for it to finish or for a digit */
628                         if (c->stream) {
629                                 digit = ast_waitstream(c, AST_DIGIT_ANY);
630                                 ast_stopstream(c);
631                                 /* Hang up if something goes wrong */
632                                 if (digit < 0) {
633                                         if (option_verbose > 2)
634                                                 ast_verbose(VERBOSE_PREFIX_3 "Lost connection on %s\n", c->name);
635                                         goto out;
636                                 }
637                                 else if (digit) {
638                                         exten[pos++] = digit;
639                                         break;
640                                 }
641                         }
642                         firstpass = 0;
643                         c->priority++;
644                 }
645                 /* Done, wait for an extension */
646                 if (digit)
647                         waittime = c->pbx->dtimeout;
648                 else
649                         waittime = c->pbx->rtimeout;
650                 while(!ast_exists_extension(c, c->context, exten, 1) && 
651                        ast_canmatch_extension(c, c->context, exten, 1)) {
652                         /* As long as we're willing to wait, and as long as it's not defined, 
653                            keep reading digits until we can't possibly get a right answer anymore.  */
654                         digit = ast_waitfordigit(c, waittime * 1000);
655                         if (!digit)
656                                 /* No entry */
657                                 break;
658                         if (digit < 0)
659                                 /* Error, maybe a  hangup */
660                                 goto out;
661                         exten[pos++] = digit;
662                         waittime = c->pbx->dtimeout;
663                 }
664                 if (ast_exists_extension(c, c->context, exten, 1)) {
665                         /* Prepare the next cycle */
666                         strncpy(c->exten, exten, sizeof(c->exten));
667                         c->priority = 1;
668                 } else {
669                         /* No such extension */
670                         if (strlen(exten)) {
671                                 /* An invalid extension */
672                                 if (ast_exists_extension(c, c->context, "i", 1)) {
673                                         if (option_verbose > 2)
674                                                 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name);
675                                         strncpy(c->exten, "i", sizeof(c->exten));
676                                         c->priority = 1;
677                                 } else {
678                                         ast_log(LOG_WARNING, "Invalid extension, but no rule 'i' in context '%s'\n", c->context);
679                                         goto out;
680                                 }
681                         } else {
682                                 /* A simple timeout */
683                                 if (ast_exists_extension(c, c->context, "t", 1)) {
684                                         if (option_verbose > 2)
685                                                 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
686                                         strncpy(c->exten, "t", sizeof(c->exten));
687                                         c->priority = 1;
688                                 } else {
689                                         ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
690                                         goto out;
691                                 }
692                         }       
693                 }
694         }
695         if (firstpass) 
696                 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
697 out:
698         pbx_destroy(c->pbx);
699         c->pbx = NULL;
700         if (res != AST_PBX_KEEPALIVE)
701                 ast_hangup(c);
702         return 0;
703 }
704
705 static void *pbx_thread(void *data)
706 {
707         /* Oh joyeous kernel, we're a new thread, with nothing to do but
708            answer this channel and get it going.  The setjmp stuff is fairly
709            confusing, but necessary to get smooth transitions between
710            the execution of different applications (without the use of
711            additional threads) */
712         struct ast_channel *c = data;
713         ast_pbx_run(c);
714         pthread_exit(NULL);
715         return NULL;
716 }
717
718 int ast_pbx_start(struct ast_channel *c)
719 {
720         pthread_t t;
721         if (!c) {
722                 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
723                 return -1;
724         }
725         /* Start a new thread, and get something handling this channel. */
726         if (pthread_create(&t, NULL, pbx_thread, c)) {
727                 ast_log(LOG_WARNING, "Failed to create new channel thread\n");
728                 return -1;
729         }
730         return 0;
731 }
732 #if 0
733 int ast_remove_extension(struct ast_context *con, char *extension, int priority)
734 {
735         /* XXX Implement me XXX */
736         return -1;
737 }
738 #endif
739 int ast_register_application(char *app, int (*execute)(struct ast_channel *, void *))
740 {
741         struct ast_app *tmp;
742         if (pthread_mutex_lock(&applock)) {
743                 ast_log(LOG_ERROR, "Unable to lock application list\n");
744                 return -1;
745         }
746         tmp = apps;
747         while(tmp) {
748                 if (!strcasecmp(app, tmp->name)) {
749                         ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
750                         pthread_mutex_unlock(&applock);
751                         return -1;
752                 }
753                 tmp = tmp->next;
754         }
755         tmp = malloc(sizeof(struct ast_app));
756         if (tmp) {
757                 strncpy(tmp->name, app, sizeof(tmp->name));
758                 tmp->execute = execute;
759                 tmp->next = apps;
760                 apps = tmp;
761         } else {
762                 ast_log(LOG_WARNING, "Out of memory\n");
763                 pthread_mutex_unlock(&applock);
764                 return -1;
765         }
766         if (option_verbose > 1)
767                 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", tmp->name);
768         pthread_mutex_unlock(&applock);
769         return 0;
770 }
771
772 int ast_unregister_application(char *app) {
773         struct ast_app *tmp, *tmpl = NULL;
774         if (pthread_mutex_lock(&applock)) {
775                 ast_log(LOG_ERROR, "Unable to lock application list\n");
776                 return -1;
777         }
778         tmp = apps;
779         while(tmp) {
780                 if (!strcasecmp(app, tmp->name)) {
781                         if (tmpl)
782                                 tmpl->next = tmp->next;
783                         else
784                                 apps = tmp->next;
785                         if (option_verbose > 1)
786                                 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
787                         pthread_mutex_unlock(&applock);
788                         return 0;
789                 }
790                 tmpl = tmp;
791                 tmp = tmp->next;
792         }
793         pthread_mutex_unlock(&applock);
794         return -1;
795 }
796
797 struct ast_context *ast_context_create(char *name)
798 {
799         struct ast_context *tmp;
800         
801         pthread_mutex_lock(&conlock);
802         tmp = contexts;
803         while(tmp) {
804                 if (!strcasecmp(tmp->name, name)) {
805                         pthread_mutex_unlock(&conlock);
806                         ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
807                         return NULL;
808                 }
809                 tmp = tmp->next;
810         }
811         tmp = malloc(sizeof(struct ast_context));
812         if (tmp) {
813                 pthread_mutex_init(&tmp->lock, NULL);
814                 strncpy(tmp->name, name, sizeof(tmp->name));
815                 tmp->root = NULL;
816                 tmp->next = contexts;
817                 tmp->includes = NULL;
818                 contexts = tmp;
819                 if (option_debug)
820                         ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
821                 else if (option_verbose > 2)
822                         ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
823         } else
824                 ast_log(LOG_WARNING, "Out of memory\n");
825         
826         pthread_mutex_unlock(&conlock);
827         return tmp;
828 }
829
830 int ast_context_add_include2(struct ast_context *con, char *value)
831 {
832         struct ast_include *inc, *incc, *incl = NULL;
833         inc = malloc(sizeof(struct ast_include));
834         if (!inc) {
835                 ast_log(LOG_WARNING, "Out of memory\n");
836                 return -1;
837         }
838         strncpy(inc->name, value, sizeof(inc->name));
839         inc->next = NULL;
840         pthread_mutex_lock(&con->lock);
841         incc = con->includes;
842         while(incc) {
843                 incl = incc;
844                 if (!strcasecmp(incc->name, value)) {
845                         /* Already there */
846                         pthread_mutex_unlock(&con->lock);
847                         return 0;
848                 }
849                 incc = incc->next;
850         }
851         if (incl) 
852                 incl->next = inc;
853         else
854                 con->includes = inc;
855         pthread_mutex_unlock(&con->lock);
856         return 0;
857         
858 }
859
860 int ast_add_extension2(struct ast_context *con,
861                                           int replace, char *extension, int priority,
862                                           char *application, void *data, void (*datad)(void *))
863 {
864
865 #define LOG {   if (option_debug) \
866                 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
867         else if (option_verbose > 2) \
868                 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
869                 }
870
871         /*
872          * This is a fairly complex routine.  Different extensions are kept
873          * in order by the extension number.  Then, extensions of different
874          * priorities (same extension) are kept in a list, according to the
875          * peer pointer.
876          */
877         struct ast_exten *tmp, *e, *el = NULL, *ep = NULL;
878         int res;
879         /* Be optimistic:  Build the extension structure first */
880         tmp = malloc(sizeof(struct ast_exten));
881         if (tmp) {
882                 strncpy(tmp->exten, extension, sizeof(tmp->exten));
883                 tmp->priority = priority;
884                 strncpy(tmp->app, application, sizeof(tmp->app));
885                 tmp->data = data;
886                 tmp->datad = datad;
887                 tmp->peer = NULL;
888                 tmp->next =  NULL;
889         } else {
890                 ast_log(LOG_WARNING, "Out of memory\n");
891                 return -1;
892         }
893         if (pthread_mutex_lock(&con->lock)) {
894                 free(tmp);
895                 /* And properly destroy the data */
896                 datad(data);
897                 ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name);
898                 return -1;
899         }
900         e = con->root;
901         while(e) {
902                 res= strcasecmp(e->exten, extension);
903                 if (res == 0) {
904                         /* We have an exact match, now we find where we are
905                            and be sure there's no duplicates */
906                         while(e) {
907                                 if (e->priority == tmp->priority) {
908                                         /* Can't have something exactly the same.  Is this a
909                                            replacement?  If so, replace, otherwise, bonk. */
910                                         if (replace) {
911                                                 if (ep) {
912                                                         /* We're in the peer list, insert ourselves */
913                                                         ep->peer = tmp;
914                                                         tmp->peer = e->peer;
915                                                 } else if (el) {
916                                                         /* We're the first extension. Take over e's functions */
917                                                         el->next = tmp;
918                                                         tmp->next = e->next;
919                                                         tmp->peer = e->peer;
920                                                 } else {
921                                                         /* We're the very first extension.  */
922                                                         con->root = tmp;
923                                                         tmp->next = e->next;
924                                                         tmp->peer = e->peer;
925                                                 }
926                                                 /* Destroy the old one */
927                                                 e->datad(e->data);
928                                                 free(e);
929                                                 pthread_mutex_unlock(&con->lock);
930                                                 /* And immediately return success. */
931                                                 LOG;
932                                                 return 0;
933                                         } else {
934                                                 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name);
935                                                 tmp->datad(tmp->data);
936                                                 free(tmp);
937                                                 pthread_mutex_unlock(&con->lock);
938                                                 return -1;
939                                         }
940                                 } else if (e->priority > tmp->priority) {
941                                         /* Slip ourselves in just before e */
942                                         if (ep) {
943                                                 /* Easy enough, we're just in the peer list */
944                                                 ep->peer = tmp;
945                                                 tmp->peer = e;
946                                         } else if (el) {
947                                                 /* We're the first extension in this peer list */
948                                                 el->next = tmp;
949                                                 tmp->next = e->next;
950                                                 e->next = NULL;
951                                                 tmp->peer = e;
952                                         } else {
953                                                 /* We're the very first extension altogether */
954                                                 tmp->next = con->root;
955                                                 /* Con->root must always exist or we couldn't get here */
956                                                 tmp->peer = con->root->peer;
957                                                 con->root = tmp;
958                                         }
959                                         pthread_mutex_unlock(&con->lock);
960                                         /* And immediately return success. */
961                                         LOG;
962                                         return 0;
963                                 }
964                                 ep = e;
965                                 e = e->peer;
966                         }
967                         /* If we make it here, then it's time for us to go at the very end.
968                            ep *must* be defined or we couldn't have gotten here. */
969                         ep->peer = tmp;
970                         pthread_mutex_unlock(&con->lock);
971                         /* And immediately return success. */
972                         LOG;
973                         return 0;
974                                 
975                 } else if (res > 0) {
976                         /* Insert ourselves just before 'e'.  We're the first extension of
977                            this kind */
978                         tmp->next = e;
979                         if (el) {
980                                 /* We're in the list somewhere */
981                                 el->next = tmp;
982                         } else {
983                                 /* We're at the top of the list */
984                                 con->root = tmp;
985                         }
986                         pthread_mutex_unlock(&con->lock);
987                         /* And immediately return success. */
988                         LOG;
989                         return 0;
990                 }                       
991                         
992                 el = e;
993                 e = e->next;
994         }
995         /* If we fall all the way through to here, then we need to be on the end. */
996         if (el)
997                 el->next = tmp;
998         else
999                 con->root = tmp;
1000         pthread_mutex_unlock(&con->lock);
1001         LOG;
1002         return 0;       
1003 }
1004
1005 void ast_context_destroy(struct ast_context *con)
1006 {
1007         struct ast_context *tmp, *tmpl=NULL;
1008         struct ast_include *tmpi, *tmpil= NULL;
1009         pthread_mutex_lock(&conlock);
1010         tmp = contexts;
1011         while(tmp) {
1012                 if (tmp == con) {
1013                         /* Okay, let's lock the structure to be sure nobody else
1014                            is searching through it. */
1015                         if (pthread_mutex_lock(&tmp->lock)) {
1016                                 ast_log(LOG_WARNING, "Unable to lock context lock\n");
1017                                 return;
1018                         }
1019                         if (tmpl)
1020                                 tmpl->next = tmp->next;
1021                         else
1022                                 contexts = tmp->next;
1023                         /* Okay, now we're safe to let it go -- in a sense, we were
1024                            ready to let it go as soon as we locked it. */
1025                         pthread_mutex_unlock(&tmp->lock);
1026                         for (tmpi = tmp->includes; tmpi; ) {
1027                                 /* Free includes */
1028                                 tmpil = tmpi;
1029                                 tmpi = tmpi->next;
1030                                 free(tmpil);
1031                                 tmpil = tmpi;
1032                         }
1033                         free(tmp);
1034                         pthread_mutex_unlock(&conlock);
1035                         return;
1036                 }
1037                 tmpl = tmp;
1038                 tmp = tmp->next;
1039         }
1040         pthread_mutex_unlock(&conlock);
1041 }
1042
1043 int pbx_builtin_answer(struct ast_channel *chan, void *data)
1044 {
1045         if (chan->state != AST_STATE_RING) {
1046                 if (option_debug)
1047                         ast_log(LOG_DEBUG, "Ignoring answer request since line is not ringing\n");
1048                 return 0;
1049         } else
1050                 return ast_answer(chan);
1051 }
1052
1053 int pbx_builtin_setlanguage(struct ast_channel *chan, void *data)
1054 {
1055         /* Copy the language as specified */
1056         strncpy(chan->language, (char *)data, sizeof(chan->language));
1057         return 0;
1058 }
1059
1060 int pbx_builtin_hangup(struct ast_channel *chan, void *data)
1061 {
1062         /* Just return non-zero and it will hang up */
1063         return -1;
1064 }
1065
1066 int pbx_builtin_stripmsd(struct ast_channel *chan, void *data)
1067 {
1068         char newexten[AST_MAX_EXTENSION] = "";
1069         if (!data || !atoi(data)) {
1070                 ast_log(LOG_DEBUG, "Ignoring, since number of digits to strip is 0\n");
1071                 return 0;
1072         }
1073         if (strlen(chan->exten) > atoi(data)) {
1074                 strncpy(newexten, chan->exten + atoi(data), sizeof(newexten));
1075         }
1076         strncpy(chan->exten, newexten, sizeof(chan->exten));
1077         return 0;
1078 }
1079
1080 int pbx_builtin_prefix(struct ast_channel *chan, void *data)
1081 {
1082         char newexten[AST_MAX_EXTENSION] = "";
1083         if (!data || !strlen(data)) {
1084                 ast_log(LOG_DEBUG, "Ignoring, since there is no prefix to add\n");
1085                 return 0;
1086         }
1087         snprintf(newexten, sizeof(newexten), "%s%s", (char *)data, chan->exten);
1088         strncpy(chan->exten, newexten, sizeof(chan->exten));
1089         return 0;
1090 }
1091
1092 int pbx_builtin_wait(struct ast_channel *chan, void *data)
1093 {
1094         /* Wait for "n" seconds */
1095         if (data && atoi((char *)data))
1096                 sleep(atoi((char *)data));
1097         return 0;
1098 }
1099
1100 int pbx_builtin_background(struct ast_channel *chan, void *data)
1101 {
1102         int res;
1103         /* Answer if need be */
1104         if (chan->state != AST_STATE_UP)
1105                 if (ast_answer(chan))
1106                         return -1;
1107         /* Stop anything playing */
1108         ast_stopstream(chan);
1109         /* Stream a file */
1110         res = ast_streamfile(chan, (char *)data, chan->language);
1111         return res;
1112 }
1113
1114 int pbx_builtin_rtimeout(struct ast_channel *chan, void *data)
1115 {
1116         /* Set the timeout for how long to wait between digits */
1117         chan->pbx->rtimeout = atoi((char *)data);
1118         if (option_verbose > 2)
1119                 ast_verbose( VERBOSE_PREFIX_3 "Set Response Timeout to %d\n", chan->pbx->rtimeout);
1120         return 0;
1121 }
1122
1123 int pbx_builtin_dtimeout(struct ast_channel *chan, void *data)
1124 {
1125         /* Set the timeout for how long to wait between digits */
1126         chan->pbx->dtimeout = atoi((char *)data);
1127         if (option_verbose > 2)
1128                 ast_verbose( VERBOSE_PREFIX_3 "Set Digit Timeout to %d\n", chan->pbx->dtimeout);
1129         return 0;
1130 }
1131
1132 int pbx_builtin_goto(struct ast_channel *chan, void *data)
1133 {
1134         char *s;
1135         char *exten, *pri, *context;
1136         if (!data) {
1137                 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
1138                 return -1;
1139         }
1140         s = strdup((void *) data);
1141         context = strtok(s, "|");
1142         exten = strtok(NULL, "|");
1143         if (!exten) {
1144                 /* Only a priority in this one */
1145                 pri = context;
1146                 exten = NULL;
1147                 context = NULL;
1148         } else {
1149                 pri = strtok(NULL, "|");
1150                 if (!pri) {
1151                         /* Only an extension and priority in this one */
1152                         pri = exten;
1153                         exten = context;
1154                         context = NULL;
1155                 }
1156         }
1157         if (atoi(pri) < 0) {
1158                 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", pri);
1159                 free(s);
1160                 return -1;
1161         }
1162         /* At this point we have a priority and maybe an extension and a context */
1163         chan->priority = atoi(pri) - 1;
1164         if (exten)
1165                 strncpy(chan->exten, exten, sizeof(chan->exten));
1166         if (context)
1167                 strncpy(chan->context, context, sizeof(chan->context));
1168         if (option_verbose > 2)
1169                 ast_verbose( VERBOSE_PREFIX_3 "Goto (%s,%s,%d)\n", chan->context,chan->exten, chan->priority+1);
1170         return 0;
1171 }
1172 int load_pbx(void)
1173 {
1174         int x;
1175         /* Initialize the PBX */
1176         if (option_verbose) {
1177                 ast_verbose( "Asterisk PBX Core Initializing\n");
1178                 ast_verbose( "Registering builtin applications:\n");
1179         }
1180         for (x=0;x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) {
1181                 if (option_verbose)
1182                         ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name);
1183                 if (ast_register_application(builtins[x].name, builtins[x].execute)) {
1184                         ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
1185                         return -1;
1186                 }
1187         }
1188         return 0;
1189 }
1190