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