Asterisk - The Open Source Telephony Project  GIT-master-1f78ee9
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 */
3152  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
3153  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
3154  e->registrar);
3155  if (!(e = ast_hint_extension(c, context, exten))) {
3156  /* Improbable, but not impossible */
3157  return -1;
3158  }
3159  }
3160 
3161  return ast_extension_state2(e, device_state_info); /* Check all devices in the hint */
3162 }
3163 
3164 /*! \brief Check extension state for an extension by using hint */
3165 int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
3166 {
3167  return internal_extension_state_extended(c, context, exten, NULL);
3168 }
3169 
3170 /*! \brief Check extended extension state for an extension by using hint */
3171 int ast_extension_state_extended(struct ast_channel *c, const char *context, const char *exten,
3172  struct ao2_container **device_state_info)
3173 {
3174  struct ao2_container *container = NULL;
3175  int ret;
3176 
3177  if (device_state_info) {
3178  container = alloc_device_state_info();
3179  }
3180 
3181  ret = internal_extension_state_extended(c, context, exten, container);
3182  if (ret < 0 && container) {
3183  ao2_ref(container, -1);
3184  container = NULL;
3185  }
3186 
3187  if (device_state_info) {
3189  *device_state_info = container;
3190  }
3191 
3192  return ret;
3193 }
3194 
3195 static int extension_presence_state_helper(struct ast_exten *e, char **subtype, char **message)
3196 {
3197  struct ast_str *hint_app = ast_str_thread_get(&extensionstate_buf, 32);
3198  char *presence_provider;
3199  const char *app;
3200 
3201  if (!e || !hint_app) {
3202  return -1;
3203  }
3204 
3205  app = ast_get_extension_app(e);
3206  if (ast_strlen_zero(app)) {
3207  return -1;
3208  }
3209 
3210  ast_str_set(&hint_app, 0, "%s", app);
3211  presence_provider = parse_hint_presence(hint_app);
3212 
3213  if (ast_strlen_zero(presence_provider)) {
3214  /* No presence string in the hint */
3215  return 0;
3216  }
3217 
3218  return ast_presence_state(presence_provider, subtype, message);
3219 }
3220 
3221 int ast_hint_presence_state(struct ast_channel *c, const char *context, const char *exten, char **subtype, char **message)
3222 {
3223  struct ast_exten *e;
3224 
3225  if (!(e = ast_hint_extension(c, context, exten))) { /* Do we have a hint for this extension ? */
3226  return -1; /* No hint, return -1 */
3227  }
3228 
3229  if (e->exten[0] == '_') {
3230  /* Create this hint on-the-fly */
3231  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
3232  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
3233  e->registrar);
3234  if (!(e = ast_hint_extension(c, context, exten))) {
3235  /* Improbable, but not impossible */
3236  return -1;
3237  }
3238  }
3239 
3240  return extension_presence_state_helper(e, subtype, message);
3241 }
3242 
3244  const char *context,
3245  const char *exten,
3246  void *data,
3247  enum ast_state_cb_update_reason reason,
3248  struct ast_hint *hint,
3249  struct ao2_container *device_state_info)
3250 {
3251  int res = 0;
3252  struct ast_state_cb_info info = { 0, };
3253 
3254  info.reason = reason;
3255 
3256  /* Copy over current hint data */
3257  if (hint) {
3258  ao2_lock(hint);
3259  info.exten_state = hint->laststate;
3261  info.presence_state = hint->last_presence_state;
3262  if (!(ast_strlen_zero(hint->last_presence_subtype))) {
3264  } else {
3265  info.presence_subtype = "";
3266  }
3267  if (!(ast_strlen_zero(hint->last_presence_message))) {
3269  } else {
3270  info.presence_message = "";
3271  }
3272  ao2_unlock(hint);
3273  } else {
3275  }
3276 
3277  res = cb(context, exten, &info, data);
3278 
3279  return res;
3280 }
3281 
3282 /*!
3283  * /internal
3284  * /brief Identify a channel for every device which is supposedly responsible for the device state.
3285  *
3286  * Especially when the device is ringing, the oldest ringing channel is chosen.
3287  * For all other cases the first encountered channel in the specific state is chosen.
3288  */
3290 {
3291  struct ao2_iterator iter;
3292  struct ast_device_state_info *info;
3293  struct ast_channel *chan;
3294 
3295  if (!c || !ao2_container_count(c)) {
3296  return;
3297  }
3298  iter = ao2_iterator_init(c, 0);
3299  for (; (info = ao2_iterator_next(&iter)); ao2_ref(info, -1)) {
3300  enum ast_channel_state search_state = 0; /* prevent false uninit warning */
3301  char match[AST_CHANNEL_NAME];
3302  struct ast_channel_iterator *chan_iter;
3303  struct timeval chantime = {0, }; /* prevent false uninit warning */
3304 
3305  switch (info->device_state) {
3306  case AST_DEVICE_RINGING:
3307  case AST_DEVICE_RINGINUSE:
3308  /* find ringing channel */
3309  search_state = AST_STATE_RINGING;
3310  break;
3311  case AST_DEVICE_BUSY:
3312  /* find busy channel */
3313  search_state = AST_STATE_BUSY;
3314  break;
3315  case AST_DEVICE_ONHOLD:
3316  case AST_DEVICE_INUSE:
3317  /* find up channel */
3318  search_state = AST_STATE_UP;
3319  break;
3320  case AST_DEVICE_UNKNOWN:
3321  case AST_DEVICE_NOT_INUSE:
3322  case AST_DEVICE_INVALID:
3324  case AST_DEVICE_TOTAL /* not a state */:
3325  /* no channels are of interest */
3326  continue;
3327  }
3328 
3329  /* iterate over all channels of the device */
3330  snprintf(match, sizeof(match), "%s-", info->device_name);
3331  chan_iter = ast_channel_iterator_by_name_new(match, strlen(match));
3332  for (; (chan = ast_channel_iterator_next(chan_iter)); ast_channel_unref(chan)) {
3333  ast_channel_lock(chan);
3334  /* this channel's state doesn't match */
3335  if (search_state != ast_channel_state(chan)) {
3336  ast_channel_unlock(chan);
3337  continue;
3338  }
3339  /* any non-ringing channel will fit */
3340  if (search_state != AST_STATE_RINGING) {
3341  ast_channel_unlock(chan);
3342  info->causing_channel = chan; /* is kept ref'd! */
3343  break;
3344  }
3345  /* but we need the oldest ringing channel of the device to match with undirected pickup */
3346  if (!info->causing_channel) {
3347  chantime = ast_channel_creationtime(chan);
3348  ast_channel_ref(chan); /* must ref it! */
3349  info->causing_channel = chan;
3350  } else if (ast_tvcmp(ast_channel_creationtime(chan), chantime) < 0) {
3351  chantime = ast_channel_creationtime(chan);
3353  ast_channel_ref(chan); /* must ref it! */
3354  info->causing_channel = chan;
3355  }
3356  ast_channel_unlock(chan);
3357  }
3358  ast_channel_iterator_destroy(chan_iter);
3359  }
3360  ao2_iterator_destroy(&iter);
3361 }
3362 
3363 static void device_state_notify_callbacks(struct ast_hint *hint, struct ast_str **hint_app)
3364 {
3365  struct ao2_iterator cb_iter;
3366  struct ast_state_cb *state_cb;
3367  int state;
3368  int same_state;
3369  struct ao2_container *device_state_info;
3370  int first_extended_cb_call = 1;
3373 
3374  ao2_lock(hint);
3375  if (!hint->exten) {
3376  /* The extension has already been destroyed */
3377  ao2_unlock(hint);
3378  return;
3379  }
3380 
3381  /*
3382  * Save off strings in case the hint extension gets destroyed
3383  * while we are notifying the watchers.
3384  */
3385  ast_copy_string(context_name,
3387  sizeof(context_name));
3388  ast_copy_string(exten_name, ast_get_extension_name(hint->exten),
3389  sizeof(exten_name));
3390  ast_str_set(hint_app, 0, "%s", ast_get_extension_app(hint->exten));
3391  ao2_unlock(hint);
3392 
3393  /*
3394  * Get device state for this hint.
3395  *
3396  * NOTE: We cannot hold any locks while determining the hint
3397  * device state or notifying the watchers without causing a
3398  * deadlock. (conlock, hints, and hint)
3399  */
3400 
3401  /* Make a container so state3 can fill it if we wish.
3402  * If that failed we simply do not provide the extended state info.
3403  */
3404  device_state_info = alloc_device_state_info();
3405 
3406  state = ast_extension_state3(*hint_app, device_state_info);
3407  same_state = state == hint->laststate;
3408  if (same_state && (~state & AST_EXTENSION_RINGING)) {
3409  ao2_cleanup(device_state_info);
3410  return;
3411  }
3412 
3413  /* Device state changed since last check - notify the watchers. */
3414  hint->laststate = state; /* record we saw the change */
3415 
3416  /* For general callbacks */
3417  if (!same_state) {
3418  cb_iter = ao2_iterator_init(statecbs, 0);
3419  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3421  context_name,
3422  exten_name,
3423  state_cb->data,
3425  hint,
3426  NULL);
3427  }
3428  ao2_iterator_destroy(&cb_iter);
3429  }
3430 
3431  /* For extension callbacks */
3432  /* extended callbacks are called when the state changed or when AST_STATE_RINGING is
3433  * included. Normal callbacks are only called when the state changed.
3434  */
3435  cb_iter = ao2_iterator_init(hint->callbacks, 0);
3436  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3437  if (state_cb->extended && first_extended_cb_call) {
3438  /* Fill detailed device_state_info now that we know it is used by extd. callback */
3439  first_extended_cb_call = 0;
3440  get_device_state_causing_channels(device_state_info);
3441  }
3442  if (state_cb->extended || !same_state) {
3444  context_name,
3445  exten_name,
3446  state_cb->data,
3448  hint,
3449  state_cb->extended ? device_state_info : NULL);
3450  }
3451  }
3452  ao2_iterator_destroy(&cb_iter);
3453 
3454  ao2_cleanup(device_state_info);
3455 }
3456 
3457 static void presence_state_notify_callbacks(struct ast_hint *hint, struct ast_str **hint_app,
3458  struct ast_presence_state_message *presence_state)
3459 {
3460  struct ao2_iterator cb_iter;
3461  struct ast_state_cb *state_cb;
3464 
3465  ao2_lock(hint);
3466  if (!hint->exten) {
3467  /* The extension has already been destroyed */
3468  ao2_unlock(hint);
3469  return;
3470  }
3471 
3472  /*
3473  * Save off strings in case the hint extension gets destroyed
3474  * while we are notifying the watchers.
3475  */
3476  ast_copy_string(context_name,
3478  sizeof(context_name));
3479  ast_copy_string(exten_name, ast_get_extension_name(hint->exten),
3480  sizeof(exten_name));
3481  ast_str_set(hint_app, 0, "%s", ast_get_extension_app(hint->exten));
3482  ao2_unlock(hint);
3483 
3484  /* Check to see if update is necessary */
3485  if ((hint->last_presence_state == presence_state->state) &&
3486  ((hint->last_presence_subtype && presence_state->subtype &&
3487  !strcmp(hint->last_presence_subtype, presence_state->subtype)) ||
3488  (!hint->last_presence_subtype && !presence_state->subtype)) &&
3489  ((hint->last_presence_message && presence_state->message &&
3490  !strcmp(hint->last_presence_message, presence_state->message)) ||
3491  (!hint->last_presence_message && !presence_state->message))) {
3492  /* this update is the same as the last, do nothing */
3493  return;
3494  }
3495 
3496  /* update new values */
3499  hint->last_presence_state = presence_state->state;
3500  hint->last_presence_subtype = presence_state->subtype ? ast_strdup(presence_state->subtype) : NULL;
3501  hint->last_presence_message = presence_state->message ? ast_strdup(presence_state->message) : NULL;
3502 
3503  /* For general callbacks */
3504  cb_iter = ao2_iterator_init(statecbs, 0);
3505  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3507  context_name,
3508  exten_name,
3509  state_cb->data,
3511  hint,
3512  NULL);
3513  }
3514  ao2_iterator_destroy(&cb_iter);
3515 
3516  /* For extension callbacks */
3517  cb_iter = ao2_iterator_init(hint->callbacks, 0);
3518  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_cleanup(state_cb)) {
3520  context_name,
3521  exten_name,
3522  state_cb->data,
3524  hint,
3525  NULL);
3526  }
3527  ao2_iterator_destroy(&cb_iter);
3528 }
3529 
3531 {
3532  struct ast_hint *hint;
3533  struct ast_str *hint_app;
3534 
3535  if (hint_change_message_type() != stasis_message_type(msg)) {
3536  return 0;
3537  }
3538 
3539  if (!(hint_app = ast_str_create(1024))) {
3540  return -1;
3541  }
3542 
3543  hint = stasis_message_data(msg);
3544 
3545  switch (reason) {
3547  device_state_notify_callbacks(hint, &hint_app);
3548  break;
3550  {
3551  char *presence_subtype = NULL;
3552  char *presence_message = NULL;
3553  int state;
3554 
3556  hint->exten, &presence_subtype, &presence_message);
3557  {
3558  struct ast_presence_state_message presence_state = {
3559  .state = state > 0 ? state : AST_PRESENCE_INVALID,
3560  .subtype = presence_subtype,
3561  .message = presence_message
3562  };
3563 
3564  presence_state_notify_callbacks(hint, &hint_app, &presence_state);
3565  }
3566 
3567  ast_free(presence_subtype);
3568  ast_free(presence_message);
3569  }
3570  break;
3571  }
3572 
3573  ast_free(hint_app);
3574  return 1;
3575 }
3576 
3577 static void device_state_cb(void *unused, struct stasis_subscription *sub, struct stasis_message *msg)
3578 {
3579  struct ast_device_state_message *dev_state;
3580  struct ast_str *hint_app;
3581  struct ast_hintdevice *device;
3582  struct ast_hintdevice *cmpdevice;
3583  struct ao2_iterator *dev_iter;
3584  struct ao2_iterator auto_iter;
3585  struct ast_autohint *autohint;
3586  char *virtual_device;
3587  char *type;
3588  char *device_name;
3589 
3591  return;
3592  }
3593 
3594  if (hint_remove_message_type() == stasis_message_type(msg)) {
3595  /* The extension has already been destroyed */
3596  struct ast_state_cb *state_cb;
3597  struct ao2_iterator cb_iter;
3598  struct ast_hint *hint = stasis_message_data(msg);
3599 
3600  ao2_lock(hint);
3602  ao2_unlock(hint);
3603 
3604  cb_iter = ao2_iterator_init(hint->callbacks, 0);
3605  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
3607  hint->context_name,
3608  hint->exten_name,
3609  state_cb->data,
3611  hint,
3612  NULL);
3613  }
3614  ao2_iterator_destroy(&cb_iter);
3615  return;
3616  }
3617 
3619  return;
3620  }
3621 
3622  dev_state = stasis_message_data(msg);
3623  if (dev_state->eid) {
3624  /* ignore non-aggregate states */
3625  return;
3626  }
3627 
3628  if (ao2_container_count(hintdevices) == 0 && ao2_container_count(autohints) == 0) {
3629  /* There are no hints monitoring devices. */
3630  return;
3631  }
3632 
3633  hint_app = ast_str_create(1024);
3634  if (!hint_app) {
3635  return;
3636  }
3637 
3638  cmpdevice = ast_alloca(sizeof(*cmpdevice) + strlen(dev_state->device));
3639  strcpy(cmpdevice->hintdevice, dev_state->device);
3640 
3641  ast_mutex_lock(&context_merge_lock);/* Hold off ast_merge_contexts_and_delete */
3642 
3643  /* Initially we find all hints for the device and notify them */
3644  dev_iter = ao2_t_callback(hintdevices,
3647  cmpdevice,
3648  "find devices in container");
3649  if (dev_iter) {
3650  for (; (device = ao2_iterator_next(dev_iter)); ao2_t_ref(device, -1, "Next device")) {
3651  if (device->hint) {
3652  device_state_notify_callbacks(device->hint, &hint_app);
3653  }
3654  }
3655  ao2_iterator_destroy(dev_iter);
3656  }
3657 
3658  /* Second stage we look for any autohint contexts and if the device is not already in the hints
3659  * we create it.
3660  */
3661  type = ast_strdupa(dev_state->device);
3662  if (ast_strlen_zero(type)) {
3663  goto end;
3664  }
3665 
3666  /* Determine if this is a virtual/custom device or a real device */
3667  virtual_device = strchr(type, ':');
3668  device_name = strchr(type, '/');
3669  if (virtual_device && (!device_name || (virtual_device < device_name))) {
3670  device_name = virtual_device;
3671  }
3672 
3673  /* Invalid device state name - not a virtual/custom device and not a real device */
3674  if (ast_strlen_zero(device_name)) {
3675  goto end;
3676  }
3677 
3678  *device_name++ = '\0';
3679 
3680  auto_iter = ao2_iterator_init(autohints, 0);
3681  for (; (autohint = ao2_iterator_next(&auto_iter)); ao2_t_ref(autohint, -1, "Next autohint")) {
3682  if (ast_get_hint(NULL, 0, NULL, 0, NULL, autohint->context, device_name)) {
3683  continue;
3684  }
3685 
3686  /* The device has no hint in the context referenced by this autohint so create one */
3687  ast_add_extension(autohint->context, 0, device_name,
3688  PRIORITY_HINT, NULL, NULL, dev_state->device,
3689  ast_strdup(dev_state->device), ast_free_ptr, autohint->registrar);
3690 
3691  /* Since this hint was just created there are no watchers, so we don't need to notify anyone */
3692  }
3693  ao2_iterator_destroy(&auto_iter);
3694 
3695 end:
3697  ast_free(hint_app);
3698  return;
3699 }
3700 
3701 /*!
3702  * \internal
3703  * \brief Destroy the given state callback object.
3704  *
3705  * \param doomed State callback to destroy.
3706  *
3707  * \return Nothing
3708  */
3709 static void destroy_state_cb(void *doomed)
3710 {
3711  struct ast_state_cb *state_cb = doomed;
3712 
3713  if (state_cb->destroy_cb) {
3714  state_cb->destroy_cb(state_cb->id, state_cb->data);
3715  }
3716 }
3717 
3718 /*!
3719  * \internal
3720  * \brief Add watcher for extension states with destructor
3721  */
3722 static int extension_state_add_destroy(const char *context, const char *exten,
3724 {
3725  struct ast_hint *hint;
3726  struct ast_state_cb *state_cb;
3727  struct ast_exten *e;
3728  int id;
3729 
3730  /* If there's no context and extension: add callback to statecbs list */
3731  if (!context && !exten) {
3732  /* Prevent multiple adds from adding the same change_cb at the same time. */
3733  ao2_lock(statecbs);
3734 
3735  /* Remove any existing change_cb. */
3736  ao2_find(statecbs, change_cb, OBJ_UNLINK | OBJ_NODATA);
3737 
3738  /* Now insert the change_cb */
3739  if (!(state_cb = ao2_alloc(sizeof(*state_cb), destroy_state_cb))) {
3740  ao2_unlock(statecbs);
3741  return -1;
3742  }
3743  state_cb->id = 0;
3744  state_cb->change_cb = change_cb;
3745  state_cb->destroy_cb = destroy_cb;
3746  state_cb->data = data;
3747  state_cb->extended = extended;
3748  ao2_link(statecbs, state_cb);
3749 
3750  ao2_ref(state_cb, -1);
3751  ao2_unlock(statecbs);
3752  return 0;
3753  }
3754 
3755  if (!context || !exten)
3756  return -1;
3757 
3758  /* This callback type is for only one hint, so get the hint */
3759  e = ast_hint_extension(NULL, context, exten);
3760  if (!e) {
3761  return -1;
3762  }
3763 
3764  /* If this is a pattern, dynamically create a new extension for this
3765  * particular match. Note that this will only happen once for each
3766  * individual extension, because the pattern will no longer match first.
3767  */
3768  if (e->exten[0] == '_') {
3769  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
3770  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
3771  e->registrar);
3772  e = ast_hint_extension(NULL, context, exten);
3773  if (!e || e->exten[0] == '_') {
3774  return -1;
3775  }
3776  }
3777 
3778  /* Find the hint in the hints container */
3779  ao2_lock(hints);/* Locked to hold off ast_merge_contexts_and_delete */
3780  hint = ao2_find(hints, e, 0);
3781  if (!hint) {
3782  ao2_unlock(hints);
3783  return -1;
3784  }
3785 
3786  /* Now insert the callback in the callback list */
3787  if (!(state_cb = ao2_alloc(sizeof(*state_cb), destroy_state_cb))) {
3788  ao2_ref(hint, -1);
3789  ao2_unlock(hints);
3790  return -1;
3791  }
3792  do {
3793  id = stateid++; /* Unique ID for this callback */
3794  /* Do not allow id to ever be -1 or 0. */
3795  } while (id == -1 || id == 0);
3796  state_cb->id = id;
3797  state_cb->change_cb = change_cb; /* Pointer to callback routine */
3798  state_cb->destroy_cb = destroy_cb;
3799  state_cb->data = data; /* Data for the callback */
3800  state_cb->extended = extended;
3801  ao2_link(hint->callbacks, state_cb);
3802 
3803  ao2_ref(state_cb, -1);
3804  ao2_ref(hint, -1);
3805  ao2_unlock(hints);
3806 
3807  return id;
3808 }
3809 
3810 int ast_extension_state_add_destroy(const char *context, const char *exten,
3811  ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
3812 {
3813  return extension_state_add_destroy(context, exten, change_cb, destroy_cb, data, 0);
3814 }
3815 
3816 int ast_extension_state_add(const char *context, const char *exten,
3817  ast_state_cb_type change_cb, void *data)
3818 {
3819  return extension_state_add_destroy(context, exten, change_cb, NULL, data, 0);
3820 }
3821 
3822 int ast_extension_state_add_destroy_extended(const char *context, const char *exten,
3823  ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
3824 {
3825  return extension_state_add_destroy(context, exten, change_cb, destroy_cb, data, 1);
3826 }
3827 
3828 int ast_extension_state_add_extended(const char *context, const char *exten,
3829  ast_state_cb_type change_cb, void *data)
3830 {
3831  return extension_state_add_destroy(context, exten, change_cb, NULL, data, 1);
3832 }
3833 
3834 /*! \brief Find Hint by callback id */
3835 static int find_hint_by_cb_id(void *obj, void *arg, int flags)
3836 {
3837  struct ast_state_cb *state_cb;
3838  const struct ast_hint *hint = obj;
3839  int *id = arg;
3840 
3841  if ((state_cb = ao2_find(hint->callbacks, id, 0))) {
3842  ao2_ref(state_cb, -1);
3843  return CMP_MATCH | CMP_STOP;
3844  }
3845 
3846  return 0;
3847 }
3848 
3850 {
3851  struct ast_state_cb *p_cur;
3852  int ret = -1;
3853 
3854  if (!id) { /* id == 0 is a callback without extension */
3855  if (!change_cb) {
3856  return ret;
3857  }
3858  p_cur = ao2_find(statecbs, change_cb, OBJ_UNLINK);
3859  if (p_cur) {
3860  ret = 0;
3861  ao2_ref(p_cur, -1);
3862  }
3863  } else { /* callback with extension, find the callback based on ID */
3864  struct ast_hint *hint;
3865 
3866  ao2_lock(hints);/* Locked to hold off ast_merge_contexts_and_delete */
3867  hint = ao2_callback(hints, 0, find_hint_by_cb_id, &id);
3868  if (hint) {
3869  p_cur = ao2_find(hint->callbacks, &id, OBJ_UNLINK);
3870  if (p_cur) {
3871  ret = 0;
3872  ao2_ref(p_cur, -1);
3873  }
3874  ao2_ref(hint, -1);
3875  }
3876  ao2_unlock(hints);
3877  }
3878 
3879  return ret;
3880 }
3881 
3882 static int hint_id_cmp(void *obj, void *arg, int flags)
3883 {
3884  const struct ast_state_cb *cb = obj;
3885  int *id = arg;
3886 
3887  return (cb->id == *id) ? CMP_MATCH | CMP_STOP : 0;
3888 }
3889 
3890 /*!
3891  * \internal
3892  * \brief Destroy the given hint object.
3893  *
3894  * \param obj Hint to destroy.
3895  *
3896  * \return Nothing
3897  */
3898 static void destroy_hint(void *obj)
3899 {
3900  struct ast_hint *hint = obj;
3901  int i;
3902 
3903  ao2_cleanup(hint->callbacks);
3904 
3905  for (i = 0; i < AST_VECTOR_SIZE(&hint->devices); i++) {
3906  char *device = AST_VECTOR_GET(&hint->devices, i);
3907  ast_free(device);
3908  }
3909  AST_VECTOR_FREE(&hint->devices);
3912 }
3913 
3914 /*! \brief Publish a hint removed event */
3915 static int publish_hint_remove(struct ast_hint *hint)
3916 {
3917  struct stasis_message *message;
3918 
3919  if (!hint_remove_message_type()) {
3920  return -1;
3921  }
3922 
3923  if (!(message = stasis_message_create(hint_remove_message_type(), hint))) {
3924  ao2_ref(hint, -1);
3925  return -1;
3926  }
3927 
3929 
3930  ao2_ref(message, -1);
3931 
3932  return 0;
3933 }
3934 
3935 /*! \brief Remove hint from extension */
3936 static int ast_remove_hint(struct ast_exten *e)
3937 {
3938  /* Cleanup the Notifys if hint is removed */
3939  struct ast_hint *hint;
3940 
3941  if (!e) {
3942  return -1;
3943  }
3944 
3945  hint = ao2_find(hints, e, OBJ_UNLINK);
3946  if (!hint) {
3947  return -1;
3948  }
3949 
3950  remove_hintdevice(hint);
3951 
3952  /*
3953  * The extension is being destroyed so we must save some
3954  * information to notify that the extension is deactivated.
3955  */
3956  ao2_lock(hint);
3959  sizeof(hint->context_name));
3961  sizeof(hint->exten_name));
3962  hint->exten = NULL;
3963  ao2_unlock(hint);
3964 
3965  publish_hint_remove(hint);
3966 
3967  ao2_ref(hint, -1);
3968 
3969  return 0;
3970 }
3971 
3972 /*! \brief Add hint to hint list, check initial extension state */
3973 static int ast_add_hint(struct ast_exten *e)
3974 {
3975  struct ast_hint *hint_new;
3976  struct ast_hint *hint_found;
3977  char *message = NULL;
3978  char *subtype = NULL;
3979  int presence_state;
3980 
3981  if (!e) {
3982  return -1;
3983  }
3984 
3985  /*
3986  * We must create the hint we wish to add before determining if
3987  * it is already in the hints container to avoid possible
3988  * deadlock when getting the current extension state.
3989  */
3990  hint_new = ao2_alloc(sizeof(*hint_new), destroy_hint);
3991  if (!hint_new) {
3992  return -1;
3993  }
3994  AST_VECTOR_INIT(&hint_new->devices, 8);
3995 
3996  /* Initialize new hint. */
3998  if (!hint_new->callbacks) {
3999  ao2_ref(hint_new, -1);
4000  return -1;
4001  }
4002  hint_new->exten = e;
4003  if (strstr(e->app, "${") && e->exten[0] == '_') {
4004  /* The hint is dynamic and hasn't been evaluted yet */
4005  hint_new->laststate = AST_DEVICE_INVALID;
4007  } else {
4008  hint_new->laststate = ast_extension_state2(e, NULL);
4009  if ((presence_state = extension_presence_state_helper(e, &subtype, &message)) > 0) {
4010  hint_new->last_presence_state = presence_state;
4011  hint_new->last_presence_subtype = subtype;
4012  hint_new->last_presence_message = message;
4013  }
4014  }
4015 
4016  /* Prevent multiple add hints from adding the same hint at the same time. */
4017  ao2_lock(hints);
4018 
4019  /* Search if hint exists, do nothing */
4020  hint_found = ao2_find(hints, e, 0);
4021  if (hint_found) {
4022  ao2_ref(hint_found, -1);
4023  ao2_unlock(hints);
4024  ao2_ref(hint_new, -1);
4025  ast_debug(2, "HINTS: Not re-adding existing hint %s: %s\n",
4027  return -1;
4028  }
4029 
4030  /* Add new hint to the hints container */
4031  ast_debug(2, "HINTS: Adding hint %s: %s\n",
4033  ao2_link(hints, hint_new);
4034  if (add_hintdevice(hint_new, ast_get_extension_app(e))) {
4035  ast_log(LOG_WARNING, "Could not add devices for hint: %s@%s.\n",
4038  }
4039 
4040  /* if not dynamic */
4041  if (!(strstr(e->app, "${") && e->exten[0] == '_')) {
4042  struct ast_state_cb *state_cb;
4043  struct ao2_iterator cb_iter;
4044 
4045  /* For general callbacks */
4046  cb_iter = ao2_iterator_init(statecbs, 0);
4047  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
4051  state_cb->data,
4053  hint_new,
4054  NULL);
4055  }
4056  ao2_iterator_destroy(&cb_iter);
4057  }
4058  ao2_unlock(hints);
4059  ao2_ref(hint_new, -1);
4060 
4061  return 0;
4062 }
4063 
4064 /*! \brief Publish a hint changed event */
4065 static int publish_hint_change(struct ast_hint *hint, struct ast_exten *ne)
4066 {
4067  struct stasis_message *message;
4068 
4069  if (!hint_change_message_type()) {
4070  return -1;
4071  }
4072 
4073  if (!(message = stasis_message_create(hint_change_message_type(), hint))) {
4074  ao2_ref(hint, -1);
4075  return -1;
4076  }
4077 
4080 
4081  ao2_ref(message, -1);
4082 
4083  return 0;
4084 }
4085 
4086 /*! \brief Change hint for an extension */
4087 static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
4088 {
4089  struct ast_hint *hint;
4090 
4091  if (!oe || !ne) {
4092  return -1;
4093  }
4094 
4095  ao2_lock(hints);/* Locked to hold off others while we move the hint around. */
4096 
4097  /*
4098  * Unlink the hint from the hints container as the extension
4099  * name (which is the hash value) could change.
4100  */
4101  hint = ao2_find(hints, oe, OBJ_UNLINK);
4102  if (!hint) {
4103  ao2_unlock(hints);
4105  return -1;
4106  }
4107 
4108  remove_hintdevice(hint);
4109 
4110  /* Update the hint and put it back in the hints container. */
4111  ao2_lock(hint);
4112  hint->exten = ne;
4113 
4114  ao2_unlock(hint);
4115 
4116  ao2_link(hints, hint);
4117  if (add_hintdevice(hint, ast_get_extension_app(ne))) {
4118  ast_log(LOG_WARNING, "Could not add devices for hint: %s@%s.\n",
4121  }
4122  ao2_unlock(hints);
4123 
4124  publish_hint_change(hint, ne);
4125 
4126  ao2_ref(hint, -1);
4127 
4128  return 0;
4129 }
4130 
4131 /*! \brief Get hint for channel */
4132 int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
4133 {
4134  struct ast_exten *e = ast_hint_extension(c, context, exten);
4135 
4136  if (e) {
4137  if (hint)
4138  ast_copy_string(hint, ast_get_extension_app(e), hintsize);
4139  if (name) {
4140  const char *tmp = ast_get_extension_app_data(e);
4141  if (tmp)
4142  ast_copy_string(name, tmp, namesize);
4143  }
4144  return -1;
4145  }
4146  return 0;
4147 }
4148 
4149 /*! \brief Get hint for channel */
4150 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)
4151 {
4152  struct ast_exten *e = ast_hint_extension(c, context, exten);
4153 
4154  if (!e) {
4155  return 0;
4156  }
4157 
4158  if (hint) {
4159  ast_str_set(hint, hintsize, "%s", ast_get_extension_app(e));
4160  }
4161  if (name) {
4162  const char *tmp = ast_get_extension_app_data(e);
4163  if (tmp) {
4164  ast_str_set(name, namesize, "%s", tmp);
4165  }
4166  }
4167  return -1;
4168 }
4169 
4170 int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
4171 {
4172  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
4173 }
4174 
4175 int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
4176 {
4177  return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
4178 }
4179 
4180 int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
4181 {
4182  return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
4183 }
4184 
4185 int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
4186 {
4187  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
4188 }
4189 
4190 int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
4191 {
4192  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
4193 }
4194 
4195 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)
4196 {
4197  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
4198 }
4199 
4200 void ast_pbx_h_exten_run(struct ast_channel *chan, const char *context)
4201 {
4202  int autoloopflag;
4203  int found;
4204  int spawn_error;
4205 
4206  ast_channel_lock(chan);
4207 
4208  /*
4209  * Make sure that the channel is marked as hungup since we are
4210  * going to run the h exten on it.
4211  */
4213 
4214  /* Set h exten location */
4215  if (context != ast_channel_context(chan)) {
4216  ast_channel_context_set(chan, context);
4217  }
4218  ast_channel_exten_set(chan, "h");
4219  ast_channel_priority_set(chan, 1);
4220 
4221  /* Save autoloop flag */
4222  autoloopflag = ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
4224  ast_channel_unlock(chan);
4225 
4226  for (;;) {
4227  spawn_error = ast_spawn_extension(chan, ast_channel_context(chan),
4229  S_COR(ast_channel_caller(chan)->id.number.valid,
4230  ast_channel_caller(chan)->id.number.str, NULL), &found, 1);
4231 
4232  ast_channel_lock(chan);
4233  if (spawn_error) {
4234  /* The code after the loop needs the channel locked. */
4235  break;
4236  }
4238  ast_channel_unlock(chan);
4239  }
4240  if (found && spawn_error) {
4241  /* Something bad happened, or a hangup has been requested. */
4242  ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n",
4244  ast_channel_priority(chan), ast_channel_name(chan));
4245  ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n",
4247  ast_channel_priority(chan), ast_channel_name(chan));
4248  }
4249 
4250  /* An "h" exten has been run, so indicate that one has been run. */
4252 
4253  /* Restore autoloop flag */
4255  ast_channel_unlock(chan);
4256 }
4257 
4258 /*! helper function to set extension and priority */
4259 void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
4260 {
4261  ast_channel_lock(c);
4262  ast_channel_exten_set(c, exten);
4263  ast_channel_priority_set(c, pri);
4264  ast_channel_unlock(c);
4265 }
4266 
4267 /*!
4268  * \brief collect digits from the channel into the buffer.
4269  * \param c, buf, buflen, pos
4270  * \param waittime is in milliseconds
4271  * \retval 0 on timeout or done.
4272  * \retval -1 on error.
4273 */
4274 static int collect_digits(struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
4275 {
4276  int digit;
4277 
4278  buf[pos] = '\0'; /* make sure it is properly terminated */
4279  while (ast_matchmore_extension(c, ast_channel_context(c), buf, 1,
4280  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4281  /* As long as we're willing to wait, and as long as it's not defined,
4282  keep reading digits until we can't possibly get a right answer anymore. */
4283  digit = ast_waitfordigit(c, waittime);
4285  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_ASYNCGOTO);
4286  } else {
4287  if (!digit) /* No entry */
4288  break;
4289  if (digit < 0) /* Error, maybe a hangup */
4290  return -1;
4291  if (pos < buflen - 1) { /* XXX maybe error otherwise ? */
4292  buf[pos++] = digit;
4293  buf[pos] = '\0';
4294  }
4295  waittime = ast_channel_pbx(c)->dtimeoutms;
4296  }
4297  }
4298  return 0;
4299 }
4300 
4302  struct ast_pbx_args *args)
4303 {
4304  int found = 0; /* set if we find at least one match */
4305  int res = 0;
4306  int autoloopflag;
4307  int error = 0; /* set an error conditions */
4308  struct ast_pbx *pbx;
4309  ast_callid callid;
4310 
4311  /* A little initial setup here */
4312  if (ast_channel_pbx(c)) {
4313  ast_log(LOG_WARNING, "%s already has PBX structure??\n", ast_channel_name(c));
4314  /* XXX and now what ? */
4316  }
4317  if (!(pbx = ast_calloc(1, sizeof(*pbx)))) {
4318  return AST_PBX_FAILED;
4319  }
4320 
4321  callid = ast_read_threadstorage_callid();
4322  /* If the thread isn't already associated with a callid, we should create that association. */
4323  if (!callid) {
4324  /* Associate new PBX thread with the channel call id if it is availble.
4325  * If not, create a new one instead.
4326  */
4327  callid = ast_channel_callid(c);
4328  if (!callid) {
4329  callid = ast_create_callid();
4330  if (callid) {
4331  ast_channel_lock(c);
4332  ast_channel_callid_set(c, callid);
4333  ast_channel_unlock(c);
4334  }
4335  }
4337  callid = 0;
4338  }
4339 
4340  ast_channel_pbx_set(c, pbx);
4341  /* Set reasonable defaults */
4342  ast_channel_pbx(c)->rtimeoutms = 10000;
4343  ast_channel_pbx(c)->dtimeoutms = 5000;
4344 
4345  ast_channel_lock(c);
4346  autoloopflag = ast_test_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
4348  ast_channel_unlock(c);
4349 
4351  /* If not successful fall back to 's' - but only if there is no given exten */
4352  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));
4353  /* XXX the original code used the existing priority in the call to
4354  * ast_exists_extension(), and reset it to 1 afterwards.
4355  * I believe the correct thing is to set it to 1 immediately.
4356  */
4357  set_ext_pri(c, "s", 1);
4358  }
4359 
4360  for (;;) {
4361  char dst_exten[256]; /* buffer to accumulate digits */
4362  int pos = 0; /* XXX should check bounds */
4363  int digit = 0;
4364  int invalid = 0;
4365  int timeout = 0;
4366 
4367  /* No digits pressed yet */
4368  dst_exten[pos] = '\0';
4369 
4370  /* loop on priorities in this context/exten */
4372  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL),
4373  &found, 1))) {
4374 
4375  if (!ast_check_hangup(c)) {
4377  continue;
4378  }
4379 
4380  /* Check softhangup flags. */
4382  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_ASYNCGOTO);
4383  continue;
4384  }
4386  if (ast_exists_extension(c, ast_channel_context(c), "T", 1,
4387  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4388  set_ext_pri(c, "T", 1);
4389  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4390  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4391  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT);
4392  continue;
4393  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4394  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4395  raise_exception(c, "ABSOLUTETIMEOUT", 1);
4396  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4397  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4398  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT);
4399  continue;
4400  }
4401 
4402  /* Call timed out with no special extension to jump to. */
4403  error = 1;
4404  break;
4405  }
4406  ast_debug(1, "Extension %s, priority %d returned normally even though call was hung up\n",
4408  error = 1;
4409  break;
4410  } /* end while - from here on we can use 'break' to go out */
4411  if (found && res) {
4412  /* Something bad happened, or a hangup has been requested. */
4413  if (strchr("0123456789ABCDEF*#", res)) {
4414  ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res);
4415  pos = 0;
4416  dst_exten[pos++] = digit = res;
4417  dst_exten[pos] = '\0';
4418  } else if (res == AST_PBX_INCOMPLETE) {
4419  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));
4420  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));
4421 
4422  /* Don't cycle on incomplete - this will happen if the only extension that matches is our "incomplete" extension */
4424  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4425  invalid = 1;
4426  } else {
4427  ast_copy_string(dst_exten, ast_channel_exten(c), sizeof(dst_exten));
4428  digit = 1;
4429  pos = strlen(dst_exten);
4430  }
4431  } else {
4432  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));
4433  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));
4434 
4435  if ((res == AST_PBX_ERROR)
4436  && ast_exists_extension(c, ast_channel_context(c), "e", 1,
4437  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4438  /* if we are already on the 'e' exten, don't jump to it again */
4439  if (!strcmp(ast_channel_exten(c), "e")) {
4440  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));
4441  error = 1;
4442  } else {
4443  raise_exception(c, "ERROR", 1);
4444  continue;
4445  }
4446  }
4447 
4449  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_ASYNCGOTO);
4450  continue;
4451  }
4453  if (ast_exists_extension(c, ast_channel_context(c), "T", 1,
4454  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4455  set_ext_pri(c, "T", 1);
4456  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4457  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4458  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT);
4459  continue;
4460  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4461  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4462  raise_exception(c, "ABSOLUTETIMEOUT", 1);
4463  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
4464  memset(ast_channel_whentohangup(c), 0, sizeof(*ast_channel_whentohangup(c)));
4465  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT);
4466  continue;
4467  }
4468  /* Call timed out with no special extension to jump to. */
4469  }
4470  error = 1;
4471  break;
4472  }
4473  }
4474  if (error)
4475  break;
4476 
4477  /*!\note
4478  * We get here on a failure of some kind: non-existing extension or
4479  * hangup. We have options, here. We can either catch the failure
4480  * and continue, or we can drop out entirely. */
4481 
4482  if (invalid
4483  || (ast_strlen_zero(dst_exten) &&
4485  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL)))) {
4486  /*!\note
4487  * If there is no match at priority 1, it is not a valid extension anymore.
4488  * Try to continue at "i" (for invalid) or "e" (for exception) or exit if
4489  * neither exist.
4490  */
4491  if (ast_exists_extension(c, ast_channel_context(c), "i", 1,
4492  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4493  ast_verb(3, "Channel '%s' sent to invalid extension: context,exten,priority=%s,%s,%d\n",
4495  pbx_builtin_setvar_helper(c, "INVALID_EXTEN", ast_channel_exten(c));
4496  set_ext_pri(c, "i", 1);
4497  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4498  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4499  raise_exception(c, "INVALID", 1);
4500  } else {
4501  ast_log(LOG_WARNING, "Channel '%s' sent to invalid extension but no invalid handler: context,exten,priority=%s,%s,%d\n",
4503  error = 1; /* we know what to do with it */
4504  break;
4505  }
4507  /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
4508  ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT);
4509  } else { /* keypress received, get more digits for a full extension */
4510  int waittime = 0;
4511  if (digit)
4512  waittime = ast_channel_pbx(c)->dtimeoutms;
4513  else if (!autofallthrough)
4514  waittime = ast_channel_pbx(c)->rtimeoutms;
4515  if (!waittime) {
4516  const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
4517  if (!status)
4518  status = "UNKNOWN";
4519  ast_verb(3, "Auto fallthrough, channel '%s' status is '%s'\n", ast_channel_name(c), status);
4520  if (!strcasecmp(status, "CONGESTION"))
4521  res = indicate_congestion(c, "10");
4522  else if (!strcasecmp(status, "CHANUNAVAIL"))
4523  res = indicate_congestion(c, "10");
4524  else if (!strcasecmp(status, "BUSY"))
4525  res = indicate_busy(c, "10");
4526  error = 1; /* XXX disable message */
4527  break; /* exit from the 'for' loop */
4528  }
4529 
4530  if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos))
4531  break;
4532  if (res == AST_PBX_INCOMPLETE && ast_strlen_zero(&dst_exten[pos]))
4533  timeout = 1;
4534  if (!timeout
4535  && ast_exists_extension(c, ast_channel_context(c), dst_exten, 1,
4536  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) { /* Prepare the next cycle */
4537  set_ext_pri(c, dst_exten, 1);
4538  } else {
4539  /* No such extension */
4540  if (!timeout && !ast_strlen_zero(dst_exten)) {
4541  /* An invalid extension */
4542  if (ast_exists_extension(c, ast_channel_context(c), "i", 1,
4543  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4544  ast_verb(3, "Invalid extension '%s' in context '%s' on %s\n", dst_exten, ast_channel_context(c), ast_channel_name(c));
4545  pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
4546  set_ext_pri(c, "i", 1);
4547  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4548  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4549  raise_exception(c, "INVALID", 1);
4550  } else {
4552  "Invalid extension '%s', but no rule 'i' or 'e' in context '%s'\n",
4553  dst_exten, ast_channel_context(c));
4554  found = 1; /* XXX disable message */
4555  break;
4556  }
4557  } else {
4558  /* A simple timeout */
4559  if (ast_exists_extension(c, ast_channel_context(c), "t", 1,
4560  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4561  ast_verb(3, "Timeout on %s\n", ast_channel_name(c));
4562  set_ext_pri(c, "t", 1);
4563  } else if (ast_exists_extension(c, ast_channel_context(c), "e", 1,
4564  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
4565  raise_exception(c, "RESPONSETIMEOUT", 1);
4566  } else {
4568  "Timeout, but no rule 't' or 'e' in context '%s'\n",
4569  ast_channel_context(c));
4570  found = 1; /* XXX disable message */
4571  break;
4572  }
4573  }
4574  }
4575  }
4576  }
4577 
4578  if (!found && !error) {
4579  ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", ast_channel_name(c));
4580  }
4581 
4582  if (!args || !args->no_hangup_chan) {
4585  && ast_exists_extension(c, ast_channel_context(c), "h", 1,
4586  S_COR(ast_channel_caller(c)->id.number.valid,
4587  ast_channel_caller(c)->id.number.str, NULL))) {
4589  }
4591  }
4592 
4593  ast_channel_lock(c);
4595  ast_clear_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */
4596  ast_channel_unlock(c);
4599 
4600  if (!args || !args->no_hangup_chan) {
4601  ast_hangup(c);
4602  }
4603 
4604  return AST_PBX_SUCCESS;
4605 }
4606 
4607 /*!
4608  * \brief Increase call count for channel
4609  * \retval 0 on success
4610  * \retval non-zero if a configured limit (maxcalls, maxload, minmemfree) was reached
4611 */
4612 static int increase_call_count(const struct ast_channel *c)
4613 {
4614  int failed = 0;
4615  double curloadavg;
4616 #if defined(HAVE_SYSINFO)
4617  struct sysinfo sys_info;
4618 #endif
4619 
4621  if (ast_option_maxcalls) {
4622  if (countcalls >= ast_option_maxcalls) {
4623  ast_log(LOG_WARNING, "Maximum call limit of %d calls exceeded by '%s'!\n", ast_option_maxcalls, ast_channel_name(c));
4624  failed = -1;
4625  }
4626  }
4627  if (ast_option_maxload) {
4628  getloadavg(&curloadavg, 1);
4629  if (curloadavg >= ast_option_maxload) {
4630  ast_log(LOG_WARNING, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", ast_option_maxload, ast_channel_name(c), curloadavg);
4631  failed = -1;
4632  }
4633  }
4634 #if defined(HAVE_SYSINFO)
4635  if (option_minmemfree) {
4636  /* Make sure that the free system memory is above the configured low watermark */
4637  if (!sysinfo(&sys_info)) {
4638  /* Convert the amount of available RAM from mem_units to MB. The calculation
4639  * was done this way to avoid overflow problems */
4640  uint64_t curfreemem = sys_info.freeram + sys_info.bufferram;
4641  curfreemem *= sys_info.mem_unit;
4642  curfreemem /= 1024 * 1024;
4643  if (curfreemem < option_minmemfree) {
4644  ast_log(LOG_WARNING, "Available system memory (~%" PRIu64 "MB) is below the configured low watermark (%ldMB)\n",
4645  curfreemem, option_minmemfree);
4646  failed = -1;
4647  }
4648  }
4649  }
4650 #endif
4651 
4652  if (!failed) {
4653  countcalls++;
4654  totalcalls++;
4655  }
4657 
4658  return failed;
4659 }
4660 
4661 static void decrease_call_count(void)
4662 {
4664  if (countcalls > 0)
4665  countcalls--;
4667 }
4668 
4669 static void destroy_exten(struct ast_exten *e)
4670 {
4671  if (e->priority == PRIORITY_HINT)
4672  ast_remove_hint(e);
4673 
4674  if (e->peer_table)
4676  if (e->peer_label_table)
4678  if (e->datad)
4679  e->datad(e->data);
4680  ast_free(e);
4681 }
4682 
4683 static void *pbx_thread(void *data)
4684 {
4685  /* Oh joyeous kernel, we're a new thread, with nothing to do but
4686  answer this channel and get it going.
4687  */
4688  /* NOTE:
4689  The launcher of this function _MUST_ increment 'countcalls'
4690  before invoking the function; it will be decremented when the
4691  PBX has finished running on the channel
4692  */
4693  struct ast_channel *c = data;
4694 
4695  __ast_pbx_run(c, NULL);
4697 
4698  pthread_exit(NULL);
4699 
4700  return NULL;
4701 }
4702 
4704 {
4705  pthread_t t;
4706 
4707  if (!c) {
4708  ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
4709  return AST_PBX_FAILED;
4710  }
4711 
4713  ast_log(LOG_WARNING, "PBX requires Asterisk to be fully booted\n");
4714  return AST_PBX_FAILED;
4715  }
4716 
4717  if (increase_call_count(c))
4718  return AST_PBX_CALL_LIMIT;
4719 
4720  /* Start a new thread, and get something handling this channel. */
4722  ast_log(LOG_WARNING, "Failed to create new channel thread\n");
4724  return AST_PBX_FAILED;
4725  }
4726 
4727  return AST_PBX_SUCCESS;
4728 }
4729 
4731 {
4732  enum ast_pbx_result res = AST_PBX_SUCCESS;
4733 
4735  ast_log(LOG_WARNING, "PBX requires Asterisk to be fully booted\n");
4736  return AST_PBX_FAILED;
4737  }
4738 
4739  if (increase_call_count(c)) {
4740  return AST_PBX_CALL_LIMIT;
4741  }
4742 
4743  res = __ast_pbx_run(c, args);
4744 
4746 
4747  return res;
4748 }
4749 
4751 {
4752  return ast_pbx_run_args(c, NULL);
4753 }
4754 
4756 {
4757  return countcalls;
4758 }
4759 
4761 {
4762  return totalcalls;
4763 }
4764 
4766 {
4767  int oldval = autofallthrough;
4768  autofallthrough = newval;
4769  return oldval;
4770 }
4771 
4773 {
4774  int oldval = extenpatternmatchnew;
4775  extenpatternmatchnew = newval;
4776  return oldval;
4777 }
4778 
4779 void pbx_set_overrideswitch(const char *newval)
4780 {
4781  if (overrideswitch) {
4782  ast_free(overrideswitch);
4783  }
4784  if (!ast_strlen_zero(newval)) {
4785  overrideswitch = ast_strdup(newval);
4786  } else {
4787  overrideswitch = NULL;
4788  }
4789 }
4790 
4791 /*!
4792  * \brief lookup for a context with a given name,
4793  * \retval found context or NULL if not found.
4794  */
4795 static struct ast_context *find_context(const char *context)
4796 {
4797  struct fake_context item;
4798 
4799  ast_copy_string(item.name, context, sizeof(item.name));
4800 
4801  return ast_hashtab_lookup(contexts_table, &item);
4802 }
4803 
4804 /*!
4805  * \brief lookup for a context with a given name,
4806  * \retval with conlock held if found.
4807  * \retval NULL if not found.
4808  */
4809 static struct ast_context *find_context_locked(const char *context)
4810 {
4811  struct ast_context *c;
4812  struct fake_context item;
4813 
4814  ast_copy_string(item.name, context, sizeof(item.name));
4815 
4817  c = ast_hashtab_lookup(contexts_table, &item);
4818  if (!c) {
4820  }
4821 
4822  return c;
4823 }
4824 
4825 /*!
4826  * \brief Remove included contexts.
4827  * This function locks contexts list by &conlist, search for the right context
4828  * structure, leave context list locked and call ast_context_remove_include2
4829  * which removes include, unlock contexts list and return ...
4830  */
4831 int ast_context_remove_include(const char *context, const char *include, const char *registrar)
4832 {
4833  int ret = -1;
4834  struct ast_context *c;
4835 
4836  c = find_context_locked(context);
4837  if (c) {
4838  /* found, remove include from this context ... */
4839  ret = ast_context_remove_include2(c, include, registrar);
4841  }
4842  return ret;
4843 }
4844 
4845 /*!
4846  * \brief Locks context, remove included contexts, unlocks context.
4847  * When we call this function, &conlock lock must be locked, because when
4848  * we giving *con argument, some process can remove/change this context
4849  * and after that there can be segfault.
4850  *
4851  * \retval 0 on success.
4852  * \retval -1 on failure.
4853  */
4854 int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
4855 {
4856  int ret = -1;
4857  int idx;
4858 
4859  ast_wrlock_context(con);
4860 
4861  /* find our include */
4862  for (idx = 0; idx < ast_context_includes_count(con); idx++) {
4863  struct ast_include *i = AST_VECTOR_GET(&con->includes, idx);
4864 
4865  if (!strcmp(ast_get_include_name(i), include) &&
4866  (!registrar || !strcmp(ast_get_include_registrar(i), registrar))) {
4867 
4868  /* remove from list */
4869  ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar);
4870  AST_VECTOR_REMOVE_ORDERED(&con->includes, idx);
4871 
4872  /* free include and return */
4873  include_free(i);
4874  ret = 0;
4875  break;
4876  }
4877  }
4878 
4879  ast_unlock_context(con);
4880 
4881  return ret;
4882 }
4883 
4884 /*!
4885  * \note This function locks contexts list by &conlist, search for the rigt context
4886  * structure, leave context list locked and call ast_context_remove_switch2
4887  * which removes switch, unlock contexts list and return ...
4888  */
4889 int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar)
4890 {
4891  int ret = -1; /* default error return */
4892  struct ast_context *c;
4893 
4894  c = find_context_locked(context);
4895  if (c) {
4896  /* remove switch from this context ... */
4897  ret = ast_context_remove_switch2(c, sw, data, registrar);
4899  }
4900  return ret;
4901 }
4902 
4903 /*!
4904  * \brief This function locks given context, removes switch, unlock context and
4905  * return.
4906  * \note When we call this function, &conlock lock must be locked, because when
4907  * we giving *con argument, some process can remove/change this context
4908  * and after that there can be segfault.
4909  *
4910  */
4911 int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
4912 {
4913  int idx;
4914  int ret = -1;
4915 
4916  ast_wrlock_context(con);
4917 
4918  /* walk switches */
4919  for (idx = 0; idx < ast_context_switches_count(con); idx++) {
4920  struct ast_sw *i = AST_VECTOR_GET(&con->alts, idx);
4921 
4922  if (!strcmp(ast_get_switch_name(i), sw) &&
4923  !strcmp(ast_get_switch_data(i), data) &&
4924  (!registrar || !strcmp(ast_get_switch_registrar(i), registrar))) {
4925 
4926  /* found, remove from list */
4927  ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar);
4928  AST_VECTOR_REMOVE_ORDERED(&con->alts, idx);
4929 
4930  /* free switch and return */
4931  sw_free(i);
4932  ret = 0;
4933  break;
4934  }
4935  }
4936 
4937  ast_unlock_context(con);
4938 
4939  return ret;
4940 }
4941 
4942 /*! \note This function will lock conlock. */
4943 int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
4944 {
4945  return ast_context_remove_extension_callerid(context, extension, priority, NULL, AST_EXT_MATCHCID_ANY, registrar);
4946 }
4947 
4948 int ast_context_remove_extension_callerid(const char *context, const char *extension, int priority, const char *callerid, int matchcallerid, const char *registrar)
4949 {
4950  int ret = -1; /* default error return */
4951  struct ast_context *c;
4952 
4953  c = find_context_locked(context);
4954  if (c) { /* ... remove extension ... */
4955  ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid,
4956  matchcallerid, registrar, 0);
4958  }
4959 
4960  return ret;
4961 }
4962 
4963 /*!
4964  * \brief This functionc locks given context, search for the right extension and
4965  * fires out all peer in this extensions with given priority. If priority
4966  * is set to 0, all peers are removed. After that, unlock context and
4967  * return.
4968  * \note When do you want to call this function, make sure that &conlock is locked,
4969  * because some process can handle with your *con context before you lock
4970  * it.
4971  *
4972  */
4973 int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked)
4974 {
4975  return ast_context_remove_extension_callerid2(con, extension, priority, NULL, AST_EXT_MATCHCID_ANY, registrar, already_locked);
4976 }
4977 
4978 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)
4979 {
4980  struct ast_exten *exten, *prev_exten = NULL;
4981  struct ast_exten *peer;
4982  struct ast_exten ex, *exten2, *exten3;
4983  char dummy_name[1024];
4984  char dummy_cid[1024];
4985  struct ast_exten *previous_peer = NULL;
4986  struct ast_exten *next_peer = NULL;
4987  int found = 0;
4988 
4989  if (!already_locked)
4990  ast_wrlock_context(con);
4991 
4992 #ifdef NEED_DEBUG
4993  ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcallerid ? "/" : "", matchcallerid ? callerid : "", registrar);
4994 #endif
4995 #ifdef CONTEXT_DEBUG
4996  check_contexts(__FILE__, __LINE__);
4997 #endif
4998  /* find this particular extension */
4999  ex.exten = dummy_name;
5000  ext_strncpy(dummy_name, extension, sizeof(dummy_name), 1);
5001  ex.matchcid = matchcallerid;
5002  if (callerid) {
5003  ex.cidmatch = dummy_cid;
5004  ext_strncpy(dummy_cid, callerid, sizeof(dummy_cid), 1);
5005  } else {
5006  ex.cidmatch = NULL;
5007  }
5008  exten = ast_hashtab_lookup(con->root_table, &ex);
5009  if (exten) {
5010  if (priority == 0) {
5011  exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
5012  if (!exten2)
5013  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);
5014  if (con->pattern_tree) {
5015  struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
5016 
5017  if (x->exten) { /* this test for safety purposes */
5018  x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
5019  x->exten = 0; /* get rid of what will become a bad pointer */
5020  } else {
5021  ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n");
5022  }
5023  }
5024  } else {
5025  ex.priority = priority;
5026  exten2 = ast_hashtab_lookup(exten->peer_table, &ex);
5027  if (exten2) {
5028  if (exten2->label) { /* if this exten has a label, remove that, too */
5029  exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2);
5030  if (!exten3) {
5031  ast_log(LOG_ERROR, "Did not remove this priority label (%d/%s) "
5032  "from the peer_label_table of context %s, extension %s!\n",
5033  priority, exten2->label, con->name, exten2->name);
5034  }
5035  }
5036 
5037  exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2);
5038  if (!exten3) {
5039  ast_log(LOG_ERROR, "Did not remove this priority (%d) from the "
5040  "peer_table of context %s, extension %s!\n",
5041  priority, con->name, exten2->name);
5042  }
5043  if (exten2 == exten && exten2->peer) {
5044  exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
5046  }
5047  if (ast_hashtab_size(exten->peer_table) == 0) {
5048  /* well, if the last priority of an exten is to be removed,
5049  then, the extension is removed, too! */
5050  exten3 = ast_hashtab_remove_this_object(con->root_table, exten);
5051  if (!exten3) {
5052  ast_log(LOG_ERROR, "Did not remove this exten (%s) from the "
5053  "context root_table (%s) (priority %d)\n",
5054  exten->name, con->name, priority);
5055  }
5056  if (con->pattern_tree) {
5057  struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
5058  if (x->exten) { /* this test for safety purposes */
5059  x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
5060  x->exten = 0; /* get rid of what will become a bad pointer */
5061  }
5062  }
5063  }
5064  } else {
5065  ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n",
5066  priority, exten->name, con->name);
5067  }
5068  }
5069  } else {
5070  /* hmmm? this exten is not in this pattern tree? */
5071  ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n",
5072  extension, con->name);
5073  }
5074 #ifdef NEED_DEBUG
5075  if (con->pattern_tree) {
5076  ast_log(LOG_NOTICE,"match char tree after exten removal:\n");
5077  log_match_char_tree(con->pattern_tree, " ");
5078  }
5079 #endif
5080 
5081  /* scan the extension list to find first matching extension-registrar */
5082  for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
5083  if (!strcmp(exten->exten, ex.exten) &&
5084  (!matchcallerid ||
5085  (!ast_strlen_zero(ex.cidmatch) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, ex.cidmatch)) ||
5086  (ast_strlen_zero(ex.cidmatch) && ast_strlen_zero(exten->cidmatch)))) {
5087  break;
5088  }
5089  }
5090  if (!exten) {
5091  /* we can't find right extension */
5092  if (!already_locked)
5093  ast_unlock_context(con);
5094  return -1;
5095  }
5096 
5097  /* scan the priority list to remove extension with exten->priority == priority */
5098  for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
5099  peer && !strcmp(peer->exten, ex.exten) &&
5100  (!callerid || (!matchcallerid && !peer->matchcid) || (matchcallerid && peer->matchcid && !strcmp(peer->cidmatch, ex.cidmatch))) ;
5101  peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
5102 
5103  if ((priority == 0 || peer->priority == priority) &&
5104  (!registrar || !strcmp(peer->registrar, registrar) )) {
5105  found = 1;
5106 
5107  /* we are first priority extension? */
5108  if (!previous_peer) {
5109  /*
5110  * We are first in the priority chain, so must update the extension chain.
5111  * The next node is either the next priority or the next extension
5112  */
5113  struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
5114  if (peer->peer) {
5115  /* move the peer_table and peer_label_table down to the next peer, if
5116  it is there */
5117  peer->peer->peer_table = peer->peer_table;
5118  peer->peer->peer_label_table = peer->peer_label_table;
5119  peer->peer_table = NULL;
5120  peer->peer_label_table = NULL;
5121  }
5122  if (!prev_exten) { /* change the root... */
5123  con->root = next_node;
5124  } else {
5125  prev_exten->next = next_node; /* unlink */
5126  }
5127  if (peer->peer) { /* update the new head of the pri list */
5128  peer->peer->next = peer->