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