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