fix various spelling mistakes in comments (issue #8237, jmls)
[asterisk/asterisk.git] / main / pbx.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Core PBX routines.
22  *
23  * \author Mark Spencer <markster@digium.com>
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include <sys/types.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <ctype.h>
36 #include <errno.h>
37 #include <time.h>
38 #include <sys/time.h>
39 #include <limits.h>
40
41 #include "asterisk/lock.h"
42 #include "asterisk/cli.h"
43 #include "asterisk/pbx.h"
44 #include "asterisk/channel.h"
45 #include "asterisk/options.h"
46 #include "asterisk/logger.h"
47 #include "asterisk/file.h"
48 #include "asterisk/callerid.h"
49 #include "asterisk/cdr.h"
50 #include "asterisk/config.h"
51 #include "asterisk/term.h"
52 #include "asterisk/manager.h"
53 #include "asterisk/ast_expr.h"
54 #include "asterisk/linkedlists.h"
55 #define SAY_STUBS       /* generate declarations and stubs for say methods */
56 #include "asterisk/say.h"
57 #include "asterisk/utils.h"
58 #include "asterisk/causes.h"
59 #include "asterisk/musiconhold.h"
60 #include "asterisk/app.h"
61 #include "asterisk/devicestate.h"
62 #include "asterisk/stringfields.h"
63
64 /*!
65  * \note I M P O R T A N T :
66  *
67  *              The speed of extension handling will likely be among the most important
68  * aspects of this PBX.  The switching scheme as it exists right now isn't
69  * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
70  * of priorities, but a constant search time here would be great ;-)
71  *
72  */
73
74 #ifdef LOW_MEMORY
75 #define EXT_DATA_SIZE 256
76 #else
77 #define EXT_DATA_SIZE 8192
78 #endif
79
80 #define SWITCH_DATA_LENGTH 256
81
82 #define VAR_BUF_SIZE 4096
83
84 #define VAR_NORMAL              1
85 #define VAR_SOFTTRAN    2
86 #define VAR_HARDTRAN    3
87
88 #define BACKGROUND_SKIP         (1 << 0)
89 #define BACKGROUND_NOANSWER     (1 << 1)
90 #define BACKGROUND_MATCHEXTEN   (1 << 2)
91 #define BACKGROUND_PLAYBACK     (1 << 3)
92
93 AST_APP_OPTIONS(background_opts, {
94         AST_APP_OPTION('s', BACKGROUND_SKIP),
95         AST_APP_OPTION('n', BACKGROUND_NOANSWER),
96         AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN),
97         AST_APP_OPTION('p', BACKGROUND_PLAYBACK),
98 });
99
100 #define WAITEXTEN_MOH           (1 << 0)
101
102 AST_APP_OPTIONS(waitexten_opts, {
103         AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 0),
104 });
105
106 struct ast_context;
107 struct ast_app;
108
109 /*!
110    \brief ast_exten: An extension
111         The dialplan is saved as a linked list with each context
112         having it's own linked list of extensions - one item per
113         priority.
114 */
115 struct ast_exten {
116         char *exten;                    /*!< Extension name */
117         int matchcid;                   /*!< Match caller id ? */
118         const char *cidmatch;           /*!< Caller id to match for this extension */
119         int priority;                   /*!< Priority */
120         const char *label;              /*!< Label */
121         struct ast_context *parent;     /*!< The context this extension belongs to  */
122         const char *app;                /*!< Application to execute */
123         struct ast_app *cached_app;     /*!< Cached location of application */
124         void *data;                     /*!< Data to use (arguments) */
125         void (*datad)(void *);          /*!< Data destructor */
126         struct ast_exten *peer;         /*!< Next higher priority with our extension */
127         const char *registrar;          /*!< Registrar */
128         struct ast_exten *next;         /*!< Extension with a greater ID */
129         char stuff[0];
130 };
131
132 /*! \brief ast_include: include= support in extensions.conf */
133 struct ast_include {
134         const char *name;
135         const char *rname;                      /*!< Context to include */
136         const char *registrar;                  /*!< Registrar */
137         int hastime;                            /*!< If time construct exists */
138         struct ast_timing timing;               /*!< time construct */
139         struct ast_include *next;               /*!< Link them together */
140         char stuff[0];
141 };
142
143 /*! \brief ast_sw: Switch statement in extensions.conf */
144 struct ast_sw {
145         char *name;
146         const char *registrar;                  /*!< Registrar */
147         char *data;                             /*!< Data load */
148         int eval;
149         AST_LIST_ENTRY(ast_sw) list;
150         char *tmpdata;
151         char stuff[0];
152 };
153
154 /*! \brief ast_ignorepat: Ignore patterns in dial plan */
155 struct ast_ignorepat {
156         const char *registrar;
157         struct ast_ignorepat *next;
158         const char pattern[0];
159 };
160
161 /*! \brief ast_context: An extension context */
162 struct ast_context {
163         ast_mutex_t lock;                       /*!< A lock to prevent multiple threads from clobbering the context */
164         struct ast_exten *root;                 /*!< The root of the list of extensions */
165         struct ast_context *next;               /*!< Link them together */
166         struct ast_include *includes;           /*!< Include other contexts */
167         struct ast_ignorepat *ignorepats;       /*!< Patterns for which to continue playing dialtone */
168         const char *registrar;                  /*!< Registrar */
169         AST_LIST_HEAD_NOLOCK(, ast_sw) alts;    /*!< Alternative switches */
170         ast_mutex_t macrolock;                  /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
171         char name[0];                           /*!< Name of the context */
172 };
173
174
175 /*! \brief ast_app: A registered application */
176 struct ast_app {
177         int (*execute)(struct ast_channel *chan, void *data);
178         const char *synopsis;                   /*!< Synopsis text for 'show applications' */
179         const char *description;                /*!< Description (help text) for 'show application &lt;name&gt;' */
180         AST_LIST_ENTRY(ast_app) list;           /*!< Next app in list */
181         struct module *module;                  /*!< Module this app belongs to */
182         char name[0];                           /*!< Name of the application */
183 };
184
185 /*! \brief ast_state_cb: An extension state notify register item */
186 struct ast_state_cb {
187         int id;
188         void *data;
189         ast_state_cb_type callback;
190         struct ast_state_cb *next;
191 };
192
193 /*! \brief Structure for dial plan hints
194
195   \note Hints are pointers from an extension in the dialplan to one or
196   more devices (tech/name) */
197 struct ast_hint {
198         struct ast_exten *exten;        /*!< Extension */
199         int laststate;                  /*!< Last known state */
200         struct ast_state_cb *callbacks; /*!< Callback list for this extension */
201         AST_LIST_ENTRY(ast_hint) list;  /*!< Pointer to next hint in list */
202 };
203
204 static const struct cfextension_states {
205         int extension_state;
206         const char * const text;
207 } extension_states[] = {
208         { AST_EXTENSION_NOT_INUSE,                     "Idle" },
209         { AST_EXTENSION_INUSE,                         "InUse" },
210         { AST_EXTENSION_BUSY,                          "Busy" },
211         { AST_EXTENSION_UNAVAILABLE,                   "Unavailable" },
212         { AST_EXTENSION_RINGING,                       "Ringing" },
213         { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
214         { AST_EXTENSION_ONHOLD,                        "Hold" },
215         { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD,  "InUse&Hold" }
216 };
217
218 static int pbx_builtin_answer(struct ast_channel *, void *);
219 static int pbx_builtin_goto(struct ast_channel *, void *);
220 static int pbx_builtin_hangup(struct ast_channel *, void *);
221 static int pbx_builtin_background(struct ast_channel *, void *);
222 static int pbx_builtin_wait(struct ast_channel *, void *);
223 static int pbx_builtin_waitexten(struct ast_channel *, void *);
224 static int pbx_builtin_resetcdr(struct ast_channel *, void *);
225 static int pbx_builtin_setamaflags(struct ast_channel *, void *);
226 static int pbx_builtin_ringing(struct ast_channel *, void *);
227 static int pbx_builtin_progress(struct ast_channel *, void *);
228 static int pbx_builtin_congestion(struct ast_channel *, void *);
229 static int pbx_builtin_busy(struct ast_channel *, void *);
230 static int pbx_builtin_noop(struct ast_channel *, void *);
231 static int pbx_builtin_gotoif(struct ast_channel *, void *);
232 static int pbx_builtin_gotoiftime(struct ast_channel *, void *);
233 static int pbx_builtin_execiftime(struct ast_channel *, void *);
234 static int pbx_builtin_saynumber(struct ast_channel *, void *);
235 static int pbx_builtin_saydigits(struct ast_channel *, void *);
236 static int pbx_builtin_saycharacters(struct ast_channel *, void *);
237 static int pbx_builtin_sayphonetic(struct ast_channel *, void *);
238 int pbx_builtin_setvar(struct ast_channel *, void *);
239 static int pbx_builtin_importvar(struct ast_channel *, void *);
240
241 AST_MUTEX_DEFINE_STATIC(globalslock);
242 static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
243
244 static int autofallthrough = 1;
245
246 AST_MUTEX_DEFINE_STATIC(maxcalllock);
247 static int countcalls = 0;
248
249 static AST_LIST_HEAD_STATIC(acf_root, ast_custom_function);
250
251 /*! \brief Declaration of builtin applications */
252 static struct pbx_builtin {
253         char name[AST_MAX_APP];
254         int (*execute)(struct ast_channel *chan, void *data);
255         char *synopsis;
256         char *description;
257 } builtins[] =
258 {
259         /* These applications are built into the PBX core and do not
260            need separate modules */
261
262         { "Answer", pbx_builtin_answer,
263         "Answer a channel if ringing",
264         "  Answer([delay]): If the call has not been answered, this application will\n"
265         "answer it. Otherwise, it has no effect on the call. If a delay is specified,\n"
266         "Asterisk will wait this number of milliseconds before answering the call.\n"
267         },
268
269         { "BackGround", pbx_builtin_background,
270         "Play an audio file while waiting for digits of an extension to go to.",
271         "  Background(filename1[&filename2...][|options[|langoverride][|context]]):\n"
272         "This application will play the given list of files while waiting for an\n"
273         "extension to be dialed by the calling channel. To continue waiting for digits\n"
274         "after this application has finished playing files, the WaitExten application\n"
275         "should be used. The 'langoverride' option explicitly specifies which language\n"
276         "to attempt to use for the requested sound files. If a 'context' is specified,\n"
277         "this is the dialplan context that this application will use when exiting to a\n"
278         "dialed extension."
279         "  If one of the requested sound files does not exist, call processing will be\n"
280         "terminated.\n"
281         "  Options:\n"
282         "    s - Causes the playback of the message to be skipped\n"
283         "          if the channel is not in the 'up' state (i.e. it\n"
284         "          hasn't been answered yet). If this happens, the\n"
285         "          application will return immediately.\n"
286         "    n - Don't answer the channel before playing the files.\n"
287         "    m - Only break if a digit hit matches a one digit\n"
288         "          extension in the destination context.\n"
289         "This application sets the following channel variable upon completion:\n"
290         " BACKGROUNDSTATUS    The status of the background attempt as a text string, one of\n"
291         "               SUCCESS | FAILED\n"
292         },
293
294         { "Busy", pbx_builtin_busy,
295         "Indicate the Busy condition",
296         "  Busy([timeout]): This application will indicate the busy condition to\n"
297         "the calling channel. If the optional timeout is specified, the calling channel\n"
298         "will be hung up after the specified number of seconds. Otherwise, this\n"
299         "application will wait until the calling channel hangs up.\n"
300         },
301
302         { "Congestion", pbx_builtin_congestion,
303         "Indicate the Congestion condition",
304         "  Congestion([timeout]): This application will indicate the congestion\n"
305         "condition to the calling channel. If the optional timeout is specified, the\n"
306         "calling channel will be hung up after the specified number of seconds.\n"
307         "Otherwise, this application will wait until the calling channel hangs up.\n"
308         },
309
310         { "ExecIfTime", pbx_builtin_execiftime,
311         "Conditional application execution based on the current time",
312         "  ExecIfTime(<times>|<weekdays>|<mdays>|<months>?appname[|appargs]):\n"
313         "This application will execute the specified dialplan application, with optional\n"
314         "arguments, if the current time matches the given time specification.\n"
315         },
316
317         { "Goto", pbx_builtin_goto,
318         "Jump to a particular priority, extension, or context",
319         "  Goto([[context|]extension|]priority): This application will cause the\n"
320         "calling channel to continue dialplan execution at the specified priority.\n"
321         "If no specific extension, or extension and context, are specified, then this\n"
322         "application will jump to the specified priority of the current extension.\n"
323         "  If the attempt to jump to another location in the dialplan is not successful,\n"
324         "then the channel will continue at the next priority of the current extension.\n"
325         },
326
327         { "GotoIf", pbx_builtin_gotoif,
328         "Conditional goto",
329         "  GotoIf(condition?[labeliftrue]:[labeliffalse]): This application will cause\n"
330         "the calling channel to jump to the specified location in the dialplan based on\n"
331         "the evaluation of the given condition. The channel will continue at\n"
332         "'labeliftrue' if the condition is true, or 'labeliffalse' if the condition is\n"
333         "false. The labels are specified with the same syntax as used within the Goto\n"
334         "application.  If the label chosen by the condition is omitted, no jump is\n"
335         "performed, but execution continues with the next priority in the dialplan.\n"
336         },
337
338         { "GotoIfTime", pbx_builtin_gotoiftime,
339         "Conditional Goto based on the current time",
340         "  GotoIfTime(<times>|<weekdays>|<mdays>|<months>?[[context|]exten|]priority):\n"
341         "This application will have the calling channel jump to the specified location\n"
342         "in the dialplan if the current time matches the given time specification.\n"
343         },
344
345         { "ImportVar", pbx_builtin_importvar,
346         "Import a variable from a channel into a new variable",
347         "  ImportVar(newvar=channelname|variable): This application imports a variable\n"
348         "from the specified channel (as opposed to the current one) and stores it as\n"
349         "a variable in the current channel (the channel that is calling this\n"
350         "application). Variables created by this application have the same inheritance\n"
351         "properties as those created with the Set application. See the documentation for\n"
352         "Set for more information.\n"
353         },
354
355         { "Hangup", pbx_builtin_hangup,
356         "Hang up the calling channel",
357         "  Hangup([causecode]): This application will hang up the calling channel.\n"
358         "If a causecode is given the channel's hangup cause will be set to the given\n"
359         "value.\n"
360         },
361
362         { "NoOp", pbx_builtin_noop,
363         "Do Nothing",
364         "  NoOp(): This applicatiion does nothing. However, it is useful for debugging\n"
365         "purposes. Any text that is provided as arguments to this application can be\n"
366         "viewed at the Asterisk CLI. This method can be used to see the evaluations of\n"
367         "variables or functions without having any effect."
368         },
369
370         { "Progress", pbx_builtin_progress,
371         "Indicate progress",
372         "  Progress(): This application will request that in-band progress information\n"
373         "be provided to the calling channel.\n"
374         },
375
376         { "ResetCDR", pbx_builtin_resetcdr,
377         "Resets the Call Data Record",
378         "  ResetCDR([options]):  This application causes the Call Data Record to be\n"
379         "reset.\n"
380         "  Options:\n"
381         "    w -- Store the current CDR record before resetting it.\n"
382         "    a -- Store any stacked records.\n"
383         "    v -- Save CDR variables.\n"
384         },
385
386         { "Ringing", pbx_builtin_ringing,
387         "Indicate ringing tone",
388         "  Ringing(): This application will request that the channel indicate a ringing\n"
389         "tone to the user.\n"
390         },
391
392         { "SayAlpha", pbx_builtin_saycharacters,
393         "Say Alpha",
394         "  SayAlpha(string): This application will play the sounds that correspond to\n"
395         "the letters of the given string.\n"
396         },
397
398         { "SayDigits", pbx_builtin_saydigits,
399         "Say Digits",
400         "  SayDigits(digits): This application will play the sounds that correspond\n"
401         "to the digits of the given number. This will use the language that is currently\n"
402         "set for the channel. See the LANGUAGE function for more information on setting\n"
403         "the language for the channel.\n"
404         },
405
406         { "SayNumber", pbx_builtin_saynumber,
407         "Say Number",
408         "  SayNumber(digits[,gender]): This application will play the sounds that\n"
409         "correspond to the given number. Optionally, a gender may be specified.\n"
410         "This will use the language that is currently set for the channel. See the\n"
411         "LANGUAGE function for more information on setting the language for the channel.\n"
412         },
413
414         { "SayPhonetic", pbx_builtin_sayphonetic,
415         "Say Phonetic",
416         "  SayPhonetic(string): This application will play the sounds from the phonetic\n"
417         "alphabet that correspond to the letters in the given string.\n"
418         },
419
420         { "Set", pbx_builtin_setvar,
421         "Set channel variable(s) or function value(s)",
422         "  Set(name1=value1|name2=value2|..[|options])\n"
423         "This function can be used to set the value of channel variables or dialplan\n"
424         "functions. It will accept up to 24 name/value pairs. When setting variables,\n"
425         "if the variable name is prefixed with _, the variable will be inherited into\n"
426         "channels created from the current channel. If the variable name is prefixed\n"
427         "with __, the variable will be inherited into channels created from the current\n"
428         "channel and all children channels.\n"
429         "  Options:\n"
430         "    g - Set variable globally instead of on the channel\n"
431         "        (applies only to variables, not functions)\n"
432         },
433
434         { "SetAMAFlags", pbx_builtin_setamaflags,
435         "Set the AMA Flags",
436         "  SetAMAFlags([flag]): This application will set the channel's AMA Flags for\n"
437         "  billing purposes.\n"
438         },
439
440         { "Wait", pbx_builtin_wait,
441         "Waits for some time",
442         "  Wait(seconds): This application waits for a specified number of seconds.\n"
443         "Then, dialplan execution will continue at the next priority.\n"
444         "  Note that the seconds can be passed with fractions of a second. For example,\n"
445         "'1.5' will ask the application to wait for 1.5 seconds.\n"
446         },
447
448         { "WaitExten", pbx_builtin_waitexten,
449         "Waits for an extension to be entered",
450         "  WaitExten([seconds][|options]): This application waits for the user to enter\n"
451         "a new extension for a specified number of seconds.\n"
452         "  Note that the seconds can be passed with fractions of a second. For example,\n"
453         "'1.5' will ask the application to wait for 1.5 seconds.\n"
454         "  Options:\n"
455         "    m[(x)] - Provide music on hold to the caller while waiting for an extension.\n"
456         "               Optionally, specify the class for music on hold within parenthesis.\n"
457         },
458
459 };
460
461 static struct ast_context *contexts = NULL;
462 AST_MUTEX_DEFINE_STATIC(conlock);               /*!< Lock for the ast_context list */
463
464 static AST_LIST_HEAD_STATIC(apps, ast_app);
465
466 static AST_LIST_HEAD_STATIC(switches, ast_switch);
467
468 static int stateid = 1;
469 /* WARNING:
470    When holding this list's lock, do _not_ do anything that will cause conlock
471    to be taken, unless you _already_ hold it. The ast_merge_contexts_and_delete
472    function will take the locks in conlock/hints order, so any other
473    paths that require both locks must also take them in that order.
474 */
475 static AST_LIST_HEAD_STATIC(hints, ast_hint);
476 struct ast_state_cb *statecbs = NULL;
477
478 /*
479    \note This function is special. It saves the stack so that no matter
480    how many times it is called, it returns to the same place */
481 int pbx_exec(struct ast_channel *c,             /*!< Channel */
482                 struct ast_app *app,            /*!< Application */
483                 void *data)                     /*!< Data for execution */
484 {
485         int res;
486
487         const char *saved_c_appl;
488         const char *saved_c_data;
489
490         if (c->cdr)
491                 ast_cdr_setapp(c->cdr, app->name, data);
492
493         /* save channel values */
494         saved_c_appl= c->appl;
495         saved_c_data= c->data;
496
497         c->appl = app->name;
498         c->data = data;
499         /* XXX remember what to to when we have linked apps to modules */
500         if (app->module) {
501                 /* XXX LOCAL_USER_ADD(app->module) */
502         }
503         res = app->execute(c, data);
504         if (app->module) {
505                 /* XXX LOCAL_USER_REMOVE(app->module) */
506         }
507         /* restore channel values */
508         c->appl = saved_c_appl;
509         c->data = saved_c_data;
510         return res;
511 }
512
513
514 /*! Go no deeper than this through includes (not counting loops) */
515 #define AST_PBX_MAX_STACK       128
516
517 /*! \brief Find application handle in linked list
518  */
519 struct ast_app *pbx_findapp(const char *app)
520 {
521         struct ast_app *tmp;
522
523         AST_LIST_LOCK(&apps);
524         AST_LIST_TRAVERSE(&apps, tmp, list) {
525                 if (!strcasecmp(tmp->name, app))
526                         break;
527         }
528         AST_LIST_UNLOCK(&apps);
529
530         return tmp;
531 }
532
533 static struct ast_switch *pbx_findswitch(const char *sw)
534 {
535         struct ast_switch *asw;
536
537         AST_LIST_LOCK(&switches);
538         AST_LIST_TRAVERSE(&switches, asw, list) {
539                 if (!strcasecmp(asw->name, sw))
540                         break;
541         }
542         AST_LIST_UNLOCK(&switches);
543
544         return asw;
545 }
546
547 static inline int include_valid(struct ast_include *i)
548 {
549         if (!i->hastime)
550                 return 1;
551
552         return ast_check_timing(&(i->timing));
553 }
554
555 static void pbx_destroy(struct ast_pbx *p)
556 {
557         free(p);
558 }
559
560 /*
561  * Special characters used in patterns:
562  *      '_'     underscore is the leading character of a pattern.
563  *              In other position it is treated as a regular char.
564  *      ' ' '-' space and '-' are separator and ignored.
565  *      .       one or more of any character. Only allowed at the end of
566  *              a pattern.
567  *      !       zero or more of anything. Also impacts the result of CANMATCH
568  *              and MATCHMORE. Only allowed at the end of a pattern.
569  *              In the core routine, ! causes a match with a return code of 2.
570  *              In turn, depending on the search mode: (XXX check if it is implemented)
571  *              - E_MATCH retuns 1 (does match)
572  *              - E_MATCHMORE returns 0 (no match)
573  *              - E_CANMATCH returns 1 (does match)
574  *
575  *      /       should not appear as it is considered the separator of the CID info.
576  *              XXX at the moment we may stop on this char.
577  *
578  *      X Z N   match ranges 0-9, 1-9, 2-9 respectively.
579  *      [       denotes the start of a set of character. Everything inside
580  *              is considered literally. We can have ranges a-d and individual
581  *              characters. A '[' and '-' can be considered literally if they
582  *              are just before ']'.
583  *              XXX currently there is no way to specify ']' in a range, nor \ is
584  *              considered specially.
585  *
586  * When we compare a pattern with a specific extension, all characters in the extension
587  * itself are considered literally with the only exception of '-' which is considered
588  * as a separator and thus ignored.
589  * XXX do we want to consider space as a separator as well ?
590  * XXX do we want to consider the separators in non-patterns as well ?
591  */
592
593 /*!
594  * \brief helper functions to sort extensions and patterns in the desired way,
595  * so that more specific patterns appear first.
596  *
597  * ext_cmp1 compares individual characters (or sets of), returning
598  * an int where bits 0-7 are the ASCII code of the first char in the set,
599  * while bit 8-15 are the cardinality of the set minus 1.
600  * This way more specific patterns (smaller cardinality) appear first.
601  * Wildcards have a special value, so that we can directly compare them to
602  * sets by subtracting the two values. In particular:
603  *      0x000xx         one character, xx
604  *      0x0yyxx         yy character set starting with xx
605  *      0x10000         '.' (one or more of anything)
606  *      0x20000         '!' (zero or more of anything)
607  *      0x30000         NUL (end of string)
608  *      0x40000         error in set.
609  * The pointer to the string is advanced according to needs.
610  * NOTES:
611  *      1. the empty set is equivalent to NUL.
612  *      2. given that a full set has always 0 as the first element,
613  *         we could encode the special cases as 0xffXX where XX
614  *         is 1, 2, 3, 4 as used above.
615  */
616 static int ext_cmp1(const char **p)
617 {
618         uint32_t chars[8];
619         int c, cmin = 0xff, count = 0;
620         const char *end;
621
622         /* load, sign extend and advance pointer until we find
623          * a valid character.
624          */
625         while ( (c = *(*p)++) && (c == ' ' || c == '-') )
626                 ;       /* ignore some characters */
627
628         /* always return unless we have a set of chars */
629         switch (c) {
630         default:        /* ordinary character */
631                 return 0x0000 | (c & 0xff);
632
633         case 'N':       /* 2..9 */
634                 return 0x0700 | '2' ;
635
636         case 'X':       /* 0..9 */
637                 return 0x0900 | '0';
638
639         case 'Z':       /* 1..9 */
640                 return 0x0800 | '1';
641
642         case '.':       /* wildcard */
643                 return 0x10000;
644
645         case '!':       /* earlymatch */
646                 return 0x20000; /* less specific than NULL */
647
648         case '\0':      /* empty string */
649                 *p = NULL;
650                 return 0x30000;
651
652         case '[':       /* pattern */
653                 break;
654         }
655         /* locate end of set */
656         end = strchr(*p, ']');  
657
658         if (end == NULL) {
659                 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
660                 return 0x40000; /* XXX make this entry go last... */
661         }
662
663         bzero(chars, sizeof(chars));    /* clear all chars in the set */
664         for (; *p < end  ; (*p)++) {
665                 unsigned char c1, c2;   /* first-last char in range */
666                 c1 = (unsigned char)((*p)[0]);
667                 if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
668                         c2 = (unsigned char)((*p)[2]);
669                         *p += 2;        /* skip a total of 3 chars */
670                 } else                  /* individual character */
671                         c2 = c1;
672                 if (c1 < cmin)
673                         cmin = c1;
674                 for (; c1 <= c2; c1++) {
675                         uint32_t mask = 1 << (c1 % 32);
676                         if ( (chars[ c1 / 32 ] & mask) == 0)
677                                 count += 0x100;
678                         chars[ c1 / 32 ] |= mask;
679                 }
680         }
681         (*p)++;
682         return count == 0 ? 0x30000 : (count | cmin);
683 }
684
685 /*!
686  * \brief the full routine to compare extensions in rules.
687  */
688 static int ext_cmp(const char *a, const char *b)
689 {
690         /* make sure non-patterns come first.
691          * If a is not a pattern, it either comes first or
692          * we use strcmp to compare the strings.
693          */
694         int ret = 0;
695
696         if (a[0] != '_')
697                 return (b[0] == '_') ? -1 : strcmp(a, b);
698
699         /* Now we know a is a pattern; if b is not, a comes first */
700         if (b[0] != '_')
701                 return 1;
702 #if 0   /* old mode for ext matching */
703         return strcmp(a, b);
704 #endif
705         /* ok we need full pattern sorting routine */
706         while (!ret && a && b)
707                 ret = ext_cmp1(&a) - ext_cmp1(&b);
708         if (ret == 0)
709                 return 0;
710         else
711                 return (ret > 0) ? 1 : -1;
712 }
713
714 /*!
715  * When looking up extensions, we can have different requests
716  * identified by the 'action' argument, as follows.
717  * Note that the coding is such that the low 4 bits are the
718  * third argument to extension_match_core.
719  */
720 enum ext_match_t {
721         E_MATCHMORE =   0x00,   /* extension can match but only with more 'digits' */
722         E_CANMATCH =    0x01,   /* extension can match with or without more 'digits' */
723         E_MATCH =       0x02,   /* extension is an exact match */
724         E_MATCH_MASK =  0x03,   /* mask for the argument to extension_match_core() */
725         E_SPAWN =       0x12,   /* want to spawn an extension. Requires exact match */
726         E_FINDLABEL =   0x22    /* returns the priority for a given label. Requires exact match */
727 };
728
729 /*
730  * Internal function for ast_extension_{match|close}
731  * return 0 on no-match, 1 on match, 2 on early match.
732  * mode is as follows:
733  *      E_MATCH         success only on exact match
734  *      E_MATCHMORE     success only on partial match (i.e. leftover digits in pattern)
735  *      E_CANMATCH      either of the above.
736  */
737
738 static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
739 {
740         mode &= E_MATCH_MASK;   /* only consider the relevant bits */
741
742         if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */
743                 return 1;
744
745         if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
746                 int ld = strlen(data), lp = strlen(pattern);
747
748                 if (lp < ld)            /* pattern too short, cannot match */
749                         return 0;
750                 /* depending on the mode, accept full or partial match or both */
751                 if (mode == E_MATCH)
752                         return !strcmp(pattern, data); /* 1 on match, 0 on fail */
753                 if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */
754                         return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
755                 else
756                         return 0;
757         }
758         pattern++; /* skip leading _ */
759         /*
760          * XXX below we stop at '/' which is a separator for the CID info. However we should
761          * not store '/' in the pattern at all. When we insure it, we can remove the checks.
762          */
763         while (*data && *pattern && *pattern != '/') {
764                 const char *end;
765
766                 if (*data == '-') { /* skip '-' in data (just a separator) */
767                         data++;
768                         continue;
769                 }
770                 switch (toupper(*pattern)) {
771                 case '[':       /* a range */
772                         end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */
773                         if (end == NULL) {
774                                 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
775                                 return 0;       /* unconditional failure */
776                         }
777                         for (pattern++; pattern != end; pattern++) {
778                                 if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
779                                         if (*data >= pattern[0] && *data <= pattern[2])
780                                                 break;  /* match found */
781                                         else {
782                                                 pattern += 2; /* skip a total of 3 chars */
783                                                 continue;
784                                         }
785                                 } else if (*data == pattern[0])
786                                         break;  /* match found */
787                         }
788                         if (pattern == end)
789                                 return 0;
790                         pattern = end;  /* skip and continue */
791                         break;
792                 case 'N':
793                         if (*data < '2' || *data > '9')
794                                 return 0;
795                         break;
796                 case 'X':
797                         if (*data < '0' || *data > '9')
798                                 return 0;
799                         break;
800                 case 'Z':
801                         if (*data < '1' || *data > '9')
802                                 return 0;
803                         break;
804                 case '.':       /* Must match, even with more digits */
805                         return 1;
806                 case '!':       /* Early match */
807                         return 2;
808                 case ' ':
809                 case '-':       /* Ignore these in patterns */
810                         data--; /* compensate the final data++ */
811                         break;
812                 default:
813                         if (*data != *pattern)
814                                 return 0;
815                 }
816                 data++;
817                 pattern++;
818         }
819         if (*data)                      /* data longer than pattern, no match */
820                 return 0;
821         /*
822          * match so far, but ran off the end of the data.
823          * Depending on what is next, determine match or not.
824          */
825         if (*pattern == '\0' || *pattern == '/')        /* exact match */
826                 return (mode == E_MATCHMORE) ? 0 : 1;   /* this is a failure for E_MATCHMORE */
827         else if (*pattern == '!')                       /* early match */
828                 return 2;
829         else                                            /* partial match */
830                 return (mode == E_MATCH) ? 0 : 1;       /* this is a failure for E_MATCH */
831 }
832
833 /*
834  * Wrapper around _extension_match_core() to do performance measurement
835  * using the profiling code.
836  */
837 static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
838 {
839         int i;
840         static int prof_id = -2;        /* marker for 'unallocated' id */
841         if (prof_id == -2)
842                 prof_id = ast_add_profile("ext_match", 0);
843         ast_mark(prof_id, 1);
844         i = _extension_match_core(pattern, data, mode);
845         ast_mark(prof_id, 0);
846         return i;
847 }
848
849 int ast_extension_match(const char *pattern, const char *data)
850 {
851         return extension_match_core(pattern, data, E_MATCH);
852 }
853
854 int ast_extension_close(const char *pattern, const char *data, int needmore)
855 {
856         if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
857                 ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
858         return extension_match_core(pattern, data, needmore);
859 }
860
861 struct ast_context *ast_context_find(const char *name)
862 {
863         struct ast_context *tmp = NULL;
864         ast_mutex_lock(&conlock);
865         while ( (tmp = ast_walk_contexts(tmp)) ) {
866                 if (!name || !strcasecmp(name, tmp->name))
867                         break;
868         }
869         ast_mutex_unlock(&conlock);
870         return tmp;
871 }
872
873 #define STATUS_NO_CONTEXT       1
874 #define STATUS_NO_EXTENSION     2
875 #define STATUS_NO_PRIORITY      3
876 #define STATUS_NO_LABEL         4
877 #define STATUS_SUCCESS          5
878
879 static int matchcid(const char *cidpattern, const char *callerid)
880 {
881         /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
882            failing to get a number should count as a match, otherwise not */
883
884         if (ast_strlen_zero(callerid))
885                 return ast_strlen_zero(cidpattern) ? 1 : 0;
886
887         return ast_extension_match(cidpattern, callerid);
888 }
889
890 /* request and result for pbx_find_extension */
891 struct pbx_find_info {
892 #if 0
893         const char *context;
894         const char *exten;
895         int priority;
896 #endif
897
898         char *incstack[AST_PBX_MAX_STACK];      /* filled during the search */
899         int stacklen;                   /* modified during the search */
900         int status;                     /* set on return */
901         struct ast_switch *swo;         /* set on return */
902         const char *data;               /* set on return */
903         const char *foundcontext;       /* set on return */
904 };
905
906 static struct ast_exten *pbx_find_extension(struct ast_channel *chan,
907         struct ast_context *bypass, struct pbx_find_info *q,
908         const char *context, const char *exten, int priority,
909         const char *label, const char *callerid, enum ext_match_t action)
910 {
911         int x, res;
912         struct ast_context *tmp;
913         struct ast_exten *e, *eroot;
914         struct ast_include *i;
915         struct ast_sw *sw;
916
917         /* Initialize status if appropriate */
918         if (q->stacklen == 0) {
919                 q->status = STATUS_NO_CONTEXT;
920                 q->swo = NULL;
921                 q->data = NULL;
922                 q->foundcontext = NULL;
923         }
924         /* Check for stack overflow */
925         if (q->stacklen >= AST_PBX_MAX_STACK) {
926                 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
927                 return NULL;
928         }
929         /* Check first to see if we've already been checked */
930         for (x = 0; x < q->stacklen; x++) {
931                 if (!strcasecmp(q->incstack[x], context))
932                         return NULL;
933         }
934         if (bypass)     /* bypass means we only look there */
935                 tmp = bypass;
936         else {  /* look in contexts */
937                 tmp = NULL;
938                 while ((tmp = ast_walk_contexts(tmp)) ) {
939                         if (!strcmp(tmp->name, context))
940                                 break;
941                 }
942                 if (!tmp)
943                         return NULL;
944         }
945         if (q->status < STATUS_NO_EXTENSION)
946                 q->status = STATUS_NO_EXTENSION;
947
948         /* scan the list trying to match extension and CID */
949         eroot = NULL;
950         while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
951                 int match = extension_match_core(eroot->exten, exten, action);
952                 /* 0 on fail, 1 on match, 2 on earlymatch */
953
954                 if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
955                         continue;       /* keep trying */
956                 if (match == 2 && action == E_MATCHMORE) {
957                         /* We match an extension ending in '!'.
958                          * The decision in this case is final and is NULL (no match).
959                          */
960                         return NULL;
961                 }
962                 /* found entry, now look for the right priority */
963                 if (q->status < STATUS_NO_PRIORITY)
964                         q->status = STATUS_NO_PRIORITY;
965                 e = NULL;
966                 while ( (e = ast_walk_extension_priorities(eroot, e)) ) {
967                         /* Match label or priority */
968                         if (action == E_FINDLABEL) {
969                                 if (q->status < STATUS_NO_LABEL)
970                                         q->status = STATUS_NO_LABEL;
971                                 if (label && e->label && !strcmp(label, e->label))
972                                         break;  /* found it */
973                         } else if (e->priority == priority) {
974                                 break;  /* found it */
975                         } /* else keep searching */
976                 }
977                 if (e) {        /* found a valid match */
978                         q->status = STATUS_SUCCESS;
979                         q->foundcontext = context;
980                         return e;
981                 }
982         }
983         /* Check alternative switches */
984         AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
985                 struct ast_switch *asw = pbx_findswitch(sw->name);
986                 ast_switch_f *aswf = NULL;
987                 char *datap;
988
989                 if (!asw) {
990                         ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
991                         continue;
992                 }
993                 /* Substitute variables now */
994                 if (sw->eval)
995                         pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1);
996
997                 /* equivalent of extension_match_core() at the switch level */
998                 if (action == E_CANMATCH)
999                         aswf = asw->canmatch;
1000                 else if (action == E_MATCHMORE)
1001                         aswf = asw->matchmore;
1002                 else /* action == E_MATCH */
1003                         aswf = asw->exists;
1004                 datap = sw->eval ? sw->tmpdata : sw->data;
1005                 res = !aswf ? 0 : aswf(chan, context, exten, priority, callerid, datap);
1006                 if (res) {      /* Got a match */
1007                         q->swo = asw;
1008                         q->data = datap;
1009                         q->foundcontext = context;
1010                         /* XXX keep status = STATUS_NO_CONTEXT ? */
1011                         return NULL;
1012                 }
1013         }
1014         q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
1015         /* Now try any includes we have in this context */
1016         for (i = tmp->includes; i; i = i->next) {
1017                 if (include_valid(i)) {
1018                         if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action)))
1019                                 return e;
1020                         if (q->swo)
1021                                 return NULL;
1022                 }
1023         }
1024         return NULL;
1025 }
1026
1027 /*! \brief extract offset:length from variable name.
1028  * Returns 1 if there is a offset:length part, which is
1029  * trimmed off (values go into variables)
1030  */
1031 static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
1032 {
1033         int parens=0;
1034
1035         *offset = 0;
1036         *length = INT_MAX;
1037         *isfunc = 0;
1038         for (; *var; var++) {
1039                 if (*var == '(') {
1040                         (*isfunc)++;
1041                         parens++;
1042                 } else if (*var == ')') {
1043                         parens--;
1044                 } else if (*var == ':' && parens == 0) {
1045                         *var++ = '\0';
1046                         sscanf(var, "%d:%d", offset, length);
1047                         return 1; /* offset:length valid */
1048                 }
1049         }
1050         return 0;
1051 }
1052
1053 /*! \brief takes a substring. It is ok to call with value == workspace.
1054  *
1055  * offset < 0 means start from the end of the string and set the beginning
1056  *   to be that many characters back.
1057  * length is the length of the substring.  A value less than 0 means to leave
1058  * that many off the end.
1059  * Always return a copy in workspace.
1060  */
1061 static char *substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
1062 {
1063         char *ret = workspace;
1064         int lr; /* length of the input string after the copy */
1065
1066         ast_copy_string(workspace, value, workspace_len); /* always make a copy */
1067
1068         lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
1069
1070         /* Quick check if no need to do anything */
1071         if (offset == 0 && length >= lr)        /* take the whole string */
1072                 return ret;
1073
1074         if (offset < 0) {       /* translate negative offset into positive ones */
1075                 offset = lr + offset;
1076                 if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
1077                         offset = 0;
1078         }
1079
1080         /* too large offset result in empty string so we know what to return */
1081         if (offset >= lr)
1082                 return ret + lr;        /* the final '\0' */
1083
1084         ret += offset;          /* move to the start position */
1085         if (length >= 0 && length < lr - offset)        /* truncate if necessary */
1086                 ret[length] = '\0';
1087         else if (length < 0) {
1088                 if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */
1089                         ret[lr + length - offset] = '\0';
1090                 else
1091                         ret[0] = '\0';
1092         }
1093
1094         return ret;
1095 }
1096
1097 /*! \brief  pbx_retrieve_variable: Support for Asterisk built-in variables and
1098       functions in the dialplan
1099   ---*/
1100 void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
1101 {
1102         const char not_found = '\0';
1103         char *tmpvar;
1104         const char *s;  /* the result */
1105         int offset, length;
1106         int i, need_substring;
1107         struct varshead *places[2] = { headp, &globals };       /* list of places where we may look */
1108
1109         if (c) {
1110                 places[0] = &c->varshead;
1111         }
1112         /*
1113          * Make a copy of var because parse_variable_name() modifies the string.
1114          * Then if called directly, we might need to run substring() on the result;
1115          * remember this for later in 'need_substring', 'offset' and 'length'
1116          */
1117         tmpvar = ast_strdupa(var);      /* parse_variable_name modifies the string */
1118         need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
1119
1120         /*
1121          * Look first into predefined variables, then into variable lists.
1122          * Variable 's' points to the result, according to the following rules:
1123          * s == &not_found (set at the beginning) means that we did not find a
1124          *      matching variable and need to look into more places.
1125          * If s != &not_found, s is a valid result string as follows:
1126          * s = NULL if the variable does not have a value;
1127          *      you typically do this when looking for an unset predefined variable.
1128          * s = workspace if the result has been assembled there;
1129          *      typically done when the result is built e.g. with an snprintf(),
1130          *      so we don't need to do an additional copy.
1131          * s != workspace in case we have a string, that needs to be copied
1132          *      (the ast_copy_string is done once for all at the end).
1133          *      Typically done when the result is already available in some string.
1134          */
1135         s = &not_found; /* default value */
1136         if (c) {        /* This group requires a valid channel */
1137                 /* Names with common parts are looked up a piece at a time using strncmp. */
1138                 if (!strncmp(var, "CALL", 4)) {
1139                         if (!strncmp(var + 4, "ING", 3)) {
1140                                 if (!strcmp(var + 7, "PRES")) {                 /* CALLINGPRES */
1141                                         snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
1142                                         s = workspace;
1143                                 } else if (!strcmp(var + 7, "ANI2")) {          /* CALLINGANI2 */
1144                                         snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
1145                                         s = workspace;
1146                                 } else if (!strcmp(var + 7, "TON")) {           /* CALLINGTON */
1147                                         snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
1148                                         s = workspace;
1149                                 } else if (!strcmp(var + 7, "TNS")) {           /* CALLINGTNS */
1150                                         snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
1151                                         s = workspace;
1152                                 }
1153                         }
1154                 } else if (!strcmp(var, "HINT")) {
1155                         s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
1156                 } else if (!strcmp(var, "HINTNAME")) {
1157                         s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
1158                 } else if (!strcmp(var, "EXTEN")) {
1159                         s = c->exten;
1160                 } else if (!strcmp(var, "CONTEXT")) {
1161                         s = c->context;
1162                 } else if (!strcmp(var, "PRIORITY")) {
1163                         snprintf(workspace, workspacelen, "%d", c->priority);
1164                         s = workspace;
1165                 } else if (!strcmp(var, "CHANNEL")) {
1166                         s = c->name;
1167                 } else if (!strcmp(var, "UNIQUEID")) {
1168                         s = c->uniqueid;
1169                 } else if (!strcmp(var, "HANGUPCAUSE")) {
1170                         snprintf(workspace, workspacelen, "%d", c->hangupcause);
1171                         s = workspace;
1172                 }
1173         }
1174         if (s == &not_found) { /* look for more */
1175                 if (!strcmp(var, "EPOCH")) {
1176                         snprintf(workspace, workspacelen, "%u",(int)time(NULL));
1177                         s = workspace;
1178                 } else if (!strcmp(var, "SYSTEMNAME")) {
1179                         s = ast_config_AST_SYSTEM_NAME;
1180                 }
1181         }
1182         /* if not found, look into chanvars or global vars */
1183         for (i = 0; s == &not_found && i < (sizeof(places) / sizeof(places[0])); i++) {
1184                 struct ast_var_t *variables;
1185                 if (!places[i])
1186                         continue;
1187                 if (places[i] == &globals)
1188                         ast_mutex_lock(&globalslock);
1189                 AST_LIST_TRAVERSE(places[i], variables, entries) {
1190                         if (strcasecmp(ast_var_name(variables), var)==0) {
1191                                 s = ast_var_value(variables);
1192                                 break;
1193                         }
1194                 }
1195                 if (places[i] == &globals)
1196                         ast_mutex_unlock(&globalslock);
1197         }
1198         if (s == &not_found || s == NULL)
1199                 *ret = NULL;
1200         else {
1201                 if (s != workspace)
1202                         ast_copy_string(workspace, s, workspacelen);
1203                 *ret = workspace;
1204                 if (need_substring)
1205                         *ret = substring(*ret, offset, length, workspace, workspacelen);
1206         }
1207 }
1208
1209 static int handle_show_functions(int fd, int argc, char *argv[])
1210 {
1211         struct ast_custom_function *acf;
1212         int count_acf = 0;
1213         int like = 0;
1214
1215         if (argc == 5 && (!strcmp(argv[3], "like")) ) {
1216                 like = 1;
1217         } else if (argc != 3) {
1218                 return RESULT_SHOWUSAGE;
1219         }
1220
1221         ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed");
1222
1223         AST_LIST_LOCK(&acf_root);
1224         AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
1225                 if (!like || strstr(acf->name, argv[4])) {
1226                         count_acf++;
1227                         ast_cli(fd, "%-20.20s  %-35.35s  %s\n", acf->name, acf->syntax, acf->synopsis);
1228                 }
1229         }
1230         AST_LIST_UNLOCK(&acf_root);
1231
1232         ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : "");
1233
1234         return RESULT_SUCCESS;
1235 }
1236
1237 static int handle_show_function(int fd, int argc, char *argv[])
1238 {
1239         struct ast_custom_function *acf;
1240         /* Maximum number of characters added by terminal coloring is 22 */
1241         char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
1242         char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
1243         char stxtitle[40], *syntax = NULL;
1244         int synopsis_size, description_size, syntax_size;
1245
1246         if (argc < 4)
1247                 return RESULT_SHOWUSAGE;
1248
1249         if (!(acf = ast_custom_function_find(argv[3]))) {
1250                 ast_cli(fd, "No function by that name registered.\n");
1251                 return RESULT_FAILURE;
1252
1253         }
1254
1255         if (acf->synopsis)
1256                 synopsis_size = strlen(acf->synopsis) + 23;
1257         else
1258                 synopsis_size = strlen("Not available") + 23;
1259         synopsis = alloca(synopsis_size);
1260
1261         if (acf->desc)
1262                 description_size = strlen(acf->desc) + 23;
1263         else
1264                 description_size = strlen("Not available") + 23;
1265         description = alloca(description_size);
1266
1267         if (acf->syntax)
1268                 syntax_size = strlen(acf->syntax) + 23;
1269         else
1270                 syntax_size = strlen("Not available") + 23;
1271         syntax = alloca(syntax_size);
1272
1273         snprintf(info, 64 + AST_MAX_APP, "\n  -= Info about function '%s' =- \n\n", acf->name);
1274         term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
1275         term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
1276         term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
1277         term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
1278         term_color(syntax,
1279                    acf->syntax ? acf->syntax : "Not available",
1280                    COLOR_CYAN, 0, syntax_size);
1281         term_color(synopsis,
1282                    acf->synopsis ? acf->synopsis : "Not available",
1283                    COLOR_CYAN, 0, synopsis_size);
1284         term_color(description,
1285                    acf->desc ? acf->desc : "Not available",
1286                    COLOR_CYAN, 0, description_size);
1287
1288         ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description);
1289
1290         return RESULT_SUCCESS;
1291 }
1292
1293 static char *complete_show_function(const char *line, const char *word, int pos, int state)
1294 {
1295         struct ast_custom_function *acf;
1296         char *ret = NULL;
1297         int which = 0;
1298         int wordlen = strlen(word);
1299
1300         /* case-insensitive for convenience in this 'complete' function */
1301         AST_LIST_LOCK(&acf_root);
1302         AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
1303                 if (!strncasecmp(word, acf->name, wordlen) && ++which > state) {
1304                         ret = strdup(acf->name);
1305                         break;
1306                 }
1307         }
1308         AST_LIST_UNLOCK(&acf_root);
1309
1310         return ret;
1311 }
1312
1313 struct ast_custom_function *ast_custom_function_find(const char *name)
1314 {
1315         struct ast_custom_function *acf = NULL;
1316
1317         AST_LIST_LOCK(&acf_root);
1318         AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
1319                 if (!strcmp(name, acf->name))
1320                         break;
1321         }
1322         AST_LIST_UNLOCK(&acf_root);
1323
1324         return acf;
1325 }
1326
1327 int ast_custom_function_unregister(struct ast_custom_function *acf)
1328 {
1329         struct ast_custom_function *cur;
1330
1331         if (!acf)
1332                 return -1;
1333
1334         AST_LIST_LOCK(&acf_root);
1335         AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
1336                 if (cur == acf) {
1337                         AST_LIST_REMOVE_CURRENT(&acf_root, acflist);
1338                         if (option_verbose > 1)
1339                                 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
1340                         break;
1341                 }
1342         }
1343         AST_LIST_TRAVERSE_SAFE_END
1344         AST_LIST_UNLOCK(&acf_root);
1345
1346         return acf ? 0 : -1;
1347 }
1348
1349 int ast_custom_function_register(struct ast_custom_function *acf)
1350 {
1351         struct ast_custom_function *cur;
1352
1353         if (!acf)
1354                 return -1;
1355
1356         AST_LIST_LOCK(&acf_root);
1357
1358         if (ast_custom_function_find(acf->name)) {
1359                 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
1360                 AST_LIST_UNLOCK(&acf_root);
1361                 return -1;
1362         }
1363
1364         /* Store in alphabetical order */
1365         AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
1366                 if (strcasecmp(acf->name, cur->name) < 0) {
1367                         AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
1368                         break;
1369                 }
1370         }
1371         AST_LIST_TRAVERSE_SAFE_END
1372         if (!cur)
1373                 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist);
1374
1375         AST_LIST_UNLOCK(&acf_root);
1376
1377         if (option_verbose > 1)
1378                 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
1379
1380         return 0;
1381 }
1382
1383 /*! \brief return a pointer to the arguments of the function,
1384  * and terminates the function name with '\\0'
1385  */
1386 static char *func_args(char *function)
1387 {
1388         char *args = strchr(function, '(');
1389
1390         if (!args)
1391                 ast_log(LOG_WARNING, "Function doesn't contain parentheses.  Assuming null argument.\n");
1392         else {
1393                 char *p;
1394                 *args++ = '\0';
1395                 if ((p = strrchr(args, ')')) )
1396                         *p = '\0';
1397                 else
1398                         ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
1399         }
1400         return args;
1401 }
1402
1403 int ast_func_read(struct ast_channel *chan, char *function, char *workspace, size_t len)
1404 {
1405         char *args = func_args(function);
1406         struct ast_custom_function *acfptr = ast_custom_function_find(function);
1407
1408         if (acfptr == NULL)
1409                 ast_log(LOG_ERROR, "Function %s not registered\n", function);
1410         else if (!acfptr->read)
1411                 ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
1412         else
1413                 return acfptr->read(chan, function, args, workspace, len);
1414         return -1;
1415 }
1416
1417 int ast_func_write(struct ast_channel *chan, char *function, const char *value)
1418 {
1419         char *args = func_args(function);
1420         struct ast_custom_function *acfptr = ast_custom_function_find(function);
1421
1422         if (acfptr == NULL)
1423                 ast_log(LOG_ERROR, "Function %s not registered\n", function);
1424         else if (!acfptr->write)
1425                 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function);
1426         else
1427                 return acfptr->write(chan, function, args, value);
1428
1429         return -1;
1430 }
1431
1432 static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count)
1433 {
1434         /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be
1435            zero-filled */
1436         char *cp4;
1437         const char *tmp, *whereweare;
1438         int length, offset, offset2, isfunction;
1439         char *workspace = NULL;
1440         char *ltmp = NULL, *var = NULL;
1441         char *nextvar, *nextexp, *nextthing;
1442         char *vars, *vare;
1443         int pos, brackets, needsub, len;
1444
1445         whereweare=tmp=cp1;
1446         while (!ast_strlen_zero(whereweare) && count) {
1447                 /* Assume we're copying the whole remaining string */
1448                 pos = strlen(whereweare);
1449                 nextvar = NULL;
1450                 nextexp = NULL;
1451                 nextthing = strchr(whereweare, '$');
1452                 if (nextthing) {
1453                         switch(nextthing[1]) {
1454                         case '{':
1455                                 nextvar = nextthing;
1456                                 pos = nextvar - whereweare;
1457                                 break;
1458                         case '[':
1459                                 nextexp = nextthing;
1460                                 pos = nextexp - whereweare;
1461                                 break;
1462                         }
1463                 }
1464
1465                 if (pos) {
1466                         /* Can't copy more than 'count' bytes */
1467                         if (pos > count)
1468                                 pos = count;
1469
1470                         /* Copy that many bytes */
1471                         memcpy(cp2, whereweare, pos);
1472
1473                         count -= pos;
1474                         cp2 += pos;
1475                         whereweare += pos;
1476                 }
1477
1478                 if (nextvar) {
1479                         /* We have a variable.  Find the start and end, and determine
1480                            if we are going to have to recursively call ourselves on the
1481                            contents */
1482                         vars = vare = nextvar + 2;
1483                         brackets = 1;
1484                         needsub = 0;
1485
1486                         /* Find the end of it */
1487                         while (brackets && *vare) {
1488                                 if ((vare[0] == '$') && (vare[1] == '{')) {
1489                                         needsub++;
1490                                 } else if (vare[0] == '{') {
1491                                         brackets++;
1492                                 } else if (vare[0] == '}') {
1493                                         brackets--;
1494                                 } else if ((vare[0] == '$') && (vare[1] == '['))
1495                                         needsub++;
1496                                 vare++;
1497                         }
1498                         if (brackets)
1499                                 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n");
1500                         len = vare - vars - 1;
1501
1502                         /* Skip totally over variable string */
1503                         whereweare += (len + 3);
1504
1505                         if (!var)
1506                                 var = alloca(VAR_BUF_SIZE);
1507
1508                         /* Store variable name (and truncate) */
1509                         ast_copy_string(var, vars, len + 1);
1510
1511                         /* Substitute if necessary */
1512                         if (needsub) {
1513                                 if (!ltmp)
1514                                         ltmp = alloca(VAR_BUF_SIZE);
1515
1516                                 memset(ltmp, 0, VAR_BUF_SIZE);
1517                                 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
1518                                 vars = ltmp;
1519                         } else {
1520                                 vars = var;
1521                         }
1522
1523                         if (!workspace)
1524                                 workspace = alloca(VAR_BUF_SIZE);
1525
1526                         workspace[0] = '\0';
1527
1528                         parse_variable_name(vars, &offset, &offset2, &isfunction);
1529                         if (isfunction) {
1530                                 /* Evaluate function */
1531                                 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
1532                                 if (option_debug)
1533                                         ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)");
1534                         } else {
1535                                 /* Retrieve variable value */
1536                                 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);
1537                         }
1538                         if (cp4) {
1539                                 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);
1540
1541                                 length = strlen(cp4);
1542                                 if (length > count)
1543                                         length = count;
1544                                 memcpy(cp2, cp4, length);
1545                                 count -= length;
1546                                 cp2 += length;
1547                         }
1548                 } else if (nextexp) {
1549                         /* We have an expression.  Find the start and end, and determine
1550                            if we are going to have to recursively call ourselves on the
1551                            contents */
1552                         vars = vare = nextexp + 2;
1553                         brackets = 1;
1554                         needsub = 0;
1555
1556                         /* Find the end of it */
1557                         while(brackets && *vare) {
1558                                 if ((vare[0] == '$') && (vare[1] == '[')) {
1559                                         needsub++;
1560                                         brackets++;
1561                                         vare++;
1562                                 } else if (vare[0] == '[') {
1563                                         brackets++;
1564                                 } else if (vare[0] == ']') {
1565                                         brackets--;
1566                                 } else if ((vare[0] == '$') && (vare[1] == '{')) {
1567                                         needsub++;
1568                                         vare++;
1569                                 }
1570                                 vare++;
1571                         }
1572                         if (brackets)
1573                                 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
1574                         len = vare - vars - 1;
1575
1576                         /* Skip totally over expression */
1577                         whereweare += (len + 3);
1578
1579                         if (!var)
1580                                 var = alloca(VAR_BUF_SIZE);
1581
1582                         /* Store variable name (and truncate) */
1583                         ast_copy_string(var, vars, len + 1);
1584
1585                         /* Substitute if necessary */
1586                         if (needsub) {
1587                                 if (!ltmp)
1588                                         ltmp = alloca(VAR_BUF_SIZE);
1589
1590                                 memset(ltmp, 0, VAR_BUF_SIZE);
1591                                 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
1592                                 vars = ltmp;
1593                         } else {
1594                                 vars = var;
1595                         }
1596
1597                         length = ast_expr(vars, cp2, count);
1598
1599                         if (length) {
1600                                 if (option_debug)
1601                                         ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2);
1602                                 count -= length;
1603                                 cp2 += length;
1604                         }
1605                 } else
1606                         break;
1607         }
1608 }
1609
1610 void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
1611 {
1612         pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
1613 }
1614
1615 void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count)
1616 {
1617         pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
1618 }
1619
1620 static void pbx_substitute_variables(char *passdata, int datalen, struct ast_channel *c, struct ast_exten *e)
1621 {
1622         memset(passdata, 0, datalen);
1623
1624         /* No variables or expressions in e->data, so why scan it? */
1625         if (!strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) {
1626                 ast_copy_string(passdata, e->data, datalen);
1627                 return;
1628         }
1629
1630         pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1);
1631 }
1632
1633 /*! \brief The return value depends on the action:
1634  *
1635  * E_MATCH, E_CANMATCH, E_MATCHMORE require a real match,
1636  *      and return 0 on failure, -1 on match;
1637  * E_FINDLABEL maps the label to a priority, and returns
1638  *      the priority on success, ... XXX
1639  * E_SPAWN, spawn an application,
1640  *      and return 0 on success, -1 on failure.
1641  */
1642 static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
1643         const char *context, const char *exten, int priority,
1644         const char *label, const char *callerid, enum ext_match_t action)
1645 {
1646         struct ast_exten *e;
1647         struct ast_app *app;
1648         int res;
1649         struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
1650         char passdata[EXT_DATA_SIZE];
1651
1652         int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
1653
1654         ast_mutex_lock(&conlock);
1655         e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
1656         if (e) {
1657                 if (matching_action) {
1658                         ast_mutex_unlock(&conlock);
1659                         return -1;      /* success, we found it */
1660                 } else if (action == E_FINDLABEL) { /* map the label to a priority */
1661                         res = e->priority;
1662                         ast_mutex_unlock(&conlock);
1663                         return res;     /* the priority we were looking for */
1664                 } else {        /* spawn */
1665                         if (!e->cached_app)
1666                                 e->cached_app = pbx_findapp(e->app);
1667                         app = e->cached_app;
1668                         ast_mutex_unlock(&conlock);
1669                         if (!app) {
1670                                 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
1671                                 return -1;
1672                         }
1673                         if (c->context != context)
1674                                 ast_copy_string(c->context, context, sizeof(c->context));
1675                         if (c->exten != exten)
1676                                 ast_copy_string(c->exten, exten, sizeof(c->exten));
1677                         c->priority = priority;
1678                         pbx_substitute_variables(passdata, sizeof(passdata), c, e);
1679                         if (option_debug) {
1680                                 char atmp[80];
1681                                 char atmp2[EXT_DATA_SIZE+100];
1682                                 if (option_debug)
1683                                         ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
1684                                 snprintf(atmp, sizeof(atmp), "STACK-%s-%s-%d", context, exten, priority);
1685                                 snprintf(atmp2, sizeof(atmp2), "%s(\"%s\", \"%s\") %s",
1686                                         app->name, c->name, passdata, "in new stack");
1687                                 pbx_builtin_setvar_helper(c, atmp, atmp2);
1688                         }
1689                         if (option_verbose > 2) {
1690                                 char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE];
1691                                 ast_verbose( VERBOSE_PREFIX_3 "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n",
1692                                         exten, context, priority,
1693                                         term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
1694                                         term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
1695                                         term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)),
1696                                         "in new stack");
1697                         }
1698                         manager_event(EVENT_FLAG_CALL, "Newexten",
1699                                         "Channel: %s\r\n"
1700                                         "Context: %s\r\n"
1701                                         "Extension: %s\r\n"
1702                                         "Priority: %d\r\n"
1703                                         "Application: %s\r\n"
1704                                         "AppData: %s\r\n"
1705                                         "Uniqueid: %s\r\n",
1706                                         c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid);
1707                         return pbx_exec(c, app, passdata);      /* 0 on success, -1 on failure */
1708                 }
1709         } else if (q.swo) {     /* not found here, but in another switch */
1710                 ast_mutex_unlock(&conlock);
1711                 if (matching_action)
1712                         return -1;
1713                 else {
1714                         if (!q.swo->exec) {
1715                                 ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
1716                                 res = -1;
1717                         }
1718                         return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
1719                 }
1720         } else {        /* not found anywhere, see what happened */
1721                 ast_mutex_unlock(&conlock);
1722                 switch (q.status) {
1723                 case STATUS_NO_CONTEXT:
1724                         if (!matching_action)
1725                                 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
1726                         break;
1727                 case STATUS_NO_EXTENSION:
1728                         if (!matching_action)
1729                                 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
1730                         break;
1731                 case STATUS_NO_PRIORITY:
1732                         if (!matching_action)
1733                                 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
1734                         break;
1735                 case STATUS_NO_LABEL:
1736                         if (context)
1737                                 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context);
1738                         break;
1739                 default:
1740                         if (option_debug)
1741                                 ast_log(LOG_DEBUG, "Shouldn't happen!\n");
1742                 }
1743
1744                 return (matching_action) ? 0 : -1;
1745         }
1746 }
1747
1748 /*! \brief  ast_hint_extension: Find hint for given extension in context */
1749 static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
1750 {
1751         struct ast_exten *e;
1752         struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
1753
1754         ast_mutex_lock(&conlock);
1755         e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH);
1756         ast_mutex_unlock(&conlock);
1757
1758         return e;
1759 }
1760
1761 /*! \brief  ast_extensions_state2: Check state of extension by using hints */
1762 static int ast_extension_state2(struct ast_exten *e)
1763 {
1764         char hint[AST_MAX_EXTENSION];
1765         char *cur, *rest;
1766         int allunavailable = 1, allbusy = 1, allfree = 1, allonhold = 1;
1767         int busy = 0, inuse = 0, ring = 0;
1768
1769         if (!e)
1770                 return -1;
1771
1772         ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint));
1773
1774         rest = hint;    /* One or more devices separated with a & character */
1775         while ( (cur = strsep(&rest, "&")) ) {
1776                 int res = ast_device_state(cur);
1777                 switch (res) {
1778                 case AST_DEVICE_NOT_INUSE:
1779                         allunavailable = 0;
1780                         allbusy = 0;
1781                         allonhold = 0;
1782                         break;
1783                 case AST_DEVICE_INUSE:
1784                         inuse = 1;
1785                         allunavailable = 0;
1786                         allfree = 0;
1787                         allonhold = 0;
1788                         break;
1789                 case AST_DEVICE_RINGING:
1790                         ring = 1;
1791                         allunavailable = 0;
1792                         allfree = 0;
1793                         allonhold = 0;
1794                         break;
1795                 case AST_DEVICE_RINGINUSE:
1796                         inuse = 1;
1797                         ring = 1;
1798                         allunavailable = 0;
1799                         allfree = 0;
1800                         allonhold = 0;
1801                         break;
1802                 case AST_DEVICE_ONHOLD:
1803                         allunavailable = 0;
1804                         allfree = 0;
1805                         break;
1806                 case AST_DEVICE_BUSY:
1807                         allunavailable = 0;
1808                         allfree = 0;
1809                         allonhold = 0;
1810                         busy = 1;
1811                         break;
1812                 case AST_DEVICE_UNAVAILABLE:
1813                 case AST_DEVICE_INVALID:
1814                         allbusy = 0;
1815                         allfree = 0;
1816                         allonhold = 0;
1817                         break;
1818                 default:
1819                         allunavailable = 0;
1820                         allbusy = 0;
1821                         allfree = 0;
1822                         allonhold = 0;
1823                 }
1824         }
1825
1826         if (!inuse && ring)
1827                 return AST_EXTENSION_RINGING;
1828         if (inuse && ring)
1829                 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
1830         if (inuse)
1831                 return AST_EXTENSION_INUSE;
1832         if (allfree)
1833                 return AST_EXTENSION_NOT_INUSE;
1834         if (allonhold)
1835                 return AST_EXTENSION_ONHOLD;
1836         if (allbusy)
1837                 return AST_EXTENSION_BUSY;
1838         if (allunavailable)
1839                 return AST_EXTENSION_UNAVAILABLE;
1840         if (busy)
1841                 return AST_EXTENSION_INUSE;
1842
1843         return AST_EXTENSION_NOT_INUSE;
1844 }
1845
1846 /*! \brief  ast_extension_state2str: Return extension_state as string */
1847 const char *ast_extension_state2str(int extension_state)
1848 {
1849         int i;
1850
1851         for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
1852                 if (extension_states[i].extension_state == extension_state)
1853                         return extension_states[i].text;
1854         }
1855         return "Unknown";
1856 }
1857
1858 /*! \brief  ast_extension_state: Check extension state for an extension by using hint */
1859 int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
1860 {
1861         struct ast_exten *e;
1862
1863         e = ast_hint_extension(c, context, exten);      /* Do we have a hint for this extension ? */
1864         if (!e)
1865                 return -1;                              /* No hint, return -1 */
1866
1867         return ast_extension_state2(e);                 /* Check all devices in the hint */
1868 }
1869
1870 void ast_hint_state_changed(const char *device)
1871 {
1872         struct ast_hint *hint;
1873
1874         AST_LIST_LOCK(&hints);
1875
1876         AST_LIST_TRAVERSE(&hints, hint, list) {
1877                 struct ast_state_cb *cblist;
1878                 char buf[AST_MAX_EXTENSION];
1879                 char *parse = buf;
1880                 char *cur;
1881                 int state;
1882
1883                 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
1884                 while ( (cur = strsep(&parse, "&")) ) {
1885                         if (!strcasecmp(cur, device))
1886                                 break;
1887                 }
1888                 if (!cur)
1889                         continue;
1890
1891                 /* Get device state for this hint */
1892                 state = ast_extension_state2(hint->exten);
1893
1894                 if ((state == -1) || (state == hint->laststate))
1895                         continue;
1896
1897                 /* Device state changed since last check - notify the watchers */
1898
1899                 /* For general callbacks */
1900                 for (cblist = statecbs; cblist; cblist = cblist->next)
1901                         cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
1902
1903                 /* For extension callbacks */
1904                 for (cblist = hint->callbacks; cblist; cblist = cblist->next)
1905                         cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
1906
1907                 hint->laststate = state;        /* record we saw the change */
1908         }
1909
1910         AST_LIST_UNLOCK(&hints);
1911 }
1912
1913 /*! \brief  ast_extension_state_add: Add watcher for extension states */
1914 int ast_extension_state_add(const char *context, const char *exten,
1915                             ast_state_cb_type callback, void *data)
1916 {
1917         struct ast_hint *hint;
1918         struct ast_state_cb *cblist;
1919         struct ast_exten *e;
1920
1921         /* If there's no context and extension:  add callback to statecbs list */
1922         if (!context && !exten) {
1923                 AST_LIST_LOCK(&hints);
1924
1925                 for (cblist = statecbs; cblist; cblist = cblist->next) {
1926                         if (cblist->callback == callback) {
1927                                 cblist->data = data;
1928                                 AST_LIST_UNLOCK(&hints);
1929                                 return 0;
1930                         }
1931                 }
1932
1933                 /* Now insert the callback */
1934                 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
1935                         AST_LIST_UNLOCK(&hints);
1936                         return -1;
1937                 }
1938                 cblist->id = 0;
1939                 cblist->callback = callback;
1940                 cblist->data = data;
1941
1942                 cblist->next = statecbs;
1943                 statecbs = cblist;
1944
1945                 AST_LIST_UNLOCK(&hints);
1946                 return 0;
1947         }
1948
1949         if (!context || !exten)
1950                 return -1;
1951
1952         /* This callback type is for only one hint, so get the hint */
1953         e = ast_hint_extension(NULL, context, exten);
1954         if (!e) {
1955                 return -1;
1956         }
1957
1958         /* Find the hint in the list of hints */
1959         AST_LIST_LOCK(&hints);
1960
1961         AST_LIST_TRAVERSE(&hints, hint, list) {
1962                 if (hint->exten == e)
1963                         break;
1964         }
1965
1966         if (!hint) {
1967                 /* We have no hint, sorry */
1968                 AST_LIST_UNLOCK(&hints);
1969                 return -1;
1970         }
1971
1972         /* Now insert the callback in the callback list  */
1973         if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
1974                 AST_LIST_UNLOCK(&hints);
1975                 return -1;
1976         }
1977         cblist->id = stateid++;         /* Unique ID for this callback */
1978         cblist->callback = callback;    /* Pointer to callback routine */
1979         cblist->data = data;            /* Data for the callback */
1980
1981         cblist->next = hint->callbacks;
1982         hint->callbacks = cblist;
1983
1984         AST_LIST_UNLOCK(&hints);
1985         return cblist->id;
1986 }
1987
1988 /*! \brief  ast_extension_state_del: Remove a watcher from the callback list */
1989 int ast_extension_state_del(int id, ast_state_cb_type callback)
1990 {
1991         struct ast_state_cb **p_cur = NULL;     /* address of pointer to us */
1992         int ret = -1;
1993
1994         if (!id && !callback)
1995                 return -1;
1996
1997         AST_LIST_LOCK(&hints);
1998
1999         if (!id) {      /* id == 0 is a callback without extension */
2000                 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
2001                         if ((*p_cur)->callback == callback)
2002                                 break;
2003                 }
2004         } else { /* callback with extension, find the callback based on ID */
2005                 struct ast_hint *hint;
2006                 AST_LIST_TRAVERSE(&hints, hint, list) {
2007                         for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
2008                                 if ((*p_cur)->id == id)
2009                                         break;
2010                         }
2011                         if (*p_cur)     /* found in the inner loop */
2012                                 break;
2013                 }
2014         }
2015         if (p_cur && *p_cur) {
2016                 struct ast_state_cb *cur = *p_cur;
2017                 *p_cur = cur->next;
2018                 free(cur);
2019                 ret = 0;
2020         }
2021         AST_LIST_UNLOCK(&hints);
2022         return ret;
2023 }
2024
2025 /*! \brief  ast_add_hint: Add hint to hint list, check initial extension state */
2026 static int ast_add_hint(struct ast_exten *e)
2027 {
2028         struct ast_hint *hint;
2029
2030         if (!e)
2031                 return -1;
2032
2033         AST_LIST_LOCK(&hints);
2034
2035         /* Search if hint exists, do nothing */
2036         AST_LIST_TRAVERSE(&hints, hint, list) {
2037                 if (hint->exten == e) {
2038                         AST_LIST_UNLOCK(&hints);
2039                         if (option_debug > 1)
2040                                 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
2041                         return -1;
2042                 }
2043         }
2044
2045         if (option_debug > 1)
2046                 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
2047
2048         if (!(hint = ast_calloc(1, sizeof(*hint)))) {
2049                 AST_LIST_UNLOCK(&hints);
2050                 return -1;
2051         }
2052         /* Initialize and insert new item at the top */
2053         hint->exten = e;
2054         hint->laststate = ast_extension_state2(e);
2055         AST_LIST_INSERT_HEAD(&hints, hint, list);
2056
2057         AST_LIST_UNLOCK(&hints);
2058         return 0;
2059 }
2060
2061 /*! \brief  ast_change_hint: Change hint for an extension */
2062 static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
2063 {
2064         struct ast_hint *hint;
2065         int res = -1;
2066
2067         AST_LIST_LOCK(&hints);
2068         AST_LIST_TRAVERSE(&hints, hint, list) {
2069                 if (hint->exten == oe) {
2070                         hint->exten = ne;
2071                         res = 0;
2072                         break;
2073                 }
2074         }
2075         AST_LIST_UNLOCK(&hints);
2076
2077         return res;
2078 }
2079
2080 /*! \brief  ast_remove_hint: Remove hint from extension */
2081 static int ast_remove_hint(struct ast_exten *e)
2082 {
2083         /* Cleanup the Notifys if hint is removed */
2084         struct ast_hint *hint;
2085         struct ast_state_cb *cblist, *cbprev;
2086         int res = -1;
2087
2088         if (!e)
2089                 return -1;
2090
2091         AST_LIST_LOCK(&hints);
2092         AST_LIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) {
2093                 if (hint->exten == e) {
2094                         cbprev = NULL;
2095                         cblist = hint->callbacks;
2096                         while (cblist) {
2097                                 /* Notify with -1 and remove all callbacks */
2098                                 cbprev = cblist;
2099                                 cblist = cblist->next;
2100                                 cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data);
2101                                 free(cbprev);
2102                         }
2103                         hint->callbacks = NULL;
2104                         AST_LIST_REMOVE_CURRENT(&hints, list);
2105                         free(hint);
2106                         res = 0;
2107                         break;
2108                 }
2109         }
2110         AST_LIST_TRAVERSE_SAFE_END
2111         AST_LIST_UNLOCK(&hints);
2112
2113         return res;
2114 }
2115
2116
2117 /*! \brief  ast_get_hint: Get hint for channel */
2118 int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
2119 {
2120         struct ast_exten *e = ast_hint_extension(c, context, exten);
2121
2122         if (e) {
2123                 if (hint)
2124                         ast_copy_string(hint, ast_get_extension_app(e), hintsize);
2125                 if (name) {
2126                         const char *tmp = ast_get_extension_app_data(e);
2127                         if (tmp)
2128                                 ast_copy_string(name, tmp, namesize);
2129                 }
2130                 return -1;
2131         }
2132         return 0;
2133 }
2134
2135 int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
2136 {
2137         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
2138 }
2139
2140 int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
2141 {
2142         return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
2143 }
2144
2145 int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
2146 {
2147         return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
2148 }
2149
2150 int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
2151 {
2152         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
2153 }
2154
2155 int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
2156 {
2157         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
2158 }
2159
2160 int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
2161 {
2162         return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
2163 }
2164
2165 /* helper function to set extension and priority */
2166 static void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
2167 {
2168         ast_copy_string(c->exten, exten, sizeof(c->exten));
2169         c->priority = pri;
2170 }
2171
2172 /*!
2173  * \brief collect digits from the channel into the buffer,
2174  * return -1 on error, 0 on timeout or done.
2175  */
2176 static int collect_digits(struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
2177 {
2178         int digit;
2179
2180         buf[pos] = '\0';        /* make sure it is properly terminated */
2181         while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) {
2182                 /* As long as we're willing to wait, and as long as it's not defined,
2183                    keep reading digits until we can't possibly get a right answer anymore.  */
2184                 digit = ast_waitfordigit(c, waittime * 1000);
2185                 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
2186                         c->_softhangup = 0;
2187                 } else {
2188                         if (!digit)     /* No entry */
2189                                 break;
2190                         if (digit < 0)  /* Error, maybe a  hangup */
2191                                 return -1;
2192                         if (pos < buflen - 1) { /* XXX maybe error otherwise ? */
2193                                 buf[pos++] = digit;
2194                                 buf[pos] = '\0';
2195                         }
2196                         waittime = c->pbx->dtimeout;
2197                 }
2198         }
2199         return 0;
2200 }
2201
2202 static int __ast_pbx_run(struct ast_channel *c)
2203 {
2204         int found = 0;  /* set if we find at least one match */
2205         int res = 0;
2206         int autoloopflag;
2207         int error = 0;          /* set an error conditions */
2208
2209         /* A little initial setup here */
2210         if (c->pbx) {
2211                 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
2212                 /* XXX and now what ? */
2213                 free(c->pbx);
2214         }
2215         if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx))))
2216                 return -1;
2217         if (c->amaflags) {
2218                 if (!c->cdr) {
2219                         c->cdr = ast_cdr_alloc();
2220                         if (!c->cdr) {
2221                                 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
2222                                 free(c->pbx);
2223                                 return -1;
2224                         }
2225                         ast_cdr_init(c->cdr, c);
2226                 }
2227         }
2228         /* Set reasonable defaults */
2229         c->pbx->rtimeout = 10;
2230         c->pbx->dtimeout = 5;
2231
2232         autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP);  /* save value to restore at the end */
2233         ast_set_flag(c, AST_FLAG_IN_AUTOLOOP);
2234
2235         /* Start by trying whatever the channel is set to */
2236         if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
2237                 /* If not successful fall back to 's' */
2238                 if (option_verbose > 1)
2239                         ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
2240                 /* XXX the original code used the existing priority in the call to
2241                  * ast_exists_extension(), and reset it to 1 afterwards.
2242                  * I believe the correct thing is to set it to 1 immediately.
2243                  */
2244                 set_ext_pri(c, "s", 1);
2245                 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
2246                         /* JK02: And finally back to default if everything else failed */
2247                         if (option_verbose > 1)
2248                                 ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
2249                         ast_copy_string(c->context, "default", sizeof(c->context));
2250                 }
2251         }
2252         if (c->cdr && ast_tvzero(c->cdr->start))
2253                 ast_cdr_start(c->cdr);
2254         for (;;) {
2255                 char dst_exten[256];    /* buffer to accumulate digits */
2256                 int pos = 0;            /* XXX should check bounds */
2257                 int digit = 0;
2258
2259                 /* loop on priorities in this context/exten */
2260                 while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
2261                         found = 1;
2262                         if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
2263                                 /* Something bad happened, or a hangup has been requested. */
2264                                 if (strchr("0123456789ABCDEF*#", res)) {
2265                                         if (option_debug)
2266                                                 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
2267                                         pos = 0;
2268                                         dst_exten[pos++] = digit = res;
2269                                         dst_exten[pos] = '\0';
2270                                         break;
2271                                 }
2272                                 if (res == AST_PBX_KEEPALIVE) {
2273                                         if (option_debug)
2274                                                 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
2275                                         if (option_verbose > 1)
2276                                                 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
2277                                         error = 1;
2278                                         break;
2279                                 }
2280                                 if (option_debug)
2281                                         ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2282                                 if (option_verbose > 1)
2283                                         ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2284                                 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
2285                                         c->_softhangup =0;
2286                                 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
2287                                         /* atimeout, nothing bad */
2288                                 } else {
2289                                         if (c->cdr)
2290                                                 ast_cdr_update(c);
2291                                         error = 1;
2292                                         break;
2293                                 }
2294                         }
2295                         if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c,c->context,"T",1,c->cid.cid_num)) {
2296                                 set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */
2297                                 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
2298                                 c->whentohangup = 0;
2299                                 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
2300                         } else if (c->_softhangup) {
2301                                 if (option_debug)
2302                                         ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
2303                                                 c->exten, c->priority);
2304                                 error = 1;
2305                                 break;
2306                         }
2307                         c->priority++;
2308                 } /* end while  - from here on we can use 'break' to go out */
2309                 if (error)
2310                         break;
2311
2312                 /* XXX we get here on non-existing extension or a keypress or hangup ? */
2313
2314                 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
2315                         /* If there is no match at priority 1, it is not a valid extension anymore.
2316                          * Try to continue at "i", 1 or exit if the latter does not exist.
2317                          */
2318                         if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
2319                                 if (option_verbose > 2)
2320                                         ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
2321                                 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
2322                                 set_ext_pri(c, "i", 1);
2323                         } else {
2324                                 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
2325                                         c->name, c->exten, c->context);
2326                                 error = 1; /* we know what to do with it */
2327                                 break;
2328                         }
2329                 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
2330                         /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
2331                         c->_softhangup = 0;
2332                 } else {        /* keypress received, get more digits for a full extension */
2333                         int waittime = 0;
2334                         if (digit)
2335                                 waittime = c->pbx->dtimeout;
2336                         else if (!autofallthrough)
2337                                 waittime = c->pbx->rtimeout;
2338                         if (!waittime) {
2339                                 const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
2340                                 if (!status)
2341                                         status = "UNKNOWN";
2342                                 if (option_verbose > 2)
2343                                         ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status);
2344                                 if (!strcasecmp(status, "CONGESTION"))
2345                                         res = pbx_builtin_congestion(c, "10");
2346                                 else if (!strcasecmp(status, "CHANUNAVAIL"))
2347                                         res = pbx_builtin_congestion(c, "10");
2348                                 else if (!strcasecmp(status, "BUSY"))
2349                                         res = pbx_builtin_busy(c, "10");
2350                                 error = 1; /* XXX disable message */
2351                                 break;  /* exit from the 'for' loop */
2352                         }
2353
2354                         if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos))
2355                                 break;
2356                         if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */
2357                                 set_ext_pri(c, dst_exten, 1);
2358                         else {
2359                                 /* No such extension */
2360                                 if (!ast_strlen_zero(dst_exten)) {
2361                                         /* An invalid extension */
2362                                         if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
2363                                                 if (option_verbose > 2)
2364                                                         ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name);
2365                                                 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
2366                                                 set_ext_pri(c, "i", 1);
2367                                         } else {
2368                                                 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context);
2369                                                 found = 1; /* XXX disable message */
2370                                                 break;
2371                                         }
2372                                 } else {
2373                                         /* A simple timeout */
2374                                         if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) {
2375                                                 if (option_verbose > 2)
2376                                                         ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
2377                                                 set_ext_pri(c, "t", 1);
2378                                         } else {
2379                                                 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
2380                                                 found = 1; /* XXX disable message */
2381                                                 break;
2382                                         }
2383                                 }
2384                         }
2385                         if (c->cdr) {
2386                                 if (option_verbose > 2)
2387                                         ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name);
2388                                 ast_cdr_update(c);
2389                         }
2390                 }
2391         }
2392         if (!found && !error)
2393                 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
2394         if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
2395                 if (c->cdr && ast_opt_end_cdr_before_h_exten)
2396                         ast_cdr_end(c->cdr);
2397                 set_ext_pri(c, "h", 1);
2398                 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
2399                         if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
2400                                 /* Something bad happened, or a hangup has been requested. */
2401                                 if (option_debug)
2402                                         ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2403                                 if (option_verbose > 1)
2404                                         ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
2405                                 break;
2406                         }
2407                         c->priority++;
2408                 }
2409         }
2410         ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP);
2411
2412         pbx_destroy(c->pbx);
2413         c->pbx = NULL;
2414         if (res != AST_PBX_KEEPALIVE)
2415                 ast_hangup(c);
2416         return 0;
2417 }
2418
2419 /* Returns 0 on success, non-zero if call limit was reached */
2420 static int increase_call_count(const struct ast_channel *c)
2421 {
2422         int failed = 0;
2423         double curloadavg;
2424         ast_mutex_lock(&maxcalllock);
2425         if (option_maxcalls) {
2426                 if (countcalls >= option_maxcalls) {
2427                         ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name);
2428                         failed = -1;
2429                 }
2430         }
2431         if (option_maxload) {
2432                 getloadavg(&curloadavg, 1);
2433                 if (curloadavg >= option_maxload) {
2434                         ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg);
2435                         failed = -1;
2436                 }
2437         }
2438         if (!failed)
2439                 countcalls++;
2440         ast_mutex_unlock(&maxcalllock);
2441
2442         return failed;
2443 }
2444
2445 static void decrease_call_count(void)
2446 {
2447         ast_mutex_lock(&maxcalllock);
2448         if (countcalls > 0)
2449                 countcalls--;
2450         ast_mutex_unlock(&maxcalllock);
2451 }
2452
2453 static void destroy_exten(struct ast_exten *e)
2454 {
2455         if (e->priority == PRIORITY_HINT)
2456                 ast_remove_hint(e);
2457
2458         if (e->datad)
2459                 e->datad(e->data);
2460         free(e);
2461 }
2462
2463 static void *pbx_thread(void *data)
2464 {
2465         /* Oh joyeous kernel, we're a new thread, with nothing to do but
2466            answer this channel and get it going.
2467         */
2468         /* NOTE:
2469            The launcher of this function _MUST_ increment 'countcalls'
2470            before invoking the function; it will be decremented when the
2471            PBX has finished running on the channel
2472          */
2473         struct ast_channel *c = data;
2474
2475         __ast_pbx_run(c);
2476         decrease_call_count();
2477
2478         pthread_exit(NULL);
2479
2480         return NULL;
2481 }
2482
2483 enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
2484 {
2485         pthread_t t;
2486         pthread_attr_t attr;
2487
2488         if (!c) {
2489                 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
2490                 return AST_PBX_FAILED;
2491         }
2492
2493         if (increase_call_count(c))
2494                 return AST_PBX_CALL_LIMIT;
2495
2496         /* Start a new thread, and get something handling this channel. */
2497         pthread_attr_init(&attr);
2498         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2499         if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
2500                 ast_log(LOG_WARNING, "Failed to create new channel thread\n");
2501                 return AST_PBX_FAILED;
2502         }
2503
2504         return AST_PBX_SUCCESS;
2505 }
2506
2507 enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
2508 {
2509         enum ast_pbx_result res = AST_PBX_SUCCESS;
2510
2511         if (increase_call_count(c))
2512                 return AST_PBX_CALL_LIMIT;
2513
2514         res = __ast_pbx_run(c);
2515         decrease_call_count();
2516
2517         return res;
2518 }
2519
2520 int ast_active_calls(void)
2521 {
2522         return countcalls;
2523 }
2524
2525 int pbx_set_autofallthrough(int newval)
2526 {
2527         int oldval = autofallthrough;
2528         autofallthrough = newval;
2529         return oldval;
2530 }
2531
2532 /* lookup for a context with a given name,
2533  * return with conlock held if found, NULL if not found
2534  */
2535 static struct ast_context *find_context_locked(const char *context)
2536 {
2537         struct ast_context *c = NULL;
2538
2539         ast_lock_contexts();
2540         while ( (c = ast_walk_contexts(c)) ) {
2541                 if (!strcmp(ast_get_context_name(c), context))
2542                         return c;
2543         }
2544         ast_unlock_contexts();
2545
2546         return NULL;
2547 }
2548
2549 /*
2550  * This function locks contexts list by &conlist, search for the right context
2551  * structure, leave context list locked and call ast_context_remove_include2
2552  * which removes include, unlock contexts list and return ...
2553  */
2554 int ast_context_remove_include(const char *context, const char *include, const char *registrar)
2555 {
2556         int ret = -1;
2557         struct ast_context *c = find_context_locked(context);
2558
2559         if (c) {
2560                 /* found, remove include from this context ... */
2561                 ret = ast_context_remove_include2(c, include, registrar);
2562                 ast_unlock_contexts();
2563         }
2564         return ret;
2565 }
2566
2567 /*
2568  * When we call this function, &conlock lock must be locked, because when
2569  * we giving *con argument, some process can remove/change this context
2570  * and after that there can be segfault.
2571  *
2572  * This function locks given context, removes include, unlock context and
2573  * return.
2574  */
2575 int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
2576 {
2577         struct ast_include *i, *pi = NULL;
2578         int ret = -1;
2579
2580         ast_mutex_lock(&con->lock);
2581
2582         /* find our include */
2583         for (i = con->includes; i; pi = i, i = i->next) {
2584                 if (!strcmp(i->name, include) &&
2585                                 (!registrar || !strcmp(i->registrar, registrar))) {
2586                         /* remove from list */
2587                         if (pi)
2588                                 pi->next = i->next;
2589                         else
2590                                 con->includes = i->next;
2591                         /* free include and return */
2592                         free(i);
2593                         ret = 0;
2594                         break;
2595                 }
2596         }
2597
2598         ast_mutex_unlock(&con->lock);
2599         return ret;
2600 }
2601
2602 /*!
2603  * \note This function locks contexts list by &conlist, search for the rigt context
2604  * structure, leave context list locked and call ast_context_remove_switch2
2605  * which removes switch, unlock contexts list and return ...
2606  */
2607 int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar)
2608 {
2609         int ret = -1; /* default error return */
2610         struct ast_context *c = find_context_locked(context);
2611
2612         if (c) {
2613                 /* remove switch from this context ... */
2614                 ret = ast_context_remove_switch2(c, sw, data, registrar);
2615                 ast_unlock_contexts();
2616         }
2617         return ret;
2618 }
2619
2620 /*!
2621  * \brief This function locks given context, removes switch, unlock context and
2622  * return.
2623  * \note When we call this function, &conlock lock must be locked, because when
2624  * we giving *con argument, some process can remove/change this context
2625  * and after that there can be segfault.
2626  *
2627  */
2628 int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
2629 {
2630         struct ast_sw *i;
2631         int ret = -1;
2632
2633         ast_mutex_lock(&con->lock);
2634
2635         /* walk switches */
2636         AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
2637                 if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
2638                         (!registrar || !strcmp(i->registrar, registrar))) {
2639                         /* found, remove from list */
2640                         AST_LIST_REMOVE_CURRENT(&con->alts, list);
2641                         free(i); /* free switch and return */
2642                         ret = 0;
2643                         break;
2644                 }
2645         }
2646         AST_LIST_TRAVERSE_SAFE_END
2647
2648         ast_mutex_unlock(&con->lock);
2649
2650         return ret;
2651 }
2652
2653 /*
2654  * \note This functions lock contexts list, search for the right context,
2655  * call ast_context_remove_extension2, unlock contexts list and return.
2656  * In this function we are using
2657  */
2658 int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
2659 {
2660         int ret = -1; /* default error return */
2661         struct ast_context *c = find_context_locked(context);
2662
2663         if (c) { /* ... remove extension ... */
2664                 ret = ast_context_remove_extension2(c, extension, priority, registrar);
2665                 ast_unlock_contexts();
2666         }
2667         return ret;
2668 }
2669
2670 /*!
2671  * \brief This functionc locks given context, search for the right extension and
2672  * fires out all peer in this extensions with given priority. If priority
2673  * is set to 0, all peers are removed. After that, unlock context and
2674  * return.
2675  * \note When do you want to call this function, make sure that &conlock is locked,
2676  * because some process can handle with your *con context before you lock
2677  * it.
2678  *
2679  */
2680 int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar)
2681 {
2682         struct ast_exten *exten, *prev_exten = NULL;
2683         struct ast_exten *peer;
2684
2685         ast_mutex_lock(&con->lock);
2686
2687         /* scan the extension list to find matching extension-registrar */
2688         for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
2689                 if (!strcmp(exten->exten, extension) &&
2690                         (!registrar || !strcmp(exten->registrar, registrar)))
2691                         break;
2692         }
2693         if (!exten) {
2694                 /* we can't find right extension */
2695                 ast_mutex_unlock(&con->lock);
2696                 return -1;
2697         }
2698
2699         /* should we free all peers in this extension? (priority == 0)? */
2700         if (priority == 0) {
2701                 /* remove this extension from context list */
2702                 if (prev_exten)
2703                         prev_exten->next = exten->next;
2704                 else
2705                         con->root = exten->next;
2706
2707                 /* fire out all peers */
2708                 while ( (peer = exten) ) {
2709                         exten = peer->peer; /* prepare for next entry */
2710                         destroy_exten(peer);
2711                 }
2712         } else {
2713                 /* scan the priority list to remove extension with exten->priority == priority */
2714                 struct ast_exten *previous_peer = NULL;
2715
2716                 for (peer = exten; peer; previous_peer = peer, peer = peer->peer) {
2717                         if (peer->priority == priority &&
2718                                         (!registrar || !strcmp(peer->registrar, registrar) ))
2719                                 break; /* found our priority */
2720                 }
2721                 if (!peer) { /* not found */
2722                         ast_mutex_unlock(&con->lock);
2723                         return -1;
2724                 }
2725                 /* we are first priority extension? */
2726                 if (!previous_peer) {
2727                         /*
2728                          * We are first in the priority chain, so must update the extension chain.
2729                          * The next node is either the next priority or the next extension
2730                          */
2731                         struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
2732
2733                         if (!prev_exten)        /* change the root... */
2734                                 con->root = next_node;
2735                         else
2736                                 prev_exten->next = next_node; /* unlink */
2737                         if (peer->peer) /* XXX update the new head of the pri list */
2738                                 peer->peer->next = peer->next;
2739                 } else { /* easy, we are not first priority in extension */
2740                         previous_peer->peer = peer->peer;
2741                 }
2742
2743                 /* now, free whole priority extension */
2744                 destroy_exten(peer);
2745                 /* XXX should we return -1 ? */
2746         }
2747         ast_mutex_unlock(&con->lock);
2748         return 0;
2749 }
2750
2751
2752 /*!
2753  * \note This function locks contexts list by &conlist, searches for the right context
2754  * structure, and locks the macrolock mutex in that context.
2755  * macrolock is used to limit a macro to be executed by one call at a time.
2756  */
2757 int ast_context_lockmacro(const char *context)
2758 {
2759         struct ast_context *c = NULL;
2760         int ret = -1;
2761
2762         ast_lock_contexts();
2763
2764         while ((c = ast_walk_contexts(c))) {
2765                 if (!strcmp(ast_get_context_name(c), context)) {
2766                         ret = 0;
2767                         break;
2768                 }
2769         }
2770
2771         ast_unlock_contexts();
2772
2773         /* if we found context, lock macrolock */
2774         if (ret == 0) 
2775                 ret = ast_mutex_lock(&c->macrolock);
2776
2777         return ret;
2778 }
2779
2780 /*!
2781  * \note This function locks contexts list by &conlist, searches for the right context
2782  * structure, and unlocks the macrolock mutex in that context.
2783  * macrolock is used to limit a macro to be executed by one call at a time.
2784  */
2785 int ast_context_unlockmacro(const char *context)
2786 {
2787         struct ast_context *c = NULL;
2788         int ret = -1;
2789
2790         ast_lock_contexts();
2791
2792         while ((c = ast_walk_contexts(c))) {
2793                 if (!strcmp(ast_get_context_name(c), context)) {
2794                         ret = 0;
2795                         break;
2796                 }
2797         }
2798
2799         ast_unlock_contexts();
2800
2801         /* if we found context, unlock macrolock */
2802         if (ret == 0) 
2803                 ret = ast_mutex_unlock(&c->macrolock);
2804
2805         return ret;
2806 }
2807
2808 /*! \brief Dynamically register a new dial plan application */
2809 int ast_register_application(const char *app, int (*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
2810 {
2811         struct ast_app *tmp, *cur = NULL;
2812         char tmps[80];
2813         int length;
2814
2815         AST_LIST_LOCK(&apps);
2816         AST_LIST_TRAVERSE(&apps, tmp, list) {
2817                 if (!strcasecmp(app, tmp->name)) {
2818                         ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
2819                         AST_LIST_UNLOCK(&apps);
2820                         return -1;
2821                 }
2822         }
2823
2824         length = sizeof(*tmp) + strlen(app) + 1;
2825
2826         if (!(tmp = ast_calloc(1, length))) {
2827                 AST_LIST_UNLOCK(&apps);
2828                 return -1;
2829         }
2830
2831         strcpy(tmp->name, app);
2832         tmp->execute = execute;
2833         tmp->synopsis = synopsis;
2834         tmp->description = description;
2835
2836         /* Store in alphabetical order */
2837         AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
2838                 if (strcasecmp(tmp->name, cur->name) < 0) {
2839                         AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list);
2840                         break;
2841                 }
2842         }
2843         AST_LIST_TRAVERSE_SAFE_END
2844         if (!cur)
2845                 AST_LIST_INSERT_TAIL(&apps, tmp, list);
2846
2847         if (option_verbose > 1)
2848                 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
2849
2850         AST_LIST_UNLOCK(&apps);
2851
2852         return 0;
2853 }
2854
2855 /*
2856  * Append to the list. We don't have a tail pointer because we need
2857  * to scan the list anyways to check for duplicates during insertion.
2858  */
2859 int ast_register_switch(struct ast_switch *sw)
2860 {
2861         struct ast_switch *tmp;
2862
2863         AST_LIST_LOCK(&switches);
2864         AST_LIST_TRAVERSE(&switches, tmp, list) {
2865                 if (!strcasecmp(tmp->name, sw->name)) {
2866                         AST_LIST_UNLOCK(&switches);
2867                         ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
2868                         return -1;
2869                 }
2870         }
2871         AST_LIST_INSERT_TAIL(&switches, sw, list);
2872         AST_LIST_UNLOCK(&switches);
2873
2874         return 0;
2875 }
2876
2877 void ast_unregister_switch(struct ast_switch *sw)
2878 {
2879         AST_LIST_LOCK(&switches);
2880         AST_LIST_REMOVE(&switches, sw, list);
2881         AST_LIST_UNLOCK(&switches);
2882 }
2883
2884 /*
2885  * Help for CLI commands ...
2886  */
2887 static char show_applications_help[] =
2888 "Usage: core list applications [{like|describing} <text>]\n"
2889 "       List applications which are currently available.\n"
2890 "       If 'like', <text> will be a substring of the app name\n"
2891 "       If 'describing', <text> will be a substring of the description\n";
2892
2893 static char show_functions_help[] =
2894 "Usage: core list functions [like <text>]\n"
2895 "       List builtin functions, optionally only those matching a given string\n";
2896
2897 static char show_switches_help[] =
2898 "Usage: core list switches\n"
2899 "       List registered switches\n";
2900
2901 static char show_hints_help[] =
2902 "Usage: core list hints\n"
2903 "       List registered hints\n";
2904
2905 static char show_globals_help[] =
2906 "Usage: core list globals\n"
2907 "       List current global dialplan variables and their values\n";
2908
2909 static char show_application_help[] =
2910 "Usage: core show application <application> [<application> [<application> [...]]]\n"
2911 "       Describes a particular application.\n";
2912
2913 static char show_function_help[] =
2914 "Usage: core show function <function>\n"
2915 "       Describe a particular dialplan function.\n";
2916
2917 static char show_dialplan_help[] =
2918 "Usage: dialplan show [exten@][context]\n"
2919 "       Show dialplan\n";
2920
2921 static char set_global_help[] =
2922 "Usage: core set global <name> <value>\n"
2923 "       Set global dialplan variable <name> to <value>\n";
2924
2925
2926 /*
2927  * \brief 'show application' CLI command implementation functions ...
2928  */
2929
2930 /*
2931  * There is a possibility to show informations about more than one
2932  * application at one time. You can type 'show application Dial Echo' and
2933  * you will see informations about these two applications ...
2934  */
2935 static char *complete_show_application(const char *line, const char *word, int pos, int state)
2936 {
2937         struct ast_app *a;
2938         char *ret = NULL;
2939         int which = 0;
2940         int wordlen = strlen(word);
2941
2942         /* return the n-th [partial] matching entry */
2943         AST_LIST_LOCK(&apps);
2944         AST_LIST_TRAVERSE(&apps, a, list) {
2945                 if (!strncasecmp(word, a->name, wordlen) && ++which > state) {
2946                         ret = strdup(a->name);
2947                         break;
2948                 }
2949         }
2950         AST_LIST_UNLOCK(&apps);
2951
2952         return ret;
2953 }
2954
2955 static int handle_show_application(int fd, int argc, char *argv[])
2956 {
2957         struct ast_app *a;
2958         int app, no_registered_app = 1;
2959
2960         if (argc < 4)
2961                 return RESULT_SHOWUSAGE;
2962
2963         /* ... go through all applications ... */
2964         AST_LIST_LOCK(&apps);
2965         AST_LIST_TRAVERSE(&apps, a, list) {
2966                 /* ... compare this application name with all arguments given
2967                  * to 'show application' command ... */
2968                 for (app = 3; app < argc; app++) {
2969                         if (!strcasecmp(a->name, argv[app])) {
2970                                 /* Maximum number of characters added by terminal coloring is 22 */
2971                                 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
2972                                 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
2973                                 int synopsis_size, description_size;
2974
2975                                 no_registered_app = 0;
2976
2977                                 if (a->synopsis)
2978                                         synopsis_size = strlen(a->synopsis) + 23;
2979                                 else
2980                                         synopsis_size = strlen("Not available") + 23;
2981                                 synopsis = alloca(synopsis_size);
2982
2983                                 if (a->description)
2984                                         description_size = strlen(a->description) + 23;
2985                                 else
2986                                         description_size = strlen("Not available") + 23;
2987                                 description = alloca(description_size);
2988
2989                                 if (synopsis && description) {
2990                                         snprintf(info, 64 + AST_MAX_APP, "\n  -= Info about application '%s' =- \n\n", a->name);
2991                                         term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
2992                                         term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
2993                                         term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
2994                                         term_color(synopsis,
2995                                                                         a->synopsis ? a->synopsis : "Not available",
2996                                                                         COLOR_CYAN, 0, synopsis_size);
2997                                         term_color(description,
2998                                                                         a->description ? a->description : "Not available",
2999                                                                         COLOR_CYAN, 0, description_size);
3000
3001                                         ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description);
3002                                 } else {
3003                                         /* ... one of our applications, show info ...*/
3004                                         ast_cli(fd,"\n  -= Info about application '%s' =- \n\n"
3005                                                 "[Synopsis]\n  %s\n\n"
3006                                                 "[Description]\n%s\n",
3007                                                 a->name,
3008                                                 a->synopsis ? a->synopsis : "Not available",
3009                                                 a->description ? a->description : "Not available");
3010                                 }
3011                         }
3012                 }
3013         }
3014         AST_LIST_UNLOCK(&apps);
3015
3016         /* we found at least one app? no? */
3017         if (no_registered_app) {
3018                 ast_cli(fd, "Your application(s) is (are) not registered\n");
3019                 return RESULT_FAILURE;
3020         }
3021
3022         return RESULT_SUCCESS;
3023 }
3024
3025 /*! \brief  handle_show_hints: CLI support for listing registered dial plan hints */
3026 static int handle_show_hints(int fd, int argc, char *argv[])
3027 {
3028         struct ast_hint *hint;
3029         int num = 0;
3030         int watchers;
3031         struct ast_state_cb *watcher;
3032
3033         if (AST_LIST_EMPTY(&hints)) {
3034                 ast_cli(fd, "There are no registered dialplan hints\n");
3035                 return RESULT_SUCCESS;
3036         }
3037         /* ... we have hints ... */
3038         ast_cli(fd, "\n    -= Registered Asterisk Dial Plan Hints =-\n");
3039         AST_LIST_LOCK(&hints);
3040         AST_LIST_TRAVERSE(&hints, hint, list) {
3041                 watchers = 0;
3042                 for (watcher = hint->callbacks; watcher; watcher = watcher->next)
3043                         watchers++;
3044                 ast_cli(fd, "   %20s@%-20.20s: %-20.20s  State:%-15.15s Watchers %2d\n",
3045                         ast_get_extension_name(hint->exten),
3046                         ast_get_context_name(ast_get_extension_context(hint->exten)),
3047                         ast_get_extension_app(hint->exten),
3048                         ast_extension_state2str(hint->laststate), watchers);
3049                 num++;
3050         }
3051         ast_cli(fd, "----------------\n");
3052         ast_cli(fd, "- %d hints registered\n", num);
3053         AST_LIST_UNLOCK(&hints);
3054         return RESULT_SUCCESS;
3055 }
3056
3057 /*! \brief  handle_show_switches: CLI support for listing registered dial plan switches */
3058 static int handle_show_switches(int fd, int argc, char *argv[])
3059 {
3060         struct ast_switch *sw;
3061
3062         AST_LIST_LOCK(&switches);
3063
3064         if (AST_LIST_EMPTY(&switches)) {
3065                 AST_LIST_UNLOCK(&switches);
3066                 ast_cli(fd, "There are no registered alternative switches\n");
3067                 return RESULT_SUCCESS;
3068         }
3069
3070         ast_cli(fd, "\n    -= Registered Asterisk Alternative Switches =-\n");
3071         AST_LIST_TRAVERSE(&switches, sw, list)
3072                 ast_cli(fd, "%s: %s\n", sw->name, sw->description);
3073
3074         AST_LIST_UNLOCK(&switches);
3075
3076         return RESULT_SUCCESS;
3077 }
3078
3079 static int handle_show_applications(int fd, int argc, char *argv[])
3080 {
3081         struct ast_app *a;
3082         int like = 0, describing = 0;
3083         int total_match = 0;    /* Number of matches in like clause */
3084         int total_apps = 0;     /* Number of apps registered */
3085
3086         AST_LIST_LOCK(&apps);
3087
3088         if (AST_LIST_EMPTY(&apps)) {
3089                 ast_cli(fd, "There are no registered applications\n");
3090                 AST_LIST_UNLOCK(&apps);
3091                 return -1;
3092         }
3093
3094         /* core list applications like <keyword> */
3095         if ((argc == 5) && (!strcmp(argv[3], "like"))) {
3096                 like = 1;
3097         } else if ((argc > 4) && (!strcmp(argv[3], "describing"))) {
3098                 describing = 1;
3099         }
3100
3101         /* core list applications describing <keyword1> [<keyword2>] [...] */
3102         if ((!like) && (!describing)) {
3103                 ast_cli(fd, "    -= Registered Asterisk Applications =-\n");
3104         } else {
3105                 ast_cli(fd, "    -= Matching Asterisk Applications =-\n");
3106         }
3107
3108         AST_LIST_TRAVERSE(&apps, a, list) {
3109                 int printapp = 0;
3110                 total_apps++;
3111                 if (like) {
3112                         if (strcasestr(a->name, argv[4])) {
3113                                 printapp = 1;
3114                                 total_match++;
3115                         }
3116                 } else if (describing) {
3117                         if (a->description) {
3118                                 /* Match all words on command line */
3119                                 int i;
3120                                 printapp = 1;
3121                                 for (i = 4; i < argc; i++) {
3122                                         if (!strcasestr(a->description, argv[i])) {
3123                                                 printapp = 0;
3124                                         } else {
3125                                                 total_match++;
3126                                         }
3127                                 }
3128                         }
3129                 } else {
3130                         printapp = 1;
3131                 }
3132
3133                 if (printapp) {
3134                         ast_cli(fd,"  %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>");
3135                 }
3136         }
3137         if ((!like) && (!describing)) {
3138                 ast_cli(fd, "    -= %d Applications Registered =-\n",total_apps);
3139         } else {
3140                 ast_cli(fd, "    -= %d Applications Matching =-\n",total_match);
3141         }
3142
3143         AST_LIST_UNLOCK(&apps);
3144
3145         return RESULT_SUCCESS;
3146 }
3147
3148 static char *complete_show_applications(const char *line, const char *word, int pos, int state)
3149 {
3150         static char* choices[] = { "like", "describing", NULL };
3151
3152         return (pos != 3) ? NULL : ast_cli_complete(word, choices, state);
3153 }
3154
3155 /*
3156  * 'show dialplan' CLI command implementation functions ...
3157  */
3158 static char *complete_show_dialplan_context(const char *line, const char *word, int pos,
3159         int state)
3160 {
3161         struct ast_context *c = NULL;
3162         char *ret = NULL;
3163         int which = 0;
3164         int wordlen;
3165
3166         /* we are do completion of [exten@]context on second position only */
3167         if (pos != 2)
3168                 return NULL;
3169
3170         ast_lock_contexts();
3171
3172         wordlen = strlen(word);
3173
3174         /* walk through all contexts and return the n-th match */
3175         while ( (c = ast_walk_contexts(c)) ) {
3176                 if (!strncasecmp(word, ast_get_context_name(c), wordlen) && ++which > state) {
3177                         ret = ast_strdup(ast_get_context_name(c));
3178                         break;
3179                 }
3180         }
3181
3182         ast_unlock_contexts();
3183
3184         return ret;
3185 }
3186
3187 struct dialplan_counters {
3188         int total_context;
3189         int total_exten;
3190         int total_prio;
3191         int context_existence;
3192         int extension_existence;
3193 };
3194
3195 /*! \brief helper function to print an extension */
3196 static void print_ext(struct ast_exten *e, char * buf, int buflen)
3197 {
3198         int prio = ast_get_extension_priority(e);
3199         if (prio == PRIORITY_HINT) {
3200                 snprintf(buf, buflen, "hint: %s",
3201                         ast_get_extension_app(e));
3202         } else {
3203                 snprintf(buf, buflen, "%d. %s(%s)",
3204                         prio, ast_get_extension_app(e),
3205                         (char *)ast_get_extension_app_data(e));
3206         }
3207 }
3208
3209 /* XXX not verified */
3210 static int show_dialplan_helper(int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[])
3211 {
3212         struct ast_context *c = NULL;
3213         int res = 0, old_total_exten = dpc->total_exten;
3214
3215         ast_lock_contexts();
3216
3217         /* walk all contexts ... */
3218         while ( (c = ast_walk_contexts(c)) ) {
3219                 struct ast_exten *e;
3220                 struct ast_include *i;
3221                 struct ast_ignorepat *ip;
3222                 char buf[256], buf2[256];
3223                 int context_info_printed = 0;
3224
3225                 if (context && strcmp(ast_get_context_name(c), context))
3226                         continue;       /* skip this one, name doesn't match */
3227
3228                 dpc->context_existence = 1;
3229
3230                 ast_lock_context(c);
3231
3232                 /* are we looking for exten too? if yes, we print context
3233                  * only if we find our extension.
3234                  * Otherwise print context even if empty ?
3235                  * XXX i am not sure how the rinclude is handled.
3236                  * I think it ought to go inside.
3237                  */
3238                 if (!exten) {
3239                         dpc->total_context++;
3240                         ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
3241                                 ast_get_context_name(c), ast_get_context_registrar(c));
3242                         context_info_printed = 1;
3243                 }
3244
3245                 /* walk extensions ... */
3246                 e = NULL;
3247                 while ( (e = ast_walk_context_extensions(c, e)) ) {
3248                         struct ast_exten *p;
3249
3250                         if (exten && !ast_extension_match(ast_get_extension_name(e), exten))
3251                                 continue;       /* skip, extension match failed */
3252
3253                         dpc->extension_existence = 1;
3254
3255                         /* may we print context info? */
3256                         if (!context_info_printed) {
3257                                 dpc->total_context++;
3258                                 if (rinclude) { /* TODO Print more info about rinclude */
3259                                         ast_cli(fd, "[ Included context '%s' created by '%s' ]\n",
3260                                                 ast_get_context_name(c), ast_get_context_registrar(c));
3261                                 } else {
3262                                         ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
3263                                                 ast_get_context_name(c), ast_get_context_registrar(c));
3264                                 }
3265                                 context_info_printed = 1;
3266                         }
3267                         dpc->total_prio++;
3268
3269                         /* write extension name and first peer */
3270                         snprintf(buf, sizeof(buf), "'%s' =>", ast_get_extension_name(e));
3271
3272                         print_ext(e, buf2, sizeof(buf2));
3273
3274                         ast_cli(fd, "  %-17s %-45s [%s]\n", buf, buf2,
3275                                 ast_get_extension_registrar(e));
3276
3277                         dpc->total_exten++;
3278                         /* walk next extension peers */
3279                         p = e;  /* skip the first one, we already got it */
3280                         while ( (p = ast_walk_extension_priorities(e, p)) ) {
3281                                 const char *el = ast_get_extension_label(p);
3282                                 dpc->total_prio++;
3283                                 if (el)
3284                                         snprintf(buf, sizeof(buf), "   [%s]", el);
3285                                 else
3286                                         buf[0] = '\0';
3287                                 print_ext(p, buf2, sizeof(buf2));
3288
3289                                 ast_cli(fd,"  %-17s %-45s [%s]\n", buf, buf2,
3290                                         ast_get_extension_registrar(p));
3291                         }
3292                 }
3293
3294                 /* walk included and write info ... */
3295                 i = NULL;
3296                 while ( (i = ast_walk_context_includes(c, i)) ) {
3297                         snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i));
3298                         if (exten) {
3299                                 /* Check all includes for the requested extension */
3300                                 if (includecount >= AST_PBX_MAX_STACK) {
3301                                         ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n");
3302                                 } else {
3303                                         int dupe=0;
3304                                         int x;
3305                                         for (x=0;x<includecount;x++) {
3306                                                 if (!strcasecmp(includes[x], ast_get_include_name(i))) {
3307                                                         dupe++;
3308                                                         break;
3309                                                 }
3310                                         }
3311                                         if (!dupe) {
3312                                                 includes[includecount] = ast_get_include_name(i);
3313                                                 show_dialplan_helper(fd, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes);
3314                                         } else {
3315                                                 ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context);
3316                                         }
3317                                 }
3318                         } else {
3319                                 ast_cli(fd, "  Include =>        %-45s [%s]\n",
3320                                         buf, ast_get_include_registrar(i));
3321                         }
3322                 }
3323
3324                 /* walk ignore patterns and write info ... */
3325                 ip = NULL;
3326                 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) {
3327                         const char *ipname = ast_get_ignorepat_name(ip);
3328                         char ignorepat[AST_MAX_EXTENSION];
3329                         snprintf(buf, sizeof(buf), "'%s'", ipname);
3330                         snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname);
3331                         if (!exten || ast_extension_match(ignorepat, exten)) {
3332                                 ast_cli(fd, "  Ignore pattern => %-45s [%s]\n",
3333                                         buf, ast_get_ignorepat_registrar(ip));
3334                         }
3335                 }
3336                 if (!rinclude) {
3337                         struct ast_sw *sw = NULL;
3338                         while ( (sw = ast_walk_context_switches(c, sw)) ) {
3339                                 snprintf(buf, sizeof(buf), "'%s/%s'",
3340                                         ast_get_switch_name(sw),
3341                                         ast_get_switch_data(sw));
3342                                 ast_cli(fd, "  Alt. Switch =>    %-45s [%s]\n",
3343                                         buf, ast_get_switch_registrar(sw));
3344                         }
3345                 }
3346
3347                 ast_unlock_context(c);
3348
3349                 /* if we print something in context, make an empty line */
3350                 if (context_info_printed)
3351                         ast_cli(fd, "\r\n");
3352         }
3353         ast_unlock_contexts();
3354
3355         return (dpc->total_exten == old_total_exten) ? -1 : res;
3356 }
3357
3358 static int handle_show_dialplan(int fd, int argc, char *argv[])
3359 {
3360         char *exten = NULL, *context = NULL;
3361         /* Variables used for different counters */
3362         struct dialplan_counters counters;
3363
3364         const char *incstack[AST_PBX_MAX_STACK];
3365         memset(&counters, 0, sizeof(counters));
3366
3367         if (argc != 2 && argc != 3)
3368                 return RESULT_SHOWUSAGE;
3369
3370         /* we obtain [exten@]context? if yes, split them ... */
3371         if (argc == 3) {
3372                 if (strchr(argv[2], '@')) {     /* split into exten & context */
3373                         context = ast_strdupa(argv[2]);
3374                         exten = strsep(&context, "@");
3375                         /* change empty strings to NULL */
3376                         if (ast_strlen_zero(exten))
3377                                 exten = NULL;
3378                 } else { /* no '@' char, only context given */
3379                         context = argv[2];
3380                 }
3381                 if (ast_strlen_zero(context))
3382                         context = NULL;
3383         }
3384         /* else Show complete dial plan, context and exten are NULL */
3385         show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack);
3386
3387         /* check for input failure and throw some error messages */
3388         if (context && !counters.context_existence) {
3389                 ast_cli(fd, "There is no existence of '%s' context\n", context);
3390                 return RESULT_FAILURE;
3391         }
3392
3393         if (exten && !counters.extension_existence) {
3394                 if (context)
3395                         ast_cli(fd, "There is no existence of %s@%s extension\n",
3396                                 exten, context);
3397                 else
3398                         ast_cli(fd,
3399                                 "There is no existence of '%s' extension in all contexts\n",
3400                                 exten);
3401                 return RESULT_FAILURE;
3402         }
3403
3404         ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n",
3405                                 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions",
3406                                 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities",
3407                                 counters.total_context, counters.total_context == 1 ? "context" : "contexts");
3408
3409         /* everything ok */
3410         return RESULT_SUCCESS;
3411 }
3412
3413 /*! \brief CLI support for listing global variables in a parseable way */
3414 static int handle_show_globals(int fd, int argc, char *argv[])
3415 {
3416         int i = 0;
3417         struct ast_var_t *newvariable;
3418
3419         ast_mutex_lock(&globalslock);
3420         AST_LIST_TRAVERSE (&globals, newvariable, entries) {
3421                 i++;
3422                 ast_cli(fd, "   %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable));
3423         }
3424         ast_mutex_unlock(&globalslock);
3425         ast_cli(fd, "\n    -- %d variables\n", i);
3426
3427         return RESULT_SUCCESS;
3428 }
3429
3430 static int handle_set_global(int fd, int argc, char *argv[])
3431 {
3432         if (argc != 5)
3433                 return RESULT_SHOWUSAGE;
3434
3435         pbx_builtin_setvar_helper(NULL, argv[3], argv[4]);
3436         ast_cli(fd, "\n    -- Global variable %s set to %s\n", argv[3], argv[4]);
3437
3438         return RESULT_SUCCESS;
3439 }
3440
3441
3442
3443 /*
3444  * CLI entries for upper commands ...
3445  */
3446 static struct ast_cli_entry pbx_cli[] = {
3447         { { "core", "list", "applications", NULL },
3448         handle_show_applications, "Shows registered dialplan applications",
3449         show_applications_help, complete_show_applications },
3450
3451         { { "core", "list", "functions", NULL },
3452         handle_show_functions, "Shows registered dialplan functions",
3453         show_functions_help },
3454
3455         { { "core", "list", "switches", NULL },
3456         handle_show_switches, "Show alternative switches",
3457         show_switches_help },
3458
3459         { { "core", "list", "hints", NULL },
3460         handle_show_hints, "Show dialplan hints",
3461         show_hints_help },
3462
3463         { { "core", "list", "globals", NULL },
3464         handle_show_globals, "Show global dialplan variables",
3465         show_globals_help },
3466
3467         { { "core", "show" , "function", NULL },
3468         handle_show_function, "Describe a specific dialplan function",
3469         show_function_help, complete_show_function },
3470
3471         { { "core", "show", "application", NULL },
3472         handle_show_application, "Describe a specific dialplan application",
3473         show_application_help, complete_show_application },
3474
3475         { { "core", "set", "global", NULL },
3476         handle_set_global, "Set global dialplan variable",
3477         set_global_help },
3478
3479         { { "dialplan", "show", NULL },
3480         handle_show_dialplan, "Show dialplan",
3481         show_dialplan_help, complete_show_dialplan_context },
3482 };
3483
3484 static void unreference_cached_app(struct ast_app *app)
3485 {
3486         struct ast_context *context = NULL;
3487         struct ast_exten *eroot = NULL, *e = NULL;
3488
3489         ast_lock_contexts();
3490         while ((context = ast_walk_contexts(context))) {
3491                 while ((eroot = ast_walk_context_extensions(context, eroot))) {
3492                         while ((e = ast_walk_extension_priorities(eroot, e))) {
3493                                 if (e->cached_app == app)
3494                                         e->cached_app = NULL;
3495                         }
3496                 }
3497         }
3498         ast_unlock_contexts();
3499
3500         return;
3501 }
3502
3503 int ast_unregister_application(const char *app)
3504 {
3505         struct ast_app *tmp;
3506
3507         AST_LIST_LOCK(&apps);
3508         AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
3509                 if (!strcasecmp(app, tmp->name)) {
3510                         unreference_cached_app(tmp);
3511                         AST_LIST_REMOVE_CURRENT(&apps, list);
3512                         if (option_verbose > 1)
3513                                 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
3514                         free(tmp);
3515                         break;
3516                 }
3517         }
3518         AST_LIST_TRAVERSE_SAFE_END
3519         AST_LIST_UNLOCK(&apps);
3520
3521         return tmp ? 0 : -1;
3522 }
3523
3524 static struct ast_context *__ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar, int existsokay)
3525 {
3526         struct ast_context *tmp, **local_contexts;
3527         int length = sizeof(struct ast_context) + strlen(name) + 1;
3528
3529         if (!extcontexts) {
3530                 ast_mutex_lock(&conlock);
3531                 local_contexts = &contexts;
3532         } else
3533                 local_contexts = extcontexts;
3534
3535         for (tmp = *local_contexts; tmp; tmp = tmp->next) {
3536                 if (!strcasecmp(tmp->name, name)) {
3537                         if (!existsokay) {
3538                                 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
3539                                 tmp = NULL;
3540                         }
3541                         if (!extcontexts)
3542                                 ast_mutex_unlock(&conlock);
3543                         return tmp;
3544                 }
3545         }
3546         if ((tmp = ast_calloc(1, length))) {
3547                 ast_mutex_init(&tmp->lock);
3548                 ast_mutex_init(&tmp->macrolock);
3549                 strcpy(tmp->name, name);
3550                 tmp->root = NULL;
3551                 tmp->registrar = registrar;
3552                 tmp->next = *local_contexts;
3553                 tmp->includes = NULL;
3554                 tmp->ignorepats = NULL;
3555                 *local_contexts = tmp;
3556                 if (option_debug)
3557                         ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
3558                 if (option_verbose > 2)
3559                         ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
3560         }
3561
3562         if (!extcontexts)
3563                 ast_mutex_unlock(&conlock);
3564         return tmp;
3565 }
3566
3567 struct ast_context *ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar)
3568 {
3569         return __ast_context_create(extcontexts, name, registrar, 0);
3570 }
3571
3572 struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, const char *name, const char *registrar)
3573 {
3574         return __ast_context_create(extcontexts, name, registrar, 1);
3575 }
3576 void __ast_context_destroy(struct ast_context *con, const char *registrar);
3577
3578 struct store_hint {
3579         char *context;
3580         char *exten;
3581         struct ast_state_cb *callbacks;
3582         int laststate;
3583         AST_LIST_ENTRY(store_hint) list;
3584         char data[1];
3585 };
3586
3587 AST_LIST_HEAD(store_hints, store_hint);
3588
3589 /* XXX this does not check that multiple contexts are merged */
3590 void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar)
3591 {
3592         struct ast_context *tmp, *lasttmp = NULL;