3c8c17c6b5fd50529dc1134108f62284a8bc6da3
[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 /* An extension context */
65 struct ast_context {
66         /* Name of the context */
67         char name[AST_MAX_EXTENSION];
68         /* A lock to prevent multiple threads from clobbering the context */
69         pthread_mutex_t lock;
70         /* The root of the list of extensions */
71         struct ast_exten *root;
72         /* Link them together */
73         struct ast_context *next;
74 };
75
76
77 /* An application */
78 struct ast_app {
79         /* Name of the application */
80         char name[AST_MAX_APP];
81         int (*execute)(struct ast_channel *chan, void *data);
82         struct ast_app *next;
83 };
84
85 static int pbx_builtin_prefix(struct ast_channel *, void *);
86 static int pbx_builtin_stripmsd(struct ast_channel *, void *);
87 static int pbx_builtin_answer(struct ast_channel *, void *);
88 static int pbx_builtin_goto(struct ast_channel *, void *);
89 static int pbx_builtin_hangup(struct ast_channel *, void *);
90 static int pbx_builtin_background(struct ast_channel *, void *);
91 static int pbx_builtin_dtimeout(struct ast_channel *, void *);
92 static int pbx_builtin_rtimeout(struct ast_channel *, void *);
93 static int pbx_builtin_wait(struct ast_channel *, void *);
94
95 static struct pbx_builtin {
96         char name[AST_MAX_APP];
97         int (*execute)(struct ast_channel *chan, void *data);
98 } builtins[] = 
99 {
100         /* These applications are built into the PBX core and do not
101            need separate modules */
102         { "Answer", pbx_builtin_answer },
103         { "Goto", pbx_builtin_goto },
104         { "Hangup", pbx_builtin_hangup },
105         { "DigitTimeout", pbx_builtin_dtimeout },
106         { "ResponseTimeout", pbx_builtin_rtimeout },
107         { "BackGround", pbx_builtin_background },
108         { "Wait", pbx_builtin_wait },
109         { "StripMSD", pbx_builtin_stripmsd },
110         { "Prefix", pbx_builtin_prefix },
111 };
112
113 /* Lock for the application list */
114 static pthread_mutex_t applock = PTHREAD_MUTEX_INITIALIZER;
115 static struct ast_context *contexts = NULL;
116 /* Lock for the ast_context list */
117 static pthread_mutex_t conlock = PTHREAD_MUTEX_INITIALIZER;
118 static struct ast_app *apps = NULL;
119
120 static int pbx_exec(struct ast_channel *c, /* Channel */
121                                         int (*execute)(struct ast_channel *chan, void *data), 
122                                         void *data,                             /* Data for execution */
123                                         int newstack)                   /* Force stack increment */
124 {
125         /* This function is special.  It saves the stack so that no matter
126            how many times it is called, it returns to the same place */
127         int res;
128         int stack = c->stack;
129         if (newstack && stack > AST_CHANNEL_MAX_STACK - 2) {
130                 /* Don't allow us to go over the max number of stacks we
131                    permit saving. */
132                 ast_log(LOG_WARNING, "Stack overflow, cannot create another stack\n");
133                 return -1;
134         }
135         if (newstack && (res = setjmp(c->jmp[++c->stack]))) {
136                 /* Okay, here's where it gets weird.  If newstack is non-zero, 
137                    then we increase the stack increment, but setjmp is not going
138                    to return until longjmp is called -- when the application
139                    exec'd is finished running. */
140                 if (res == 1)
141                         res = 0;
142                 if (c->stack != stack + 1) 
143                         ast_log(LOG_WARNING, "Stack returned to an unexpected place!\n");
144                 else if (c->app[c->stack])
145                         ast_log(LOG_WARNING, "Application may have forgotten to free its memory\n");
146                 c->stack = stack;
147                 return res;
148         } else {
149                 res = execute(c, data);
150                 /* Any application that returns, we longjmp back, just in case. */
151                 if (c->stack != stack + 1)
152                         ast_log(LOG_WARNING, "Stack is not at expected value\n");
153                 longjmp(c->jmp[stack+1], res);
154                 /* Never returns */
155         }
156 }
157
158
159 #define HELPER_EXISTS 0
160 #define HELPER_SPAWN 1
161 #define HELPER_EXEC 2
162 #define HELPER_CANMATCH 3
163
164 static struct ast_app *pbx_findapp(char *app) 
165 {
166         struct ast_app *tmp;
167         if (pthread_mutex_lock(&applock)) {
168                 ast_log(LOG_WARNING, "Unable to obtain application lock\n");
169                 return NULL;
170         }
171         tmp = apps;
172         while(tmp) {
173                 if (!strcasecmp(tmp->name, app))
174                         break;
175                 tmp = tmp->next;
176         }
177         pthread_mutex_unlock(&applock);
178         return tmp;
179 }
180
181 static void pbx_destroy(struct ast_pbx *p)
182 {
183         free(p);
184 }
185
186 static int extension_match(char *pattern, char *data)
187 {
188         int match;
189         /* If they're the same return */
190         if (!strcasecmp(pattern, data))
191                 return 1;
192         /* All patterns begin with _ */
193         if (pattern[0] != '_') 
194                 return 0;
195         /* Obviously must be the same length */
196         if (strlen(pattern) != strlen(data) + 1)
197                 return 0;
198         /* Start optimistic */
199         match=1;
200         pattern++;
201         while(match && *data && *pattern) {
202                 switch(toupper(*pattern)) {
203                 case 'N':
204                         if ((*data < '2') || (*data > '9'))
205                                 match=0;
206                         break;
207                 case 'X':
208                         if ((*data < '0') || (*data > '9'))
209                                 match = 0;
210                         break;
211                 default:
212                         if (*data != *pattern)
213                                 match =0;
214                 }
215                 data++;
216                 pattern++;
217         }
218         return match;
219 }
220
221 static int extension_close(char *pattern, char *data)
222 {
223         int match;
224         /* If "data" is longer, it can'be a subset of pattern */
225         if (strlen(pattern) < strlen(data)) 
226                 return 0;
227         
228         if (!strncasecmp(pattern, data, strlen(data))) {
229                 return 1;
230         }
231         /* All patterns begin with _ */
232         if (pattern[0] != '_') 
233                 return 0;
234         /* Start optimistic */
235         match=1;
236         pattern++;
237         while(match && *data && *pattern) {
238                 switch(toupper(*pattern)) {
239                 case 'N':
240                         if ((*data < '2') || (*data > '9'))
241                                 match=0;
242                         break;
243                 case 'X':
244                         if ((*data < '0') || (*data > '9'))
245                                 match = 0;
246                         break;
247                 default:
248                         if (*data != *pattern)
249                                 match =0;
250                 }
251                 data++;
252                 pattern++;
253         }
254         return match;
255 }
256
257 static int pbx_extension_helper(struct ast_channel *c, char *context, char *exten, int priority, int action) 
258 {
259         struct ast_context *tmp;
260         struct ast_exten *e;
261         struct ast_app *app;
262         int newstack = 0;
263         int res;
264         if (pthread_mutex_lock(&conlock)) {
265                 ast_log(LOG_WARNING, "Unable to obtain lock\n");
266                 if ((action == HELPER_EXISTS) || (action == HELPER_CANMATCH))
267                         return 0;
268                 else
269                         return -1;
270         }
271         tmp = contexts;
272         while(tmp) {
273                 if (!strcasecmp(tmp->name, context)) {
274 #if 0
275                         /* By locking tmp, not only can the state of its entries not
276                            change, but it cannot be destroyed either. */
277                         pthread_mutex_lock(&tmp->lock);
278 #endif
279                         e = tmp->root;
280                         while(e) {
281                                 if (extension_match(e->exten, exten) || 
282                                         ((action == HELPER_CANMATCH) && extension_close(e->exten, exten))) {
283                                         while(e) {
284                                                 if (e->priority == priority) {
285                                                         /* We have a winner! Maybe there are some races
286                                                            in here though. XXX */
287                                                         switch(action) {
288                                                         case HELPER_CANMATCH:
289                                                                 pthread_mutex_unlock(&conlock);
290                                                                 return -1;
291                                                         case HELPER_EXISTS:
292                                                                 pthread_mutex_unlock(&conlock);
293                                                                 return -1;
294                                                         case HELPER_SPAWN:
295                                                                 newstack++;
296                                                                 /* Fall through */
297                                                         case HELPER_EXEC:
298                                                                 app = pbx_findapp(e->app);
299                                                                 pthread_mutex_unlock(&conlock);
300                                                                 if (app) {
301                                                                         strncpy(c->context, context, sizeof(c->context));
302                                                                         strncpy(c->exten, exten, sizeof(c->exten));
303                                                                         c->priority = priority;
304                                                                         if (option_debug)
305                                                                                 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
306                                                                         else if (option_verbose > 2)
307                                                                                 ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n", 
308                                                                                                 app->name, c->name, (e->data ? (char *)e->data : NULL), (newstack ? "in new stack" : "in same stack"));
309                                                                         c->appl = app->name;
310                                                                         c->data = e->data;              
311                                                                         res = pbx_exec(c, app->execute, e->data, newstack);
312                                                                         c->appl = NULL;
313                                                                         c->data = NULL;
314                                                                         pthread_mutex_unlock(&conlock);
315                                                                         return res;
316                                                                 } else {
317                                                                         ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
318                                                                         return -1;
319                                                                 }
320                                                         default:
321                                                                 ast_log(LOG_WARNING, "Huh (%d)?\n", action);
322                                                         }
323                                                 }
324                                                 e = e->peer;
325                                         }
326                                         pthread_mutex_unlock(&tmp->lock);
327                                         if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH)) {
328                                                 ast_log(LOG_WARNING, "No such priority '%d' in '%s' in '%s'\n", priority, exten, context);
329                                                 pthread_mutex_unlock(&conlock);
330                                                 return -1;
331                                         } else {
332                                                 pthread_mutex_unlock(&conlock);
333                                                 return 0;
334                                         }
335                                 }
336                                 e = e->next;
337                         }
338                         if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH)) {
339                                 pthread_mutex_unlock(&conlock);
340                                 ast_log(LOG_WARNING, "No such extension '%s' in '%s'\n", exten, context);
341                                 return -1;
342                         } else {
343                                 pthread_mutex_unlock(&conlock);
344                                 return 0;
345                         }
346                 }
347                 tmp = tmp->next;
348         }
349         pthread_mutex_unlock(&conlock);
350         if (action != HELPER_EXISTS) {
351                 ast_log(LOG_WARNING, "No such context '%s'\n", context);
352                 return -1;
353         } else
354                 return 0;
355 }
356 int ast_pbx_longest_extension(char *context) 
357 {
358         struct ast_context *tmp;
359         struct ast_exten *e;
360         int len = 0;
361         if (pthread_mutex_lock(&conlock)) {
362                 ast_log(LOG_WARNING, "Unable to obtain lock\n");
363                 return -1;
364         }
365         tmp = contexts;
366         while(tmp) {
367                 if (!strcasecmp(tmp->name, context)) {
368                         /* By locking tmp, not only can the state of its entries not
369                            change, but it cannot be destroyed either. */
370                         pthread_mutex_lock(&tmp->lock);
371                         /* But we can relieve the conlock, as tmp will not change */
372                         pthread_mutex_unlock(&conlock);
373                         e = tmp->root;
374                         while(e) {
375                                 if (strlen(e->exten) > len)
376                                         len = strlen(e->exten);
377                                 e = e->next;
378                         }
379                         pthread_mutex_unlock(&tmp->lock);
380                         return len;
381                 }
382                 tmp = tmp->next;
383         }
384         ast_log(LOG_WARNING, "No such context '%s'\n", context);
385         return -1;
386 }
387
388 int ast_exists_extension(struct ast_channel *c, char *context, char *exten, int priority) 
389 {
390         return pbx_extension_helper(c, context, exten, priority, HELPER_EXISTS);
391 }
392
393 int ast_canmatch_extension(struct ast_channel *c, char *context, char *exten, int priority)
394 {
395         return pbx_extension_helper(c, context, exten, priority, HELPER_CANMATCH);
396 }
397
398 int ast_spawn_extension(struct ast_channel *c, char *context, char *exten, int priority) 
399 {
400         return pbx_extension_helper(c, context, exten, priority, HELPER_SPAWN);
401 }
402
403 static void *pbx_thread(void *data)
404 {
405         /* Oh joyeous kernel, we're a new thread, with nothing to do but
406            answer this channel and get it going.  The setjmp stuff is fairly
407            confusing, but necessary to get smooth transitions between
408            the execution of different applications (without the use of
409            additional threads) */
410         struct ast_channel *c = data;
411         int firstpass = 1;
412         char digit;
413         char exten[256];
414         int pos;
415         int waittime;
416         if (option_debug)
417                 ast_log(LOG_DEBUG, "PBX_THREAD(%s)\n", c->name);
418         else if (option_verbose > 1)
419                 ast_verbose( VERBOSE_PREFIX_2 "Accepting call on '%s'\n", c->name);
420                 
421         
422         /* Start by trying whatever the channel is set to */
423         if (!ast_exists_extension(c, c->context, c->exten, c->priority)) {
424                 strncpy(c->context, "default", sizeof(c->context));
425                 strncpy(c->exten, "s", sizeof(c->exten));
426                 c->priority = 1;
427         }
428         for(;;) {
429                 memset(exten, 0, sizeof(exten));
430                 pos = 0;
431                 digit = 0;
432                 while(ast_exists_extension(c, c->context, c->exten, c->priority)) {
433                         if (ast_spawn_extension(c, c->context, c->exten, c->priority)) {
434                                 /* Something bad happened, or a hangup has been requested. */
435                                 if (option_debug)
436                                         ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
437                                 else if (option_verbose > 1)
438                                         ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
439                                 goto out;
440                         }
441                         /* If we're playing something in the background, wait for it to finish or for a digit */
442                         if (c->stream || (c->trans && c->trans->stream)) {
443                                 digit = ast_waitstream(c, AST_DIGIT_ANY);
444                                 ast_stopstream(c);
445                                 /* Hang up if something goes wrong */
446                                 if (digit < 0)
447                                         goto out;
448                                 else if (digit) {
449                                         exten[pos++] = digit;
450                                         break;
451                                 }
452                         }
453                         firstpass = 0;
454                         c->priority++;
455                 }
456                 /* Done, wait for an extension */
457                 if (digit)
458                         waittime = c->pbx->dtimeout;
459                 else
460                         waittime = c->pbx->rtimeout;
461                 while(!ast_exists_extension(c, c->context, exten, 1) && 
462                       ast_canmatch_extension(c, c->context, exten, 1)) {
463                         /* As long as we're willing to wait, and as long as it's not defined, 
464                            keep reading digits until we can't possibly get a right answer anymore.  */
465                         digit = ast_waitfordigit(c, waittime * 1000);
466                         if (!digit)
467                                 /* No entry */
468                                 break;
469                         if (digit < 0)
470                                 /* Error, maybe a  hangup */
471                                 goto out;
472                         exten[pos++] = digit;
473                         waittime = c->pbx->dtimeout;
474                 }
475                 if (ast_exists_extension(c, c->context, exten, 1)) {
476                         /* Prepare the next cycle */
477                         strncpy(c->exten, exten, sizeof(c->exten));
478                         c->priority = 1;
479                 } else {
480                         /* No such extension */
481                         if (strlen(exten)) {
482                                 /* An invalid extension */
483                                 if (ast_exists_extension(c, c->context, "i", 1)) {
484                                         if (option_verbose > 2)
485                                                 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name);
486                                         strncpy(c->exten, "i", sizeof(c->exten));
487                                         c->priority = 1;
488                                 } else {
489                                         ast_log(LOG_WARNING, "Invalid extension, but no rule 'i' in context '%s'\n", c->context);
490                                         goto out;
491                                 }
492                         } else {
493                                 /* A simple timeout */
494                                 if (ast_exists_extension(c, c->context, "t", 1)) {
495                                         if (option_verbose > 2)
496                                                 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
497                                         strncpy(c->exten, "t", sizeof(c->exten));
498                                         c->priority = 1;
499                                 } else {
500                                         ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
501                                         goto out;
502                                 }
503                         }       
504                 }
505         }
506         if (firstpass) 
507                 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
508 out:
509         pbx_destroy(c->pbx);
510         c->pbx = NULL;
511         ast_hangup(c);
512         pthread_exit(NULL);
513         
514 }
515
516 int ast_pbx_start(struct ast_channel *c)
517 {
518         pthread_t t;
519         if (!c) {
520                 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
521                 return -1;
522         }
523         if (c->pbx)
524                 ast_log(LOG_WARNING, "%s already has PBX structure??\n");
525         c->pbx = malloc(sizeof(struct ast_pbx));
526         if (!c->pbx) {
527                 ast_log(LOG_WARNING, "Out of memory\n");
528                 return -1;
529         }
530         memset(c->pbx, 0, sizeof(struct ast_pbx));
531         /* Set reasonable defaults */
532         c->pbx->rtimeout = 10;
533         c->pbx->dtimeout = 5;
534         /* Start a new thread, and get something handling this channel. */
535         if (pthread_create(&t, NULL, pbx_thread, c)) {
536                 ast_log(LOG_WARNING, "Failed to create new channel thread\n");
537                 return -1;
538         }
539         return 0;
540 }
541 #if 0
542 int ast_remove_extension(struct ast_context *con, char *extension, int priority)
543 {
544         /* XXX Implement me XXX */
545         return -1;
546 }
547 #endif
548 int ast_register_application(char *app, int (*execute)(struct ast_channel *, void *))
549 {
550         struct ast_app *tmp;
551         if (pthread_mutex_lock(&applock)) {
552                 ast_log(LOG_ERROR, "Unable to lock application list\n");
553                 return -1;
554         }
555         tmp = apps;
556         while(tmp) {
557                 if (!strcasecmp(app, tmp->name)) {
558                         ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
559                         pthread_mutex_unlock(&applock);
560                         return -1;
561                 }
562                 tmp = tmp->next;
563         }
564         tmp = malloc(sizeof(struct ast_app));
565         if (tmp) {
566                 strncpy(tmp->name, app, sizeof(tmp->name));
567                 tmp->execute = execute;
568                 tmp->next = apps;
569                 apps = tmp;
570         } else {
571                 ast_log(LOG_WARNING, "Out of memory\n");
572                 pthread_mutex_unlock(&applock);
573                 return -1;
574         }
575         if (option_verbose > 1)
576                 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", tmp->name);
577         pthread_mutex_unlock(&applock);
578         return 0;
579 }
580
581 int ast_unregister_application(char *app) {
582         struct ast_app *tmp, *tmpl = NULL;
583         if (pthread_mutex_lock(&applock)) {
584                 ast_log(LOG_ERROR, "Unable to lock application list\n");
585                 return -1;
586         }
587         tmp = apps;
588         while(tmp) {
589                 if (!strcasecmp(app, tmp->name)) {
590                         if (tmpl)
591                                 tmpl->next = tmp->next;
592                         else
593                                 apps = tmp->next;
594                         if (option_verbose > 1)
595                                 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
596                         pthread_mutex_unlock(&applock);
597                         return 0;
598                 }
599                 tmpl = tmp;
600                 tmp = tmp->next;
601         }
602         pthread_mutex_unlock(&applock);
603         return -1;
604 }
605
606 struct ast_context *ast_context_create(char *name)
607 {
608         struct ast_context *tmp;
609         
610         pthread_mutex_lock(&conlock);
611         tmp = contexts;
612         while(tmp) {
613                 if (!strcasecmp(tmp->name, name)) {
614                         pthread_mutex_unlock(&conlock);
615                         ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
616                         return NULL;
617                 }
618                 tmp = tmp->next;
619         }
620         tmp = malloc(sizeof(struct ast_context));
621         if (tmp) {
622                 pthread_mutex_init(&tmp->lock, NULL);
623                 strncpy(tmp->name, name, sizeof(tmp->name));
624                 tmp->root = NULL;
625                 tmp->next = contexts;
626                 contexts = tmp;
627                 if (option_debug)
628                         ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
629                 else if (option_verbose > 2)
630                         ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
631         } else
632                 ast_log(LOG_WARNING, "Out of memory\n");
633         
634         pthread_mutex_unlock(&conlock);
635         return tmp;
636 }
637
638 int ast_add_extension2(struct ast_context *con,
639                                           int replace, char *extension, int priority,
640                                           char *application, void *data, void (*datad)(void *))
641 {
642
643 #define LOG {   if (option_debug) \
644                 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
645         else if (option_verbose > 2) \
646                 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
647                 }
648
649         /*
650          * This is a fairly complex routine.  Different extensions are kept
651          * in order by the extension number.  Then, extensions of different
652          * priorities (same extension) are kept in a list, according to the
653          * peer pointer.
654          */
655         struct ast_exten *tmp, *e, *el = NULL, *ep = NULL;
656         int res;
657         /* Be optimistic:  Build the extension structure first */
658         tmp = malloc(sizeof(struct ast_exten));
659         if (tmp) {
660                 strncpy(tmp->exten, extension, sizeof(tmp->exten));
661                 tmp->priority = priority;
662                 strncpy(tmp->app, application, sizeof(tmp->app));
663                 tmp->data = data;
664                 tmp->datad = datad;
665                 tmp->peer = NULL;
666                 tmp->next =  NULL;
667         } else {
668                 ast_log(LOG_WARNING, "Out of memory\n");
669                 return -1;
670         }
671         if (pthread_mutex_lock(&con->lock)) {
672                 free(tmp);
673                 /* And properly destroy the data */
674                 datad(data);
675                 ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name);
676                 return -1;
677         }
678         e = con->root;
679         while(e) {
680                 res= strcasecmp(e->exten, extension);
681                 if (res == 0) {
682                         /* We have an exact match, now we find where we are
683                            and be sure there's no duplicates */
684                         while(e) {
685                                 if (e->priority == tmp->priority) {
686                                         /* Can't have something exactly the same.  Is this a
687                                            replacement?  If so, replace, otherwise, bonk. */
688                                         if (replace) {
689                                                 if (ep) {
690                                                         /* We're in the peer list, insert ourselves */
691                                                         ep->peer = tmp;
692                                                         tmp->peer = e->peer;
693                                                 } else if (el) {
694                                                         /* We're the first extension. Take over e's functions */
695                                                         el->next = tmp;
696                                                         tmp->next = e->next;
697                                                         tmp->peer = e->peer;
698                                                 } else {
699                                                         /* We're the very first extension.  */
700                                                         con->root = tmp;
701                                                         tmp->next = e->next;
702                                                         tmp->peer = e->peer;
703                                                 }
704                                                 /* Destroy the old one */
705                                                 e->datad(e->data);
706                                                 free(e);
707                                                 pthread_mutex_unlock(&con->lock);
708                                                 /* And immediately return success. */
709                                                 LOG;
710                                                 return 0;
711                                         } else {
712                                                 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name);
713                                                 tmp->datad(tmp->data);
714                                                 free(tmp);
715                                                 pthread_mutex_unlock(&con->lock);
716                                                 return -1;
717                                         }
718                                 } else if (e->priority > tmp->priority) {
719                                         /* Slip ourselves in just before e */
720                                         if (ep) {
721                                                 /* Easy enough, we're just in the peer list */
722                                                 ep->peer = tmp;
723                                                 tmp->peer = e;
724                                         } else if (el) {
725                                                 /* We're the first extension in this peer list */
726                                                 el->next = tmp;
727                                                 tmp->next = e->next;
728                                                 e->next = NULL;
729                                                 tmp->peer = e;
730                                         } else {
731                                                 /* We're the very first extension altogether */
732                                                 tmp->next = con->root;
733                                                 /* Con->root must always exist or we couldn't get here */
734                                                 tmp->peer = con->root->peer;
735                                                 con->root = tmp;
736                                         }
737                                         pthread_mutex_unlock(&con->lock);
738                                         /* And immediately return success. */
739                                         LOG;
740                                         return 0;
741                                 }
742                                 ep = e;
743                                 e = e->peer;
744                         }
745                         /* If we make it here, then it's time for us to go at the very end.
746                            ep *must* be defined or we couldn't have gotten here. */
747                         ep->peer = tmp;
748                         pthread_mutex_unlock(&con->lock);
749                         /* And immediately return success. */
750                         LOG;
751                         return 0;
752                                 
753                 } else if (res > 0) {
754                         /* Insert ourselves just before 'e'.  We're the first extension of
755                            this kind */
756                         tmp->next = e;
757                         if (el) {
758                                 /* We're in the list somewhere */
759                                 el->next = tmp;
760                         } else {
761                                 /* We're at the top of the list */
762                                 con->root = tmp;
763                         }
764                         pthread_mutex_unlock(&con->lock);
765                         /* And immediately return success. */
766                         LOG;
767                         return 0;
768                 }                       
769                         
770                 el = e;
771                 e = e->next;
772         }
773         /* If we fall all the way through to here, then we need to be on the end. */
774         if (el)
775                 el->next = tmp;
776         else
777                 con->root = tmp;
778         pthread_mutex_unlock(&con->lock);
779         LOG;
780         return 0;       
781 }
782
783 void ast_context_destroy(struct ast_context *con)
784 {
785         struct ast_context *tmp, *tmpl=NULL;
786         pthread_mutex_lock(&conlock);
787         tmp = contexts;
788         while(tmp) {
789                 if (tmp == con) {
790                         /* Okay, let's lock the structure to be sure nobody else
791                            is searching through it. */
792                         if (pthread_mutex_lock(&tmp->lock)) {
793                                 ast_log(LOG_WARNING, "Unable to lock context lock\n");
794                                 return;
795                         }
796                         if (tmpl)
797                                 tmpl->next = tmp->next;
798                         else
799                                 contexts = tmp->next;
800                         /* Okay, now we're safe to let it go -- in a sense, we were
801                            ready to let it go as soon as we locked it. */
802                         pthread_mutex_unlock(&tmp->lock);
803                         free(tmp);
804                         pthread_mutex_unlock(&conlock);
805                         return;
806                 }
807                 tmpl = tmp;
808                 tmp = tmp->next;
809         }
810         pthread_mutex_unlock(&conlock);
811 }
812
813 int pbx_builtin_answer(struct ast_channel *chan, void *data)
814 {
815         if (chan->state != AST_STATE_RING) {
816                 if (option_debug)
817                         ast_log(LOG_DEBUG, "Ignoring answer request since line is not ringing\n");
818                 return 0;
819         } else
820                 return ast_answer(chan);
821 }
822
823 int pbx_builtin_hangup(struct ast_channel *chan, void *data)
824 {
825         /* Just return non-zero and it will hang up */
826         return -1;
827 }
828
829 int pbx_builtin_stripmsd(struct ast_channel *chan, void *data)
830 {
831         char newexten[AST_MAX_EXTENSION] = "";
832         if (!data || !atoi(data)) {
833                 ast_log(LOG_DEBUG, "Ignoring, since number of digits to strip is 0\n");
834                 return 0;
835         }
836         if (strlen(chan->exten) > atoi(data)) {
837                 strncpy(newexten, chan->exten + atoi(data), sizeof(newexten));
838         }
839         strncpy(chan->exten, newexten, sizeof(chan->exten));
840         return 0;
841 }
842
843 int pbx_builtin_prefix(struct ast_channel *chan, void *data)
844 {
845         char newexten[AST_MAX_EXTENSION] = "";
846         if (!data || !strlen(data)) {
847                 ast_log(LOG_DEBUG, "Ignoring, since there is no prefix to add\n");
848                 return 0;
849         }
850         snprintf(newexten, sizeof(newexten), "%s%s", (char *)data, chan->exten);
851         strncpy(chan->exten, newexten, sizeof(chan->exten));
852         return 0;
853 }
854
855 int pbx_builtin_wait(struct ast_channel *chan, void *data)
856 {
857         /* Wait for "n" seconds */
858         if (data && atoi((char *)data))
859                 sleep(atoi((char *)data));
860         return 0;
861 }
862
863 int pbx_builtin_background(struct ast_channel *chan, void *data)
864 {
865         int res;
866         /* Stop anything playing */
867         ast_stopstream(chan);
868         /* Stream a file */
869         res = ast_streamfile(chan, (char *)data);
870         return res;
871 }
872
873 int pbx_builtin_rtimeout(struct ast_channel *chan, void *data)
874 {
875         /* Set the timeout for how long to wait between digits */
876         chan->pbx->rtimeout = atoi((char *)data);
877         if (option_verbose > 2)
878                 ast_verbose( VERBOSE_PREFIX_3 "Set Response Timeout to %d\n", chan->pbx->rtimeout);
879         return 0;
880 }
881
882 int pbx_builtin_dtimeout(struct ast_channel *chan, void *data)
883 {
884         /* Set the timeout for how long to wait between digits */
885         chan->pbx->dtimeout = atoi((char *)data);
886         if (option_verbose > 2)
887                 ast_verbose( VERBOSE_PREFIX_3 "Set Digit Timeout to %d\n", chan->pbx->dtimeout);
888         return 0;
889 }
890
891 int pbx_builtin_goto(struct ast_channel *chan, void *data)
892 {
893         char *s;
894         char *exten, *pri, *context;
895         if (!data) {
896                 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
897                 return -1;
898         }
899         s = strdup((void *) data);
900         context = strtok(s, "|");
901         exten = strtok(NULL, "|");
902         if (!exten) {
903                 /* Only a priority in this one */
904                 pri = context;
905                 exten = NULL;
906                 context = NULL;
907         } else {
908                 pri = strtok(NULL, "|");
909                 if (!pri) {
910                         /* Only an extension and priority in this one */
911                         pri = exten;
912                         exten = context;
913                         context = NULL;
914                 }
915         }
916         if (atoi(pri) < 0) {
917                 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", pri);
918                 free(s);
919                 return -1;
920         }
921         /* At this point we have a priority and maybe an extension and a context */
922         chan->priority = atoi(pri) - 1;
923         if (exten)
924                 strncpy(chan->exten, exten, sizeof(chan->exten));
925         if (context)
926                 strncpy(chan->context, context, sizeof(chan->context));
927         if (option_verbose > 2)
928                 ast_verbose( VERBOSE_PREFIX_3 "Goto (%s,%s,%d)\n", chan->context,chan->exten, chan->priority+1);
929         return 0;
930 }
931 int load_pbx(void)
932 {
933         int x;
934         /* Initialize the PBX */
935         if (option_verbose) {
936                 ast_verbose( "Asterisk PBX Core Initializing\n");
937                 ast_verbose( "Registering builtin applications:\n");
938         }
939         for (x=0;x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) {
940                 if (option_verbose)
941                         ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name);
942                 if (ast_register_application(builtins[x].name, builtins[x].execute)) {
943                         ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
944                         return -1;
945                 }
946         }
947         return 0;
948 }
949