Asterisk - The Open Source Telephony Project  GIT-master-b91fb3c
pbx.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, 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 /*** MODULEINFO
27  <support_level>core</support_level>
28  ***/
29 
30 #include "asterisk.h"
31 
32 #include "asterisk/_private.h"
33 #include "asterisk/paths.h" /* use ast_config_AST_SYSTEM_NAME */
34 #include <ctype.h>
35 #include <time.h>
36 #include <sys/time.h>
37 #if defined(HAVE_SYSINFO)
38 #include <sys/sysinfo.h>
39 #endif
40 #if defined(SOLARIS)
41 #include <sys/loadavg.h>
42 #endif
43 
44 #include "asterisk/lock.h"
45 #include "asterisk/cli.h"
46 #include "asterisk/pbx.h"
47 #include "asterisk/channel.h"
48 #include "asterisk/file.h"
49 #include "asterisk/callerid.h"
50 #include "asterisk/cdr.h"
51 #include "asterisk/config.h"
52 #include "asterisk/term.h"
53 #include "asterisk/time.h"
54 #include "asterisk/manager.h"
55 #include "asterisk/ast_expr.h"
56 #include "asterisk/linkedlists.h"
57 #define SAY_STUBS /* generate declarations and stubs for say methods */
58 #include "asterisk/say.h"
59 #include "asterisk/utils.h"
60 #include "asterisk/causes.h"
61 #include "asterisk/musiconhold.h"
62 #include "asterisk/app.h"
63 #include "asterisk/devicestate.h"
64 #include "asterisk/presencestate.h"
65 #include "asterisk/hashtab.h"
66 #include "asterisk/module.h"
67 #include "asterisk/indications.h"
68 #include "asterisk/taskprocessor.h"
69 #include "asterisk/xmldoc.h"
70 #include "asterisk/astobj2.h"
72 #include "asterisk/dial.h"
73 #include "asterisk/vector.h"
74 #include "pbx_private.h"
75 
76 /*!
77  * \note I M P O R T A N T :
78  *
79  * The speed of extension handling will likely be among the most important
80  * aspects of this PBX. The switching scheme as it exists right now isn't
81  * terribly bad (it's O(N+M), where N is the # of extensions and M is the avg #
82  * of priorities, but a constant search time here would be great ;-)
83  *
84  * A new algorithm to do searching based on a 'compiled' pattern tree is introduced
85  * here, and shows a fairly flat (constant) search time, even for over
86  * 10000 patterns.
87  *
88  * Also, using a hash table for context/priority name lookup can help prevent
89  * the find_extension routines from absorbing exponential cpu cycles as the number
90  * of contexts/priorities grow. I've previously tested find_extension with red-black trees,
91  * which have O(log2(n)) speed. Right now, I'm using hash tables, which do
92  * searches (ideally) in O(1) time. While these techniques do not yield much
93  * speed in small dialplans, they are worth the trouble in large dialplans.
94  *
95  */
96 
97 /*** DOCUMENTATION
98  <function name="EXCEPTION" language="en_US">
99  <synopsis>
100  Retrieve the details of the current dialplan exception.
101  </synopsis>
102  <syntax>
103  <parameter name="field" required="true">
104  <para>The following fields are available for retrieval:</para>
105  <enumlist>
106  <enum name="reason">
107  <para>INVALID, ERROR, RESPONSETIMEOUT, ABSOLUTETIMEOUT, or custom
108  value set by the RaiseException() application</para>
109  </enum>
110  <enum name="context">
111  <para>The context executing when the exception occurred.</para>
112  </enum>
113  <enum name="exten">
114  <para>The extension executing when the exception occurred.</para>
115  </enum>
116  <enum name="priority">
117  <para>The numeric priority executing when the exception occurred.</para>
118  </enum>
119  </enumlist>
120  </parameter>
121  </syntax>
122  <description>
123  <para>Retrieve the details (specified <replaceable>field</replaceable>) of the current dialplan exception.</para>
124  </description>
125  <see-also>
126  <ref type="application">RaiseException</ref>
127  </see-also>
128  </function>
129  <function name="TESTTIME" language="en_US">
130  <synopsis>
131  Sets a time to be used with the channel to test logical conditions.
132  </synopsis>
133  <syntax>
134  <parameter name="date" required="true" argsep=" ">
135  <para>Date in ISO 8601 format</para>
136  </parameter>
137  <parameter name="time" required="true" argsep=" ">
138  <para>Time in HH:MM:SS format (24-hour time)</para>
139  </parameter>
140  <parameter name="zone" required="false">
141  <para>Timezone name</para>
142  </parameter>
143  </syntax>
144  <description>
145  <para>To test dialplan timing conditions at times other than the current time, use
146  this function to set an alternate date and time. For example, you may wish to evaluate
147  whether a location will correctly identify to callers that the area is closed on Christmas
148  Day, when Christmas would otherwise fall on a day when the office is normally open.</para>
149  </description>
150  <see-also>
151  <ref type="application">GotoIfTime</ref>
152  </see-also>
153  </function>
154  <manager name="ShowDialPlan" language="en_US">
155  <synopsis>
156  Show dialplan contexts and extensions
157  </synopsis>
158  <syntax>
159  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
160  <parameter name="Extension">
161  <para>Show a specific extension.</para>
162  </parameter>
163  <parameter name="Context">
164  <para>Show a specific context.</para>
165  </parameter>
166  </syntax>
167  <description>
168  <para>Show dialplan contexts and extensions. Be aware that showing the full dialplan
169  may take a lot of capacity.</para>
170  </description>
171  </manager>
172  <manager name="ExtensionStateList" language="en_US">
173  <synopsis>
174  List the current known extension states.
175  </synopsis>
176  <syntax>
177  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
178  </syntax>
179  <description>
180  <para>This will list out all known extension states in a
181  sequence of <replaceable>ExtensionStatus</replaceable> events.
182  When finished, a <replaceable>ExtensionStateListComplete</replaceable> event
183  will be emitted.</para>
184  </description>
185  <see-also>
186  <ref type="manager">ExtensionState</ref>
187  <ref type="function">HINT</ref>
188  <ref type="function">EXTENSION_STATE</ref>
189  </see-also>
190  <responses>
191  <list-elements>
192  <xi:include xpointer="xpointer(/docs/managerEvent[@name='ExtensionStatus'])" />
193  </list-elements>
194  <managerEvent name="ExtensionStateListComplete" language="en_US">
195  <managerEventInstance class="EVENT_FLAG_COMMAND">
196  <synopsis>
197  Indicates the end of the list the current known extension states.
198  </synopsis>
199  <syntax>
200  <parameter name="EventList">
201  <para>Conveys the status of the event list.</para>
202  </parameter>
203  <parameter name="ListItems">
204  <para>Conveys the number of statuses reported.</para>
205  </parameter>
206  </syntax>
207  </managerEventInstance>
208  </managerEvent>
209  </responses>
210  </manager>
211  ***/
212 
213 #ifdef LOW_MEMORY
214 #define EXT_DATA_SIZE 256
215 #else
216 #define EXT_DATA_SIZE 8192
217 #endif
218 
219 #define SWITCH_DATA_LENGTH 256
220 
221 #define VAR_NORMAL 1
222 #define VAR_SOFTTRAN 2
223 #define VAR_HARDTRAN 3
224 
225 struct ast_context;
226 struct ast_app;
227 
230 
231 /*!
232  \brief ast_exten: An extension
233  The dialplan is saved as a linked list with each context
234  having it's own linked list of extensions - one item per
235  priority.
236 */
237 struct ast_exten {
238  char *exten; /*!< Clean Extension id */
239  char *name; /*!< Extension name (may include '-' eye candy) */
240  int matchcid; /*!< Match caller id ? */
241  const char *cidmatch; /*!< Caller id to match for this extension */
242  const char *cidmatch_display; /*!< Caller id to match (display version) */
243  int priority; /*!< Priority */
244  const char *label; /*!< Label */
245  struct ast_context *parent; /*!< The context this extension belongs to */
246  const char *app; /*!< Application to execute */
247  struct ast_app *cached_app; /*!< Cached location of application */
248  void *data; /*!< Data to use (arguments) */
249  void (*datad)(void *); /*!< Data destructor */
250  struct ast_exten *peer; /*!< Next higher priority with our extension */
251  struct ast_hashtab *peer_table; /*!< Priorities list in hashtab form -- only on the head of the peer list */
252  struct ast_hashtab *peer_label_table; /*!< labeled priorities in the peers -- only on the head of the peer list */
253  const char *registrar; /*!< Registrar */
254  const char *registrar_file; /*!< File name used to register extension */
255  int registrar_line; /*!< Line number the extension was registered in text */
256  struct ast_exten *next; /*!< Extension with a greater ID */
257  char stuff[0];
258 };
259 
260 /*! \brief match_char: forms a syntax tree for quick matching of extension patterns */
262 {
263  int is_pattern; /* the pattern started with '_' */
264  int deleted; /* if this is set, then... don't return it */
265  int specificity; /* simply the strlen of x, or 10 for X, 9 for Z, and 8 for N; and '.' and '!' will add 11 ? */
268  struct ast_exten *exten; /* attached to last char of a pattern for exten */
269  char x[1]; /* the pattern itself-- matches a single char */
270 };
271 
272 struct scoreboard /* make sure all fields are 0 before calling new_find_extension */
273 {
276  char last_char; /* set to ! or . if they are the end of the pattern */
277  int canmatch; /* if the string to match was just too short */
278  struct match_char *node;
280  struct ast_exten *exten;
281 };
282 
283 /*! \brief ast_context: An extension context - must remain in sync with fake_context */
284 struct ast_context {
285  ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
286  struct ast_exten *root; /*!< The root of the list of extensions */
287  struct ast_hashtab *root_table; /*!< For exact matches on the extensions in the pattern tree, and for traversals of the pattern_tree */
288  struct match_char *pattern_tree; /*!< A tree to speed up extension pattern matching */
289  struct ast_context *next; /*!< Link them together */
290  struct ast_includes includes; /*!< Include other contexts */
291  struct ast_ignorepats ignorepats; /*!< Patterns for which to continue playing dialtone */
292  struct ast_sws alts; /*!< Alternative switches */
293  char *registrar; /*!< Registrar -- make sure you malloc this, as the registrar may have to survive module unloads */
294  int refcount; /*!< each module that would have created this context should inc/dec this as appropriate */
295  int autohints; /*!< Whether autohints support is enabled or not */
296  ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
297  char name[0]; /*!< Name of the context */
298 };
299 
300 /*! \brief ast_state_cb: An extension state notify register item */
301 struct ast_state_cb {
302  /*! Watcher ID returned when registered. */
303  int id;
304  /*! Arbitrary data passed for callbacks. */
305  void *data;
306  /*! Flag if this callback is an extended callback containing detailed device status */
307  int extended;
308  /*! Callback when state changes. */
310  /*! Callback when destroyed so any resources given by the registerer can be freed. */
312  /*! \note Only used by ast_merge_contexts_and_delete */
314 };
315 
316 /*!
317  * \brief Structure for dial plan hints
318  *
319  * \note Hints are pointers from an extension in the dialplan to
320  * one or more devices (tech/name)
321  *
322  * See \ref AstExtState
323  */
324 struct ast_hint {
325  /*!
326  * \brief Hint extension
327  *
328  * \note
329  * Will never be NULL while the hint is in the hints container.
330  */
331  struct ast_exten *exten;
332  struct ao2_container *callbacks; /*!< Device state callback container for this extension */
333 
334  /*! Dev state variables */
335  int laststate; /*!< Last known device state */
336 
337  /*! Presence state variables */
338  int last_presence_state; /*!< Last known presence state */
339  char *last_presence_subtype; /*!< Last known presence subtype string */
340  char *last_presence_message; /*!< Last known presence message string */
341 
342  char context_name[AST_MAX_CONTEXT];/*!< Context of destroyed hint extension. */
343  char exten_name[AST_MAX_EXTENSION];/*!< Extension of destroyed hint extension. */
344 
345  AST_VECTOR(, char *) devices; /*!< Devices associated with the hint */
346 };
347 
348 STASIS_MESSAGE_TYPE_DEFN_LOCAL(hint_change_message_type);
349 STASIS_MESSAGE_TYPE_DEFN_LOCAL(hint_remove_message_type);
350 
351 #define HINTDEVICE_DATA_LENGTH 16
353 
354 /* --- Hash tables of various objects --------*/
355 #ifdef LOW_MEMORY
356 #define HASH_EXTENHINT_SIZE 17
357 #else
358 #define HASH_EXTENHINT_SIZE 563
359 #endif
360 
361 
362 /*! \brief Container for hint devices */
363 static struct ao2_container *hintdevices;
364 
365 /*!
366  * \brief Structure for dial plan hint devices
367  * \note hintdevice is one device pointing to a hint.
368  */
370  /*!
371  * \brief Hint this hintdevice belongs to.
372  * \note Holds a reference to the hint object.
373  */
374  struct ast_hint *hint;
375  /*! Name of the hint device. */
376  char hintdevice[1];
377 };
378 
379 /*! \brief Container for autohint contexts */
380 static struct ao2_container *autohints;
381 
382 /*!
383  * \brief Structure for dial plan autohints
384  */
385 struct ast_autohint {
386  /*! \brief Name of the registrar */
387  char *registrar;
388  /*! \brief Name of the context */
389  char context[1];
390 };
391 
392 /*!
393  * \note Using the device for hash
394  */
395 static int hintdevice_hash_cb(const void *obj, const int flags)
396 {
397  const struct ast_hintdevice *ext;
398  const char *key;
399 
400  switch (flags & OBJ_SEARCH_MASK) {
401  case OBJ_SEARCH_KEY:
402  key = obj;
403  break;
404  case OBJ_SEARCH_OBJECT:
405  ext = obj;
406  key = ext->hintdevice;
407  break;
408  default:
409  ast_assert(0);
410  return 0;
411  }
412 
413  return ast_str_case_hash(key);
414 }
415 
416 /*!
417  * \note Devices on hints are not unique so no CMP_STOP is returned
418  * Dont use ao2_find against hintdevices container cause there always
419  * could be more than one result.
420  */
421 static int hintdevice_cmp_multiple(void *obj, void *arg, int flags)
422 {
423  struct ast_hintdevice *left = obj;
424  struct ast_hintdevice *right = arg;
425  const char *right_key = arg;
426  int cmp;
427 
428  switch (flags & OBJ_SEARCH_MASK) {
429  case OBJ_SEARCH_OBJECT:
430  right_key = right->hintdevice;
431  /* Fall through */
432  case OBJ_SEARCH_KEY:
433  cmp = strcasecmp(left->hintdevice, right_key);
434  break;
436  /*
437  * We could also use a partial key struct containing a length
438  * so strlen() does not get called for every comparison instead.
439  */
440  cmp = strncmp(left->hintdevice, right_key, strlen(right_key));
441  break;
442  default:
443  ast_assert(0);
444  cmp = 0;
445  break;
446  }
447  return cmp ? 0 : CMP_MATCH;
448 }
449 
450 /*!
451  * \note Using the context name for hash
452  */
453 static int autohint_hash_cb(const void *obj, const int flags)
454 {
455  const struct ast_autohint *autohint;
456  const char *key;
457 
458  switch (flags & OBJ_SEARCH_MASK) {
459  case OBJ_SEARCH_KEY:
460  key = obj;
461  break;
462  case OBJ_SEARCH_OBJECT:
463  autohint = obj;
464  key = autohint->context;
465  break;
466  default:
467  ast_assert(0);
468  return 0;
469  }
470 
471  return ast_str_case_hash(key);
472 }
473 
474 static int autohint_cmp(void *obj, void *arg, int flags)
475 {
476  struct ast_autohint *left = obj;
477  struct ast_autohint *right = arg;
478  const char *right_key = arg;
479  int cmp;
480 
481  switch (flags & OBJ_SEARCH_MASK) {
482  case OBJ_SEARCH_OBJECT:
483  right_key = right->context;
484  /* Fall through */
485  case OBJ_SEARCH_KEY:
486  cmp = strcasecmp(left->context, right_key);
487  break;
489  /*
490  * We could also use a partial key struct containing a length
491  * so strlen() does not get called for every comparison instead.
492  */
493  cmp = strncmp(left->context, right_key, strlen(right_key));
494  break;
495  default:
496  ast_assert(0);
497  cmp = 0;
498  break;
499  }
500  return cmp ? 0 : CMP_MATCH | CMP_STOP;
501 }
502 
503 /*! \internal \brief \c ao2_callback function to remove hintdevices */
504 static int hintdevice_remove_cb(void *obj, void *arg, void *data, int flags)
505 {
506  struct ast_hintdevice *candidate = obj;
507  char *device = arg;
508  struct ast_hint *hint = data;
509 
510  if (!strcasecmp(candidate->hintdevice, device)
511  && candidate->hint == hint) {
512  return CMP_MATCH;
513  }
514  return 0;
515 }
516 
517 static int remove_hintdevice(struct ast_hint *hint)
518 {
519  while (AST_VECTOR_SIZE(&hint->devices) > 0) {
520  char *device = AST_VECTOR_GET(&hint->devices, 0);
521 
523  hintdevice_remove_cb, device, hint, "Remove device from container");
524  AST_VECTOR_REMOVE_UNORDERED(&hint->devices, 0);
525  ast_free(device);
526  }
527 
528  return 0;
529 }
530 
531 static char *parse_hint_device(struct ast_str *hint_args);
532 /*!
533  * \internal
534  * \brief Destroy the given hintdevice object.
535  *
536  * \param obj Hint device to destroy.
537  *
538  * \return Nothing
539  */
540 static void hintdevice_destroy(void *obj)
541 {
542  struct ast_hintdevice *doomed = obj;
543 
544  if (doomed->hint) {
545  ao2_ref(doomed->hint, -1);
546  doomed->hint = NULL;
547  }
548 }
549 
550 /*! \brief add hintdevice structure and link it into the container.
551  */
552 static int add_hintdevice(struct ast_hint *hint, const char *devicelist)
553 {
554  struct ast_str *str;
555  char *parse;
556  char *cur;
557  struct ast_hintdevice *device;
558  int devicelength;
559 
560  if (!hint || !devicelist) {
561  /* Trying to add garbage? Don't bother. */
562  return 0;
563  }
564  if (!(str = ast_str_thread_get(&hintdevice_data, 16))) {
565  return -1;
566  }
567  ast_str_set(&str, 0, "%s", devicelist);
568  parse = ast_str_buffer(str);
569 
570  /* Spit on '&' and ',' to handle presence hints as well */
571  while ((cur = strsep(&parse, "&,"))) {
572  char *device_name;
573 
574  devicelength = strlen(cur);
575  if (!devicelength) {
576  continue;
577  }
578 
579  device_name = ast_strdup(cur);
580  if (!device_name) {
581  return -1;
582  }
583 
584  device = ao2_t_alloc(sizeof(*device) + devicelength, hintdevice_destroy,
585  "allocating a hintdevice structure");
586  if (!device) {
587  ast_free(device_name);
588  return -1;
589  }
590  strcpy(device->hintdevice, cur);
591  ao2_ref(hint, +1);
592  device->hint = hint;
593  if (AST_VECTOR_APPEND(&hint->devices, device_name)) {
594  ast_free(device_name);
595  ao2_ref(device, -1);
596  return -1;
597  }
598  ao2_t_link(hintdevices, device, "Linking device into hintdevice container.");
599  ao2_t_ref(device, -1, "hintdevice is linked so we can unref");
600  }
601 
602  return 0;
603 }
604 
605 
606 static const struct cfextension_states {
608  const char * const text;
609 } extension_states[] = {
610  { AST_EXTENSION_NOT_INUSE, "Idle" },
611  { AST_EXTENSION_INUSE, "InUse" },
612  { AST_EXTENSION_BUSY, "Busy" },
613  { AST_EXTENSION_UNAVAILABLE, "Unavailable" },
614  { AST_EXTENSION_RINGING, "Ringing" },
615  { AST_EXTENSION_INUSE | AST_EXTENSION_RINGING, "InUse&Ringing" },
616  { AST_EXTENSION_ONHOLD, "Hold" },
617  { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" }
618 };
619 
622  AST_STRING_FIELD(context); /*!< Context associated with this exception */
623  AST_STRING_FIELD(exten); /*!< Exten associated with this exception */
624  AST_STRING_FIELD(reason); /*!< The exception reason */
625  );
626 
627  int priority; /*!< Priority associated with this exception */
628 };
629 
630 static int matchcid(const char *cidpattern, const char *callerid);
631 #ifdef NEED_DEBUG
632 static void log_match_char_tree(struct match_char *node, char *prefix); /* for use anywhere */
633 #endif
634 static void new_find_extension(const char *str, struct scoreboard *score,
635  struct match_char *tree, int length, int spec, const char *callerid,
636  const char *label, enum ext_match_t action);
637 static struct match_char *already_in_tree(struct match_char *current, char *pat, int is_pattern);
638 static struct match_char *add_exten_to_pattern_tree(struct ast_context *con,
639  struct ast_exten *e1, int findonly);
640 static void create_match_char_tree(struct ast_context *con);
641 static struct ast_exten *get_canmatch_exten(struct match_char *node);
642 static void destroy_pattern_tree(struct match_char *pattern_tree);
643 static int hashtab_compare_extens(const void *ha_a, const void *ah_b);
644 static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b);
645 static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b);
646 static unsigned int hashtab_hash_extens(const void *obj);
647 static unsigned int hashtab_hash_priority(const void *obj);
648 static unsigned int hashtab_hash_labels(const void *obj);
649 static void __ast_internal_context_destroy( struct ast_context *con);
650 static int ast_add_extension_nolock(const char *context, int replace, const char *extension,
651  int priority, const char *label, const char *callerid,
652  const char *application, void *data, void (*datad)(void *), const char *registrar);
653 static int ast_add_extension2_lockopt(struct ast_context *con,
654  int replace, const char *extension, int priority, const char *label, const char *callerid,
655  const char *application, void *data, void (*datad)(void *),
656  const char *registrar, const char *registrar_file, int registrar_line,
657  int lock_context);
658 static struct ast_context *find_context_locked(const char *context);
659 static struct ast_context *find_context(const char *context);
661 static unsigned int ext_strncpy(char *dst, const char *src, size_t dst_size, int nofluff);
662 
663 /*!
664  * \internal
665  * \brief Character array comparison function for qsort.
666  *
667  * \param a Left side object.
668  * \param b Right side object.
669  *
670  * \retval <0 if a < b
671  * \retval =0 if a = b
672  * \retval >0 if a > b
673  */
674 static int compare_char(const void *a, const void *b)
675 {
676  const unsigned char *ac = a;
677  const unsigned char *bc = b;
678 
679  return *ac - *bc;
680 }
681 
682 /* labels, contexts are case sensitive priority numbers are ints */
683 int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
684 {
685  const struct ast_context *ac = ah_a;
686  const struct ast_context *bc = ah_b;
687  if (!ac || !bc) /* safety valve, but it might prevent a crash you'd rather have happen */
688  return 1;
689  /* assume context names are registered in a string table! */
690  return strcmp(ac->name, bc->name);
691 }
692 
693 static int hashtab_compare_extens(const void *ah_a, const void *ah_b)
694 {
695  const struct ast_exten *ac = ah_a;
696  const struct ast_exten *bc = ah_b;
697  int x = strcmp(ac->exten, bc->exten);
698  if (x) { /* if exten names are diff, then return */
699  return x;
700  }
701 
702  /* but if they are the same, do the cidmatch values match? */
703  /* not sure which side may be using ast_ext_matchcid_types, so check both */
705  return 0;
706  }
708  return 0;
709  }
710  if (ac->matchcid != bc->matchcid) {
711  return 1;
712  }
713  /* all other cases already disposed of, match now required on callerid string (cidmatch) */
714  /* although ast_add_extension2_lockopt() enforces non-zero ptr, caller may not have */
716  return 0;
717  }
718  return strcmp(ac->cidmatch, bc->cidmatch);
719 }
720 
721 static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b)
722 {
723  const struct ast_exten *ac = ah_a;
724  const struct ast_exten *bc = ah_b;
725  return ac->priority != bc->priority;
726 }
727 
728 static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b)
729 {
730  const struct ast_exten *ac = ah_a;
731  const struct ast_exten *bc = ah_b;
732  return strcmp(S_OR(ac->label, ""), S_OR(bc->label, ""));
733 }
734 
735 unsigned int ast_hashtab_hash_contexts(const void *obj)
736 {
737  const struct ast_context *ac = obj;
738  return ast_hashtab_hash_string(ac->name);
739 }
740 
741 static unsigned int hashtab_hash_extens(const void *obj)
742 {
743  const struct ast_exten *ac = obj;
744  unsigned int x = ast_hashtab_hash_string(ac->exten);
745  unsigned int y = 0;
746  if (ac->matchcid == AST_EXT_MATCHCID_ON)
748  return x+y;
749 }
750 
751 static unsigned int hashtab_hash_priority(const void *obj)
752 {
753  const struct ast_exten *ac = obj;
754  return ast_hashtab_hash_int(ac->priority);
755 }
756 
757 static unsigned int hashtab_hash_labels(const void *obj)
758 {
759  const struct ast_exten *ac = obj;
760  return ast_hashtab_hash_string(S_OR(ac->label, ""));
761 }
762 
763 static int autofallthrough = 1;
764 static int extenpatternmatchnew = 0;
765 static char *overrideswitch = NULL;
766 
767 /*! \brief Subscription for device state change events */
769 /*! \brief Subscription for presence state change events */
771 
773 static int countcalls;
774 static int totalcalls;
775 
776 static struct ast_context *contexts;
777 static struct ast_hashtab *contexts_table = NULL;
778 
779 /*!
780  * \brief Lock for the ast_context list
781  * \note
782  * This lock MUST be recursive, or a deadlock on reload may result. See
783  * https://issues.asterisk.org/view.php?id=17643
784  */
786 
787 /*!
788  * \brief Lock to hold off restructuring of hints by ast_merge_contexts_and_delete.
789  */
791 
792 static int stateid = 1;
793 /*!
794  * \note When holding this container's lock, do _not_ do
795  * anything that will cause conlock to be taken, unless you
796  * _already_ hold it. The ast_merge_contexts_and_delete function
797  * will take the locks in conlock/hints order, so any other
798  * paths that require both locks must also take them in that
799  * order.
800  */
801 static struct ao2_container *hints;
802 
803 static struct ao2_container *statecbs;
804 
805 #ifdef CONTEXT_DEBUG
806 
807 /* these routines are provided for doing run-time checks
808  on the extension structures, in case you are having
809  problems, this routine might help you localize where
810  the problem is occurring. It's kinda like a debug memory
811  allocator's arena checker... It'll eat up your cpu cycles!
812  but you'll see, if you call it in the right places,
813  right where your problems began...
814 */
815 
816 /* you can break on the check_contexts_trouble()
817 routine in your debugger to stop at the moment
818 there's a problem */
819 void check_contexts_trouble(void);
820 
821 void check_contexts_trouble(void)
822 {
823  int x = 1;
824  x = 2;
825 }
826 
827 int check_contexts(char *, int);
828 
829 int check_contexts(char *file, int line )
830 {
831  struct ast_hashtab_iter *t1;
832  struct ast_context *c1, *c2;
833  int found = 0;
834  struct ast_exten *e1, *e2, *e3;
835  struct ast_exten ex;
836 
837  /* try to find inconsistencies */
838  /* is every context in the context table in the context list and vice-versa ? */
839 
840  if (!contexts_table) {
841  ast_log(LOG_NOTICE,"Called from: %s:%d: No contexts_table!\n", file, line);
842  usleep(500000);
843  }
844 
845  t1 = ast_hashtab_start_traversal(contexts_table);
846  while( (c1 = ast_hashtab_next(t1))) {
847  for(c2=contexts;c2;c2=c2->next) {
848  if (!strcmp(c1->name, c2->name)) {
849  found = 1;
850  break;
851  }
852  }
853  if (!found) {
854  ast_log(LOG_NOTICE,"Called from: %s:%d: Could not find the %s context in the linked list\n", file, line, c1->name);
855  check_contexts_trouble();
856  }
857  }
859  for(c2=contexts;c2;c2=c2->next) {
860  c1 = find_context_locked(c2->name);
861  if (!c1) {
862  ast_log(LOG_NOTICE,"Called from: %s:%d: Could not find the %s context in the hashtab\n", file, line, c2->name);
863  check_contexts_trouble();
864  } else
866  }
867 
868  /* loop thru all contexts, and verify the exten structure compares to the
869  hashtab structure */
870  for(c2=contexts;c2;c2=c2->next) {
871  c1 = find_context_locked(c2->name);
872  if (c1) {
874 
875  /* is every entry in the root list also in the root_table? */
876  for(e1 = c1->root; e1; e1=e1->next)
877  {
878  char dummy_name[1024];
879  ex.exten = dummy_name;
880  ex.matchcid = e1->matchcid;
881  ex.cidmatch = e1->cidmatch;
882  ast_copy_string(dummy_name, e1->exten, sizeof(dummy_name));
883  e2 = ast_hashtab_lookup(c1->root_table, &ex);
884  if (!e2) {
885  if (e1->matchcid == AST_EXT_MATCHCID_ON) {
886  ast_log(LOG_NOTICE, "Called from: %s:%d: The %s context records "
887  "the exten %s (CID match: %s) but it is not in its root_table\n",
888  file, line, c2->name, dummy_name, e1->cidmatch_display);
889  } else {
890  ast_log(LOG_NOTICE, "Called from: %s:%d: The %s context records "
891  "the exten %s but it is not in its root_table\n",
892  file, line, c2->name, dummy_name);
893  }
894  check_contexts_trouble();
895  }
896  }
897 
898  /* is every entry in the root_table also in the root list? */
899  if (!c2->root_table) {
900  if (c2->root) {
901  ast_log(LOG_NOTICE,"Called from: %s:%d: No c2->root_table for context %s!\n", file, line, c2->name);
902  usleep(500000);
903  }
904  } else {
906  while( (e2 = ast_hashtab_next(t1)) ) {
907  for(e1=c2->root;e1;e1=e1->next) {
908  if (!strcmp(e1->exten, e2->exten)) {
909  found = 1;
910  break;
911  }
912  }
913  if (!found) {
914  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context records the exten %s but it is not in its root_table\n", file, line, c2->name, e2->exten);
915  check_contexts_trouble();
916  }
917 
918  }
920  }
921  }
922  /* is every priority reflected in the peer_table at the head of the list? */
923 
924  /* is every entry in the root list also in the root_table? */
925  /* are the per-extension peer_tables in the right place? */
926 
927  for(e1 = c2->root; e1; e1 = e1->next) {
928 
929  for(e2=e1;e2;e2=e2->peer) {
930  ex.priority = e2->priority;
931  if (e2 != e1 && e2->peer_table) {
932  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority has a peer_table entry, and shouldn't!\n", file, line, c2->name, e1->exten, e2->priority );
933  check_contexts_trouble();
934  }
935 
936  if (e2 != e1 && e2->peer_label_table) {
937  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority has a peer_label_table entry, and shouldn't!\n", file, line, c2->name, e1->exten, e2->priority );
938  check_contexts_trouble();
939  }
940 
941  if (e2 == e1 && !e2->peer_table){
942  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority doesn't have a peer_table!\n", file, line, c2->name, e1->exten, e2->priority );
943  check_contexts_trouble();
944  }
945 
946  if (e2 == e1 && !e2->peer_label_table) {
947  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority doesn't have a peer_label_table!\n", file, line, c2->name, e1->exten, e2->priority );
948  check_contexts_trouble();
949  }
950 
951 
952  e3 = ast_hashtab_lookup(e1->peer_table, &ex);
953  if (!e3) {
954  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority is not reflected in the peer_table\n", file, line, c2->name, e1->exten, e2->priority );
955  check_contexts_trouble();
956  }
957  }
958 
959  if (!e1->peer_table){
960  ast_log(LOG_NOTICE,"Called from: %s:%d: No e1->peer_table!\n", file, line);
961  usleep(500000);
962  }
963 
964  /* is every entry in the peer_table also in the peer list? */
966  while( (e2 = ast_hashtab_next(t1)) ) {
967  for(e3=e1;e3;e3=e3->peer) {
968  if (e3->priority == e2->priority) {
969  found = 1;
970  break;
971  }
972  }
973  if (!found) {
974  ast_log(LOG_NOTICE,"Called from: %s:%d: The %s context, %s exten, %d priority is not reflected in the peer list\n", file, line, c2->name, e1->exten, e2->priority );
975  check_contexts_trouble();
976  }
977  }
979  }
980  }
981  return 0;
982 }
983 #endif
984 
985 static void pbx_destroy(struct ast_pbx *p)
986 {
987  ast_free(p);
988 }
989 
990 /* form a tree that fully describes all the patterns in a context's extensions
991  * in this tree, a "node" represents an individual character or character set
992  * meant to match the corresponding character in a dial string. The tree
993  * consists of a series of match_char structs linked in a chain
994  * via the alt_char pointers. More than one pattern can share the same parts of the
995  * tree as other extensions with the same pattern to that point.
996  * My first attempt to duplicate the finding of the 'best' pattern was flawed in that
997  * I misunderstood the general algorithm. I thought that the 'best' pattern
998  * was the one with lowest total score. This was not true. Thus, if you have
999  * patterns "1XXXXX" and "X11111", you would be tempted to say that "X11111" is
1000  * the "best" match because it has fewer X's, and is therefore more specific,
1001  * but this is not how the old algorithm works. It sorts matching patterns
1002  * in a similar collating sequence as sorting alphabetic strings, from left to
1003  * right. Thus, "1XXXXX" comes before "X11111", and would be the "better" match,
1004  * because "1" is more specific than "X".
1005  * So, to accomodate this philosophy, I sort the tree branches along the alt_char
1006  * line so they are lowest to highest in specificity numbers. This way, as soon
1007  * as we encounter our first complete match, we automatically have the "best"
1008  * match and can stop the traversal immediately. Same for CANMATCH/MATCHMORE.
1009  * If anyone would like to resurrect the "wrong" pattern trie searching algorithm,
1010  * they are welcome to revert pbx to before 1 Apr 2008.
1011  * As an example, consider these 4 extensions:
1012  * (a) NXXNXXXXXX
1013  * (b) 307754XXXX
1014  * (c) fax
1015  * (d) NXXXXXXXXX
1016  *
1017  * In the above, between (a) and (d), (a) is a more specific pattern than (d), and would win over
1018  * most numbers. For all numbers beginning with 307754, (b) should always win.
1019  *
1020  * These pattern should form a (sorted) tree that looks like this:
1021  * { "3" } --next--> { "0" } --next--> { "7" } --next--> { "7" } --next--> { "5" } ... blah ... --> { "X" exten_match: (b) }
1022  * |
1023  * |alt
1024  * |
1025  * { "f" } --next--> { "a" } --next--> { "x" exten_match: (c) }
1026  * { "N" } --next--> { "X" } --next--> { "X" } --next--> { "N" } --next--> { "X" } ... blah ... --> { "X" exten_match: (a) }
1027  * | |
1028  * | |alt
1029  * |alt |
1030  * | { "X" } --next--> { "X" } ... blah ... --> { "X" exten_match: (d) }
1031  * |
1032  * NULL
1033  *
1034  * In the above, I could easily turn "N" into "23456789", but I think that a quick "if( *z >= '2' && *z <= '9' )" might take
1035  * fewer CPU cycles than a call to strchr("23456789",*z), where *z is the char to match...
1036  *
1037  * traversal is pretty simple: one routine merely traverses the alt list, and for each matching char in the pattern, it calls itself
1038  * on the corresponding next pointer, incrementing also the pointer of the string to be matched, and passing the total specificity and length.
1039  * We pass a pointer to a scoreboard down through, also.
1040  * The scoreboard isn't as necessary to the revised algorithm, but I kept it as a handy way to return the matched extension.
1041  * The first complete match ends the traversal, which should make this version of the pattern matcher faster
1042  * the previous. The same goes for "CANMATCH" or "MATCHMORE"; the first such match ends the traversal. In both
1043  * these cases, the reason we can stop immediately, is because the first pattern match found will be the "best"
1044  * according to the sort criteria.
1045  * Hope the limit on stack depth won't be a problem... this routine should
1046  * be pretty lean as far a stack usage goes. Any non-match terminates the recursion down a branch.
1047  *
1048  * In the above example, with the number "3077549999" as the pattern, the traversor could match extensions a, b and d. All are
1049  * of length 10; they have total specificities of 24580, 10246, and 25090, respectively, not that this matters
1050  * at all. (b) wins purely because the first character "3" is much more specific (lower specificity) than "N". I have
1051  * left the specificity totals in the code as an artifact; at some point, I will strip it out.
1052  *
1053  * Just how much time this algorithm might save over a plain linear traversal over all possible patterns is unknown,
1054  * because it's a function of how many extensions are stored in a context. With thousands of extensions, the speedup
1055  * can be very noticeable. The new matching algorithm can run several hundreds of times faster, if not a thousand or
1056  * more times faster in extreme cases.
1057  *
1058  * MatchCID patterns are also supported, and stored in the tree just as the extension pattern is. Thus, you
1059  * can have patterns in your CID field as well.
1060  *
1061  * */
1062 
1063 
1064 static void update_scoreboard(struct scoreboard *board, int length, int spec, struct ast_exten *exten, char last, const char *callerid, int deleted, struct match_char *node)
1065 {
1066  /* if this extension is marked as deleted, then skip this -- if it never shows
1067  on the scoreboard, it will never be found, nor will halt the traversal. */
1068  if (deleted)
1069  return;
1070  board->total_specificity = spec;
1071  board->total_length = length;
1072  board->exten = exten;
1073  board->last_char = last;
1074  board->node = node;
1075 #ifdef NEED_DEBUG_HERE
1076  ast_log(LOG_NOTICE,"Scoreboarding (LONGER) %s, len=%d, score=%d\n", exten->exten, length, spec);
1077 #endif
1078 }
1079 
1080 #ifdef NEED_DEBUG
1081 static void log_match_char_tree(struct match_char *node, char *prefix)
1082 {
1083  char extenstr[40];
1084  struct ast_str *my_prefix = ast_str_alloca(1024);
1085 
1086  extenstr[0] = '\0';
1087 
1088  if (node && node->exten)
1089  snprintf(extenstr, sizeof(extenstr), "(%p)", node->exten);
1090 
1091  if (strlen(node->x) > 1) {
1092  ast_debug(1, "%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N',
1093  node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"",
1094  node->exten ? node->exten->exten : "", extenstr);
1095  } else {
1096  ast_debug(1, "%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y':'N',
1097  node->deleted? 'D':'-', node->specificity, node->exten? "EXTEN:":"",
1098  node->exten ? node->exten->exten : "", extenstr);
1099  }
1100 
1101  ast_str_set(&my_prefix, 0, "%s+ ", prefix);
1102 
1103  if (node->next_char)
1104  log_match_char_tree(node->next_char, ast_str_buffer(my_prefix));
1105 
1106  if (node->alt_char)
1107  log_match_char_tree(node->alt_char, prefix);
1108 }
1109 #endif
1110 
1111 static void cli_match_char_tree(struct match_char *node, char *prefix, int fd)
1112 {
1113  char extenstr[40];
1114  struct ast_str *my_prefix = ast_str_alloca(1024);
1115 
1116  extenstr[0] = '\0';
1117 
1118  if (node->exten) {
1119  snprintf(extenstr, sizeof(extenstr), "(%p)", node->exten);
1120  }
1121 
1122  if (strlen(node->x) > 1) {
1123  ast_cli(fd, "%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y' : 'N',
1124  node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:" : "",
1125  node->exten ? node->exten->name : "", extenstr);
1126  } else {
1127  ast_cli(fd, "%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y' : 'N',
1128  node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:" : "",
1129  node->exten ? node->exten->name : "", extenstr);
1130  }
1131 
1132  ast_str_set(&my_prefix, 0, "%s+ ", prefix);
1133 
1134  if (node->next_char)
1135  cli_match_char_tree(node->next_char, ast_str_buffer(my_prefix), fd);
1136 
1137  if (node->alt_char)
1138  cli_match_char_tree(node->alt_char, prefix, fd);
1139 }
1140 
1141 static struct ast_exten *get_canmatch_exten(struct match_char *node)
1142 {
1143  /* find the exten at the end of the rope */
1144  struct match_char *node2 = node;
1145 
1146  for (node2 = node; node2; node2 = node2->next_char) {
1147  if (node2->exten) {
1148 #ifdef NEED_DEBUG_HERE
1149  ast_log(LOG_NOTICE,"CanMatch_exten returns exten %s(%p)\n", node2->exten->exten, node2->exten);
1150 #endif
1151  return node2->exten;
1152  }
1153  }
1154 #ifdef NEED_DEBUG_HERE
1155  ast_log(LOG_NOTICE,"CanMatch_exten returns NULL, match_char=%s\n", node->x);
1156 #endif
1157  return 0;
1158 }
1159 
1160 static struct ast_exten *trie_find_next_match(struct match_char *node)
1161 {
1162  struct match_char *m3;
1163  struct match_char *m4;
1164  struct ast_exten *e3;
1165 
1166  if (node && node->x[0] == '.' && !node->x[1]) { /* dot and ! will ALWAYS be next match in a matchmore */
1167  return node->exten;
1168  }
1169 
1170  if (node && node->x[0] == '!' && !node->x[1]) {
1171  return node->exten;
1172  }
1173 
1174  if (!node || !node->next_char) {
1175  return NULL;
1176  }
1177 
1178  m3 = node->next_char;
1179 
1180  if (m3->exten) {
1181  return m3->exten;
1182  }
1183  for (m4 = m3->alt_char; m4; m4 = m4->alt_char) {
1184  if (m4->exten) {
1185  return m4->exten;
1186  }
1187  }
1188  for (m4 = m3; m4; m4 = m4->alt_char) {
1189  e3 = trie_find_next_match(m3);
1190  if (e3) {
1191  return e3;
1192  }
1193  }
1194 
1195  return NULL;
1196 }
1197 
1198 #ifdef DEBUG_THIS
1199 static char *action2str(enum ext_match_t action)
1200 {
1201  switch (action) {
1202  case E_MATCH:
1203  return "MATCH";
1204  case E_CANMATCH:
1205  return "CANMATCH";
1206  case E_MATCHMORE:
1207  return "MATCHMORE";
1208  case E_FINDLABEL:
1209  return "FINDLABEL";
1210  case E_SPAWN:
1211  return "SPAWN";
1212  default:
1213  return "?ACTION?";
1214  }
1215 }
1216 
1217 #endif
1218 
1219 static const char *candidate_exten_advance(const char *str)
1220 {
1221  str++;
1222  while (*str == '-') {
1223  str++;
1224  }
1225  return str;
1226 }
1227 
1228 #define MORE(s) (*candidate_exten_advance(s))
1229 #define ADVANCE(s) candidate_exten_advance(s)
1230 
1231 static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid, const char *label, enum ext_match_t action)
1232 {
1233  struct match_char *p; /* note minimal stack storage requirements */
1234  struct ast_exten pattern = { .label = label };
1235 #ifdef DEBUG_THIS
1236  if (tree)
1237  ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree %s action=%s\n", str, tree->x, action2str(action));
1238  else
1239  ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree NULL action=%s\n", str, action2str(action));
1240 #endif
1241  for (p = tree; p; p = p->alt_char) {
1242  if (p->is_pattern) {
1243  if (p->x[0] == 'N') {
1244  if (p->x[1] == 0 && *str >= '2' && *str <= '9' ) {
1245 #define NEW_MATCHER_CHK_MATCH \
1246  if (p->exten && !MORE(str)) { /* if a shorter pattern matches along the way, might as well report it */ \
1247  if (action == E_MATCH || action == E_SPAWN || action == E_FINDLABEL) { /* if in CANMATCH/MATCHMORE, don't let matches get in the way */ \
1248  update_scoreboard(score, length + 1, spec + p->specificity, p->exten, 0, callerid, p->deleted, p); \
1249  if (!p->deleted) { \
1250  if (action == E_FINDLABEL) { \
1251  if (ast_hashtab_lookup(score->exten->peer_label_table, &pattern)) { \
1252  ast_debug(4, "Found label in preferred extension\n"); \
1253  return; \
1254  } \
1255  } else { \
1256  ast_debug(4, "returning an exact match-- first found-- %s\n", p->exten->name); \
1257  return; /* the first match, by definition, will be the best, because of the sorted tree */ \
1258  } \
1259  } \
1260  } \
1261  }
1262 
1263 #define NEW_MATCHER_RECURSE \
1264  if (p->next_char && (MORE(str) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0) \
1265  || p->next_char->x[0] == '!')) { \
1266  if (MORE(str) || p->next_char->x[0] == '!') { \
1267  new_find_extension(ADVANCE(str), score, p->next_char, length + 1, spec + p->specificity, callerid, label, action); \
1268  if (score->exten) { \
1269  ast_debug(4 ,"returning an exact match-- %s\n", score->exten->name); \
1270  return; /* the first match is all we need */ \
1271  } \
1272  } else { \
1273  new_find_extension("/", score, p->next_char, length + 1, spec + p->specificity, callerid, label, action); \
1274  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) { \
1275  ast_debug(4,"returning a (can/more) match--- %s\n", score->exten ? score->exten->name : \
1276  "NULL"); \
1277  return; /* the first match is all we need */ \
1278  } \
1279  } \
1280  } else if ((p->next_char || action == E_CANMATCH) && !MORE(str)) { \
1281  score->canmatch = 1; \
1282  score->canmatch_exten = get_canmatch_exten(p); \
1283  if (action == E_CANMATCH || action == E_MATCHMORE) { \
1284  ast_debug(4, "returning a canmatch/matchmore--- str=%s\n", str); \
1285  return; \
1286  } \
1287  }
1288 
1291  }
1292  } else if (p->x[0] == 'Z') {
1293  if (p->x[1] == 0 && *str >= '1' && *str <= '9' ) {
1296  }
1297  } else if (p->x[0] == 'X') {
1298  if (p->x[1] == 0 && *str >= '0' && *str <= '9' ) {
1301  }
1302  } else if (p->x[0] == '.' && p->x[1] == 0) {
1303  /* how many chars will the . match against? */
1304  int i = 0;
1305  const char *str2 = str;
1306  while (*str2 && *str2 != '/') {
1307  str2++;
1308  i++;
1309  }
1310  if (p->exten && *str2 != '/') {
1311  update_scoreboard(score, length + i, spec + (i * p->specificity), p->exten, '.', callerid, p->deleted, p);
1312  if (score->exten) {
1313  ast_debug(4, "return because scoreboard has a match with '/'--- %s\n",
1314  score->exten->name);
1315  return; /* the first match is all we need */
1316  }
1317  }
1318  if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
1319  new_find_extension("/", score, p->next_char, length + i, spec+(p->specificity*i), callerid, label, action);
1320  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
1321  ast_debug(4, "return because scoreboard has exact match OR "
1322  "CANMATCH/MATCHMORE & canmatch set--- %s\n",
1323  score->exten ? score->exten->name : "NULL");
1324  return; /* the first match is all we need */
1325  }
1326  }
1327  } else if (p->x[0] == '!' && p->x[1] == 0) {
1328  /* how many chars will the . match against? */
1329  int i = 1;
1330  const char *str2 = str;
1331  while (*str2 && *str2 != '/') {
1332  str2++;
1333  i++;
1334  }
1335  if (p->exten && *str2 != '/') {
1336  update_scoreboard(score, length + 1, spec + (p->specificity * i), p->exten, '!', callerid, p->deleted, p);
1337  if (score->exten) {
1338  ast_debug(4, "return because scoreboard has a '!' match--- %s\n",
1339  score->exten->name);
1340  return; /* the first match is all we need */
1341  }
1342  }
1343  if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
1344  new_find_extension("/", score, p->next_char, length + i, spec + (p->specificity * i), callerid, label, action);
1345  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
1346  ast_debug(4, "return because scoreboard has exact match OR "
1347  "CANMATCH/MATCHMORE & canmatch set with '/' and '!'--- %s\n",
1348  score->exten ? score->exten->name : "NULL");
1349  return; /* the first match is all we need */
1350  }
1351  }
1352  } else if (p->x[0] == '/' && p->x[1] == 0) {
1353  /* the pattern in the tree includes the cid match! */
1354  if (p->next_char && callerid && *callerid) {
1355  new_find_extension(callerid, score, p->next_char, length + 1, spec, callerid, label, action);
1356  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
1357  ast_debug(4, "return because scoreboard has exact match OR "
1358  "CANMATCH/MATCHMORE & canmatch set with '/'--- %s\n",
1359  score->exten ? score->exten->name : "NULL");
1360  return; /* the first match is all we need */
1361  }
1362  }
1363  } else if (strchr(p->x, *str)) {
1364  ast_debug(4, "Nothing strange about this match\n");
1367  }
1368  } else if (strchr(p->x, *str)) {
1369  ast_debug(4, "Nothing strange about this match\n");
1372  }
1373  }
1374  ast_debug(4, "return at end of func\n");
1375 }
1376 
1377 #undef MORE
1378 #undef ADVANCE
1379 
1380 /* the algorithm for forming the extension pattern tree is also a bit simple; you
1381  * traverse all the extensions in a context, and for each char of the extension,
1382  * you see if it exists in the tree; if it doesn't, you add it at the appropriate
1383  * spot. What more can I say? At the end of each exten, you cap it off by adding the
1384  * address of the extension involved. Duplicate patterns will be complained about.
1385  *
1386  * Ideally, this would be done for each context after it is created and fully
1387  * filled. It could be done as a finishing step after extensions.conf or .ael is
1388  * loaded, or it could be done when the first search is encountered. It should only
1389  * have to be done once, until the next unload or reload.
1390  *
1391  * I guess forming this pattern tree would be analogous to compiling a regex. Except
1392  * that a regex only handles 1 pattern, really. This trie holds any number
1393  * of patterns. Well, really, it **could** be considered a single pattern,
1394  * where the "|" (or) operator is allowed, I guess, in a way, sort of...
1395  */
1396 
1397 static struct match_char *already_in_tree(struct match_char *current, char *pat, int is_pattern)
1398 {
1399  struct match_char *t;
1400 
1401  if (!current) {
1402  return 0;
1403  }
1404 
1405  for (t = current; t; t = t->alt_char) {
1406  if (is_pattern == t->is_pattern && !strcmp(pat, t->x)) {/* uh, we may want to sort exploded [] contents to make matching easy */
1407  return t;
1408  }
1409  }
1410 
1411  return 0;
1412 }
1413 
1414 /* The first arg is the location of the tree ptr, or the
1415  address of the next_char ptr in the node, so we can mess
1416  with it, if we need to insert at the beginning of the list */
1417 
1418 static void insert_in_next_chars_alt_char_list(struct match_char **parent_ptr, struct match_char *node)
1419 {
1420  struct match_char *curr, *lcurr;
1421 
1422  /* insert node into the tree at "current", so the alt_char list from current is
1423  sorted in increasing value as you go to the leaves */
1424  if (!(*parent_ptr)) {
1425  *parent_ptr = node;
1426  return;
1427  }
1428 
1429  if ((*parent_ptr)->specificity > node->specificity) {
1430  /* insert at head */
1431  node->alt_char = (*parent_ptr);
1432  *parent_ptr = node;
1433  return;
1434  }
1435 
1436  lcurr = *parent_ptr;
1437  for (curr = (*parent_ptr)->alt_char; curr; curr = curr->alt_char) {
1438  if (curr->specificity > node->specificity) {
1439  node->alt_char = curr;
1440  lcurr->alt_char = node;
1441  break;
1442  }
1443  lcurr = curr;
1444  }
1445 
1446  if (!curr) {
1447  lcurr->alt_char = node;
1448  }
1449 
1450 }
1451 
1453  /*! Pattern node specificity */
1454  int specif;
1455  /*! Pattern node match characters. */
1456  char buf[256];
1457 };
1458 
1459 static struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, const struct pattern_node *pattern, int is_pattern, int already, struct match_char **nextcharptr)
1460 {
1461  struct match_char *m;
1462 
1463  if (!(m = ast_calloc(1, sizeof(*m) + strlen(pattern->buf)))) {
1464  return NULL;
1465  }
1466 
1467  /* strcpy is safe here since we know its size and have allocated
1468  * just enough space for when we allocated m
1469  */
1470  strcpy(m->x, pattern->buf);
1471 
1472  /* the specificity scores are the same as used in the old
1473  pattern matcher. */
1474  m->is_pattern = is_pattern;
1475  if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'N') {
1476  m->specificity = 0x0832;
1477  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'Z') {
1478  m->specificity = 0x0931;
1479  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'X') {
1480  m->specificity = 0x0a30;
1481  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == '.') {
1482  m->specificity = 0x18000;
1483  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == '!') {
1484  m->specificity = 0x28000;
1485  } else {
1486  m->specificity = pattern->specif;
1487  }
1488 
1489  if (!con->pattern_tree) {
1491  } else {
1492  if (already) { /* switch to the new regime (traversing vs appending)*/
1493  insert_in_next_chars_alt_char_list(nextcharptr, m);
1494  } else {
1496  }
1497  }
1498 
1499  return m;
1500 }
1501 
1502 /*!
1503  * \internal
1504  * \brief Extract the next exten pattern node.
1505  *
1506  * \param node Pattern node to fill.
1507  * \param src Next source character to read.
1508  * \param pattern TRUE if the exten is a pattern.
1509  * \param extenbuf Original exten buffer to use in diagnostic messages.
1510  *
1511  * \retval Ptr to next extenbuf pos to read.
1512  */
1513 static const char *get_pattern_node(struct pattern_node *node, const char *src, int pattern, const char *extenbuf)
1514 {
1515 #define INC_DST_OVERFLOW_CHECK \
1516  do { \
1517  if (dst - node->buf < sizeof(node->buf) - 1) { \
1518  ++dst; \
1519  } else { \
1520  overflow = 1; \
1521  } \
1522  } while (0)
1523 
1524  node->specif = 0;
1525  node->buf[0] = '\0';
1526  while (*src) {
1527  if (*src == '[' && pattern) {
1528  char *dst = node->buf;
1529  const char *src_next;
1530  int length;
1531  int overflow = 0;
1532 
1533  /* get past the '[' */
1534  ++src;
1535  for (;;) {
1536  if (*src == '\\') {
1537  /* Escaped character. */
1538  ++src;
1539  if (*src == '[' || *src == '\\' || *src == '-' || *src == ']') {
1540  *dst = *src++;
1542  }
1543  } else if (*src == '-') {
1544  unsigned char first;
1545  unsigned char last;
1546 
1547  src_next = src;
1548  first = *(src_next - 1);
1549  last = *++src_next;
1550 
1551  if (last == '\\') {
1552  /* Escaped character. */
1553  last = *++src_next;
1554  }
1555 
1556  /* Possible char range. */
1557  if (node->buf[0] && last) {
1558  /* Expand the char range. */
1559  while (++first <= last) {
1560  *dst = first;
1562  }
1563  src = src_next + 1;
1564  } else {
1565  /*
1566  * There was no left or right char for the range.
1567  * It is just a '-'.
1568  */
1569  *dst = *src++;
1571  }
1572  } else if (*src == '\0') {
1574  "A matching ']' was not found for '[' in exten pattern '%s'\n",
1575  extenbuf);
1576  break;
1577  } else if (*src == ']') {
1578  ++src;
1579  break;
1580  } else {
1581  *dst = *src++;
1583  }
1584  }
1585  /* null terminate the exploded range */
1586  *dst = '\0';
1587 
1588  if (overflow) {
1590  "Expanded character set too large to deal with in exten pattern '%s'. Ignoring character set.\n",
1591  extenbuf);
1592  node->buf[0] = '\0';
1593  continue;
1594  }
1595 
1596  /* Sort the characters in character set. */
1597  length = strlen(node->buf);
1598  if (!length) {
1599  ast_log(LOG_WARNING, "Empty character set in exten pattern '%s'. Ignoring.\n",
1600  extenbuf);
1601  node->buf[0] = '\0';
1602  continue;
1603  }
1604  qsort(node->buf, length, 1, compare_char);
1605 
1606  /* Remove duplicate characters from character set. */
1607  dst = node->buf;
1608  src_next = node->buf;
1609  while (*src_next++) {
1610  if (*dst != *src_next) {
1611  *++dst = *src_next;
1612  }
1613  }
1614 
1615  length = strlen(node->buf);
1616  length <<= 8;
1617  node->specif = length | (unsigned char) node->buf[0];
1618  break;
1619  } else if (*src == '-') {
1620  /* Skip dashes in all extensions. */
1621  ++src;
1622  } else {
1623  if (*src == '\\') {
1624  /*
1625  * XXX The escape character here does not remove any special
1626  * meaning to characters except the '[', '\\', and '-'
1627  * characters since they are special only in this function.
1628  */
1629  node->buf[0] = *++src;
1630  if (!node->buf[0]) {
1631  break;
1632  }
1633  } else {
1634  node->buf[0] = *src;
1635  if (pattern) {
1636  /* make sure n,x,z patterns are canonicalized to N,X,Z */
1637  if (node->buf[0] == 'n') {
1638  node->buf[0] = 'N';
1639  } else if (node->buf[0] == 'x') {
1640  node->buf[0] = 'X';
1641  } else if (node->buf[0] == 'z') {
1642  node->buf[0] = 'Z';
1643  }
1644  }
1645  }
1646  node->buf[1] = '\0';
1647  node->specif = 1;
1648  ++src;
1649  break;
1650  }
1651  }
1652  return src;
1653 
1654 #undef INC_DST_OVERFLOW_CHECK
1655 }
1656 
1657 static struct match_char *add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly)
1658 {
1659  struct match_char *m1 = NULL;
1660  struct match_char *m2 = NULL;
1661  struct match_char **m0;
1662  const char *pos;
1663  int already;
1664  int pattern = 0;
1665  int idx_cur;
1666  int idx_next;
1667  char extenbuf[512];
1668  struct pattern_node pat_node[2];
1669 
1670  if (e1->matchcid) {
1671  if (sizeof(extenbuf) < strlen(e1->exten) + strlen(e1->cidmatch) + 2) {
1673  "The pattern %s/%s is too big to deal with: it will be ignored! Disaster!\n",
1674  e1->exten, e1->cidmatch);
1675  return NULL;
1676  }
1677  sprintf(extenbuf, "%s/%s", e1->exten, e1->cidmatch);/* Safe. We just checked. */
1678  } else {
1679  ast_copy_string(extenbuf, e1->exten, sizeof(extenbuf));
1680  }
1681 
1682 #ifdef NEED_DEBUG
1683  ast_debug(1, "Adding exten %s to tree\n", extenbuf);
1684 #endif
1685  m1 = con->pattern_tree; /* each pattern starts over at the root of the pattern tree */
1686  m0 = &con->pattern_tree;
1687  already = 1;
1688 
1689  pos = extenbuf;
1690  if (*pos == '_') {
1691  pattern = 1;
1692  ++pos;
1693  }
1694  idx_cur = 0;
1695  pos = get_pattern_node(&pat_node[idx_cur], pos, pattern, extenbuf);
1696  for (; pat_node[idx_cur].buf[0]; idx_cur = idx_next) {
1697  idx_next = (idx_cur + 1) % ARRAY_LEN(pat_node);
1698  pos = get_pattern_node(&pat_node[idx_next], pos, pattern, extenbuf);
1699 
1700  /* See about adding node to tree. */
1701  m2 = NULL;
1702  if (already && (m2 = already_in_tree(m1, pat_node[idx_cur].buf, pattern))
1703  && m2->next_char) {
1704  if (!pat_node[idx_next].buf[0]) {
1705  /*
1706  * This is the end of the pattern, but not the end of the tree.
1707  * Mark this node with the exten... a shorter pattern might win
1708  * if the longer one doesn't match.
1709  */
1710  if (findonly) {
1711  return m2;
1712  }
1713  if (m2->exten) {
1714  ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n",
1715  m2->deleted ? "(deleted/invalid)" : m2->exten->name, e1->name);
1716  }
1717  m2->exten = e1;
1718  m2->deleted = 0;
1719  }
1720  m1 = m2->next_char; /* m1 points to the node to compare against */
1721  m0 = &m2->next_char; /* m0 points to the ptr that points to m1 */
1722  } else { /* not already OR not m2 OR nor m2->next_char */
1723  if (m2) {
1724  if (findonly) {
1725  return m2;
1726  }
1727  m1 = m2; /* while m0 stays the same */
1728  } else {
1729  if (findonly) {
1730  return m1;
1731  }
1732  m1 = add_pattern_node(con, m1, &pat_node[idx_cur], pattern, already, m0);
1733  if (!m1) { /* m1 is the node just added */
1734  return NULL;
1735  }
1736  m0 = &m1->next_char;
1737  }
1738  if (!pat_node[idx_next].buf[0]) {
1739  if (m2 && m2->exten) {
1740  ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n",
1741  m2->deleted ? "(deleted/invalid)" : m2->exten->name, e1->name);
1742  }
1743  m1->deleted = 0;
1744  m1->exten = e1;
1745  }
1746 
1747  /* The 'already' variable is a mini-optimization designed to make it so that we
1748  * don't have to call already_in_tree when we know it will return false.
1749  */
1750  already = 0;
1751  }
1752  }
1753  return m1;
1754 }
1755 
1756 static void create_match_char_tree(struct ast_context *con)
1757 {
1758  struct ast_hashtab_iter *t1;
1759  struct ast_exten *e1;
1760 #ifdef NEED_DEBUG
1761  int biggest_bucket, resizes, numobjs, numbucks;
1762 
1763  ast_debug(1, "Creating Extension Trie for context %s(%p)\n", con->name, con);
1764  ast_hashtab_get_stats(con->root_table, &biggest_bucket, &resizes, &numobjs, &numbucks);
1765  ast_debug(1, "This tree has %d objects in %d bucket lists, longest list=%d objects, and has resized %d times\n",
1766  numobjs, numbucks, biggest_bucket, resizes);
1767 #endif
1769  while ((e1 = ast_hashtab_next(t1))) {
1770  if (e1->exten) {
1771  add_exten_to_pattern_tree(con, e1, 0);
1772  } else {
1773  ast_log(LOG_ERROR, "Attempt to create extension with no extension name.\n");
1774  }
1775  }
1777 }
1778 
1779 static void destroy_pattern_tree(struct match_char *pattern_tree) /* pattern tree is a simple binary tree, sort of, so the proper way to destroy it is... recursively! */
1780 {
1781  /* destroy all the alternates */
1782  if (pattern_tree->alt_char) {
1783  destroy_pattern_tree(pattern_tree->alt_char);
1784  pattern_tree->alt_char = 0;
1785  }
1786  /* destroy all the nexts */
1787  if (pattern_tree->next_char) {
1788  destroy_pattern_tree(pattern_tree->next_char);
1789  pattern_tree->next_char = 0;
1790  }
1791  pattern_tree->exten = 0; /* never hurts to make sure there's no pointers laying around */
1792  ast_free(pattern_tree);
1793 }
1794 
1795 /*!
1796  * \internal
1797  * \brief Get the length of the exten string.
1798  *
1799  * \param str Exten to get length.
1800  *
1801  * \retval strlen of exten.
1802  */
1803 static int ext_cmp_exten_strlen(const char *str)
1804 {
1805  int len;
1806 
1807  len = 0;
1808  for (;;) {
1809  /* Ignore '-' chars as eye candy fluff. */
1810  while (*str == '-') {
1811  ++str;
1812  }
1813  if (!*str) {
1814  break;
1815  }
1816  ++str;
1817  ++len;
1818  }
1819  return len;
1820 }
1821 
1822 /*!
1823  * \internal
1824  * \brief Partial comparison of non-pattern extens.
1825  *
1826  * \param left Exten to compare.
1827  * \param right Exten to compare. Also matches if this string ends first.
1828  *
1829  * \retval <0 if left < right
1830  * \retval =0 if left == right
1831  * \retval >0 if left > right
1832  */
1833 static int ext_cmp_exten_partial(const char *left, const char *right)
1834 {
1835  int cmp;
1836 
1837  for (;;) {
1838  /* Ignore '-' chars as eye candy fluff. */
1839  while (*left == '-') {
1840  ++left;
1841  }
1842  while (*right == '-') {
1843  ++right;
1844  }
1845 
1846  if (!*right) {
1847  /*
1848  * Right ended first for partial match or both ended at the same
1849  * time for a match.
1850  */
1851  cmp = 0;
1852  break;
1853  }
1854 
1855  cmp = *left - *right;
1856  if (cmp) {
1857  break;
1858  }
1859  ++left;
1860  ++right;
1861  }
1862  return cmp;
1863 }
1864 
1865 /*!
1866  * \internal
1867  * \brief Comparison of non-pattern extens.
1868  *
1869  * \param left Exten to compare.
1870  * \param right Exten to compare.
1871  *
1872  * \retval <0 if left < right
1873  * \retval =0 if left == right
1874  * \retval >0 if left > right
1875  */
1876 static int ext_cmp_exten(const char *left, const char *right)
1877 {
1878  int cmp;
1879 
1880  for (;;) {
1881  /* Ignore '-' chars as eye candy fluff. */
1882  while (*left == '-') {
1883  ++left;
1884  }
1885  while (*right == '-') {
1886  ++right;
1887  }
1888 
1889  cmp = *left - *right;
1890  if (cmp) {
1891  break;
1892  }
1893  if (!*left) {
1894  /*
1895  * Get here only if both strings ended at the same time. cmp
1896  * would be non-zero if only one string ended.
1897  */
1898  break;
1899  }
1900  ++left;
1901  ++right;
1902  }
1903  return cmp;
1904 }
1905 
1906 /*
1907  * Special characters used in patterns:
1908  * '_' underscore is the leading character of a pattern.
1909  * In other position it is treated as a regular char.
1910  * '-' The '-' is a separator and ignored. Why? So patterns like NXX-XXX-XXXX work.
1911  * . one or more of any character. Only allowed at the end of
1912  * a pattern.
1913  * ! zero or more of anything. Also impacts the result of CANMATCH
1914  * and MATCHMORE. Only allowed at the end of a pattern.
1915  * In the core routine, ! causes a match with a return code of 2.
1916  * In turn, depending on the search mode: (XXX check if it is implemented)
1917  * - E_MATCH retuns 1 (does match)
1918  * - E_MATCHMORE returns 0 (no match)
1919  * - E_CANMATCH returns 1 (does match)
1920  *
1921  * / should not appear as it is considered the separator of the CID info.
1922  * XXX at the moment we may stop on this char.
1923  *
1924  * X Z N match ranges 0-9, 1-9, 2-9 respectively.
1925  * [ denotes the start of a set of character. Everything inside
1926  * is considered literally. We can have ranges a-d and individual
1927  * characters. A '[' and '-' can be considered literally if they
1928  * are just before ']'.
1929  * XXX currently there is no way to specify ']' in a range, nor \ is
1930  * considered specially.
1931  *
1932  * When we compare a pattern with a specific extension, all characters in the extension
1933  * itself are considered literally.
1934  * XXX do we want to consider space as a separator as well ?
1935  * XXX do we want to consider the separators in non-patterns as well ?
1936  */
1937 
1938 /*!
1939  * \brief helper functions to sort extension patterns in the desired way,
1940  * so that more specific patterns appear first.
1941  *
1942  * \details
1943  * The function compares individual characters (or sets of), returning
1944  * an int where bits 0-7 are the ASCII code of the first char in the set,
1945  * bits 8-15 are the number of characters in the set, and bits 16-20 are
1946  * for special cases.
1947  * This way more specific patterns (smaller character sets) appear first.
1948  * Wildcards have a special value, so that we can directly compare them to
1949  * sets by subtracting the two values. In particular:
1950  * 0x001xx one character, character set starting with xx
1951  * 0x0yyxx yy characters, character set starting with xx
1952  * 0x18000 '.' (one or more of anything)
1953  * 0x28000 '!' (zero or more of anything)
1954  * 0x30000 NUL (end of string)
1955  * 0x40000 error in set.
1956  * The pointer to the string is advanced according to needs.
1957  * NOTES:
1958  * 1. the empty set is ignored.
1959  * 2. given that a full set has always 0 as the first element,
1960  * we could encode the special cases as 0xffXX where XX
1961  * is 1, 2, 3, 4 as used above.
1962  */
1963 static int ext_cmp_pattern_pos(const char **p, unsigned char *bitwise)
1964 {
1965 #define BITS_PER 8 /* Number of bits per unit (byte). */
1966  unsigned char c;
1967  unsigned char cmin;
1968  int count;
1969  const char *end;
1970 
1971  do {
1972  /* Get character and advance. (Ignore '-' chars as eye candy fluff.) */
1973  do {
1974  c = *(*p)++;
1975  } while (c == '-');
1976 
1977  /* always return unless we have a set of chars */
1978  switch (c) {
1979  default:
1980  /* ordinary character */
1981  bitwise[c / BITS_PER] = 1 << ((BITS_PER - 1) - (c % BITS_PER));
1982  return 0x0100 | c;
1983 
1984  case 'n':
1985  case 'N':
1986  /* 2..9 */
1987  bitwise[6] = 0x3f;
1988  bitwise[7] = 0xc0;
1989  return 0x0800 | '2';
1990 
1991  case 'x':
1992  case 'X':
1993  /* 0..9 */
1994  bitwise[6] = 0xff;
1995  bitwise[7] = 0xc0;
1996  return 0x0A00 | '0';
1997 
1998  case 'z':
1999  case 'Z':
2000  /* 1..9 */
2001  bitwise[6] = 0x7f;
2002  bitwise[7] = 0xc0;
2003  return 0x0900 | '1';
2004 
2005  case '.':
2006  /* wildcard */
2007  return 0x18000;
2008 
2009  case '!':
2010  /* earlymatch */
2011  return 0x28000; /* less specific than '.' */
2012 
2013  case '\0':
2014  /* empty string */
2015  *p = NULL;
2016  return 0x30000;
2017 
2018  case '[':
2019  /* char set */
2020  break;
2021  }
2022  /* locate end of set */
2023  end = strchr(*p, ']');
2024 
2025  if (!end) {
2026  ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
2027  return 0x40000; /* XXX make this entry go last... */
2028  }
2029 
2030  count = 0;
2031  cmin = 0xFF;
2032  for (; *p < end; ++*p) {
2033  unsigned char c1; /* first char in range */
2034  unsigned char c2; /* last char in range */
2035 
2036  c1 = (*p)[0];
2037  if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
2038  c2 = (*p)[2];
2039  *p += 2; /* skip a total of 3 chars */
2040  } else { /* individual character */
2041  c2 = c1;
2042  }
2043  if (c1 < cmin) {
2044  cmin = c1;
2045  }
2046  for (; c1 <= c2; ++c1) {
2047  unsigned char mask = 1 << ((BITS_PER - 1) - (c1 % BITS_PER));
2048 
2049  /*
2050  * Note: If two character sets score the same, the one with the
2051  * lowest ASCII values will compare as coming first. Must fill
2052  * in most significant bits for lower ASCII values to accomplish
2053  * the desired sort order.
2054  */
2055  if (!(bitwise[c1 / BITS_PER] & mask)) {
2056  /* Add the character to the set. */
2057  bitwise[c1 / BITS_PER] |= mask;
2058  count += 0x100;
2059  }
2060  }
2061  }
2062  ++*p;
2063  } while (!count);/* While the char set was empty. */
2064  return count | cmin;
2065 }
2066 
2067 /*!
2068  * \internal
2069  * \brief Comparison of exten patterns.
2070  *
2071  * \param left Pattern to compare.
2072  * \param right Pattern to compare.
2073  *
2074  * \retval <0 if left < right
2075  * \retval =0 if left == right
2076  * \retval >0 if left > right
2077  */
2078 static int ext_cmp_pattern(const char *left, const char *right)
2079 {
2080  int cmp;
2081  int left_pos;
2082  int right_pos;
2083 
2084  for (;;) {
2085  unsigned char left_bitwise[32] = { 0, };
2086  unsigned char right_bitwise[32] = { 0, };
2087 
2088  left_pos = ext_cmp_pattern_pos(&left, left_bitwise);
2089  right_pos = ext_cmp_pattern_pos(&right, right_bitwise);
2090  cmp = left_pos - right_pos;
2091  if (!cmp) {
2092  /*
2093  * Are the character sets different, even though they score the same?
2094  *
2095  * Note: Must swap left and right to get the sense of the
2096  * comparison correct. Otherwise, we would need to multiply by
2097  * -1 instead.
2098  */
2099  cmp = memcmp(right_bitwise, left_bitwise, ARRAY_LEN(left_bitwise));
2100  }
2101  if (cmp) {
2102  break;
2103  }
2104  if (!left) {
2105  /*
2106  * Get here only if both patterns ended at the same time. cmp
2107  * would be non-zero if only one pattern ended.
2108  */
2109  break;
2110  }
2111  }
2112  return cmp;
2113 }
2114 
2115 /*!
2116  * \internal
2117  * \brief Comparison of dialplan extens for sorting purposes.
2118  *
2119  * \param left Exten/pattern to compare.
2120  * \param right Exten/pattern to compare.
2121  *
2122  * \retval <0 if left < right
2123  * \retval =0 if left == right
2124  * \retval >0 if left > right
2125  */
2126 static int ext_cmp(const char *left, const char *right)
2127 {
2128  /* Make sure non-pattern extens come first. */
2129  if (left[0] != '_') {
2130  if (right[0] == '_') {
2131  return -1;
2132  }
2133  /* Compare two non-pattern extens. */
2134  return ext_cmp_exten(left, right);
2135  }
2136  if (right[0] != '_') {
2137  return 1;
2138  }
2139 
2140  /*
2141  * OK, we need full pattern sorting routine.
2142  *
2143  * Skip past the underscores
2144  */
2145  return ext_cmp_pattern(left + 1, right + 1);
2146 }
2147 
2148 static int ext_fluff_count(const char *exten)
2149 {
2150  int fluff = 0;
2151 
2152  if (*exten != '_') {
2153  /* not a pattern, simple check. */
2154  while (*exten) {
2155  if (*exten == '-') {
2156  fluff++;
2157  }
2158  exten++;
2159  }
2160 
2161  return fluff;
2162  }
2163 
2164  /* do pattern check */
2165  while (*exten) {
2166  if (*exten == '-') {
2167  fluff++;
2168  } else if (*exten == '[') {
2169  /* skip set, dashes here matter. */
2170  exten = strchr(exten, ']');
2171 
2172  if (!exten) {
2173  /* we'll end up warning about this later, don't spam logs */
2174  return fluff;
2175  }
2176  }
2177  exten++;
2178  }
2179 
2180  return fluff;
2181 }
2182 
2183 int ast_extension_cmp(const char *a, const char *b)
2184 {
2185  int cmp;
2186 
2187  cmp = ext_cmp(a, b);
2188  if (cmp < 0) {
2189  return -1;
2190  }
2191  if (cmp > 0) {
2192  return 1;
2193  }
2194  return 0;
2195 }
2196 
2197 /*!
2198  * \internal
2199  * \brief used ast_extension_{match|close}
2200  * mode is as follows:
2201  * E_MATCH success only on exact match
2202  * E_MATCHMORE success only on partial match (i.e. leftover digits in pattern)
2203  * E_CANMATCH either of the above.
2204  * \retval 0 on no-match
2205  * \retval 1 on match
2206  * \retval 2 on early match.
2207  */
2208 
2209 static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
2210 {
2211  mode &= E_MATCH_MASK; /* only consider the relevant bits */
2212 
2213 #ifdef NEED_DEBUG_HERE
2214  ast_log(LOG_NOTICE,"match core: pat: '%s', dat: '%s', mode=%d\n", pattern, data, (int)mode);
2215 #endif
2216 
2217  if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
2218  int lp = ext_cmp_exten_strlen(pattern);
2219  int ld = ext_cmp_exten_strlen(data);
2220 
2221  if (lp < ld) { /* pattern too short, cannot match */
2222 #ifdef NEED_DEBUG_HERE
2223  ast_log(LOG_NOTICE,"return (0) - pattern too short, cannot match\n");
2224 #endif
2225  return 0;
2226  }
2227  /* depending on the mode, accept full or partial match or both */
2228  if (mode == E_MATCH) {
2229 #ifdef NEED_DEBUG_HERE
2230  ast_log(LOG_NOTICE,"return (!ext_cmp_exten(%s,%s) when mode== E_MATCH)\n", pattern, data);
2231 #endif
2232  return !ext_cmp_exten(pattern, data); /* 1 on match, 0 on fail */
2233  }
2234  if (ld == 0 || !ext_cmp_exten_partial(pattern, data)) { /* partial or full match */
2235 #ifdef NEED_DEBUG_HERE
2236  ast_log(LOG_NOTICE,"return (mode(%d) == E_MATCHMORE ? lp(%d) > ld(%d) : 1)\n", mode, lp, ld);
2237 #endif
2238  return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
2239  } else {
2240 #ifdef NEED_DEBUG_HERE
2241  ast_log(LOG_NOTICE,"return (0) when ld(%d) > 0 && pattern(%s) != data(%s)\n", ld, pattern, data);
2242 #endif
2243  return 0;
2244  }
2245  }
2246  if (mode == E_MATCH && data[0] == '_') {
2247  /*
2248  * XXX It is bad design that we don't know if we should be
2249  * comparing data and pattern as patterns or comparing data if
2250  * it conforms to pattern when the function is called. First,
2251  * assume they are both patterns. If they don't match then try
2252  * to see if data conforms to the given pattern.
2253  *
2254  * note: if this test is left out, then _x. will not match _x. !!!
2255  */
2256 #ifdef NEED_DEBUG_HERE
2257  ast_log(LOG_NOTICE, "Comparing as patterns first. pattern:%s data:%s\n", pattern, data);
2258 #endif
2259  if (!ext_cmp_pattern(pattern + 1, data + 1)) {
2260 #ifdef NEED_DEBUG_HERE
2261  ast_log(LOG_NOTICE,"return (1) - pattern matches pattern\n");
2262 #endif
2263  return 1;
2264  }
2265  }
2266 
2267  ++pattern; /* skip leading _ */
2268  /*
2269  * XXX below we stop at '/' which is a separator for the CID info. However we should
2270  * not store '/' in the pattern at all. When we insure it, we can remove the checks.
2271  */
2272  for (;;) {
2273  const char *end;
2274 
2275  /* Ignore '-' chars as eye candy fluff. */
2276  while (*data == '-') {
2277  ++data;
2278  }
2279  while (*pattern == '-') {
2280  ++pattern;
2281  }
2282  if (!*data || !*pattern || *pattern == '/') {
2283  break;
2284  }
2285 
2286  switch (*pattern) {
2287  case '[': /* a range */
2288  ++pattern;
2289  end = strchr(pattern, ']'); /* XXX should deal with escapes ? */
2290  if (!end) {
2291  ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
2292  return 0; /* unconditional failure */
2293  }
2294  if (pattern == end) {
2295  /* Ignore empty character sets. */
2296  ++pattern;
2297  continue;
2298  }
2299  for (; pattern < end; ++pattern) {
2300  if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
2301  if (*data >= pattern[0] && *data <= pattern[2])
2302  break; /* match found */
2303  else {
2304  pattern += 2; /* skip a total of 3 chars */
2305  continue;
2306  }
2307  } else if (*data == pattern[0])
2308  break; /* match found */
2309  }
2310  if (pattern >= end) {
2311 #ifdef NEED_DEBUG_HERE
2312  ast_log(LOG_NOTICE,"return (0) when pattern>=end\n");
2313 #endif
2314  return 0;
2315  }
2316  pattern = end; /* skip and continue */
2317  break;
2318  case 'n':
2319  case 'N':
2320  if (*data < '2' || *data > '9') {
2321 #ifdef NEED_DEBUG_HERE
2322  ast_log(LOG_NOTICE,"return (0) N is not matched\n");
2323 #endif
2324  return 0;
2325  }
2326  break;
2327  case 'x':
2328  case 'X':
2329  if (*data < '0' || *data > '9') {
2330 #ifdef NEED_DEBUG_HERE
2331  ast_log(LOG_NOTICE,"return (0) X is not matched\n");
2332 #endif
2333  return 0;
2334  }
2335  break;
2336  case 'z':
2337  case 'Z':
2338  if (*data < '1' || *data > '9') {
2339 #ifdef NEED_DEBUG_HERE
2340  ast_log(LOG_NOTICE,"return (0) Z is not matched\n");
2341 #endif
2342  return 0;
2343  }
2344  break;
2345  case '.': /* Must match, even with more digits */
2346 #ifdef NEED_DEBUG_HERE
2347  ast_log(LOG_NOTICE, "return (1) when '.' is matched\n");
2348 #endif
2349  return 1;
2350  case '!': /* Early match */
2351 #ifdef NEED_DEBUG_HERE
2352  ast_log(LOG_NOTICE, "return (2) when '!' is matched\n");
2353 #endif
2354  return 2;
2355  default:
2356  if (*data != *pattern) {
2357 #ifdef NEED_DEBUG_HERE
2358  ast_log(LOG_NOTICE, "return (0) when *data(%c) != *pattern(%c)\n", *data, *pattern);
2359 #endif
2360  return 0;
2361  }
2362  break;
2363  }
2364  ++data;
2365  ++pattern;
2366  }
2367  if (*data) /* data longer than pattern, no match */ {
2368 #ifdef NEED_DEBUG_HERE
2369  ast_log(LOG_NOTICE, "return (0) when data longer than pattern\n");
2370 #endif
2371  return 0;
2372  }
2373 
2374  /*
2375  * match so far, but ran off the end of data.
2376  * Depending on what is next, determine match or not.
2377  */
2378  if (*pattern == '\0' || *pattern == '/') { /* exact match */
2379 #ifdef NEED_DEBUG_HERE
2380  ast_log(LOG_NOTICE, "at end, return (%d) in 'exact match'\n", (mode==E_MATCHMORE) ? 0 : 1);
2381 #endif
2382  return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */
2383  } else if (*pattern == '!') { /* early match */
2384 #ifdef NEED_DEBUG_HERE
2385  ast_log(LOG_NOTICE, "at end, return (2) when '!' is matched\n");
2386 #endif
2387  return 2;
2388  } else { /* partial match */
2389 #ifdef NEED_DEBUG_HERE
2390  ast_log(LOG_NOTICE, "at end, return (%d) which deps on E_MATCH\n", (mode == E_MATCH) ? 0 : 1);
2391 #endif
2392  return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */
2393  }
2394 }
2395 
2396 /*
2397  * Wrapper around _extension_match_core() to do performance measurement
2398  * using the profiling code.
2399  */
2400 static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
2401 {
2402  int i;
2403  static int prof_id = -2; /* marker for 'unallocated' id */
2404  if (prof_id == -2) {
2405  prof_id = ast_add_profile("ext_match", 0);
2406  }
2407  ast_mark(prof_id, 1);
2408  i = _extension_match_core(ast_strlen_zero(pattern) ? "" : pattern, ast_strlen_zero(data) ? "" : data, mode);
2409  ast_mark(prof_id, 0);
2410  return i;
2411 }
2412 
2413 int ast_extension_match(const char *pattern, const char *data)
2414 {
2415  return extension_match_core(pattern, data, E_MATCH);
2416 }
2417 
2418 int ast_extension_close(const char *pattern, const char *data, int needmore)
2419 {
2420  if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
2421  ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
2422  return extension_match_core(pattern, data, needmore);
2423 }
2424 
2425 /* This structure must remain in sync with ast_context for proper hashtab matching */
2426 struct fake_context /* this struct is purely for matching in the hashtab */
2427 {
2429  struct ast_exten *root;
2433  struct ast_includes includes;
2434  struct ast_ignorepats ignorepats;
2435  struct ast_sws alts;
2436  const char *registrar;
2440  char name[256];
2441 };
2442 
2443 struct ast_context *ast_context_find(const char *name)
2444 {
2445  struct ast_context *tmp;
2446  struct fake_context item;
2447 
2448  if (!name) {
2449  return NULL;
2450  }
2452  if (contexts_table) {
2453  ast_copy_string(item.name, name, sizeof(item.name));
2454  tmp = ast_hashtab_lookup(contexts_table, &item);
2455  } else {
2456  tmp = NULL;
2457  while ((tmp = ast_walk_contexts(tmp))) {
2458  if (!strcasecmp(name, tmp->name)) {
2459  break;
2460  }
2461  }
2462  }
2464  return tmp;
2465 }
2466 
2467 #define STATUS_NO_CONTEXT 1
2468 #define STATUS_NO_EXTENSION 2
2469 #define STATUS_NO_PRIORITY 3
2470 #define STATUS_NO_LABEL 4
2471 #define STATUS_SUCCESS 5
2472 
2473 static int matchcid(const char *cidpattern, const char *callerid)
2474 {
2475  /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
2476  failing to get a number should count as a match, otherwise not */
2477 
2478  if (ast_strlen_zero(callerid)) {
2479  return ast_strlen_zero(cidpattern) ? 1 : 0;
2480  }
2481 
2482  return ast_extension_match(cidpattern, callerid);
2483 }
2484 
2486  struct ast_context *bypass, struct pbx_find_info *q,
2487  const char *context, const char *exten, int priority,
2488  const char *label, const char *callerid, enum ext_match_t action)
2489 {
2490  int x, res;
2491  struct ast_context *tmp = NULL;
2492  struct ast_exten *e = NULL, *eroot = NULL;
2493  struct ast_exten pattern = {NULL, };
2494  struct scoreboard score = {0, };
2495  struct ast_str *tmpdata = NULL;
2496  int idx;
2497 
2498  pattern.label = label;
2499  pattern.priority = priority;
2500 #ifdef NEED_DEBUG_HERE
2501  ast_log(LOG_NOTICE, "Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int) action);
2502 #endif
2503 
2504  /* Initialize status if appropriate */
2505  if (q->stacklen == 0) {
2507  q->swo = NULL;
2508  q->data = NULL;
2509  q->foundcontext = NULL;
2510  } else if (q->stacklen >= AST_PBX_MAX_STACK) {
2511  ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
2512  return NULL;
2513  }
2514 
2515  /* Check first to see if we've already been checked */
2516  for (x = 0; x < q->stacklen; x++) {
2517  if (!strcasecmp(q->incstack[x], context))
2518  return NULL;
2519  }
2520 
2521  if (bypass) { /* bypass means we only look there */
2522  tmp = bypass;
2523  } else { /* look in contexts */
2524  tmp = find_context(context);
2525  if (!tmp) {
2526  return NULL;
2527  }
2528  }
2529 
2530  if (q->status < STATUS_NO_EXTENSION)
2532 
2533  /* Do a search for matching extension */
2534 
2535  eroot = NULL;
2536  score.total_specificity = 0;
2537  score.exten = 0;
2538  score.total_length = 0;
2539  if (!tmp->pattern_tree && tmp->root_table) {
2541 #ifdef NEED_DEBUG
2542  ast_debug(1, "Tree Created in context %s:\n", context);
2543  log_match_char_tree(tmp->pattern_tree," ");
2544 #endif
2545  }
2546 #ifdef NEED_DEBUG
2547  ast_log(LOG_NOTICE, "The Trie we are searching in:\n");
2548  log_match_char_tree(tmp->pattern_tree, ":: ");
2549 #endif
2550 
2551  do {
2552  if (!ast_strlen_zero(overrideswitch)) {
2553  char *osw = ast_strdupa(overrideswitch), *name;
2554  struct ast_switch *asw;
2555  ast_switch_f *aswf = NULL;
2556  char *datap;
2557  int eval = 0;
2558 
2559  name = strsep(&osw, "/");
2560  asw = pbx_findswitch(name);
2561 
2562  if (!asw) {
2563  ast_log(LOG_WARNING, "No such switch '%s'\n", name);
2564  break;
2565  }
2566 
2567  if (osw && strchr(osw, '$')) {
2568  eval = 1;
2569  }
2570 
2571  if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) {
2572  ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!\n");
2573  break;
2574  } else if (eval) {
2575  /* Substitute variables now */
2576  pbx_substitute_variables_helper(chan, osw, ast_str_buffer(tmpdata), ast_str_size(tmpdata));
2577  datap = ast_str_buffer(tmpdata);
2578  } else {
2579  datap = osw;
2580  }
2581 
2582  /* equivalent of extension_match_core() at the switch level */
2583  if (action == E_CANMATCH)
2584  aswf = asw->canmatch;
2585  else if (action == E_MATCHMORE)
2586  aswf = asw->matchmore;
2587  else /* action == E_MATCH */
2588  aswf = asw->exists;
2589  if (!aswf) {
2590  res = 0;
2591  } else {
2592  if (chan) {
2593  ast_autoservice_start(chan);
2594  }
2595  res = aswf(chan, context, exten, priority, callerid, datap);
2596  if (chan) {
2597  ast_autoservice_stop(chan);
2598  }
2599  }
2600  if (res) { /* Got a match */
2601  q->swo = asw;
2602  q->data = datap;
2603  q->foundcontext = context;
2604  /* XXX keep status = STATUS_NO_CONTEXT ? */
2605  return NULL;
2606  }
2607  }
2608  } while (0);
2609 
2610  if (extenpatternmatchnew) {
2611  new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid, label, action);
2612  eroot = score.exten;
2613 
2614  if (score.last_char == '!' && action == E_MATCHMORE) {
2615  /* We match an extension ending in '!'.
2616  * The decision in this case is final and is NULL (no match).
2617  */
2618 #ifdef NEED_DEBUG_HERE
2619  ast_log(LOG_NOTICE,"Returning MATCHMORE NULL with exclamation point.\n");
2620 #endif
2621  return NULL;
2622  }
2623 
2624  if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) {
2625  q->status = STATUS_SUCCESS;
2626 #ifdef NEED_DEBUG_HERE
2627  ast_log(LOG_NOTICE,"Returning CANMATCH exten %s\n", score.canmatch_exten->exten);
2628 #endif
2629  return score.canmatch_exten;
2630  }
2631 
2632  if ((action == E_MATCHMORE || action == E_CANMATCH) && eroot) {
2633  if (score.node) {
2634  struct ast_exten *z = trie_find_next_match(score.node);
2635  if (z) {
2636 #ifdef NEED_DEBUG_HERE
2637  ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten %s\n", z->exten);
2638 #endif
2639  } else {
2640  if (score.canmatch_exten) {
2641 #ifdef NEED_DEBUG_HERE
2642  ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE canmatchmatch exten %s(%p)\n", score.canmatch_exten->exten, score.canmatch_exten);
2643 #endif
2644  return score.canmatch_exten;
2645  } else {
2646 #ifdef NEED_DEBUG_HERE
2647  ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten NULL\n");
2648 #endif
2649  }
2650  }
2651  return z;
2652  }
2653 #ifdef NEED_DEBUG_HERE
2654  ast_log(LOG_NOTICE, "Returning CANMATCH/MATCHMORE NULL (no next_match)\n");
2655 #endif
2656  return NULL; /* according to the code, complete matches are null matches in MATCHMORE mode */
2657  }
2658 
2659  if (eroot) {
2660  /* found entry, now look for the right priority */
2661  if (q->status < STATUS_NO_PRIORITY)
2663  e = NULL;
2664  if (action == E_FINDLABEL && label ) {
2665  if (q->status < STATUS_NO_LABEL)
2666  q->status = STATUS_NO_LABEL;
2667  e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
2668  } else {
2669  e = ast_hashtab_lookup(eroot->peer_table, &pattern);
2670  }
2671  if (e) { /* found a valid match */
2672  q->status = STATUS_SUCCESS;
2673  q->foundcontext = context;
2674 #ifdef NEED_DEBUG_HERE
2675  ast_log(LOG_NOTICE,"Returning complete match of exten %s\n", e->exten);
2676 #endif
2677  return e;
2678  }
2679  }
2680  } else { /* the old/current default exten pattern match algorithm */
2681 
2682  /* scan the list trying to match extension and CID */
2683  eroot = NULL;
2684  while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
2685  int match = extension_match_core(eroot->exten, exten, action);
2686  /* 0 on fail, 1 on match, 2 on earlymatch */
2687 
2688  if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
2689  continue; /* keep trying */
2690  if (match == 2 && action == E_MATCHMORE) {
2691  /* We match an extension ending in '!'.
2692  * The decision in this case is final and is NULL (no match).
2693  */
2694  return NULL;
2695  }
2696  /* found entry, now look for the right priority */
2697  if (q->status < STATUS_NO_PRIORITY)
2699  e = NULL;
2700  if (action == E_FINDLABEL && label ) {
2701  if (q->status < STATUS_NO_LABEL)
2702  q->status = STATUS_NO_LABEL;
2703  e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
2704  } else {
2705  e = ast_hashtab_lookup(eroot->peer_table, &pattern);
2706  }
2707  if (e) { /* found a valid match */
2708  q->status = STATUS_SUCCESS;
2709  q->foundcontext = context;
2710  return e;
2711  }
2712  }
2713  }
2714 
2715  /* Check alternative switches */
2716  for (idx = 0; idx < ast_context_switches_count(tmp); idx++) {
2717  const struct ast_sw *sw = ast_context_switches_get(tmp, idx);
2718  struct ast_switch *asw = pbx_findswitch(ast_get_switch_name(sw));
2719  ast_switch_f *aswf = NULL;
2720  const char *datap;
2721 
2722  if (!asw) {
2723  ast_log(LOG_WARNING, "No such switch '%s'\n", ast_get_switch_name(sw));
2724  continue;
2725  }
2726 
2727  /* Substitute variables now */
2728  if (ast_get_switch_eval(sw)) {
2729  if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) {
2730  ast_log(LOG_WARNING, "Can't evaluate switch?!\n");
2731  continue;
2732  }
2734  ast_str_buffer(tmpdata), ast_str_size(tmpdata));
2735  datap = ast_str_buffer(tmpdata);
2736  } else {
2737  datap = ast_get_switch_data(sw);
2738  }
2739 
2740  /* equivalent of extension_match_core() at the switch level */
2741  if (action == E_CANMATCH)
2742  aswf = asw->canmatch;
2743  else if (action == E_MATCHMORE)
2744  aswf = asw->matchmore;
2745  else /* action == E_MATCH */
2746  aswf = asw->exists;
2747  if (!aswf)
2748  res = 0;
2749  else {
2750  if (chan)
2751  ast_autoservice_start(chan);
2752  res = aswf(chan, context, exten, priority, callerid, datap);
2753  if (chan)
2754  ast_autoservice_stop(chan);
2755  }
2756  if (res) { /* Got a match */
2757  q->swo = asw;
2758  q->data = datap;
2759  q->foundcontext = context;
2760  /* XXX keep status = STATUS_NO_CONTEXT ? */
2761  return NULL;
2762  }
2763  }
2764  q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
2765  /* Now try any includes we have in this context */
2766  for (idx = 0; idx < ast_context_includes_count(tmp); idx++) {
2767  const struct ast_include *i = ast_context_includes_get(tmp, idx);
2768 
2769  if (include_valid(i)) {
2770  if ((e = pbx_find_extension(chan, bypass, q, include_rname(i), exten, priority, label, callerid, action))) {
2771 #ifdef NEED_DEBUG_HERE
2772  ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten);
2773 #endif
2774  return e;
2775  }
2776  if (q->swo)
2777  return NULL;
2778  }
2779  }
2780  return NULL;
2781 }
2782 
2783 static void exception_store_free(void *data)
2784 {
2785  struct pbx_exception *exception = data;
2786  ast_string_field_free_memory(exception);
2787  ast_free(exception);
2788 }
2789 
2791  .type = "EXCEPTION",
2792  .destroy = exception_store_free,
2793 };
2794 
2795 /*!
2796  * \internal
2797  * \brief Set the PBX to execute the exception extension.
2798  *
2799  * \param chan Channel to raise the exception on.
2800  * \param reason Reason exception is raised.
2801  * \param priority Dialplan priority to set.
2802  *
2803  * \retval 0 on success.
2804  * \retval -1 on error.
2805  */
2806 int raise_exception(struct ast_channel *chan, const char *reason, int priority)
2807 {
2808  struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
2809  struct pbx_exception *exception = NULL;
2810 
2811  if (!ds) {
2812  ds = ast_datastore_alloc(&exception_store_info, NULL);
2813  if (!ds)
2814  return -1;
2815  if (!(exception = ast_calloc_with_stringfields(1, struct pbx_exception, 128))) {
2816  ast_datastore_free(ds);
2817  return -1;
2818  }
2819  ds->data = exception;
2820  ast_channel_datastore_add(chan, ds);
2821  } else
2822  exception = ds->data;
2823 
2824  ast_string_field_set(exception, reason, reason);
2825  ast_string_field_set(exception, context, ast_channel_context(chan));
2826  ast_string_field_set(exception, exten, ast_channel_exten(chan));
2827  exception->priority = ast_channel_priority(chan);
2828  set_ext_pri(chan, "e", priority);
2829  return 0;
2830 }
2831 
2832 static int acf_exception_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
2833 {
2834  struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
2835  struct pbx_exception *exception = NULL;
2836  if (!ds || !ds->data)
2837  return -1;
2838  exception = ds->data;
2839  if (!strcasecmp(data, "REASON"))
2840  ast_copy_string(buf, exception->reason, buflen);
2841  else if (!strcasecmp(data, "CONTEXT"))
2842  ast_copy_string(buf, exception->context, buflen);
2843  else if (!strncasecmp(data, "EXTEN", 5))
2844  ast_copy_string(buf, exception->exten, buflen);
2845  else if (!strcasecmp(data, "PRIORITY"))
2846  snprintf(buf, buflen, "%d", exception->priority);
2847  else
2848  return -1;
2849  return 0;
2850 }
2851 
2853  .name = "EXCEPTION",
2854  .read = acf_exception_read,
2855 };
2856 
2857 /*!
2858  * \brief The return value depends on the action:
2859  *
2860  * E_MATCH, E_CANMATCH, E_MATCHMORE require a real match,
2861  * and return 0 on failure, -1 on match;
2862  * E_FINDLABEL maps the label to a priority, and returns
2863  * the priority on success, ... XXX
2864  * E_SPAWN, spawn an application,
2865  *
2866  * \retval 0 on success.
2867  * \retval -1 on failure.
2868  *
2869  * \note The channel is auto-serviced in this function, because doing an extension
2870  * match may block for a long time. For example, if the lookup has to use a network
2871  * dialplan switch, such as DUNDi or IAX2, it may take a while. However, the channel
2872  * auto-service code will queue up any important signalling frames to be processed
2873  * after this is done.
2874  */
2875 static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
2876  const char *context, const char *exten, int priority,
2877  const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
2878 {
2879  struct ast_exten *e;
2880  struct ast_app *app;
2881  char *substitute = NULL;
2882  struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
2883  char passdata[EXT_DATA_SIZE];
2884  int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
2885 
2887 
2888  if (!context) {
2889  context = con->name;
2890  }
2891 
2892  if (found)
2893  *found = 0;
2894 
2895  e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
2896  if (e) {
2897  if (found)
2898  *found = 1;
2899  if (matching_action) {
2901  return -1; /* success, we found it */
2902  } else if (action == E_FINDLABEL) { /* map the label to a priority */
2903  int res = e->priority;
2904 
2906 
2907  /* the priority we were looking for */
2908  return res;
2909  } else { /* spawn */
2910  if (!e->cached_app)
2911  e->cached_app = pbx_findapp(e->app);
2912  app = e->cached_app;
2913  if (ast_strlen_zero(e->data)) {
2914  *passdata = '\0';
2915  } else {
2916  const char *tmp;
2917  if ((!(tmp = strchr(e->data, '$'))) || (!strstr(tmp, "${") && !strstr(tmp, "$["))) {
2918  /* no variables to substitute, copy on through */
2919  ast_copy_string(passdata, e->data, sizeof(passdata));
2920  } else {
2921  /* save e->data on stack for later processing after lock released */
2922  substitute = ast_strdupa(e->data);
2923  }
2924  }
2926  if (!app) {
2927  ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
2928  return -1;
2929  }
2930  if (ast_channel_context(c) != context)
2931  ast_channel_context_set(c, context);
2932  if (ast_channel_exten(c) != exten)
2933  ast_channel_exten_set(c, exten);
2934  ast_channel_priority_set(c, priority);
2935  if (substitute) {
2936  pbx_substitute_variables_helper(c, substitute, passdata, sizeof(passdata)-1);
2937  }
2938  ast_debug(1, "Launching '%s'\n", app_name(app));
2939  if (VERBOSITY_ATLEAST(3)) {
2940  ast_verb(3, "Executing [%s@%s:%d] " COLORIZE_FMT "(\"" COLORIZE_FMT "\", \"" COLORIZE_FMT "\") %s\n",
2941  exten, context, priority,
2942  COLORIZE(COLOR_BRCYAN, 0, app_name(app)),
2944  COLORIZE(COLOR_BRMAGENTA, 0, passdata),
2945  "in new stack");
2946  }
2947  return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */
2948  }
2949  } else if (q.swo) { /* not found here, but in another switch */
2950  if (found)
2951  *found = 1;
2953  if (matching_action) {
2954  return -1;
2955  } else {
2956  if (!q.swo->exec) {
2957  ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
2958  return -1;
2959  }
2960  return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
2961  }
2962  } else { /* not found anywhere, see what happened */
2964  /* Using S_OR here because Solaris doesn't like NULL being passed to ast_log */
2965  switch (q.status) {
2966  case STATUS_NO_CONTEXT:
2967  if (!matching_action && !combined_find_spawn)
2968  ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", S_OR(context, ""));
2969  break;
2970  case STATUS_NO_EXTENSION:
2971  if (!matching_action && !combined_find_spawn)
2972  ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, S_OR(context, ""));
2973  break;
2974  case STATUS_NO_PRIORITY:
2975  if (!matching_action && !combined_find_spawn)
2976  ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, S_OR(context, ""));
2977  break;
2978  case STATUS_NO_LABEL:
2979  if (context && !combined_find_spawn)
2980  ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, S_OR(context, ""));
2981  break;
2982  default:
2983  ast_debug(1, "Shouldn't happen!\n");
2984  }
2985 
2986  return (matching_action) ? 0 : -1;
2987  }
2988 }
2989 
2990 /*! \brief Find hint for given extension in context */
2991 static struct ast_exten *ast_hint_extension_nolock(struct ast_channel *c, const char *context, const char *exten)
2992 {
2993  struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
2994  return pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH);
2995 }
2996 
2997 static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
2998 {
2999  struct ast_exten *e;
3001  e = ast_hint_extension_nolock(c, context, exten);
3003  return e;
3004 }
3005 
3007 {
3008  switch (devstate) {
3009  case AST_DEVICE_ONHOLD:
3010  return AST_EXTENSION_ONHOLD;
3011  case AST_DEVICE_BUSY:
3012  return AST_EXTENSION_BUSY;
3013  case AST_DEVICE_UNKNOWN:
3014  return AST_EXTENSION_NOT_INUSE;
3016  case AST_DEVICE_INVALID:
3018  case AST_DEVICE_RINGINUSE:
3020  case AST_DEVICE_RINGING:
3021  return AST_EXTENSION_RINGING;
3022  case AST_DEVICE_INUSE:
3023  return AST_EXTENSION_INUSE;
3024  case AST_DEVICE_NOT_INUSE:
3025  return AST_EXTENSION_NOT_INUSE;
3026  case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
3027  break;
3028  }
3029 
3030  return AST_EXTENSION_NOT_INUSE;
3031 }
3032 
3033 /*!
3034  * \internal
3035  * \brief Parse out the presence portion of the hint string
3036  */
3037 static char *parse_hint_presence(struct ast_str *hint_args)
3038 {
3039  char *copy = ast_strdupa(ast_str_buffer(hint_args));
3040  char *tmp = "";
3041 
3042  if ((tmp = strrchr(copy, ','))) {
3043  *tmp = '\0';
3044  tmp++;
3045  } else {
3046  return NULL;
3047  }
3048  ast_str_set(&hint_args, 0, "%s", tmp);
3049  return ast_str_buffer(hint_args);
3050 }
3051 
3052 /*!
3053  * \internal
3054  * \brief Parse out the device portion of the hint string
3055  */
3056 static char *parse_hint_device(struct ast_str *hint_args)
3057 {
3058  char *copy = ast_strdupa(ast_str_buffer(hint_args));
3059  char *tmp;
3060 
3061  if ((tmp = strrchr(copy, ','))) {
3062  *tmp = '\0';
3063  }
3064 
3065  ast_str_set(&hint_args, 0, "%s", copy);
3066  return ast_str_buffer(hint_args);
3067 }
3068 
3069 static void device_state_info_dt(void *obj)
3070 {
3071  struct ast_device_state_info *info = obj;
3072 
3074 }
3075 
3077 {
3079 }
3080 
3081 static int ast_extension_state3(struct ast_str *hint_app, struct ao2_container *device_state_info)
3082 {
3083  char *cur;
3084  char *rest;
3085  struct ast_devstate_aggregate agg;
3086 
3087  /* One or more devices separated with a & character */
3088  rest = parse_hint_device(hint_app);
3089 
3091  while ((cur = strsep(&rest, "&"))) {
3093 
3094  ast_devstate_aggregate_add(&agg, state);
3095  if (device_state_info) {
3096  struct ast_device_state_info *obj;
3097 
3098  obj = ao2_alloc_options(sizeof(*obj) + strlen(cur), device_state_info_dt, AO2_ALLOC_OPT_LOCK_NOLOCK);
3099  /* if failed we cannot add this device */
3100  if (obj) {
3101  obj->device_state = state;
3102  strcpy(obj->device_name, cur);
3103  ao2_link(device_state_info, obj);
3104  ao2_ref(obj, -1);
3105  }
3106  }
3107  }
3108 
3110 }
3111 
3112 /*! \brief Check state of extension by using hints */
3113 static int ast_extension_state2(struct ast_exten *e, struct ao2_container *device_state_info)
3114 {
3115  struct ast_str *hint_app = ast_str_thread_get(&extensionstate_buf, 32);
3116 
3117  if (!e || !hint_app) {
3118  return -1;
3119  }
3120 
3121  ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(e));
3122  return ast_extension_state3(hint_app, device_state_info);
3123 }
3124 
3125 /*! \brief Return extension_state as string */
3126 const char *ast_extension_state2str(int extension_state)
3127 {
3128  int i;
3129 
3130  for (i = 0; (i < ARRAY_LEN(extension_states)); i++) {
3131  if (extension_states[i].extension_state == extension_state)
3132  return extension_states[i].text;
3133  }
3134  return "Unknown";
3135 }
3136 
3137 /*!
3138  * \internal
3139  * \brief Check extension state for an extension by using hint
3140  */
3141 static int internal_extension_state_extended(struct ast_channel *c, const char *context, const char *exten,
3142  struct ao2_container *device_state_info)
3143 {
3144  struct ast_exten *e;
3145 
3146  if (!(e = ast_hint_extension(c, context, exten))) { /* Do we have a hint for this extension ? */
3147  return -1; /* No hint, return -1 */
3148  }
3149 
3150  if (e->exten[0] == '_') {
3151  /* Create this hint on-the-fly, we explicitly lock hints here to ensure the
3152  * same locking order as if this were done through configuration file - that is
3153  * hints is locked first and then (if needed) contexts is locked
3154  */
3155  ao2_lock(hints);
3156  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
3157  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
3158  e->registrar);
3159  ao2_unlock(hints);
3160  if (!(e = ast_hint_extension(c, context, exten))) {
3161  /* Improbable, but not impossible */
3162  return -1;
3163  }
3164  }
3165 
3166  return ast_extension_state2(e, device_state_info); /* Check all devices in the hint */
3167 }
3168 
3169 /*! \brief Check extension state for an extension by using hint */
3170 int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
3171 {
3172  return internal_extension_state_extended(c, context, exten, NULL);
3173 }
3174 
3175 /*! \brief Check extended extension state for an extension by using hint */
3176 int ast_extension_state_extended(struct ast_channel *c, const char *context, const char *exten,
3177  struct ao2_container **device_state_info)
3178 {
3179  struct ao2_container *container = NULL;
3180  int ret;
3181 
3182  if (device_state_info) {
3183  container = alloc_device_state_info();
3184  }
3185 
3186  ret = internal_extension_state_extended(c, context, exten, container);
3187  if (ret < 0 && container) {
3188  ao2_ref(container, -1);
3189  container = NULL;
3190  }
3191 
3192  if (device_state_info) {
3194  *device_state_info = container;
3195  }
3196 
3197  return ret;
3198 }
3199 
3200 static int extension_presence_state_helper(struct ast_exten *e, char **subtype, char **message)
3201 {
3202  struct ast_str *hint_app = ast_str_thread_get(&extensionstate_buf, 32);
3203  char *presence_provider;
3204  const char *app;
3205 
3206  if (!e || !hint_app) {
3207  return -1;
3208  }
3209 
3210  app = ast_get_extension_app(e);
3211  if (ast_strlen_zero(app)) {
3212  return -1;
3213  }
3214 
3215  ast_str_set(&hint_app, 0, "%s", app);
3216  presence_provider = parse_hint_presence(hint_app);
3217 
3218  if (ast_strlen_zero(presence_provider)) {
3219  /* No presence string in the hint */
3220  return 0;
3221  }
3222 
3223  return ast_presence_state(presence_provider, subtype, message);
3224 }
3225 
3226 int ast_hint_presence_state(struct ast_channel *c, const char *context, const char *exten, char **subtype, char **message)
3227 {
3228  struct ast_exten *e;
3229 
3230  if (!(e = ast_hint_extension(c, context, exten))) { /* Do we have a hint for this extension ? */
3231  return -1; /* No hint, return -1 */
3232  }
3233 
3234  if (e->exten[0] == '_') {
3235  /* Create this hint on-the-fly */
3236  ao2_lock(hints);
3237  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
3238  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
3239  e->registrar);
3240  ao2_unlock(hints);
3241  if (!(e = ast_hint_extension(c, context, exten))) {
3242  /* Improbable, but not impossible */
3243  return -1;
3244  }
3245  }
3246 
3247  return extension_presence_state_helper(e, subtype, message);
3248 }
3249 
3251  const char *context,
3252  const char *exten,
3253  void *data,
3254  enum ast_state_cb_update_reason reason,
3255  struct ast_hint *hint,
3256  struct ao2_container *device_state_info)
3257 {
3258  int res = 0;
3259  struct ast_state_cb_info info = { 0, };
3260 
3261  info.reason = reason;
3262 
3263  /* Copy over current hint data */
3264  if (hint) {
3265  ao2_lock(hint);
3266  info.exten_state = hint->laststate;
3268  info.presence_state = hint->last_presence_state;
3269  if (!(ast_strlen_zero(hint->last_presence_subtype))) {
3271  } else {
3272  info.presence_subtype = "";
3273  }
3274  if (!(ast_strlen_zero(hint->last_presence_message))) {
3276  } else {
3277  info.presence_message = "";
3278  }
3279  ao2_unlock(hint);
3280  } else {
3282  }
3283 
3284  res = cb(context, exten, &info, data);
3285 
3286  return res;
3287 }
3288 
3289 /*!
3290  * /internal
3291  * /brief Identify a channel for every device which is supposedly responsible for the device state.
3292  *
3293  * Especially when the device is ringing, the oldest ringing channel is chosen.
3294  * For all other cases the first encountered channel in the specific state is chosen.
3295  */
3297 {
3298  struct ao2_iterator iter;
3299  struct ast_device_state_info *info;
3300  struct ast_channel *chan;
3301 
3302  if (!c || !ao2_container_count(c)) {
3303  return;
3304  }
3305  iter = ao2_iterator_init(c, 0);
3306  for (; (info = ao2_iterator_next(&iter)); ao2_ref(info, -1)) {
3307  enum ast_channel_state search_state = 0; /* prevent false uninit warning */
3308  char match[AST_CHANNEL_NAME];
3309  struct ast_channel_iterator *chan_iter;
3310  struct timeval chantime = {0, }; /* prevent false uninit warning */
3311 
3312  switch (info->device_state) {
3313  case AST_DEVICE_RINGING:
3314  case AST_DEVICE_RINGINUSE:
3315  /* find ringing channel */
3316  search_state = AST_STATE_RINGING;
3317  break;
3318  case AST_DEVICE_BUSY:
3319  /* find busy channel */
3320  search_state = AST_STATE_BUSY;
3321  break;
3322  case AST_DEVICE_ONHOLD:
3323  case AST_DEVICE_INUSE:
3324  /* find up channel */
3325  search_state = AST_STATE_UP;
3326  break;
3327  case AST_DEVICE_UNKNOWN:
3328  case AST_DEVICE_NOT_INUSE:
3329  case AST_DEVICE_INVALID:
3331  case AST_DEVICE_TOTAL /* not a state */:
3332  /* no channels are of interest */
3333  continue;
3334  }
3335 
3336  /* iterate over all channels of the device */
3337  snprintf(match, sizeof(match), "%s-", info->device_name);
3338  chan_iter = ast_channel_iterator_by_name_new(match, strlen(match));
3339  for (; (chan = ast_channel_iterator_next(chan_iter)); ast_channel_unref(chan)) {
3340  ast_channel_lock(chan);
3341  /* this channel's state doesn't match */
3342  if (search_state != ast_channel_state(chan)) {
3343  ast_channel_unlock(chan);
3344  continue;
3345  }
3346  /* any non-ringing channel will fit */
3347  if (search_state != AST_STATE_RINGING) {
3348  ast_channel_unlock(chan);
3349  info->causing_channel = chan; /* is kept ref'd! */
3350  break;
3351  }
3352  /* but we need the oldest ringing channel of the device to match with undirected pickup */
3353  if (!info->causing_channel) {
3354  chantime = ast_channel_creationtime(chan);
3355  ast_channel_ref(chan); /* must ref it! */
3356  info->causing_channel = chan;
3357  } else if (ast_tvcmp(ast_channel_creationtime(chan), chantime) < 0) {
3358  chantime = ast_channel_creationtime(chan);
3360  ast_channel_ref(chan); /* must ref it! */
3361  info->causing_channel = chan;
3362  }
3363  ast_channel_unlock(chan);
3364  }
3365  ast_channel_iterator_destroy(chan_iter);
3366  }
3367  ao2_iterator_destroy(&iter);
3368 }
3369 
3370 static void device_state_notify_callbacks(struct ast_hint *hint, struct ast_str **hint_app)
3371 {
3372  struct ao2_iterator cb_iter;
3373  struct ast_state_cb *state_cb;
3374  int state;
3375  int same_state;
3376  struct ao2_container *device_state_info;
3377  int first_extended_cb_call = 1;
3380 
3381  ao2_lock(hint);
3382  if (!hint->exten) {
3383  /* The extension has already been destroyed */
3384  ao2_unlock(hint);
3385  return;
3386  }
3387 
3388  /*
3389  * Save off strings in case the hint extension gets destroyed
3390  * while we are notifying the watchers.
3391  */
3392  ast_copy_string(context_name,
3394  sizeof(context_name));
3395  ast_copy_string(exten_name, ast_get_extension_name(hint->exten),
3396  sizeof(exten_name));
3397  ast_str_set(hint_app, 0, "%s", ast_get_extension_app(hint->exten));
3398  ao2_unlock(hint);
3399 
3400  /*
3401  * Get device state for this hint.
3402  *
3403  * NOTE: We cannot hold any locks while determining the hint
3404  * device state or notifying the watchers without causing a
3405  * deadlock. (conlock, hints, and hint)
3406  */
3407 
3408  /* Make a container so state3 can fill it if we wish.
3409  * If that failed we simply do not provide the extended state info.
3410  */
3411  device_state_info = alloc_device_state_info();
3412 
3413  state = ast_extension_state3(*hint_app, device_state_info);
3414  same_state = state == hint->laststate;
3415  if (same_state && (~state & AST_EXTENSION_RINGING)) {
3416  ao2_cleanup(device_state_info);
3417  return;
3418  }
3419 
3420  /* Device state changed since last check - notify the watchers. */
3421  hint->laststate = state; /* record we saw the change */
3422 
3423  /* For general callbacks */
3424  if (!same_state) {
3425  cb_iter = ao2_iterator_init(statecbs, 0);
3426  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3428  context_name,
3429  exten_name,
3430  state_cb->data,
3432  hint,
3433  NULL);
3434  }
3435  ao2_iterator_destroy(&cb_iter);
3436  }
3437 
3438  /* For extension callbacks */
3439  /* extended callbacks are called when the state changed or when AST_STATE_RINGING is
3440  * included. Normal callbacks are only called when the state changed.
3441  */
3442  cb_iter = ao2_iterator_init(hint->callbacks, 0);
3443  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3444  if (state_cb->extended && first_extended_cb_call) {
3445  /* Fill detailed device_state_info now that we know it is used by extd. callback */
3446  first_extended_cb_call = 0;
3447  get_device_state_causing_channels(device_state_info);
3448  }
3449  if (state_cb->extended || !same_state) {
3451  context_name,
3452  exten_name,
3453  state_cb->data,
3455  hint,
3456  state_cb->extended ? device_state_info : NULL);
3457  }
3458  }
3459  ao2_iterator_destroy(&cb_iter);
3460 
3461  ao2_cleanup(device_state_info);
3462 }
3463 
3464 static void presence_state_notify_callbacks(struct ast_hint *hint, struct ast_str **hint_app,
3465  struct ast_presence_state_message *presence_state)
3466 {
3467  struct ao2_iterator cb_iter;
3468  struct ast_state_cb *state_cb;
3471 
3472  ao2_lock(hint);
3473  if (!hint->exten) {
3474  /* The extension has already been destroyed */
3475  ao2_unlock(hint);
3476  return;
3477  }
3478 
3479  /*
3480  * Save off strings in case the hint extension gets destroyed
3481  * while we are notifying the watchers.
3482  */
3483  ast_copy_string(context_name,
3485  sizeof(context_name));
3486  ast_copy_string(exten_name, ast_get_extension_name(hint->exten),
3487  sizeof(exten_name));
3488  ast_str_set(hint_app, 0, "%s", ast_get_extension_app(hint->exten));
3489  ao2_unlock(hint);
3490 
3491  /* Check to see if update is necessary */
3492  if ((hint->last_presence_state == presence_state->state) &&
3493  ((hint->last_presence_subtype && presence_state->subtype &&
3494  !strcmp(hint->last_presence_subtype, presence_state->subtype)) ||
3495  (!hint->last_presence_subtype && !presence_state->subtype)) &&
3496  ((hint->last_presence_message && presence_state->message &&
3497  !strcmp(hint->last_presence_message, presence_state->message)) ||
3498  (!hint->last_presence_message && !presence_state->message))) {
3499  /* this update is the same as the last, do nothing */
3500  return;
3501  }
3502 
3503  /* update new values */
3506  hint->last_presence_state = presence_state->state;
3507  hint->last_presence_subtype = presence_state->subtype ? ast_strdup(presence_state->subtype) : NULL;
3508  hint->last_presence_message = presence_state->message ? ast_strdup(presence_state->message) : NULL;
3509 
3510  /* For general callbacks */
3511  cb_iter = ao2_iterator_init(statecbs, 0);
3512  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3514  context_name,
3515  exten_name,
3516  state_cb->data,
3518  hint,
3519  NULL);
3520  }
3521  ao2_iterator_destroy(&cb_iter);
3522 
3523  /* For extension callbacks */
3524  cb_iter = ao2_iterator_init(hint->callbacks, 0);
3525  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_cleanup(state_cb)) {
3527  context_name,
3528  exten_name,
3529  state_cb->data,
3531  hint,
3532  NULL);
3533  }
3534  ao2_iterator_destroy(&cb_iter);
3535 }
3536 
3538 {
3539  struct ast_hint *hint;
3540  struct ast_str *hint_app;
3541 
3542  if (hint_change_message_type() != stasis_message_type(msg)) {
3543  return 0;
3544  }
3545 
3546  if (!(hint_app = ast_str_create(1024))) {
3547  return -1;
3548  }
3549 
3550  hint = stasis_message_data(msg);
3551 
3552  switch (reason) {
3554  device_state_notify_callbacks(hint, &hint_app);
3555  break;
3557  {
3558  char *presence_subtype = NULL;
3559  char *presence_message = NULL;
3560  int state;
3561 
3563  hint->exten, &presence_subtype, &presence_message);
3564  {
3565  struct ast_presence_state_message presence_state = {
3566  .state = state > 0 ? state : AST_PRESENCE_INVALID,
3567  .subtype = presence_subtype,
3568  .message = presence_message
3569  };
3570 
3571  presence_state_notify_callbacks(hint, &hint_app, &presence_state);
3572  }
3573 
3574  ast_free(presence_subtype);
3575  ast_free(presence_message);
3576  }
3577  break;
3578  }
3579 
3580  ast_free(hint_app);
3581  return 1;
3582 }
3583 
3584 static void device_state_cb(void *unused, struct stasis_subscription *sub, struct stasis_message *msg)
3585 {
3586  struct ast_device_state_message *dev_state;
3587  struct ast_str *hint_app;
3588  struct ast_hintdevice *device;
3589  struct ast_hintdevice *cmpdevice;
3590  struct ao2_iterator *dev_iter;
3591  struct ao2_iterator auto_iter;
3592  struct ast_autohint *autohint;
3593  char *virtual_device;
3594  char *type;
3595  char *device_name;
3596 
3598  return;
3599  }
3600 
3601  if (hint_remove_message_type() == stasis_message_type(msg)) {
3602  /* The extension has already been destroyed */
3603  struct ast_state_cb *state_cb;
3604  struct ao2_iterator cb_iter;
3605  struct ast_hint *hint = stasis_message_data(msg);
3606 
3607  ao2_lock(hint);
3609  ao2_unlock(hint);
3610 
3611  cb_iter = ao2_iterator_init(hint->callbacks, 0);
3612  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3614  hint->context_name,
3615  hint->exten_name,
3616  state_cb->data,
3618  hint,
3619  NULL);
3620  }
3621  ao2_iterator_destroy(&cb_iter);
3622  return;
3623  }
3624 
3626  return;
3627  }
3628 
3629  dev_state = stasis_message_data(msg);
3630  if (dev_state->eid) {
3631  /* ignore non-aggregate states */
3632  return;
3633  }
3634 
3635  if (ao2_container_count(hintdevices) == 0 && ao2_container_count(autohints) == 0) {
3636  /* There are no hints monitoring devices. */
3637  return;
3638  }
3639 
3640  hint_app = ast_str_create(1024);
3641  if (!hint_app) {
3642  return;
3643  }
3644 
3645  cmpdevice = ast_alloca(sizeof(*cmpdevice) + strlen(dev_state->device));
3646  strcpy(cmpdevice->hintdevice, dev_state->device);
3647 
3648  ast_mutex_lock(&context_merge_lock);/* Hold off ast_merge_contexts_and_delete */
3649 
3650  /* Initially we find all hints for the device and notify them */
3651  dev_iter = ao2_t_callback(hintdevices,
3654  cmpdevice,
3655  "find devices in container");
3656  if (dev_iter) {
3657  for (; (device = ao2_iterator_next(dev_iter)); ao2_t_ref(device, -1, "Next device")) {
3658  if (device->hint) {
3659  device_state_notify_callbacks(device->hint, &hint_app);
3660  }
3661  }
3662  ao2_iterator_destroy(dev_iter);
3663  }
3664 
3665  /* Second stage we look for any autohint contexts and if the device is not already in the hints
3666  * we create it.
3667  */
3668  type = ast_strdupa(dev_state->device);
3669  if (ast_strlen_zero(type)) {
3670  goto end;
3671  }
3672 
3673  /* Determine if this is a virtual/custom device or a real device */
3674  virtual_device = strchr(type, ':');
3675  device_name = strchr(type, '/');
3676  if (virtual_device && (!device_name || (virtual_device < device_name))) {
3677  device_name = virtual_device;
3678  }
3679 
3680  /* Invalid device state name - not a virtual/custom device and not a real device */
3681  if (ast_strlen_zero(device_name)) {
3682  goto end;
3683  }
3684 
3685  *device_name++ = '\0';
3686 
3687  auto_iter = ao2_iterator_init(autohints, 0);
3688  for (; (autohint = ao2_iterator_next(&auto_iter)); ao2_t_ref(autohint, -1, "Next autohint")) {
3689  if (ast_get_hint(NULL, 0, NULL, 0, NULL, autohint->context, device_name)) {
3690  continue;
3691  }
3692 
3693  /* The device has no hint in the context referenced by this autohint so create one */
3694  ast_add_extension(autohint->context, 0, device_name,
3695  PRIORITY_HINT, NULL, NULL, dev_state->device,
3696  ast_strdup(dev_state->device), ast_free_ptr, autohint->registrar);
3697 
3698  /* Since this hint was just created there are no watchers, so we don't need to notify anyone */
3699  }
3700  ao2_iterator_destroy(&auto_iter);
3701 
3702 end:
3704  ast_free(hint_app);
3705  return;
3706 }
3707 
3708 /*!
3709  * \internal
3710  * \brief Destroy the given state callback object.
3711  *
3712  * \param doomed State callback to destroy.
3713  *
3714  * \return Nothing
3715  */
3716 static void destroy_state_cb(void *doomed)
3717 {
3718  struct ast_state_cb *state_cb = doomed;
3719 
3720  if (state_cb->destroy_cb) {
3721  state_cb->destroy_cb(state_cb->id, state_cb->data);
3722  }
3723 }
3724 
3725 /*!
3726  * \internal
3727  * \brief Add watcher for extension states with destructor
3728  */
3729 static int extension_state_add_destroy(const char *context, const char *exten,
3731 {
3732  struct ast_hint *hint;
3733  struct ast_state_cb *state_cb;
3734  struct ast_exten *e;
3735  int id;
3736 
3737  /* If there's no context and extension: add callback to statecbs list */
3738  if (!context && !exten) {
3739  /* Prevent multiple adds from adding the same change_cb at the same time. */
3740  ao2_lock(statecbs);
3741 
3742  /* Remove any existing change_cb. */
3743  ao2_find(statecbs, change_cb, OBJ_UNLINK | OBJ_NODATA);
3744 
3745  /* Now insert the change_cb */
3746  if (!(state_cb = ao2_alloc(sizeof(*state_cb), destroy_state_cb))) {
3747  ao2_unlock(statecbs);
3748  return -1;
3749  }
3750  state_cb->id = 0;
3751  state_cb->change_cb = change_cb;
3752  state_cb->destroy_cb = destroy_cb;
3753  state_cb->data = data;
3754  state_cb->extended = extended;
3755  ao2_link(statecbs, state_cb);
3756 
3757  ao2_ref(state_cb, -1);
3758  ao2_unlock(statecbs);
3759  return 0;
3760  }
3761 
3762  if (!context || !exten)
3763  return -1;
3764 
3765  /* This callback type is for only one hint, so get the hint */
3766  e = ast_hint_extension(NULL, context, exten);
3767  if (!e) {
3768  return -1;
3769  }
3770 
3771  /* If this is a pattern, dynamically create a new extension for this
3772  * particular match. Note that this will only happen once for each
3773  * individual extension, because the pattern will no longer match first.
3774  */
3775  if (e->exten[0] == '_') {
3776  ao2_lock(hints);
3777  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
3778  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
3779  e->registrar);
3780  ao2_unlock(hints);
3781  e = ast_hint_extension(NULL, context, exten);
3782  if (!e || e->exten[0] == '_') {
3783  return -1;
3784  }
3785  }
3786 
3787  /* Find the hint in the hints container */
3788  ao2_lock(hints);/* Locked to hold off ast_merge_contexts_and_delete */
3789  hint = ao2_find(hints, e, 0);
3790  if (!hint) {
3791  ao2_unlock(hints);
3792  return -1;
3793  }
3794 
3795  /* Now insert the callback in the callback list */
3796  if (!(state_cb = ao2_alloc(sizeof(*state_cb), destroy_state_cb))) {
3797  ao2_ref(hint, -1);
3798  ao2_unlock(hints);
3799  return -1;
3800  }
3801  do {
3802  id = stateid++; /* Unique ID for this callback */
3803  /* Do not allow id to ever be -1 or 0. */
3804  } while (id == -1 || id == 0);
3805  state_cb->id = id;
3806  state_cb->change_cb = change_cb; /* Pointer to callback routine */
3807  state_cb->destroy_cb = destroy_cb;
3808  state_cb->data = data; /* Data for the callback */
3809  state_cb->extended = extended;
3810  ao2_link(hint->callbacks, state_cb);
3811 
3812  ao2_ref(state_cb, -1);
3813  ao2_ref(hint, -1);
3814  ao2_unlock(hints);
3815 
3816  return id;
3817 }
3818 
3819 int ast_extension_state_add_destroy(const char *context, const char *exten,
3820  ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
3821 {
3822  return extension_state_add_destroy(context, exten, change_cb, destroy_cb, data, 0);
3823 }
3824 
3825 int ast_extension_state_add(const char *context, const char *exten,
3826  ast_state_cb_type change_cb, void *data)
3827 {
3828  return extension_state_add_destroy(context, exten, change_cb, NULL, data, 0);
3829 }
3830 
3831 int ast_extension_state_add_destroy_extended(const char *context, const char *exten,
3832  ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
3833 {
3834  return extension_state_add_destroy(context, exten, change_cb, destroy_cb, data, 1);
3835 }
3836 
3837 int ast_extension_state_add_extended(const char *context, const char *exten,
3838  ast_state_cb_type change_cb, void *data)
3839 {
3840  return extension_state_add_destroy(context, exten, change_cb, NULL, data, 1);
3841 }
3842 
3843 /*! \brief Find Hint by callback id */
3844 static int find_hint_by_cb_id(void *obj, void *arg, int flags)
3845 {
3846  struct ast_state_cb *state_cb;
3847  const struct ast_hint *hint = obj;
3848  int *id = arg;
3849 
3850  if ((state_cb = ao2_find(hint->callbacks, id, 0))) {
3851  ao2_ref(state_cb, -1);
3852  return CMP_MATCH | CMP_STOP;
3853  }
3854 
3855  return 0;
3856 }
3857 
3859 {
3860  struct ast_state_cb *p_cur;
3861  int ret = -1;
3862 
3863  if (!id) { /* id == 0 is a callback without extension */
3864  if (!change_cb) {
3865  return ret;
3866  }
3867  p_cur = ao2_find(statecbs, change_cb, OBJ_UNLINK);
3868  if (p_cur) {
3869  ret = 0;
3870  ao2_ref(p_cur, -1);
3871  }
3872  } else { /* callback with extension, find the callback based on ID */
3873  struct ast_hint *hint;
3874 
3875  ao2_lock(hints);/* Locked to hold off ast_merge_contexts_and_delete */
3876  hint = ao2_callback(hints, 0, find_hint_by_cb_id, &id);
3877  if (hint) {
3878  p_cur = ao2_find(hint->callbacks, &id, OBJ_UNLINK);
3879  if (p_cur) {
3880  ret = 0;
3881  ao2_ref(p_cur, -1);
3882  }
3883  ao2_ref(hint, -1);
3884  }
3885  ao2_unlock(hints);
3886  }
3887 
3888  return ret;
3889 }
3890 
3891 static int hint_id_cmp(void *obj, void *arg, int flags)
3892 {
3893  const struct ast_state_cb *cb = obj;
3894  int *id = arg;
3895 
3896  return (cb->id == *id) ? CMP_MATCH | CMP_STOP : 0;
3897 }
3898 
3899 /*!
3900  * \internal
3901  * \brief Destroy the given hint object.
3902  *
3903  * \param obj Hint to destroy.
3904  *
3905  * \return Nothing
3906  */
3907 static void destroy_hint(void *obj)
3908 {
3909  struct ast_hint *hint = obj;
3910  int i;
3911 
3912  ao2_cleanup(hint->callbacks);
3913 
3914  for (i = 0; i < AST_VECTOR_SIZE(&hint->devices); i++) {
3915  char *device = AST_VECTOR_GET(&hint->devices, i);
3916  ast_free(device);
3917  }
3918  AST_VECTOR_FREE(&hint->devices);
3921 }
3922 
3923 /*! \brief Publish a hint removed event */
3924 static int publish_hint_remove(struct ast_hint *hint)
3925 {
3926  struct stasis_message *message;
3927 
3928  if (!hint_remove_message_type()) {
3929  return -1;
3930  }
3931 
3932  if (!(message = stasis_message_create(hint_remove_message_type(), hint))) {
3933  ao2_ref(hint, -1);
3934  return -1;
3935  }
3936 
3938 
3939  ao2_ref(message, -1);
3940 
3941  return 0;
3942 }
3943 
3944 /*! \brief Remove hint from extension */
3945 static int ast_remove_hint(struct ast_exten *e)
3946 {
3947  /* Cleanup the Notifys if hint is removed */
3948  struct ast_hint *hint;
3949 
3950  if (!e) {
3951  return -1;
3952  }
3953 
3954  hint = ao2_find(hints, e, OBJ_UNLINK);
3955  if (!hint) {
3956  return -1;
3957  }
3958 
3959  remove_hintdevice(hint);
3960 
3961  /*
3962  * The extension is being destroyed so we must save some
3963  * information to notify that the extension is deactivated.
3964  */
3965  ao2_lock(hint);
3968  sizeof(hint->context_name));
3970  sizeof(hint->exten_name));
3971  hint->exten = NULL;
3972  ao2_unlock(hint);
3973 
3974  publish_hint_remove(hint);
3975 
3976  ao2_ref(hint, -1);
3977 
3978  return 0;
3979 }
3980 
3981 /*! \brief Add hint to hint list, check initial extension state */
3982 static int ast_add_hint(struct ast_exten *e)
3983 {
3984  struct ast_hint *hint_new;
3985  struct ast_hint *hint_found;
3986  char *message = NULL;
3987  char *subtype = NULL;
3988  int presence_state;
3989 
3990  if (!e) {
3991  return -1;
3992  }
3993 
3994  /*
3995  * We must create the hint we wish to add before determining if
3996  * it is already in the hints container to avoid possible
3997  * deadlock when getting the current extension state.
3998  */
3999  hint_new = ao2_alloc(sizeof(*hint_new), destroy_hint);
4000  if (!hint_new) {
4001  return -1;
4002  }
4003  AST_VECTOR_INIT(&hint_new->devices, 8);
4004 
4005  /* Initialize new hint. */
4007  if (!hint_new->callbacks) {
4008  ao2_ref(hint_new, -1);
4009  return -1;
4010  }
4011  hint_new->exten = e;
4012  if (strstr(e->app, "${") && e->exten[0] == '_') {
4013  /* The hint is dynamic and hasn't been evaluted yet */
4014  hint_new->laststate = AST_DEVICE_INVALID;
4016  } else {
4017  hint_new->laststate = ast_extension_state2(e, NULL);
4018  if ((presence_state = extension_presence_state_helper(e, &subtype, &message)) > 0) {
4019  hint_new->last_presence_state = presence_state;
4020  hint_new->last_presence_subtype = subtype;
4021  hint_new->last_presence_message = message;
4022  }
4023  }
4024 
4025  /* Prevent multiple add hints from adding the same hint at the same time. */
4026  ao2_lock(hints);
4027 
4028  /* Search if hint exists, do nothing */
4029  hint_found = ao2_find(hints, e, 0);
4030  if (hint_found) {
4031  ao2_ref(hint_found, -1);
4032  ao2_unlock(hints);
4033  ao2_ref(hint_new, -1);
4034  ast_debug(2, "HINTS: Not re-adding existing hint %s: %s\n",
4036  return -1;
4037  }
4038 
4039  /* Add new hint to the hints container */
4040  ast_debug(2, "HINTS: Adding hint %s: %s\n",
4042  ao2_link(hints, hint_new);
4043  if (add_hintdevice(hint_new, ast_get_extension_app(e))) {
4044  ast_log(LOG_WARNING, "Could not add devices for hint: %s@%s.\n",
4047  }
4048 
4049  /* if not dynamic */
4050  if (!(strstr(e->app, "${") && e->exten[0] == '_')) {
4051  struct ast_state_cb *state_cb;
4052  struct ao2_iterator cb_iter;
4053 
4054  /* For general callbacks */
4055  cb_iter = ao2_iterator_init(statecbs, 0);
4056  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
4060  state_cb->data,
4062  hint_new,
4063  NULL);
4064  }
4065  ao2_iterator_destroy(&cb_iter);
4066  }
4067  ao2_unlock(hints);
4068  ao2_ref(hint_new, -1);
4069 
4070  return 0;
4071 }
4072 
4073 /*! \brief Publish a hint changed event */
4074 static int publish_hint_change(struct ast_hint *hint, struct ast_exten *ne)
4075 {
4076  struct stasis_message *message;
4077 
4078  if (!hint_change_message_type()) {
4079  return -1;
4080  }
4081 
4082  if (!(message = stasis_message_create(hint_change_message_type(), hint))) {
4083  ao2_ref(hint, -1);
4084  return -1;
4085  }
4086 
4089 
4090  ao2_ref(message, -1);
4091 
4092  return 0;
4093 }
4094 
4095 /*! \brief Change hint for an extension */
4096 static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
4097 {
4098  struct ast_hint *hint;
4099 
4100  if (!oe || !ne) {
4101  return -1;
4102  }
4103 
4104  ao2_lock(hints);/* Locked to hold off others while we move the hint around. */
4105 
4106  /*
4107  * Unlink the hint from the hints container as the extension
4108  * name (which is the hash value) could change.
4109  */
4110  hint = ao2_find(hints, oe, OBJ_UNLINK);
4111  if (!hint) {
4112  ao2_unlock(hints);
4114  return -1;
4115  }
4116 
4117  remove_hintdevice(hint);
4118 
4119  /* Update the hint and put it back in the hints container. */
4120  ao2_lock(hint);
4121  hint->exten = ne;
4122 
4123  ao2_unlock(hint);
4124 
4125  ao2_link(hints, hint);
4126  if (add_hintdevice(hint, ast_get_extension_app(ne))) {
4127  ast_log(LOG_WARNING, "Could not add devices for hint: %s@%s.\n",
4130  }
4131  ao2_unlock(hints);
4132 
4133  publish_hint_change(hint, ne);
4134 
4135  ao2_ref(hint, -1);
4136 
4137  return 0;
4138 }
4139 
4140 /*! \brief Get hint for channel */
4141 int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
4142 {
4143  struct ast_exten *e = ast_hint_extension(c, context, exten);
4144 
4145  if (e) {
4146  if (hint)
4147  ast_copy_string(hint, ast_get_extension_app(e), hintsize);
4148  if (name) {
4149  const char *tmp = ast_get_extension_app_data(e);
4150  if (tmp)
4151  ast_copy_string(name, tmp, namesize);
4152  }
4153  return -1;
4154  }
4155  return 0;
4156 }
4157 
4158 /*! \brief Get hint for channel */
4159 int ast_str_get_hint(struct ast_str **hint, ssize_t hintsize, struct ast_str **name, ssize_t namesize, struct ast_channel *c, const char *context, const char *exten)
4160 {
4161  struct ast_exten *e = ast_hint_extension(c, context, exten);
4162 
4163  if (!e) {
4164  return 0;
4165  }
4166 
4167  if (hint) {
4168  ast_str_set(hint, hintsize, "%s", ast_get_extension_app(e));
4169  }
4170  if (name) {
4171  const char *tmp = ast_get_extension_app_data(e);
4172  if (tmp) {
4173  ast_str_set(name, namesize, "%s", tmp);
4174  }
4175  }
4176  return -1;
4177 }
4178 
4179 int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
4180 {
4181  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
4182 }
4183 
4184 int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
4185 {
4186  return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
4187 }
4188 
4189 int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
4190 {
4191  return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
4192 }
4193 
4194 int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
4195 {
4196  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
4197 }
4198 
4199 int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
4200 {
4201  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
4202 }
4203 
4204 int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid, int *found, int combined_find_spawn)
4205 {
4206  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
4207 }
4208 
4209 void ast_pbx_h_exten_run(struct ast_channel *chan, const char *context)
4210 {
4211  int autoloopflag;
4212  int found;
4213  int spawn_error;
4214 
4215  ast_channel_lock(chan);
4216 
4217  /*
4218  * Make sure that the channel is marked as hungup since we are
4219  * going to run the h exten on it.
4220  */
4222 
4223  /* Set h exten location */
4224  if (context != ast_channel_context(chan)) {
4225  ast_channel_context_set(chan, context);
4226  }
4227  ast_channel_exten_set(chan, "h");
4228  ast_channel_priority_set(chan, 1);
4229 
4230  /* Save autoloop flag */
4231  autoloopflag = ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
4233  ast_channel_unlock(chan);
4234 
4235  for (;;) {
4236  spawn_error = ast_spawn_extension(chan, ast_channel_context(chan),
4238  S_COR(ast_channel_caller(chan)->id.number.valid,
4239  ast_channel_caller(chan)->id.number.str, NULL), &found, 1);
4240 
4241  ast_channel_lock(chan);
4242  if (spawn_error) {
4243  /* The code after the loop needs the channel locked. */
4244  break;
4245  }
4247  ast_channel_unlock(chan);
4248  }
4249  if (found && spawn_error) {
4250  /* Something bad happened, or a hangup has been requested. */
4251  ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n",
4253  ast_channel_priority(chan), ast_channel_name(chan));
4254  ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n",
4256  ast_channel_priority(chan), ast_channel_name(chan));
4257  }
4258 
4259  /* An "h" exten has been run, so indicate that one has been run. */
4261 
4262  /* Restore autoloop flag */
4264  ast_channel_unlock(chan);
4265 }
4266 
4267 /*! helper function to set extension and priority */
4268 void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
4269 {
4270  ast_channel_lock(c);
4271  ast_channel_exten_set(c, exten);
4272  ast_channel_priority_set(c, pri);
4273  ast_channel_unlock(c);
4274 }
4275 
4276 /*!
4277  * \brief collect digits from the channel into the buffer.
4278  * \param c, buf, buflen, pos
4279  * \param waittime is in milliseconds
4280  * \retval 0 on timeout or done.
4281  * \retval -1 on error.
4282 */
4283 static int collect_digits(struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
4284 {
4285  int digit;
4286 
4287  buf[pos] = '\0'; /* make sure it is properly terminated */
4288  while (ast_matchmore_extension(c, ast_channel_context(c), buf, 1,
4289  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4290  /* As long as we're willing to wait, and as long as it's not defined,
4291  keep reading digits until we can't possibly get a right answer anymore. */
4292  digit = ast_waitfordigit(c, waittime);
4294  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_ASYNCGOTO);
4295  } else {
4296  if (!digit) /* No entry */
4297  break;
4298  if (digit < 0) /* Error, maybe a hangup */
4299  return -1;
4300  if (pos < buflen - 1) { /* XXX maybe error otherwise ? */
4301  buf[pos++] = digit;
4302  buf[pos] = '\0';
4303  }
4304  waittime = ast_channel_pbx(c)->dtimeoutms;
4305  }
4306  }
4307  return 0;
4308 }
4309 
4311  struct ast_pbx_args *args)
4312 {
4313  int found = 0; /* set if we find at least one match */
4314  int res = 0;
4315  int autoloopflag;
4316  int error = 0; /* set an error conditions */
4317  struct ast_pbx *pbx;
4318  ast_callid callid;
4319 
4320  /* A little initial setup here */
4321  if (ast_channel_pbx(c)) {
4322  ast_log(LOG_WARNING, "%s already has PBX structure??\n", ast_channel_name(c));
4323  /* XXX and now what ? */
4325  }
4326  if (!(pbx = ast_calloc(1, sizeof(*pbx)))) {
4327  return AST_PBX_FAILED;
4328  }
4329 
4330  callid = ast_read_threadstorage_callid();
4331  /* If the thread isn't already associated with a callid, we should create that association. */
4332  if (!callid) {
4333  /* Associate new PBX thread with the channel call id if it is availble.
4334  * If not, create a new one instead.
4335  */
4336  callid = ast_channel_callid(c);
4337  if (!callid) {
4338  callid = ast_create_callid();
4339  if (callid) {
4340  ast_channel_lock(c);
4341  ast_channel_callid_set(c, callid);
4342  ast_channel_unlock(c);
4343  }
4344  }
4346  callid = 0;
4347  }
4348 
4349  ast_channel_pbx_set(c, pbx);
4350  /* Set reasonable defaults */
4351  ast_channel_pbx(c)->rtimeoutms = 10000;
4352  ast_channel_pbx(c)->dtimeoutms = 5000;
4353 
4354  ast_channel_lock(c);
4355  autoloopflag = ast_test_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
4357  ast_channel_unlock(c);
4358 
4360  /* If not successful fall back to 's' - but only if there is no given exten */
4361  ast_verb(2, "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", ast_channel_name(c), ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c));
4362  /* XXX the original code used the existing priority in the call to
4363  * ast_exists_extension(), and reset it to 1 afterwards.
4364  * I believe the correct thing is to set it to 1 immediately.
4365  */
4366  set_ext_pri(c, "s", 1);
4367  }
4368 
4369  for (;;) {
4370  char dst_exten[256]; /* buffer to accumulate digits */
4371  int pos = 0; /* XXX should check bounds */
4372  int digit = 0;
4373  int invalid = 0;
4374  int timeout = 0;
4375 
4376  /* No digits pressed yet */
4377  dst_exten[pos] = '\0';
4378 
4379  /* loop on priorities in this context/exten */
4381  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL),
4382  &found, 1))) {
4383 
4384  if (!ast_check_hangup(c)) {
4386  continue;
4387  }
4388 
4389  /* Check softhangup flags. */
4391  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_ASYNCGOTO);
4392  continue;
4393  }
4395  if (ast_exists_extension(c, ast_channel_context(c), "T", 1,
4396  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4397  set_ext_pri(c, "T", 1);
4398  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4399  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4400  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT);
4401  continue;
4402  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4403  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4404  raise_exception(c, "ABSOLUTETIMEOUT", 1);
4405  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4406  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4407  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT);
4408  continue;
4409  }
4410 
4411  /* Call timed out with no special extension to jump to. */
4412  error = 1;
4413  break;
4414  }
4415  ast_debug(1, "Extension %s, priority %d returned normally even though call was hung up\n",
4417  error = 1;
4418  break;
4419  } /* end while - from here on we can use 'break' to go out */
4420  if (found && res) {
4421  /* Something bad happened, or a hangup has been requested. */
4422  if (strchr("0123456789ABCDEF*#", res)) {
4423  ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res);
4424  pos = 0;
4425  dst_exten[pos++] = digit = res;
4426  dst_exten[pos] = '\0';
4427  } else if (res == AST_PBX_INCOMPLETE) {
4428  ast_debug(1, "Spawn extension (%s,%s,%d) exited INCOMPLETE on '%s'\n", ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_name(c));
4429  ast_verb(2, "Spawn extension (%s, %s, %d) exited INCOMPLETE on '%s'\n", ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_name(c));
4430 
4431  /* Don't cycle on incomplete - this will happen if the only extension that matches is our "incomplete" extension */
4433  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4434  invalid = 1;
4435  } else {
4436  ast_copy_string(dst_exten, ast_channel_exten(c), sizeof(dst_exten));
4437  digit = 1;
4438  pos = strlen(dst_exten);
4439  }
4440  } else {
4441  ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_name(c));
4442  ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_name(c));
4443 
4444  if ((res == AST_PBX_ERROR)
4445  && ast_exists_extension(c, ast_channel_context(c), "e", 1,
4446  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4447  /* if we are already on the 'e' exten, don't jump to it again */
4448  if (!strcmp(ast_channel_exten(c), "e")) {
4449  ast_verb(2, "Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s'\n", ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_name(c));
4450  error = 1;
4451  } else {
4452  raise_exception(c, "ERROR", 1);
4453  continue;
4454  }
4455  }
4456 
4458  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_ASYNCGOTO);
4459  continue;
4460  }
4462  if (ast_exists_extension(c, ast_channel_context(c), "T", 1,
4463  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4464  set_ext_pri(c, "T", 1);
4465  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4466  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4467  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT);
4468  continue;
4469  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4470  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4471  raise_exception(c, "ABSOLUTETIMEOUT", 1);
4472  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4473  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4474  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT);
4475  continue;
4476  }
4477  /* Call timed out with no special extension to jump to. */
4478  }
4479  error = 1;
4480  break;
4481  }
4482  }
4483  if (error)
4484  break;
4485 
4486  /*!\note
4487  * We get here on a failure of some kind: non-existing extension or
4488  * hangup. We have options, here. We can either catch the failure
4489  * and continue, or we can drop out entirely. */
4490 
4491  if (invalid
4492  || (ast_strlen_zero(dst_exten) &&
4494  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL)))) {
4495  /*!\note
4496  * If there is no match at priority 1, it is not a valid extension anymore.
4497  * Try to continue at "i" (for invalid) or "e" (for exception) or exit if
4498  * neither exist.
4499  */
4500  if (ast_exists_extension(c, ast_channel_context(c), "i", 1,
4501  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4502  ast_verb(3, "Channel '%s' sent to invalid extension: context,exten,priority=%s,%s,%d\n",
4504  pbx_builtin_setvar_helper(c, "INVALID_EXTEN", ast_channel_exten(c));
4505  set_ext_pri(c, "i", 1);
4506  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4507  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4508  raise_exception(c, "INVALID", 1);
4509  } else {
4510  ast_log(LOG_WARNING, "Channel '%s' sent to invalid extension but no invalid handler: context,exten,priority=%s,%s,%d\n",
4512  error = 1; /* we know what to do with it */
4513  break;
4514  }
4516  /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
4517  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT);
4518  } else { /* keypress received, get more digits for a full extension */
4519  int waittime = 0;
4520  if (digit)
4521  waittime = ast_channel_pbx(c)->dtimeoutms;
4522  else if (!autofallthrough)
4523  waittime = ast_channel_pbx(c)->rtimeoutms;
4524  if (!waittime) {
4525  const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
4526  if (!status)
4527  status = "UNKNOWN";
4528  ast_verb(3, "Auto fallthrough, channel '%s' status is '%s'\n", ast_channel_name(c), status);
4529  if (!strcasecmp(status, "CONGESTION"))
4530  res = indicate_congestion(c, "10");
4531  else if (!strcasecmp(status, "CHANUNAVAIL"))
4532  res = indicate_congestion(c, "10");
4533  else if (!strcasecmp(status, "BUSY"))
4534  res = indicate_busy(c, "10");
4535  error = 1; /* XXX disable message */
4536  break; /* exit from the 'for' loop */
4537  }
4538 
4539  if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos))
4540  break;
4541  if (res == AST_PBX_INCOMPLETE && ast_strlen_zero(&dst_exten[pos]))
4542  timeout = 1;
4543  if (!timeout
4544  && ast_exists_extension(c, ast_channel_context(c), dst_exten, 1,
4545  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) { /* Prepare the next cycle */
4546  set_ext_pri(c, dst_exten, 1);
4547  } else {
4548  /* No such extension */
4549  if (!timeout && !ast_strlen_zero(dst_exten)) {
4550  /* An invalid extension */
4551  if (ast_exists_extension(c, ast_channel_context(c), "i", 1,
4552  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4553  ast_verb(3, "Invalid extension '%s' in context '%s' on %s\n", dst_exten, ast_channel_context(c), ast_channel_name(c));
4554  pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
4555  set_ext_pri(c, "i", 1);
4556  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4557  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4558  raise_exception(c, "INVALID", 1);
4559  } else {
4561  "Invalid extension '%s', but no rule 'i' or 'e' in context '%s'\n",
4562  dst_exten, ast_channel_context(c));
4563  found = 1; /* XXX disable message */
4564  break;
4565  }
4566  } else {
4567  /* A simple timeout */
4568  if (ast_exists_extension(c, ast_channel_context(c), "t", 1,
4569  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4570  ast_verb(3, "Timeout on %s\n", ast_channel_name(c));
4571  set_ext_pri(c, "t", 1);
4572  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4573  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4574  raise_exception(c, "RESPONSETIMEOUT", 1);
4575  } else {
4577  "Timeout, but no rule 't' or 'e' in context '%s'\n",
4578  ast_channel_context(c));
4579  found = 1; /* XXX disable message */
4580  break;
4581  }
4582  }
4583  }
4584  }
4585  }
4586 
4587  if (!found && !error) {
4588  ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", ast_channel_name(c));
4589  }
4590 
4591  if (!args || !args->no_hangup_chan) {
4594  && ast_exists_extension(c, ast_channel_context(c), "h", 1,
4595  S_COR(ast_channel_caller(c)->id.number.valid,
4596  ast_channel_caller(c)->id.number.str, NULL))) {
4598  }
4600  }
4601 
4602  ast_channel_lock(c);
4604  ast_clear_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */
4605  ast_channel_unlock(c);
4608 
4609  if (!args || !args->no_hangup_chan) {
4610  ast_hangup(c);
4611  }
4612 
4613  return AST_PBX_SUCCESS;
4614 }
4615 
4616 /*!
4617  * \brief Increase call count for channel
4618  * \retval 0 on success
4619  * \retval non-zero if a configured limit (maxcalls, maxload, minmemfree) was reached
4620 */
4621 static int increase_call_count(const struct ast_channel *c)
4622 {
4623  int failed = 0;
4624  double curloadavg;
4625 #if defined(HAVE_SYSINFO)
4626  struct sysinfo sys_info;
4627 #endif
4628 
4630  if (ast_option_maxcalls) {
4631  if (countcalls >= ast_option_maxcalls) {
4632  ast_log(LOG_WARNING, "Maximum call limit of %d calls exceeded by '%s'!\n", ast_option_maxcalls, ast_channel_name(c));
4633  failed = -1;
4634  }
4635  }
4636  if (ast_option_maxload) {
4637  getloadavg(&curloadavg, 1);
4638  if (curloadavg >= ast_option_maxload) {
4639  ast_log(LOG_WARNING, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", ast_option_maxload, ast_channel_name(c), curloadavg);
4640  failed = -1;
4641  }
4642  }
4643 #if defined(HAVE_SYSINFO)
4644  if (option_minmemfree) {
4645  /* Make sure that the free system memory is above the configured low watermark */
4646  if (!sysinfo(&sys_info)) {
4647  /* Convert the amount of available RAM from mem_units to MB. The calculation
4648  * was done this way to avoid overflow problems */
4649  uint64_t curfreemem = sys_info.freeram + sys_info.bufferram;
4650  curfreemem *= sys_info.mem_unit;
4651  curfreemem /= 1024 * 1024;
4652  if (curfreemem < option_minmemfree) {
4653  ast_log(LOG_WARNING, "Available system memory (~%" PRIu64 "MB) is below the configured low watermark (%ldMB)\n",
4654  curfreemem, option_minmemfree);
4655  failed = -1;
4656  }
4657  }
4658  }
4659 #endif
4660 
4661  if (!failed) {
4662  countcalls++;
4663  totalcalls++;
4664  }
4666 
4667  return failed;
4668 }
4669 
4670 static void decrease_call_count(void)
4671 {
4673  if (countcalls > 0)
4674  countcalls--;
4676 }
4677 
4678 static void destroy_exten(struct ast_exten *e)
4679 {
4680  if (e->priority == PRIORITY_HINT)
4681  ast_remove_hint(e);
4682 
4683  if (e->peer_table)
4685  if (e->peer_label_table)
4687  if (e->datad)
4688  e->datad(e->data);
4689  ast_free(e);
4690 }
4691 
4692 static void *pbx_thread(void *data)
4693 {
4694  /* Oh joyeous kernel, we're a new thread, with nothing to do but
4695  answer this channel and get it going.
4696  */
4697  /* NOTE:
4698  The launcher of this function _MUST_ increment 'countcalls'
4699  before invoking the function; it will be decremented when the
4700  PBX has finished running on the channel
4701  */
4702  struct ast_channel *c = data;
4703 
4704  __ast_pbx_run(c, NULL);
4706 
4707  pthread_exit(NULL);
4708 
4709  return NULL;
4710 }
4711 
4713 {
4714  pthread_t t;
4715 
4716  if (!c) {
4717  ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
4718  return AST_PBX_FAILED;
4719  }
4720 
4722  ast_log(LOG_WARNING, "PBX requires Asterisk to be fully booted\n");
4723  return AST_PBX_FAILED;
4724  }
4725 
4726  if (increase_call_count(c))
4727  return AST_PBX_CALL_LIMIT;
4728 
4729  /* Start a new thread, and get something handling this channel. */
4731  ast_log(LOG_WARNING, "Failed to create new channel thread\n");
4733  return AST_PBX_FAILED;
4734  }
4735 
4736  return AST_PBX_SUCCESS;
4737 }
4738 
4740 {
4741  enum ast_pbx_result res = AST_PBX_SUCCESS;
4742 
4744  ast_log(LOG_WARNING, "PBX requires Asterisk to be fully booted\n");
4745  return AST_PBX_FAILED;
4746  }
4747 
4748  if (increase_call_count(c)) {
4749  return AST_PBX_CALL_LIMIT;
4750  }
4751 
4752  res = __ast_pbx_run(c, args);
4753 
4755 
4756  return res;
4757 }
4758 
4760 {
4761  return ast_pbx_run_args(c, NULL);
4762 }
4763 
4765 {
4766  return countcalls;
4767 }
4768 
4770 {
4771  return totalcalls;
4772 }
4773 
4775 {
4776  int oldval = autofallthrough;
4777  autofallthrough = newval;
4778  return oldval;
4779 }
4780 
4782 {
4783  int oldval = extenpatternmatchnew;
4784  extenpatternmatchnew = newval;
4785  return oldval;
4786 }
4787 
4788 void pbx_set_overrideswitch(const char *newval)
4789 {
4790  if (overrideswitch) {
4791  ast_free(overrideswitch);
4792  }
4793  if (!ast_strlen_zero(newval)) {
4794  overrideswitch = ast_strdup(newval);
4795  } else {
4796  overrideswitch = NULL;
4797  }
4798 }
4799 
4800 /*!
4801  * \brief lookup for a context with a given name,
4802  * \retval found context or NULL if not found.
4803  */
4804 static struct ast_context *find_context(const char *context)
4805 {
4806  struct fake_context item;
4807 
4808  ast_copy_string(item.name, context, sizeof(item.name));
4809 
4810  return ast_hashtab_lookup(contexts_table, &item);
4811 }
4812 
4813 /*!
4814  * \brief lookup for a context with a given name,
4815  * \retval with conlock held if found.
4816  * \retval NULL if not found.
4817  */
4818 static struct ast_context *find_context_locked(const char *context)
4819 {
4820  struct ast_context *c;
4821  struct fake_context item;
4822 
4823  ast_copy_string(item.name, context, sizeof(item.name));
4824 
4826  c = ast_hashtab_lookup(contexts_table, &item);
4827  if (!c) {
4829  }
4830 
4831  return c;
4832 }
4833 
4834 /*!
4835  * \brief Remove included contexts.
4836  * This function locks contexts list by &conlist, search for the right context
4837  * structure, leave context list locked and call ast_context_remove_include2
4838  * which removes include, unlock contexts list and return ...
4839  */
4840 int ast_context_remove_include(const char *context, const char *include, const char *registrar)
4841 {
4842  int ret = -1;
4843  struct ast_context *c;
4844 
4845  c = find_context_locked(context);
4846  if (c) {
4847  /* found, remove include from this context ... */
4848  ret = ast_context_remove_include2(c, include, registrar);
4850  }
4851  return ret;
4852 }
4853 
4854 /*!
4855  * \brief Locks context, remove included contexts, unlocks context.
4856  * When we call this function, &conlock lock must be locked, because when
4857  * we giving *con argument, some process can remove/change this context
4858  * and after that there can be segfault.
4859  *
4860  * \retval 0 on success.
4861  * \retval -1 on failure.
4862  */
4863 int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
4864 {
4865  int ret = -1;
4866  int idx;
4867 
4868  ast_wrlock_context(con);
4869 
4870  /* find our include */
4871  for (idx = 0; idx < ast_context_includes_count(con); idx++) {
4872  struct ast_include *i = AST_VECTOR_GET(&con->includes, idx);
4873 
4874  if (!strcmp(ast_get_include_name(i), include) &&
4875  (!registrar || !strcmp(ast_get_include_registrar(i), registrar))) {
4876 
4877  /* remove from list */
4878  ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar);
4879  AST_VECTOR_REMOVE_ORDERED(&con->includes, idx);
4880 
4881  /* free include and return */
4882  include_free(i);
4883  ret = 0;
4884  break;
4885  }
4886  }
4887 
4888  ast_unlock_context(con);
4889 
4890  return ret;
4891 }
4892 
4893 /*!
4894  * \note This function locks contexts list by &conlist, search for the rigt context
4895  * structure, leave context list locked and call ast_context_remove_switch2
4896  * which removes switch, unlock contexts list and return ...
4897  */
4898 int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar)
4899 {
4900  int ret = -1; /* default error return */
4901  struct ast_context *c;
4902 
4903  c = find_context_locked(context);
4904  if (c) {
4905  /* remove switch from this context ... */
4906  ret = ast_context_remove_switch2(c, sw, data, registrar);
4908  }
4909  return ret;
4910 }
4911 
4912 /*!
4913  * \brief This function locks given context, removes switch, unlock context and
4914  * return.
4915  * \note When we call this function, &conlock lock must be locked, because when
4916  * we giving *con argument, some process can remove/change this context
4917  * and after that there can be segfault.
4918  *
4919  */
4920 int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
4921 {
4922  int idx;
4923  int ret = -1;
4924 
4925  ast_wrlock_context(con);
4926 
4927  /* walk switches */
4928  for (idx = 0; idx < ast_context_switches_count(con); idx++) {
4929  struct ast_sw *i = AST_VECTOR_GET(&con->alts, idx);
4930 
4931  if (!strcmp(ast_get_switch_name(i), sw) &&
4932  !strcmp(ast_get_switch_data(i), data) &&
4933  (!registrar || !strcmp(ast_get_switch_registrar(i), registrar))) {
4934 
4935  /* found, remove from list */
4936  ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar);
4937  AST_VECTOR_REMOVE_ORDERED(&con->alts, idx);
4938 
4939  /* free switch and return */
4940  sw_free(i);
4941  ret = 0;
4942  break;
4943  }
4944  }
4945 
4946  ast_unlock_context(con);
4947 
4948  return ret;
4949 }
4950 
4951 /*! \note This function will lock conlock. */
4952 int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
4953 {
4954  return ast_context_remove_extension_callerid(context, extension, priority, NULL, AST_EXT_MATCHCID_ANY, registrar);
4955 }
4956 
4957 int ast_context_remove_extension_callerid(const char *context, const char *extension, int priority, const char *callerid, int matchcallerid, const char *registrar)
4958 {
4959  int ret = -1; /* default error return */
4960  struct ast_context *c;
4961 
4962  c = find_context_locked(context);
4963  if (c) { /* ... remove extension ... */
4964  ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid,
4965  matchcallerid, registrar, 0);
4967  }
4968 
4969  return ret;
4970 }
4971 
4972 /*!
4973  * \brief This functionc locks given context, search for the right extension and
4974  * fires out all peer in this extensions with given priority. If priority
4975  * is set to 0, all peers are removed. After that, unlock context and
4976  * return.
4977  * \note When do you want to call this function, make sure that &conlock is locked,
4978  * because some process can handle with your *con context before you lock
4979  * it.
4980  *
4981  */
4982 int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked)
4983 {
4984  return ast_context_remove_extension_callerid2(con, extension, priority, NULL, AST_EXT_MATCHCID_ANY, registrar, already_locked);
4985 }
4986 
4987 int ast_context_remove_extension_callerid2(struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcallerid, const char *registrar, int already_locked)
4988 {
4989  struct ast_exten *exten, *prev_exten = NULL;
4990  struct ast_exten *peer;
4991  struct ast_exten ex, *exten2, *exten3;
4992  char dummy_name[1024];
4993  char dummy_cid[1024];
4994  struct ast_exten *previous_peer = NULL;
4995  struct ast_exten *next_peer = NULL;
4996  int found = 0;
4997 
4998  if (!already_locked)
4999  ast_wrlock_context(con);
5000 
5001 #ifdef NEED_DEBUG
5002  ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcallerid ? "/" : "", matchcallerid ? callerid : "", registrar);
5003 #endif
5004 #ifdef CONTEXT_DEBUG
5005  check_contexts(__FILE__, __LINE__);
5006 #endif
5007  /* find this particular extension */
5008  ex.exten = dummy_name;
5009  ext_strncpy(dummy_name, extension, sizeof(dummy_name), 1);
5010  ex.matchcid = matchcallerid;
5011  if (callerid) {
5012  ex.cidmatch = dummy_cid;
5013  ext_strncpy(dummy_cid, callerid, sizeof(dummy_cid), 1);
5014  } else {
5015  ex.cidmatch = NULL;
5016  }
5017  exten = ast_hashtab_lookup(con->root_table, &ex);
5018  if (exten) {
5019  if (priority == 0) {
5020  exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
5021  if (!exten2)
5022  ast_log(LOG_ERROR,"Trying to delete the exten %s from context %s, but could not remove from the root_table\n", extension, con->name);
5023  if (con->pattern_tree) {
5024  struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
5025 
5026  if (x->exten) { /* this test for safety purposes */
5027  x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
5028  x->exten = 0; /* get rid of what will become a bad pointer */
5029  } else {
5030  ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n");
5031  }
5032  }
5033  } else {
5034  ex.priority = priority;
5035  exten2 = ast_hashtab_lookup(exten->peer_table, &ex);
5036  if (exten2) {
5037  if (exten2->label) { /* if this exten has a label, remove that, too */
5038  exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2);
5039  if (!exten3) {
5040  ast_log(LOG_ERROR, "Did not remove this priority label (%d/%s) "
5041  "from the peer_label_table of context %s, extension %s!\n",
5042  priority, exten2->label, con->name, exten2->name);
5043  }
5044  }
5045 
5046  exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2);
5047  if (!exten3) {
5048  ast_log(LOG_ERROR, "Did not remove this priority (%d) from the "
5049  "peer_table of context %s, extension %s!\n",
5050  priority, con->name, exten2->name);
5051  }
5052  if (exten2 == exten && exten2->peer) {
5053  exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
5055  }
5056  if (ast_hashtab_size(exten->peer_table) == 0) {
5057  /* well, if the last priority of an exten is to be removed,
5058  then, the extension is removed, too! */
5059  exten3 = ast_hashtab_remove_this_object(con->root_table, exten);
5060  if (!exten3) {
5061  ast_log(LOG_ERROR, "Did not remove this exten (%s) from the "
5062  "context root_table (%s) (priority %d)\n",
5063  exten->name, con->name, priority);
5064  }
5065  if (con->pattern_tree) {
5066  struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
5067  if (x->exten) { /* this test for safety purposes */
5068  x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
5069  x->exten = 0; /* get rid of what will become a bad pointer */
5070  }
5071  }
5072  }
5073  } else {
5074  ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n",
5075  priority, exten->name, con->name);
5076  }
5077  }
5078  } else {
5079  /* hmmm? this exten is not in this pattern tree? */
5080  ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n",
5081  extension, con->name);
5082  }
5083 #ifdef NEED_DEBUG
5084  if (con->pattern_tree) {
5085  ast_log(LOG_NOTICE,"match char tree after exten removal:\n");
5086  log_match_char_tree(con->pattern_tree, " ");
5087  }
5088 #endif
5089 
5090  /* scan the extension list to find first matching extension-registrar */
5091  for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
5092  if (!strcmp(exten->exten, ex.exten) &&
5093  (!matchcallerid ||
5094  (!ast_strlen_zero(ex.cidmatch) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, ex.cidmatch)) ||
5095  (ast_strlen_zero(ex.cidmatch) && ast_strlen_zero(exten->cidmatch)))) {
5096  break;
5097  }
5098  }
5099  if (!exten) {
5100  /* we can't find right extension */
5101  if (!already_locked)
5102  ast_unlock_context(con);
5103  return -1;
5104  }
5105 
5106  /* scan the priority list to remove extension with exten->priority == priority */
5107  for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
5108  peer && !strcmp(peer->exten, ex.exten) &&
5109  (!callerid || (!matchcallerid && !peer->matchcid) || (matchcallerid && peer->matchcid && !strcmp(peer->cidmatch, ex.cidmatch))) ;
5110  peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
5111 
5112  if ((priority == 0 || peer->priority == priority) &&
5113  (!registrar || !strcmp(peer->registrar, registrar) )) {
5114  found = 1;
5115 
5116  /* we are first priority extension? */
5117  if (!previous_peer) {
5118  /*
5119  * We are first in the priority chain, so must update the extension chain.
5120  * The next node is either the next priority or the next extension
5121  */
5122  struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
5123  if (peer->peer) {
5124  /* move the peer_table and peer_label_table down to the next peer, if
5125  it is there */
5126  peer->peer->peer_table = peer->peer_table;
5127  peer->peer->peer_label_table = peer->peer_label_table;
5128  peer->peer_table = NULL;
5129  peer->peer_label_table =