Wed Jan 8 2020 09:50:15

Asterisk developer's documentation


pbx.c File Reference

Core PBX routines. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include <ctype.h>
#include <time.h>
#include <sys/time.h>
#include <sys/sysinfo.h>
#include "asterisk/lock.h"
#include "asterisk/cli.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/cdr.h"
#include "asterisk/cel.h"
#include "asterisk/config.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/ast_expr.h"
#include "asterisk/linkedlists.h"
#include "asterisk/say.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/musiconhold.h"
#include "asterisk/app.h"
#include "asterisk/devicestate.h"
#include "asterisk/event.h"
#include "asterisk/hashtab.h"
#include "asterisk/module.h"
#include "asterisk/indications.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/xmldoc.h"
#include "asterisk/astobj2.h"

Go to the source code of this file.

Data Structures

struct  acf_root
 
struct  app_tmp
 
struct  apps
 
struct  ast_app
 ast_app: A registered application More...
 
struct  ast_context
 ast_context: An extension context More...
 
struct  ast_custom_escalating_function
 Extra information for an ast_custom_function holding privilege escalation information. Kept in a separate structure for ABI compatibility. More...
 
struct  ast_exten
 ast_exten: An extension The dialplan is saved as a linked list with each context having it's own linked list of extensions - one item per priority. More...
 
struct  ast_hint
 Structure for dial plan hints. More...
 
struct  ast_ignorepat
 ast_ignorepat: Ignore patterns in dial plan More...
 
struct  ast_include
 ast_include: include= support in extensions.conf More...
 
struct  ast_state_cb
 ast_state_cb: An extension state notify register item More...
 
struct  ast_sw
 ast_sw: Switch statement in extensions.conf More...
 
struct  async_stat
 
struct  cfextension_states
 
struct  dialplan_counters
 Counters for the show dialplan manager command. More...
 
struct  escalation_root
 
struct  fake_context
 
struct  match_char
 match_char: forms a syntax tree for quick matching of extension patterns More...
 
struct  pattern_node
 
struct  pbx_builtin
 Declaration of builtin applications. More...
 
struct  pbx_exception
 
struct  scoreboard
 
struct  statechange
 
struct  store_hint
 
struct  store_hints
 
struct  switches
 

Macros

#define BACKGROUND_MATCHEXTEN   (1 << 2)
 
#define BACKGROUND_NOANSWER   (1 << 1)
 
#define BACKGROUND_PLAYBACK   (1 << 3)
 
#define BACKGROUND_SKIP   (1 << 0)
 
#define BITS_PER   8 /* Number of bits per unit (byte). */
 
#define EXT_DATA_SIZE   8192
 
#define HASH_EXTENHINT_SIZE   563
 
#define INC_DST_OVERFLOW_CHECK
 
#define NEW_MATCHER_CHK_MATCH
 
#define NEW_MATCHER_RECURSE
 
#define SAY_STUBS   /* generate declarations and stubs for say methods */
 
#define STATUS_NO_CONTEXT   1
 
#define STATUS_NO_EXTENSION   2
 
#define STATUS_NO_LABEL   4
 
#define STATUS_NO_PRIORITY   3
 
#define STATUS_SUCCESS   5
 
#define SWITCH_DATA_LENGTH   256
 
#define VAR_BUF_SIZE   4096
 
#define VAR_HARDTRAN   3
 
#define VAR_NORMAL   1
 
#define VAR_SOFTTRAN   2
 
#define WAITEXTEN_DIALTONE   (1 << 1)
 
#define WAITEXTEN_MOH   (1 << 0)
 

Functions

void __ast_context_destroy (struct ast_context *list, struct ast_hashtab *contexttab, struct ast_context *con, const char *registrar)
 
int __ast_custom_function_register (struct ast_custom_function *acf, struct ast_module *mod)
 Register a custom function. More...
 
int __ast_custom_function_register_escalating (struct ast_custom_function *acf, enum ast_custom_function_escalation escalation, struct ast_module *mod)
 Register a custom function which requires escalated privileges. More...
 
static int __ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, int async)
 
static void __ast_internal_context_destroy (struct ast_context *con)
 
static enum ast_pbx_result __ast_pbx_run (struct ast_channel *c, struct ast_pbx_args *args)
 
static void __init_extensionstate_buf (void)
 
static void __init_switch_data (void)
 
static void __init_thread_inhibit_escalations_tl (void)
 A thread local indicating whether the current thread can run 'dangerous' dialplan functions. More...
 
static int _extension_match_core (const char *pattern, const char *data, enum ext_match_t mode)
 
static int acf_exception_read (struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
 
static int acf_retrieve_docs (struct ast_custom_function *acf)
 
static struct match_charadd_exten_to_pattern_tree (struct ast_context *con, struct ast_exten *e1, int findonly)
 
static struct match_charadd_pattern_node (struct ast_context *con, struct match_char *current, const struct pattern_node *pattern, int is_pattern, int already, struct match_char **nextcharptr)
 
static int add_priority (struct ast_context *con, struct ast_exten *tmp, struct ast_exten *el, struct ast_exten *e, int replace)
 add the extension in the priority chain. More...
 
static struct match_charalready_in_tree (struct match_char *current, char *pat, int is_pattern)
 
int ast_active_calls (void)
 Retrieve the number of active calls. More...
 
int ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add and extension to an extension context. More...
 
int ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Main interface to add extensions to the list for out context. More...
 
static int ast_add_extension2_lockopt (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, int lock_context)
 Same as ast_add_extension2() but controls the context locking. More...
 
static int ast_add_extension_nolock (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 
static int ast_add_hint (struct ast_exten *e)
 Add hint to hint list, check initial extension state. More...
 
int ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
 Set the channel to next execute the specified dialplan location. More...
 
int ast_async_goto_by_name (const char *channame, const char *context, const char *exten, int priority)
 Set the channel to next execute the specified dialplan location. More...
 
int ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
 
int ast_async_parseable_goto (struct ast_channel *chan, const char *goto_string)
 
int ast_build_timing (struct ast_timing *i, const char *info_in)
 Construct a timing bitmap, for use in time-based conditionals. More...
 
int ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks for a valid matching extension. More...
 
static int ast_change_hint (struct ast_exten *oe, struct ast_exten *ne)
 Change hint for an extension. More...
 
int ast_check_timing (const struct ast_timing *i)
 Evaluate a pre-constructed bitmap as to whether the current time falls within the range specified. More...
 
int ast_check_timing2 (const struct ast_timing *i, const struct timeval tv)
 Evaluate a pre-constructed bitmap as to whether a particular time falls within the range specified. More...
 
char * ast_complete_applications (const char *line, const char *word, int state)
 Command completion for the list of installed applications. More...
 
int ast_context_add_ignorepat (const char *context, const char *value, const char *registrar)
 Add an ignorepat. More...
 
int ast_context_add_ignorepat2 (struct ast_context *con, const char *value, const char *registrar)
 
int ast_context_add_include (const char *context, const char *include, const char *registrar)
 Add a context include. More...
 
int ast_context_add_include2 (struct ast_context *con, const char *value, const char *registrar)
 Add a context include. More...
 
int ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar)
 Add a switch. More...
 
int ast_context_add_switch2 (struct ast_context *con, const char *value, const char *data, int eval, const char *registrar)
 Adds a switch (first param is a ast_context) More...
 
void ast_context_destroy (struct ast_context *con, const char *registrar)
 Destroy a context (matches the specified context (or ANY context if NULL) More...
 
struct ast_contextast_context_find (const char *name)
 Find a context. More...
 
struct ast_contextast_context_find_or_create (struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
 Register a new context or find an existing one. More...
 
int ast_context_lockmacro (const char *context)
 locks the macrolock in the given given context More...
 
int ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar)
 Simply remove extension from context. More...
 
int ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar, int already_locked)
 This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return. More...
 
int ast_context_remove_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcallerid, const char *registrar)
 
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)
 
int ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar)
 
int ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
 
int ast_context_remove_include (const char *context, const char *include, const char *registrar)
 Remove included contexts. This function locks contexts list by &conlist, search for the right context structure, leave context list locked and call ast_context_remove_include2 which removes include, unlock contexts list and return ... More...
 
int ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar)
 Locks context, remove included contexts, unlocks context. When we call this function, &conlock lock must be locked, because when we giving *con argument, some process can remove/change this context and after that there can be segfault. More...
 
int ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar)
 Remove a switch. More...
 
int ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar)
 This function locks given context, removes switch, unlock context and return. More...
 
int ast_context_unlockmacro (const char *context)
 Unlocks the macrolock in the given context. More...
 
int ast_context_verify_includes (struct ast_context *con)
 Verifies includes in an ast_contect structure. More...
 
struct ast_custom_functionast_custom_function_find (const char *name)
 
int ast_custom_function_unregister (struct ast_custom_function *acf)
 Unregister a custom function. More...
 
int ast_destroy_timing (struct ast_timing *i)
 Deallocates memory structures associated with a timing bitmap. More...
 
enum ast_extension_states ast_devstate_to_extenstate (enum ast_device_state devstate)
 Map devstate to an extension state. More...
 
int ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Determine whether an extension exists. More...
 
int ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
 
int ast_extension_close (const char *pattern, const char *data, int needmore)
 
int ast_extension_cmp (const char *a, const char *b)
 Determine if one extension should match before another. More...
 
int ast_extension_match (const char *pattern, const char *data)
 Determine if a given extension matches a given pattern (in NXX format) More...
 
int ast_extension_state (struct ast_channel *c, const char *context, const char *exten)
 Check extension state for an extension by using hint. More...
 
static int ast_extension_state2 (struct ast_exten *e)
 Check state of extension by using hints. More...
 
const char * ast_extension_state2str (int extension_state)
 Return extension_state as string. More...
 
static int ast_extension_state3 (struct ast_str *hint_app)
 
int ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type change_cb, void *data)
 Add watcher for extension states. More...
 
int ast_extension_state_add_destroy (const char *context, const char *exten, ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
 Add watcher for extension states with destructor. More...
 
int ast_extension_state_del (int id, ast_state_cb_type change_cb)
 ast_extension_state_del: Remove a watcher from the callback list More...
 
int ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
 Find the priority of an extension that has the specified label. More...
 
int ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
 Find the priority of an extension that has the specified label. More...
 
int ast_func_read (struct ast_channel *chan, const char *function, char *workspace, size_t len)
 executes a read operation on a function More...
 
int ast_func_read2 (struct ast_channel *chan, const char *function, struct ast_str **str, ssize_t maxlen)
 executes a read operation on a function More...
 
int ast_func_write (struct ast_channel *chan, const char *function, const char *value)
 executes a write operation on a function More...
 
const char * ast_get_context_name (struct ast_context *con)
 
const char * ast_get_context_registrar (struct ast_context *c)
 
const char * ast_get_extension_app (struct ast_exten *e)
 
void * ast_get_extension_app_data (struct ast_exten *e)
 
const char * ast_get_extension_cidmatch (struct ast_exten *e)
 
struct ast_contextast_get_extension_context (struct ast_exten *exten)
 
const char * ast_get_extension_label (struct ast_exten *exten)
 
int ast_get_extension_matchcid (struct ast_exten *e)
 
const char * ast_get_extension_name (struct ast_exten *exten)
 
int ast_get_extension_priority (struct ast_exten *exten)
 
const char * ast_get_extension_registrar (struct ast_exten *e)
 
int ast_get_hint (char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
 Get hint for channel. More...
 
const char * ast_get_ignorepat_name (struct ast_ignorepat *ip)
 
const char * ast_get_ignorepat_registrar (struct ast_ignorepat *ip)
 
const char * ast_get_include_name (struct ast_include *inc)
 
const char * ast_get_include_registrar (struct ast_include *i)
 
const char * ast_get_switch_data (struct ast_sw *sw)
 
int ast_get_switch_eval (struct ast_sw *sw)
 
const char * ast_get_switch_name (struct ast_sw *sw)
 
const char * ast_get_switch_registrar (struct ast_sw *sw)
 
int ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
 
int ast_hashtab_compare_contexts (const void *ah_a, const void *ah_b)
 hashtable functions for contexts More...
 
unsigned int ast_hashtab_hash_contexts (const void *obj)
 
static struct ast_extenast_hint_extension (struct ast_channel *c, const char *context, const char *exten)
 
static struct ast_extenast_hint_extension_nolock (struct ast_channel *c, const char *context, const char *exten)
 Find hint for given extension in context. More...
 
int ast_ignore_pattern (const char *context, const char *pattern)
 Checks to see if a number should be ignored. More...
 
int ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks to see if adding anything to this extension might match something. (exists ^ canmatch) More...
 
void ast_merge_contexts_and_delete (struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *registrar)
 Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added. More...
 
int ast_parseable_goto (struct ast_channel *chan, const char *goto_string)
 
int ast_pbx_init (void)
 
int ast_pbx_outgoing_app (const char *type, format_t format, void *data, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
 
static int ast_pbx_outgoing_cdr_failed (void)
 Function to post an empty cdr after a spool call fails. More...
 
int ast_pbx_outgoing_exten (const char *type, format_t format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel)
 
enum ast_pbx_result ast_pbx_run (struct ast_channel *c)
 Execute the PBX in the current thread. More...
 
static void * ast_pbx_run_app (void *data)
 run the application and free the descriptor once done More...
 
enum ast_pbx_result ast_pbx_run_args (struct ast_channel *c, struct ast_pbx_args *args)
 Execute the PBX in the current thread. More...
 
enum ast_pbx_result ast_pbx_start (struct ast_channel *c)
 Create a new thread and start the PBX. More...
 
int ast_processed_calls (void)
 Retrieve the total number of calls processed through the PBX since last restart. More...
 
int ast_rdlock_context (struct ast_context *con)
 Read locks a given context. More...
 
int ast_rdlock_contexts (void)
 Read locks the context list. More...
 
int ast_register_application2 (const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
 Dynamically register a new dial plan application. More...
 
int ast_register_switch (struct ast_switch *sw)
 Register an alternative dialplan switch. More...
 
static int ast_remove_hint (struct ast_exten *e)
 Remove hint from extension. More...
 
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)
 Launch a new extension (i.e. new stack) More...
 
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)
 Get hint for channel. More...
 
const char * ast_str_retrieve_variable (struct ast_str **str, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *var)
 
void ast_str_substitute_variables (struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
 
void ast_str_substitute_variables_full (struct ast_str **buf, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *templ, size_t *used)
 
void ast_str_substitute_variables_varshead (struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
 
static const char * ast_str_substring (struct ast_str *value, int offset, int length)
 
int ast_thread_inhibit_escalations (void)
 Inhibit (in the current thread) the execution of dialplan functions which cause privilege escalations. If pbx_live_dangerously() has been called, this function has no effect. More...
 
int ast_unlock_context (struct ast_context *con)
 
int ast_unlock_contexts (void)
 Unlocks contexts. More...
 
int ast_unregister_application (const char *app)
 Unregister an application. More...
 
void ast_unregister_switch (struct ast_switch *sw)
 Unregister an alternative switch. More...
 
struct ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *exten)
 
struct ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
 
struct ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
 
struct ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
 
struct ast_contextast_walk_contexts (struct ast_context *con)
 
struct ast_extenast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority)
 
int ast_wrlock_context (struct ast_context *con)
 Write locks a given context. More...
 
int ast_wrlock_contexts (void)
 Write locks the context list. More...
 
static void * async_wait (void *data)
 
static void cli_match_char_tree (struct match_char *node, char *prefix, int fd)
 
static int collect_digits (struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
 collect digits from the channel into the buffer. More...
 
static int compare_char (const void *a, const void *b)
 
static char * complete_core_show_hint (const char *line, const char *word, int pos, int state)
 autocomplete for CLI command 'core show hint' More...
 
static char * complete_show_dialplan_context (const char *line, const char *word, int pos, int state)
 
static void context_merge (struct ast_context **extcontexts, struct ast_hashtab *exttable, struct ast_context *context, const char *registrar)
 
static void context_merge_incls_swits_igps_other_registrars (struct ast_context *new, struct ast_context *old, const char *registrar)
 
static void create_match_char_tree (struct ast_context *con)
 
static void decrease_call_count (void)
 
static void destroy_exten (struct ast_exten *e)
 
static void destroy_hint (void *obj)
 
static void destroy_pattern_tree (struct match_char *pattern_tree)
 
static void destroy_state_cb (void *doomed)
 
static void device_state_cb (const struct ast_event *event, void *unused)
 
static void exception_store_free (void *data)
 
static int ext_cmp (const char *left, const char *right)
 
static int ext_cmp_exten (const char *left, const char *right)
 
static int ext_cmp_exten_partial (const char *left, const char *right)
 
static int ext_cmp_exten_strlen (const char *str)
 
static int ext_cmp_pattern (const char *left, const char *right)
 
static int ext_cmp_pattern_pos (const char **p, unsigned char *bitwise)
 helper functions to sort extension patterns in the desired way, so that more specific patterns appear first. More...
 
static int ext_strncpy (char *dst, const char *src, int len)
 copy a string skipping whitespace More...
 
static int extension_match_core (const char *pattern, const char *data, enum ext_match_t mode)
 
static struct ast_contextfind_context (const char *context)
 lookup for a context with a given name, More...
 
static struct ast_contextfind_context_locked (const char *context)
 lookup for a context with a given name, More...
 
static int find_hint_by_cb_id (void *obj, void *arg, int flags)
 Remove a watcher from the callback list. More...
 
static char * func_args (char *function)
 return a pointer to the arguments of the function, and terminates the function name with '\0' More...
 
static struct ast_extenget_canmatch_exten (struct match_char *node)
 
static const char * get_pattern_node (struct pattern_node *node, const char *src, int pattern, const char *extenbuf)
 
static unsigned get_range (char *src, int max, const char *const names[], const char *msg)
 helper function to return a range up to max (7, 12, 31 respectively). names, if supplied, is an array of names that should be mapped to numbers. More...
 
static void get_timerange (struct ast_timing *i, char *times)
 store a bitmask of valid times, one bit each 1 minute More...
 
static char * handle_debug_dialplan (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Send ack once. More...
 
static char * handle_set_chanvar (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_set_extenpatternmatchnew (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_set_global (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_show_application (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_show_applications (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_show_chanvar (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI support for listing chanvar's variables in a parseable way. More...
 
static char * handle_show_dialplan (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_show_function (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_show_functions (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_show_globals (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI support for listing global variables in a parseable way. More...
 
static char * handle_show_hint (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handle_show_hint: CLI support for listing registered dial plan hint More...
 
static char * handle_show_hints (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handle_show_hints: CLI support for listing registered dial plan hints More...
 
static char * handle_show_switches (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handle_show_switches: CLI support for listing registered dial plan switches More...
 
static int handle_statechange (void *datap)
 
static char * handle_unset_extenpatternmatchnew (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int hashtab_compare_exten_labels (const void *ah_a, const void *ah_b)
 
static int hashtab_compare_exten_numbers (const void *ah_a, const void *ah_b)
 
static int hashtab_compare_extens (const void *ha_a, const void *ah_b)
 
static unsigned int hashtab_hash_extens (const void *obj)
 
static unsigned int hashtab_hash_labels (const void *obj)
 
static unsigned int hashtab_hash_priority (const void *obj)
 
static int hint_cmp (void *obj, void *arg, int flags)
 
static int hint_hash (const void *obj, const int flags)
 
static int hint_id_cmp (void *obj, void *arg, int flags)
 
static int hints_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
 
static int include_valid (struct ast_include *i)
 
static int increase_call_count (const struct ast_channel *c)
 Increase call count for channel. More...
 
static void insert_in_next_chars_alt_char_list (struct match_char **parent_ptr, struct match_char *node)
 
static int is_read_allowed (struct ast_custom_function *acfptr)
 Determines whether execution of a custom function's read function is allowed. More...
 
static int is_write_allowed (struct ast_custom_function *acfptr)
 Determines whether execution of a custom function's write function is allowed. More...
 
int load_pbx (void)
 
static int lookup_name (const char *s, const char *const names[], int max)
 Helper for get_range. return the index of the matching entry, starting from 1. If names is not supplied, try numeric values. More...
 
static void manager_dpsendack (struct mansession *s, const struct message *m)
 Send ack once. More...
 
static int manager_show_dialplan (struct mansession *s, const struct message *m)
 Manager listing of dial plan. More...
 
static int manager_show_dialplan_helper (struct mansession *s, const struct message *m, const char *actionidtext, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude)
 Show dialplan extensions XXX this function is similar but not exactly the same as the CLI's show dialplan. Must check whether the difference is intentional or not. More...
 
static int matchcid (const char *cidpattern, const char *callerid)
 
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)
 
static int parse_variable_name (char *var, int *offset, int *length, int *isfunc)
 extract offset:length from variable name. More...
 
static int pbx_builtin_answer (struct ast_channel *, const char *)
 
static int pbx_builtin_background (struct ast_channel *, const char *)
 
static int pbx_builtin_busy (struct ast_channel *, const char *)
 
void pbx_builtin_clear_globals (void)
 
static int pbx_builtin_congestion (struct ast_channel *, const char *)
 
static int pbx_builtin_execiftime (struct ast_channel *, const char *)
 
const char * pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name)
 Return a pointer to the value of the corresponding channel variable. More...
 
static int pbx_builtin_goto (struct ast_channel *, const char *)
 
static int pbx_builtin_gotoif (struct ast_channel *, const char *)
 
static int pbx_builtin_gotoiftime (struct ast_channel *, const char *)
 
static int pbx_builtin_hangup (struct ast_channel *, const char *)
 
static int pbx_builtin_importvar (struct ast_channel *, const char *)
 
static int pbx_builtin_incomplete (struct ast_channel *, const char *)
 
static int pbx_builtin_noop (struct ast_channel *, const char *)
 
static int pbx_builtin_proceeding (struct ast_channel *, const char *)
 
static int pbx_builtin_progress (struct ast_channel *, const char *)
 
void pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value)
 Add a variable to the channel variable stack, without removing any previously set value. More...
 
int pbx_builtin_raise_exception (struct ast_channel *chan, const char *reason)
 
static int pbx_builtin_resetcdr (struct ast_channel *, const char *)
 
static int pbx_builtin_ringing (struct ast_channel *, const char *)
 
static int pbx_builtin_saycharacters (struct ast_channel *, const char *)
 
static int pbx_builtin_saydate (struct ast_channel *, const char *)
 
static int pbx_builtin_saydigits (struct ast_channel *, const char *)
 
static int pbx_builtin_saynumber (struct ast_channel *, const char *)
 
static int pbx_builtin_sayphonetic (struct ast_channel *, const char *)
 
static int pbx_builtin_saytime (struct ast_channel *, const char *)
 
int pbx_builtin_serialize_variables (struct ast_channel *chan, struct ast_str **buf)
 Create a human-readable string, specifying all variables and their corresponding values. More...
 
static int pbx_builtin_setamaflags (struct ast_channel *, const char *)
 
int pbx_builtin_setvar (struct ast_channel *chan, const char *data)
 Parse and set a single channel variable, where the name and value are separated with an '=' character. More...
 
int pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value)
 Add a variable to the channel variable stack, removing the most recently set value for the same name. More...
 
int pbx_builtin_setvar_multiple (struct ast_channel *chan, const char *vdata)
 Parse and set multiple channel variables, where the pairs are separated by the ',' character, and name and value are separated with an '=' character. More...
 
static int pbx_builtin_wait (struct ast_channel *, const char *)
 
static int pbx_builtin_waitexten (struct ast_channel *, const char *)
 
int pbx_checkcondition (const char *condition)
 Evaluate a condition. More...
 
static void pbx_destroy (struct ast_pbx *p)
 
int pbx_exec (struct ast_channel *c, struct ast_app *app, const char *data)
 Execute an application. More...
 
static int pbx_extension_helper (struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
 The return value depends on the action: More...
 
struct ast_extenpbx_find_extension (struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
 
struct ast_apppbx_findapp (const char *app)
 Find application handle in linked list. More...
 
static struct ast_switchpbx_findswitch (const char *sw)
 
void pbx_live_dangerously (int new_live_dangerously)
 Enable/disable the execution of 'dangerous' functions from external protocols (AMI, etc.). More...
 
static int pbx_parseable_goto (struct ast_channel *chan, const char *goto_string, int async)
 
void pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
 Support for Asterisk built-in variables in the dialplan. More...
 
int pbx_set_autofallthrough (int newval)
 
int pbx_set_extenpatternmatchnew (int newval)
 
void pbx_set_overrideswitch (const char *newval)
 
static void pbx_shutdown (void)
 
void pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count)
 
void pbx_substitute_variables_helper_full (struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count, size_t *used)
 
void pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count)
 
static void * pbx_thread (void *data)
 
static void print_app_docs (struct ast_app *aa, int fd)
 
static void print_ext (struct ast_exten *e, char *buf, int buflen)
 helper function to print an extension More...
 
static int raise_exception (struct ast_channel *chan, const char *reason, int priority)
 
static int read_escalates (const struct ast_custom_function *acf)
 Returns true if given custom function escalates privileges on read. More...
 
static void set_ext_pri (struct ast_channel *c, const char *exten, int pri)
 
static int show_debug_helper (int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[])
 
static int show_dialplan_helper (int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[])
 
static int statecbs_cmp (void *obj, void *arg, int flags)
 
static char * substring (const char *value, int offset, int length, char *workspace, size_t workspace_len)
 takes a substring. It is ok to call with value == workspace. More...
 
static int testtime_write (struct ast_channel *chan, const char *cmd, char *var, const char *value)
 
static int thread_inhibits_escalations (void)
 Indicates whether the current thread inhibits the execution of dangerous functions. More...
 
static struct ast_extentrie_find_next_match (struct match_char *node)
 
static void unload_pbx (void)
 
static void unreference_cached_app (struct ast_app *app)
 
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)
 
static void wait_for_hangup (struct ast_channel *chan, const void *data)
 
static int write_escalates (const struct ast_custom_function *acf)
 Returns true if given custom function escalates privileges on write. More...
 

Variables

static struct acf_root acf_root = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct apps apps = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static int autofallthrough = 1
 
static struct ast_app_option background_opts [128] = { [ 's' ] = { .flag = (1 << 0) }, [ 'n' ] = { .flag = (1 << 1) }, [ 'm' ] = { .flag = (1 << 2) }, [ 'p' ] = { .flag = (1 << 3) }, }
 
static struct pbx_builtin builtins []
 
static ast_mutex_t conlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 Lock for the ast_context list. More...
 
static ast_mutex_t context_merge_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 Lock to hold off restructuring of hints by ast_merge_contexts_and_delete. More...
 
static struct ast_contextcontexts
 
static struct ast_hashtabcontexts_table = NULL
 
static int countcalls
 
static const char *const days []
 
static struct ast_event_subdevice_state_sub
 Subscription for device state change events. More...
 
static struct ast_taskprocessordevice_state_tps
 
static struct escalation_root escalation_root = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct ast_custom_function exception_function
 
static struct ast_datastore_info exception_store_info
 
static int extenpatternmatchnew = 0
 
static struct cfextension_states extension_states []
 
static struct ast_threadstorage extensionstate_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_extensionstate_buf , .custom_init = NULL , }
 
static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE
 
static ast_rwlock_t globalslock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 }
 
static struct ao2_containerhints
 
static struct ast_data_handler hints_data_provider
 
static int live_dangerously
 Set to true (non-zero) to globally allow all dangerous dialplan functions to run. More...
 
static ast_mutex_t maxcalllock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static const char *const months []
 
static char * overrideswitch = NULL
 
static struct ast_cli_entry pbx_cli []
 
static struct ast_data_entry pbx_data_providers []
 
static struct ast_app_option resetcdr_opts [128] = { [ 'w' ] = { .flag = AST_CDR_FLAG_POSTED }, [ 'a' ] = { .flag = AST_CDR_FLAG_LOCKED }, [ 'v' ] = { .flag = AST_CDR_FLAG_KEEP_VARS }, [ 'e' ] = { .flag = AST_CDR_FLAG_POST_ENABLE }, }
 
static struct ao2_containerstatecbs
 
static int stateid = 1
 
static struct ast_threadstorage switch_data = { .once = PTHREAD_ONCE_INIT , .key_init = __init_switch_data , .custom_init = NULL , }
 
static struct switches switches = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct ast_custom_function testtime_function
 
static struct ast_threadstorage thread_inhibit_escalations_tl = { .once = PTHREAD_ONCE_INIT , .key_init = __init_thread_inhibit_escalations_tl , .custom_init = NULL , }
 
static int totalcalls
 
static struct ast_app_option waitexten_opts [128] = { [ 'm' ] = { .flag = (1 << 0) , .arg_index = 0 + 1 }, [ 'd' ] = { .flag = (1 << 1) , .arg_index = 0 + 1 }, }
 

Detailed Description

Core PBX routines.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file pbx.c.

Macro Definition Documentation

#define BACKGROUND_MATCHEXTEN   (1 << 2)

Definition at line 841 of file pbx.c.

Referenced by pbx_builtin_background().

#define BACKGROUND_NOANSWER   (1 << 1)

Definition at line 840 of file pbx.c.

Referenced by pbx_builtin_background().

#define BACKGROUND_PLAYBACK   (1 << 3)

Definition at line 842 of file pbx.c.

Referenced by pbx_builtin_background().

#define BACKGROUND_SKIP   (1 << 0)

Definition at line 839 of file pbx.c.

Referenced by pbx_builtin_background().

#define BITS_PER   8 /* Number of bits per unit (byte). */

Referenced by ext_cmp_pattern_pos().

#define EXT_DATA_SIZE   8192
Note
I M P O R T A N T :

The speed of extension handling will likely be among the most important aspects of this PBX. The switching scheme as it exists right now isn't terribly bad (it's O(N+M), where N is the # of extensions and M is the avg # of priorities, but a constant search time here would be great ;-)

A new algorithm to do searching based on a 'compiled' pattern tree is introduced here, and shows a fairly flat (constant) search time, even for over 10000 patterns.

Also, using a hash table for context/priority name lookup can help prevent the find_extension routines from absorbing exponential cpu cycles as the number of contexts/priorities grow. I've previously tested find_extension with red-black trees, which have O(log2(n)) speed. Right now, I'm using hash tables, which do searches (ideally) in O(1) time. While these techniques do not yield much speed in small dialplans, they are worth the trouble in large dialplans.

Definition at line 828 of file pbx.c.

Referenced by pbx_extension_helper().

#define HASH_EXTENHINT_SIZE   563

Definition at line 1028 of file pbx.c.

Referenced by ast_pbx_init().

#define INC_DST_OVERFLOW_CHECK

Referenced by get_pattern_node().

#define NEW_MATCHER_CHK_MATCH

Referenced by new_find_extension().

#define NEW_MATCHER_RECURSE

Referenced by new_find_extension().

#define SAY_STUBS   /* generate declarations and stubs for say methods */

Definition at line 60 of file pbx.c.

#define STATUS_NO_CONTEXT   1

Definition at line 2995 of file pbx.c.

Referenced by pbx_extension_helper(), and pbx_find_extension().

#define STATUS_NO_EXTENSION   2

Definition at line 2996 of file pbx.c.

Referenced by pbx_extension_helper(), and pbx_find_extension().

#define STATUS_NO_LABEL   4

Definition at line 2998 of file pbx.c.

Referenced by pbx_extension_helper(), and pbx_find_extension().

#define STATUS_NO_PRIORITY   3

Definition at line 2997 of file pbx.c.

Referenced by pbx_extension_helper(), and pbx_find_extension().

#define STATUS_SUCCESS   5

Definition at line 2999 of file pbx.c.

Referenced by pbx_find_extension().

#define SWITCH_DATA_LENGTH   256

Definition at line 831 of file pbx.c.

#define VAR_BUF_SIZE   4096
#define VAR_HARDTRAN   3

Definition at line 837 of file pbx.c.

#define VAR_NORMAL   1

Definition at line 835 of file pbx.c.

#define VAR_SOFTTRAN   2

Definition at line 836 of file pbx.c.

#define WAITEXTEN_DIALTONE   (1 << 1)

Definition at line 852 of file pbx.c.

Referenced by pbx_builtin_waitexten().

#define WAITEXTEN_MOH   (1 << 0)

Definition at line 851 of file pbx.c.

Referenced by pbx_builtin_waitexten().

Function Documentation

void __ast_context_destroy ( struct ast_context list,
struct ast_hashtab contexttab,
struct ast_context con,
const char *  registrar 
)

Definition at line 9718 of file pbx.c.

References __ast_internal_context_destroy(), ast_context::alts, ast_context_remove_extension_callerid2(), ast_copy_string(), ast_debug, ast_free, ast_hashtab_end_traversal(), ast_hashtab_next(), ast_hashtab_remove_this_object(), ast_hashtab_start_traversal(), AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_MAX_EXTENSION, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_exten::cidmatch, contexts, ast_exten::exten, ast_context::ignorepats, ast_context::includes, ast_exten::matchcid, ast_context::name, ast_include::next, ast_sw::next, ast_ignorepat::next, ast_context::next, ast_exten::peer_table, ast_exten::priority, ast_context::refcount, ast_exten::registrar, ast_include::registrar, ast_sw::registrar, ast_ignorepat::registrar, ast_context::registrar, ast_context::root, and ast_context::root_table.

Referenced by ast_context_destroy().

9719 {
9720  struct ast_context *tmp, *tmpl=NULL;
9721  struct ast_exten *exten_item, *prio_item;
9722 
9723  for (tmp = list; tmp; ) {
9724  struct ast_context *next = NULL; /* next starting point */
9725  /* The following code used to skip forward to the next
9726  context with matching registrar, but this didn't
9727  make sense; individual priorities registrar'd to
9728  the matching registrar could occur in any context! */
9729  ast_debug(1, "Investigate ctx %s %s\n", tmp->name, tmp->registrar);
9730  if (con) {
9731  for (; tmp; tmpl = tmp, tmp = tmp->next) { /* skip to the matching context */
9732  ast_debug(1, "check ctx %s %s\n", tmp->name, tmp->registrar);
9733  if ( !strcasecmp(tmp->name, con->name) ) {
9734  break; /* found it */
9735  }
9736  }
9737  }
9738 
9739  if (!tmp) /* not found, we are done */
9740  break;
9741  ast_wrlock_context(tmp);
9742 
9743  if (registrar) {
9744  /* then search thru and remove any extens that match registrar. */
9745  struct ast_hashtab_iter *exten_iter;
9746  struct ast_hashtab_iter *prio_iter;
9747  struct ast_ignorepat *ip, *ipl = NULL, *ipn = NULL;
9748  struct ast_include *i, *pi = NULL, *ni = NULL;
9749  struct ast_sw *sw = NULL;
9750 
9751  /* remove any ignorepats whose registrar matches */
9752  for (ip = tmp->ignorepats; ip; ip = ipn) {
9753  ipn = ip->next;
9754  if (!strcmp(ip->registrar, registrar)) {
9755  if (ipl) {
9756  ipl->next = ip->next;
9757  ast_free(ip);
9758  continue; /* don't change ipl */
9759  } else {
9760  tmp->ignorepats = ip->next;
9761  ast_free(ip);
9762  continue; /* don't change ipl */
9763  }
9764  }
9765  ipl = ip;
9766  }
9767  /* remove any includes whose registrar matches */
9768  for (i = tmp->includes; i; i = ni) {
9769  ni = i->next;
9770  if (strcmp(i->registrar, registrar) == 0) {
9771  /* remove from list */
9772  if (pi) {
9773  pi->next = i->next;
9774  /* free include */
9775  ast_free(i);
9776  continue; /* don't change pi */
9777  } else {
9778  tmp->includes = i->next;
9779  /* free include */
9780  ast_free(i);
9781  continue; /* don't change pi */
9782  }
9783  }
9784  pi = i;
9785  }
9786  /* remove any switches whose registrar matches */
9787  AST_LIST_TRAVERSE_SAFE_BEGIN(&tmp->alts, sw, list) {
9788  if (strcmp(sw->registrar,registrar) == 0) {
9790  ast_free(sw);
9791  }
9792  }
9794 
9795  if (tmp->root_table) { /* it is entirely possible that the context is EMPTY */
9796  exten_iter = ast_hashtab_start_traversal(tmp->root_table);
9797  while ((exten_item=ast_hashtab_next(exten_iter))) {
9798  int end_traversal = 1;
9799  prio_iter = ast_hashtab_start_traversal(exten_item->peer_table);
9800  while ((prio_item=ast_hashtab_next(prio_iter))) {
9802  char cidmatch[AST_MAX_EXTENSION];
9803  if (!prio_item->registrar || strcmp(prio_item->registrar, registrar) != 0) {
9804  continue;
9805  }
9806  ast_verb(3, "Remove %s/%s/%d, registrar=%s; con=%s(%p); con->root=%p\n",
9807  tmp->name, prio_item->exten, prio_item->priority, registrar, con? con->name : "<nil>", con, con? con->root_table: NULL);
9808  ast_copy_string(extension, prio_item->exten, sizeof(extension));
9809  if (prio_item->cidmatch) {
9810  ast_copy_string(cidmatch, prio_item->cidmatch, sizeof(cidmatch));
9811  }
9812  end_traversal &= ast_context_remove_extension_callerid2(tmp, extension, prio_item->priority, cidmatch, prio_item->matchcid, NULL, 1);
9813  }
9814  /* Explanation:
9815  * ast_context_remove_extension_callerid2 will destroy the extension that it comes across. This
9816  * destruction includes destroying the exten's peer_table, which we are currently traversing. If
9817  * ast_context_remove_extension_callerid2 ever should return '0' then this means we have destroyed
9818  * the hashtable which we are traversing, and thus calling ast_hashtab_end_traversal will result
9819  * in reading invalid memory. Thus, if we detect that we destroyed the hashtable, then we will simply
9820  * free the iterator
9821  */
9822  if (end_traversal) {
9823  ast_hashtab_end_traversal(prio_iter);
9824  } else {
9825  ast_free(prio_iter);
9826  }
9827  }
9828  ast_hashtab_end_traversal(exten_iter);
9829  }
9830 
9831  /* delete the context if it's registrar matches, is empty, has refcount of 1, */
9832  /* it's not empty, if it has includes, ignorepats, or switches that are registered from
9833  another registrar. It's not empty if there are any extensions */
9834  if (strcmp(tmp->registrar, registrar) == 0 && tmp->refcount < 2 && !tmp->root && !tmp->ignorepats && !tmp->includes && AST_LIST_EMPTY(&tmp->alts)) {
9835  ast_debug(1, "delete ctx %s %s\n", tmp->name, tmp->registrar);
9836  ast_hashtab_remove_this_object(contexttab, tmp);
9837 
9838  next = tmp->next;
9839  if (tmpl)
9840  tmpl->next = next;
9841  else
9842  contexts = next;
9843  /* Okay, now we're safe to let it go -- in a sense, we were
9844  ready to let it go as soon as we locked it. */
9845  ast_unlock_context(tmp);
9847  } else {
9848  ast_debug(1,"Couldn't delete ctx %s/%s; refc=%d; tmp.root=%p\n", tmp->name, tmp->registrar,
9849  tmp->refcount, tmp->root);
9850  ast_unlock_context(tmp);
9851  next = tmp->next;
9852  tmpl = tmp;
9853  }
9854  } else if (con) {
9855  ast_verb(3, "Deleting context %s registrar=%s\n", tmp->name, tmp->registrar);
9856  ast_debug(1, "delete ctx %s %s\n", tmp->name, tmp->registrar);
9857  ast_hashtab_remove_this_object(contexttab, tmp);
9858 
9859  next = tmp->next;
9860  if (tmpl)
9861  tmpl->next = next;
9862  else
9863  contexts = next;
9864  /* Okay, now we're safe to let it go -- in a sense, we were
9865  ready to let it go as soon as we locked it. */
9866  ast_unlock_context(tmp);
9868  }
9869 
9870  /* if we have a specific match, we are done, otherwise continue */
9871  tmp = con ? NULL : next;
9872  }
9873 }
ast_include: include= support in extensions.conf
Definition: pbx.c:904
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
struct ast_include * next
Definition: pbx.c:910
static void __ast_internal_context_destroy(struct ast_context *con)
Definition: pbx.c:9670
const char * registrar
Definition: pbx.c:926
void * ast_hashtab_next(struct ast_hashtab_iter *it)
Gets the next object in the list, advances iter one step returns null on end of traversal.
Definition: hashtab.c:753
struct ast_hashtab_iter * ast_hashtab_start_traversal(struct ast_hashtab *tab)
Gives an iterator to hastable.
Definition: hashtab.c:696
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
int ast_context_remove_extension_callerid2(struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar, int already_locked)
Definition: pbx.c:6149
struct ast_hashtab * peer_table
Definition: pbx.c:896
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define ast_verb(level,...)
Definition: logger.h:243
int matchcid
Definition: pbx.c:886
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int priority
Definition: pbx.c:888
ast_sw: Switch statement in extensions.conf
Definition: pbx.c:915
const char * registrar
Definition: pbx.c:907
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
char * exten
Definition: pbx.c:885
char * registrar
Definition: pbx.c:963
char name[0]
Definition: pbx.c:967
void ast_hashtab_end_traversal(struct ast_hashtab_iter *it)
end the traversal, free the iterator, unlock if necc.
Definition: hashtab.c:746
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx.c:925
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:11055
struct ast_context * next
Definition: pbx.c:960
an iterator for traversing the buckets
Definition: hashtab.h:105
#define ast_free(a)
Definition: astmm.h:97
static char * registrar
Definition: features.c:623
const char * registrar
Definition: pbx.c:898
const char * cidmatch
Definition: pbx.c:887
struct ast_sw * next
Definition: pbx.c:920
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_hashtab * root_table
Definition: pbx.c:958
const char * registrar
Definition: pbx.c:917
static struct ast_context * contexts
Definition: pbx.c:1285
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
ast_context: An extension context
Definition: pbx.c:955
struct ast_ignorepat * next
Definition: pbx.c:927
void * ast_hashtab_remove_this_object(struct ast_hashtab *tab, void *obj)
Hash the object and then compare ptrs in bucket list instead of calling the compare routine...
Definition: hashtab.c:859
int __ast_custom_function_register ( struct ast_custom_function acf,
struct ast_module mod 
)

Register a custom function.

Definition at line 3946 of file pbx.c.

References acf_retrieve_docs(), ast_log(), AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, AST_STATIC_DOC, ast_verb, COLOR_BRCYAN, ast_custom_function::docsrc, LOG_ERROR, ast_custom_function::mod, ast_custom_function::name, and term_color().

Referenced by __ast_custom_function_register_escalating(), and load_pbx().

3947 {
3948  struct ast_custom_function *cur;
3949  char tmps[80];
3950 
3951  if (!acf) {
3952  return -1;
3953  }
3954 
3955  acf->mod = mod;
3956 #ifdef AST_XML_DOCS
3957  acf->docsrc = AST_STATIC_DOC;
3958 #endif
3959 
3960  if (acf_retrieve_docs(acf)) {
3961  return -1;
3962  }
3963 
3965 
3966  AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) {
3967  if (!strcmp(acf->name, cur->name)) {
3968  ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
3970  return -1;
3971  }
3972  }
3973 
3974  /* Store in alphabetical order */
3975  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
3976  if (strcasecmp(acf->name, cur->name) < 0) {
3977  AST_RWLIST_INSERT_BEFORE_CURRENT(acf, acflist);
3978  break;
3979  }
3980  }
3982 
3983  if (!cur) {
3984  AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist);
3985  }
3986 
3988 
3989  ast_verb(2, "Registered custom function '%s'\n", term_color(tmps, acf->name, COLOR_BRCYAN, 0, sizeof(tmps)));
3990 
3991  return 0;
3992 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
enum ast_doc_src docsrc
Definition: pbx.h:104
struct ast_module * mod
Definition: pbx.h:119
static int acf_retrieve_docs(struct ast_custom_function *acf)
Definition: pbx.c:3901
#define ast_verb(level,...)
Definition: logger.h:243
#define COLOR_BRCYAN
Definition: term.h:60
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Definition: pbx.c:1231
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:595
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
const char * name
Definition: pbx.h:96
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
int __ast_custom_function_register_escalating ( struct ast_custom_function acf,
enum ast_custom_function_escalation  escalation,
struct ast_module mod 
)

Register a custom function which requires escalated privileges.

Examples would be SHELL() (for which a read needs permission to execute arbitrary code) or FILE() (for which write needs permission to change files on the filesystem).

Definition at line 3994 of file pbx.c.

References __ast_custom_function_register(), ast_calloc, AST_CFE_BOTH, AST_CFE_NONE, AST_CFE_READ, AST_CFE_WRITE, ast_custom_function_unregister(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

3995 {
3996  struct ast_custom_escalating_function *acf_escalation = NULL;
3997  int res;
3998 
3999  res = __ast_custom_function_register(acf, mod);
4000  if (res != 0) {
4001  return -1;
4002  }
4003 
4004  if (escalation == AST_CFE_NONE) {
4005  /* No escalations; no need to do anything else */
4006  return 0;
4007  }
4008 
4009  acf_escalation = ast_calloc(1, sizeof(*acf_escalation));
4010  if (!acf_escalation) {
4012  return -1;
4013  }
4014 
4015  acf_escalation->acf = acf;
4016  switch (escalation) {
4017  case AST_CFE_NONE:
4018  break;
4019  case AST_CFE_READ:
4020  acf_escalation->read_escalates = 1;
4021  break;
4022  case AST_CFE_WRITE:
4023  acf_escalation->write_escalates = 1;
4024  break;
4025  case AST_CFE_BOTH:
4026  acf_escalation->read_escalates = 1;
4027  acf_escalation->write_escalates = 1;
4028  break;
4029  }
4030 
4032  AST_RWLIST_INSERT_TAIL(&escalation_root, acf_escalation, list);
4034 
4035  return 0;
4036 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
#define ast_calloc(a, b)
Definition: astmm.h:82
Extra information for an ast_custom_function holding privilege escalation information. Kept in a separate structure for ABI compatibility.
Definition: pbx.c:1237
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
Register a custom function.
Definition: pbx.c:3946
static int __ast_goto_if_exists ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority,
int  async 
)
static

Definition at line 11240 of file pbx.c.

References ast_async_goto(), ast_exists_extension(), ast_explicit_goto(), AST_PBX_GOTO_FAILED, ast_channel::caller, context, ast_channel::context, exten, ast_channel::exten, ast_party_caller::id, ast_party_id::number, ast_channel::priority, S_COR, ast_party_number::str, and ast_party_number::valid.

Referenced by ast_async_goto_if_exists(), and ast_goto_if_exists().

11241 {
11242  int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority);
11243 
11244  if (!chan)
11245  return -2;
11246 
11247  if (context == NULL)
11248  context = chan->context;
11249  if (exten == NULL)
11250  exten = chan->exten;
11251 
11252  goto_func = (async) ? ast_async_goto : ast_explicit_goto;
11253  if (ast_exists_extension(chan, context, exten, priority,
11254  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)))
11255  return goto_func(chan, context, exten, priority);
11256  else {
11257  return AST_PBX_GOTO_FAILED;
11258  }
11259 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int priority
Definition: channel.h:841
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:8708
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
#define AST_PBX_GOTO_FAILED
Definition: pbx.h:41
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:8731
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static void __ast_internal_context_destroy ( struct ast_context con)
static

Definition at line 9670 of file pbx.c.

References ast_context::alts, ast_free, ast_hashtab_destroy(), AST_LIST_REMOVE_HEAD, ast_mutex_destroy, ast_rwlock_destroy, destroy_exten(), destroy_pattern_tree(), el, ast_context::ignorepats, ast_context::includes, ast_context::lock, ast_context::macrolock, ast_exten::next, ast_include::next, ast_ignorepat::next, ast_context::pattern_tree, ast_exten::peer, ast_context::registrar, ast_context::root, and ast_context::root_table.

Referenced by __ast_context_destroy(), and ast_merge_contexts_and_delete().

9671 {
9672  struct ast_include *tmpi;
9673  struct ast_sw *sw;
9674  struct ast_exten *e, *el, *en;
9675  struct ast_ignorepat *ipi;
9676  struct ast_context *tmp = con;
9677 
9678  for (tmpi = tmp->includes; tmpi; ) { /* Free includes */
9679  struct ast_include *tmpil = tmpi;
9680  tmpi = tmpi->next;
9681  ast_free(tmpil);
9682  }
9683  for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */
9684  struct ast_ignorepat *ipl = ipi;
9685  ipi = ipi->next;
9686  ast_free(ipl);
9687  }
9688  if (tmp->registrar)
9689  ast_free(tmp->registrar);
9690 
9691  /* destroy the hash tabs */
9692  if (tmp->root_table) {
9694  }
9695  /* and destroy the pattern tree */
9696  if (tmp->pattern_tree)
9698 
9699  while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list)))
9700  ast_free(sw);
9701  for (e = tmp->root; e;) {
9702  for (en = e->peer; en;) {
9703  el = en;
9704  en = en->peer;
9705  destroy_exten(el);
9706  }
9707  el = e;
9708  e = e->next;
9709  destroy_exten(el);
9710  }
9711  tmp->root = NULL;
9712  ast_rwlock_destroy(&tmp->lock);
9714  ast_free(tmp);
9715 }
ast_include: include= support in extensions.conf
Definition: pbx.c:904
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
struct ast_include * next
Definition: pbx.c:910
struct ast_include * includes
Definition: pbx.c:961
#define ast_rwlock_destroy(rwlock)
Definition: lock.h:199
struct ast_ignorepat * ignorepats
Definition: pbx.c:962
static EditLine * el
Definition: asterisk.c:222
ast_mutex_t macrolock
Definition: pbx.c:966
ast_sw: Switch statement in extensions.conf
Definition: pbx.c:915
char * registrar
Definition: pbx.c:963
struct ast_exten * peer
Definition: pbx.c:895
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
ast_rwlock_t lock
Definition: pbx.c:956
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx.c:925
#define ast_free(a)
Definition: astmm.h:97
static void destroy_pattern_tree(struct match_char *pattern_tree)
Definition: pbx.c:2344
struct ast_exten * next
Definition: pbx.c:899
struct ast_context::@290 alts
struct ast_hashtab * root_table
Definition: pbx.c:958
#define ast_mutex_destroy(a)
Definition: lock.h:154
ast_context: An extension context
Definition: pbx.c:955
struct ast_ignorepat * next
Definition: pbx.c:927
struct ast_exten * root
Definition: pbx.c:957
struct match_char * pattern_tree
Definition: pbx.c:959
static void destroy_exten(struct ast_exten *e)
Definition: pbx.c:5845
void ast_hashtab_destroy(struct ast_hashtab *tab, void(*objdestroyfunc)(void *obj))
This func will free the hash table and all its memory.
Definition: hashtab.c:388
static enum ast_pbx_result __ast_pbx_run ( struct ast_channel c,
struct ast_pbx_args args 
)
static
Note
We get here on a failure of some kind: non-existing extension or hangup. We have options, here. We can either catch the failure and continue, or we can drop out entirely.
If there is no match at priority 1, it is not a valid extension anymore. Try to continue at "i" (for invalid) or "e" (for exception) or exit if neither exist.

Definition at line 5473 of file pbx.c.

References ast_channel::_softhangup, ast_calloc, ast_cdr_end(), ast_cdr_update(), ast_channel_clear_softhangup(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, ast_copy_string(), ast_debug, ast_exists_extension(), AST_FLAG_BRIDGE_HANGUP_RUN, AST_FLAG_IN_AUTOLOOP, ast_free, ast_hangup(), ast_log(), ast_matchmore_extension(), ast_opt_end_cdr_before_h_exten, AST_PBX_ERROR, AST_PBX_INCOMPLETE, ast_set2_flag, ast_set_flag, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_TIMEOUT, ast_spawn_extension(), ast_strlen_zero(), ast_test_flag, ast_verb, autofallthrough, ast_channel::caller, ast_channel::cdr, collect_digits(), ast_channel::context, ast_pbx::dtimeoutms, ast_channel::exten, ast_party_caller::id, LOG_WARNING, ast_channel::name, ast_pbx_args::no_hangup_chan, ast_party_id::number, ast_channel::pbx, pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_destroy(), ast_channel::priority, raise_exception(), ast_pbx::rtimeoutms, S_COR, set_ext_pri(), status, ast_party_number::str, ast_party_number::valid, and ast_channel::whentohangup.

Referenced by ast_pbx_run_args(), and pbx_thread().

5475 {
5476  int found = 0; /* set if we find at least one match */
5477  int res = 0;
5478  int autoloopflag;
5479  int error = 0; /* set an error conditions */
5480 
5481  /* A little initial setup here */
5482  if (c->pbx) {
5483  ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
5484  /* XXX and now what ? */
5485  ast_free(c->pbx);
5486  }
5487  if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx))))
5488  return -1;
5489  /* Set reasonable defaults */
5490  c->pbx->rtimeoutms = 10000;
5491  c->pbx->dtimeoutms = 5000;
5492 
5493  autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
5495 
5496  /* Start by trying whatever the channel is set to */
5497  if (!ast_exists_extension(c, c->context, c->exten, c->priority,
5498  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5499  /* If not successful fall back to 's' */
5500  ast_verb(2, "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
5501  /* XXX the original code used the existing priority in the call to
5502  * ast_exists_extension(), and reset it to 1 afterwards.
5503  * I believe the correct thing is to set it to 1 immediately.
5504  */
5505  set_ext_pri(c, "s", 1);
5506  if (!ast_exists_extension(c, c->context, c->exten, c->priority,
5507  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5508  /* JK02: And finally back to default if everything else failed */
5509  ast_verb(2, "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
5510  ast_copy_string(c->context, "default", sizeof(c->context));
5511  }
5512  }
5513  ast_channel_lock(c);
5514  if (c->cdr) {
5515  /* allow CDR variables that have been collected after channel was created to be visible during call */
5516  ast_cdr_update(c);
5517  }
5518  ast_channel_unlock(c);
5519  for (;;) {
5520  char dst_exten[256]; /* buffer to accumulate digits */
5521  int pos = 0; /* XXX should check bounds */
5522  int digit = 0;
5523  int invalid = 0;
5524  int timeout = 0;
5525 
5526  /* No digits pressed yet */
5527  dst_exten[pos] = '\0';
5528 
5529  /* loop on priorities in this context/exten */
5530  while (!(res = ast_spawn_extension(c, c->context, c->exten, c->priority,
5531  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL),
5532  &found, 1))) {
5533  if (!ast_check_hangup(c)) {
5534  ++c->priority;
5535  continue;
5536  }
5537 
5538  /* Check softhangup flags. */
5541  continue;
5542  }
5544  if (ast_exists_extension(c, c->context, "T", 1,
5545  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5546  set_ext_pri(c, "T", 1);
5547  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
5548  memset(&c->whentohangup, 0, sizeof(c->whentohangup));
5550  continue;
5551  } else if (ast_exists_extension(c, c->context, "e", 1,
5552  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5553  raise_exception(c, "ABSOLUTETIMEOUT", 1);
5554  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
5555  memset(&c->whentohangup, 0, sizeof(c->whentohangup));
5557  continue;
5558  }
5559 
5560  /* Call timed out with no special extension to jump to. */
5561  error = 1;
5562  break;
5563  }
5564  ast_debug(1, "Extension %s, priority %d returned normally even though call was hung up\n",
5565  c->exten, c->priority);
5566  error = 1;
5567  break;
5568  } /* end while - from here on we can use 'break' to go out */
5569  if (found && res) {
5570  /* Something bad happened, or a hangup has been requested. */
5571  if (strchr("0123456789ABCDEF*#", res)) {
5572  ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res);
5573  pos = 0;
5574  dst_exten[pos++] = digit = res;
5575  dst_exten[pos] = '\0';
5576  } else if (res == AST_PBX_INCOMPLETE) {
5577  ast_debug(1, "Spawn extension (%s,%s,%d) exited INCOMPLETE on '%s'\n", c->context, c->exten, c->priority, c->name);
5578  ast_verb(2, "Spawn extension (%s, %s, %d) exited INCOMPLETE on '%s'\n", c->context, c->exten, c->priority, c->name);
5579 
5580  /* Don't cycle on incomplete - this will happen if the only extension that matches is our "incomplete" extension */
5581  if (!ast_matchmore_extension(c, c->context, c->exten, 1,
5582  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5583  invalid = 1;
5584  } else {
5585  ast_copy_string(dst_exten, c->exten, sizeof(dst_exten));
5586  digit = 1;
5587  pos = strlen(dst_exten);
5588  }
5589  } else {
5590  ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
5591  ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
5592 
5593  if ((res == AST_PBX_ERROR)
5594  && ast_exists_extension(c, c->context, "e", 1,
5595  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5596  /* if we are already on the 'e' exten, don't jump to it again */
5597  if (!strcmp(c->exten, "e")) {
5598  ast_verb(2, "Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s'\n", c->context, c->exten, c->priority, c->name);
5599  error = 1;
5600  } else {
5601  raise_exception(c, "ERROR", 1);
5602  continue;
5603  }
5604  }
5605 
5608  continue;
5609  }
5611  if (ast_exists_extension(c, c->context, "T", 1,
5612  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5613  set_ext_pri(c, "T", 1);
5614  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
5615  memset(&c->whentohangup, 0, sizeof(c->whentohangup));
5617  continue;
5618  } else if (ast_exists_extension(c, c->context, "e", 1,
5619  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5620  raise_exception(c, "ABSOLUTETIMEOUT", 1);
5621  /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
5622  memset(&c->whentohangup, 0, sizeof(c->whentohangup));
5624  continue;
5625  }
5626  /* Call timed out with no special extension to jump to. */
5627  }
5628  ast_channel_lock(c);
5629  if (c->cdr) {
5630  ast_cdr_update(c);
5631  }
5632  ast_channel_unlock(c);
5633  error = 1;
5634  break;
5635  }
5636  }
5637  if (error)
5638  break;
5639 
5640  /*!\note
5641  * We get here on a failure of some kind: non-existing extension or
5642  * hangup. We have options, here. We can either catch the failure
5643  * and continue, or we can drop out entirely. */
5644 
5645  if (invalid
5646  || (ast_strlen_zero(dst_exten) &&
5647  !ast_exists_extension(c, c->context, c->exten, 1,
5648  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL)))) {
5649  /*!\note
5650  * If there is no match at priority 1, it is not a valid extension anymore.
5651  * Try to continue at "i" (for invalid) or "e" (for exception) or exit if
5652  * neither exist.
5653  */
5654  if (ast_exists_extension(c, c->context, "i", 1,
5655  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5656  ast_verb(3, "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
5657  pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
5658  set_ext_pri(c, "i", 1);
5659  } else if (ast_exists_extension(c, c->context, "e", 1,
5660  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5661  raise_exception(c, "INVALID", 1);
5662  } else {
5663  ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
5664  c->name, c->exten, c->context);
5665  error = 1; /* we know what to do with it */
5666  break;
5667  }
5668  } else if (c->_softhangup & AST_SOFTHANGUP_TIMEOUT) {
5669  /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
5671  } else { /* keypress received, get more digits for a full extension */
5672  int waittime = 0;
5673  if (digit)
5674  waittime = c->pbx->dtimeoutms;
5675  else if (!autofallthrough)
5676  waittime = c->pbx->rtimeoutms;
5677  if (!waittime) {
5678  const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
5679  if (!status)
5680  status = "UNKNOWN";
5681  ast_verb(3, "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status);
5682  if (!strcasecmp(status, "CONGESTION"))
5683  res = pbx_builtin_congestion(c, "10");
5684  else if (!strcasecmp(status, "CHANUNAVAIL"))
5685  res = pbx_builtin_congestion(c, "10");
5686  else if (!strcasecmp(status, "BUSY"))
5687  res = pbx_builtin_busy(c, "10");
5688  error = 1; /* XXX disable message */
5689  break; /* exit from the 'for' loop */
5690  }
5691 
5692  if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos))
5693  break;
5694  if (res == AST_PBX_INCOMPLETE && ast_strlen_zero(&dst_exten[pos]))
5695  timeout = 1;
5696  if (!timeout
5697  && ast_exists_extension(c, c->context, dst_exten, 1,
5698  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) { /* Prepare the next cycle */
5699  set_ext_pri(c, dst_exten, 1);
5700  } else {
5701  /* No such extension */
5702  if (!timeout && !ast_strlen_zero(dst_exten)) {
5703  /* An invalid extension */
5704  if (ast_exists_extension(c, c->context, "i", 1,
5705  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5706  ast_verb(3, "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name);
5707  pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
5708  set_ext_pri(c, "i", 1);
5709  } else if (ast_exists_extension(c, c->context, "e", 1,
5710  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5711  raise_exception(c, "INVALID", 1);
5712  } else {
5714  "Invalid extension '%s', but no rule 'i' or 'e' in context '%s'\n",
5715  dst_exten, c->context);
5716  found = 1; /* XXX disable message */
5717  break;
5718  }
5719  } else {
5720  /* A simple timeout */
5721  if (ast_exists_extension(c, c->context, "t", 1,
5722  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5723  ast_verb(3, "Timeout on %s\n", c->name);
5724  set_ext_pri(c, "t", 1);
5725  } else if (ast_exists_extension(c, c->context, "e", 1,
5726  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5727  raise_exception(c, "RESPONSETIMEOUT", 1);
5728  } else {
5730  "Timeout, but no rule 't' or 'e' in context '%s'\n",
5731  c->context);
5732  found = 1; /* XXX disable message */
5733  break;
5734  }
5735  }
5736  }
5737  ast_channel_lock(c);
5738  if (c->cdr) {
5739  ast_verb(2, "CDR updated on %s\n",c->name);
5740  ast_cdr_update(c);
5741  }
5742  ast_channel_unlock(c);
5743  }
5744  }
5745 
5746  if (!found && !error) {
5747  ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
5748  }
5749 
5750  if (!args || !args->no_hangup_chan) {
5752  }
5753 
5754  if ((!args || !args->no_hangup_chan)
5756  && ast_exists_extension(c, c->context, "h", 1,
5757  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5758  set_ext_pri(c, "h", 1);
5759  if (c->cdr && ast_opt_end_cdr_before_h_exten) {
5760  ast_cdr_end(c->cdr);
5761  }
5762  while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority,
5763  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL),
5764  &found, 1)) == 0) {
5765  c->priority++;
5766  }
5767  if (found && res) {
5768  /* Something bad happened, or a hangup has been requested. */
5769  ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
5770  ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
5771  }
5772  }
5773  ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP);
5774  ast_clear_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */
5775  pbx_destroy(c->pbx);
5776  c->pbx = NULL;
5777 
5778  if (!args || !args->no_hangup_chan) {
5779  ast_hangup(c);
5780  }
5781 
5782  return 0;
5783 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
Definition: pbx.c:5420
#define ast_channel_lock(chan)
Definition: channel.h:2466
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int priority
Definition: channel.h:841
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_cdr_end(struct ast_cdr *cdr)
End a call.
Definition: cdr.c:933
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:144
#define ast_opt_end_cdr_before_h_exten
Definition: options.h:122
static int autofallthrough
Definition: pbx.c:1220
struct ast_cdr * cdr
Definition: channel.h:766
#define ast_verb(level,...)
Definition: logger.h:243
static void pbx_destroy(struct ast_pbx *p)
Definition: pbx.c:1573
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static int raise_exception(struct ast_channel *chan, const char *reason, int priority)
Definition: pbx.c:3594
#define AST_PBX_ERROR
Definition: pbx.h:49
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
Clear a set of softhangup flags from a channel.
Definition: channel.c:2707
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2746
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
int ast_cdr_update(struct ast_channel *chan)
Update CDR on a channel.
Definition: cdr.c:1083
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
#define AST_PBX_INCOMPLETE
Definition: pbx.h:50
static int pbx_builtin_busy(struct ast_channel *, const char *)
Definition: pbx.c:9934
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int _softhangup
Definition: channel.h:832
static int collect_digits(struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
collect digits from the channel into the buffer.
Definition: pbx.c:5446
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_free(a)
Definition: astmm.h:97
static int pbx_builtin_congestion(struct ast_channel *, const char *)
Definition: pbx.c:9950
#define ast_clear_flag(p, flag)
Definition: utils.h:77
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)
Launch a new extension (i.e. new stack)
Definition: pbx.c:5425
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
int dtimeoutms
Definition: pbx.h:180
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct timeval whentohangup
Definition: channel.h:789
static void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
Definition: pbx.c:5431
unsigned int no_hangup_chan
Definition: pbx.h:343
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
jack_status_t status
Definition: app_jack.c:143
struct ast_pbx * pbx
Definition: channel.h:761
int rtimeoutms
Definition: pbx.h:181
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static void __init_extensionstate_buf ( void  )
static

Definition at line 865 of file pbx.c.

884 {
static void __init_switch_data ( void  )
static

Definition at line 864 of file pbx.c.

884 {
static void __init_thread_inhibit_escalations_tl ( void  )
static

A thread local indicating whether the current thread can run 'dangerous' dialplan functions.

Definition at line 870 of file pbx.c.

884 {
static int _extension_match_core ( const char *  pattern,
const char *  data,
enum ext_match_t  mode 
)
static

Definition at line 2739 of file pbx.c.

References ast_log(), ast_sw::data, E_MATCH, E_MATCH_MASK, E_MATCHMORE, ext_cmp_exten(), ext_cmp_exten_partial(), ext_cmp_exten_strlen(), ext_cmp_pattern(), LOG_NOTICE, and LOG_WARNING.

Referenced by extension_match_core().

2740 {
2741  mode &= E_MATCH_MASK; /* only consider the relevant bits */
2742 
2743 #ifdef NEED_DEBUG_HERE
2744  ast_log(LOG_NOTICE,"match core: pat: '%s', dat: '%s', mode=%d\n", pattern, data, (int)mode);
2745 #endif
2746 
2747  if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
2748  int lp = ext_cmp_exten_strlen(pattern);
2749  int ld = ext_cmp_exten_strlen(data);
2750 
2751  if (lp < ld) { /* pattern too short, cannot match */
2752 #ifdef NEED_DEBUG_HERE
2753  ast_log(LOG_NOTICE,"return (0) - pattern too short, cannot match\n");
2754 #endif
2755  return 0;
2756  }
2757  /* depending on the mode, accept full or partial match or both */
2758  if (mode == E_MATCH) {
2759 #ifdef NEED_DEBUG_HERE
2760  ast_log(LOG_NOTICE,"return (!ext_cmp_exten(%s,%s) when mode== E_MATCH)\n", pattern, data);
2761 #endif
2762  return !ext_cmp_exten(pattern, data); /* 1 on match, 0 on fail */
2763  }
2764  if (ld == 0 || !ext_cmp_exten_partial(pattern, data)) { /* partial or full match */
2765 #ifdef NEED_DEBUG_HERE
2766  ast_log(LOG_NOTICE,"return (mode(%d) == E_MATCHMORE ? lp(%d) > ld(%d) : 1)\n", mode, lp, ld);
2767 #endif
2768  return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
2769  } else {
2770 #ifdef NEED_DEBUG_HERE
2771  ast_log(LOG_NOTICE,"return (0) when ld(%d) > 0 && pattern(%s) != data(%s)\n", ld, pattern, data);
2772 #endif
2773  return 0;
2774  }
2775  }
2776  if (mode == E_MATCH && data[0] == '_') {
2777  /*
2778  * XXX It is bad design that we don't know if we should be
2779  * comparing data and pattern as patterns or comparing data if
2780  * it conforms to pattern when the function is called. First,
2781  * assume they are both patterns. If they don't match then try
2782  * to see if data conforms to the given pattern.
2783  *
2784  * note: if this test is left out, then _x. will not match _x. !!!
2785  */
2786 #ifdef NEED_DEBUG_HERE
2787  ast_log(LOG_NOTICE, "Comparing as patterns first. pattern:%s data:%s\n", pattern, data);
2788 #endif
2789  if (!ext_cmp_pattern(pattern + 1, data + 1)) {
2790 #ifdef NEED_DEBUG_HERE
2791  ast_log(LOG_NOTICE,"return (1) - pattern matches pattern\n");
2792 #endif
2793  return 1;
2794  }
2795  }
2796 
2797  ++pattern; /* skip leading _ */
2798  /*
2799  * XXX below we stop at '/' which is a separator for the CID info. However we should
2800  * not store '/' in the pattern at all. When we insure it, we can remove the checks.
2801  */
2802  for (;;) {
2803  const char *end;
2804 
2805  /* Ignore '-' chars as eye candy fluff. */
2806  while (*data == '-') {
2807  ++data;
2808  }
2809  while (*pattern == '-') {
2810  ++pattern;
2811  }
2812  if (!*data || !*pattern || *pattern == '/') {
2813  break;
2814  }
2815 
2816  switch (*pattern) {
2817  case '[': /* a range */
2818  ++pattern;
2819  end = strchr(pattern, ']'); /* XXX should deal with escapes ? */
2820  if (!end) {
2821  ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
2822  return 0; /* unconditional failure */
2823  }
2824  if (pattern == end) {
2825  /* Ignore empty character sets. */
2826  ++pattern;
2827  continue;
2828  }
2829  for (; pattern < end; ++pattern) {
2830  if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
2831  if (*data >= pattern[0] && *data <= pattern[2])
2832  break; /* match found */
2833  else {
2834  pattern += 2; /* skip a total of 3 chars */
2835  continue;
2836  }
2837  } else if (*data == pattern[0])
2838  break; /* match found */
2839  }
2840  if (pattern >= end) {
2841 #ifdef NEED_DEBUG_HERE
2842  ast_log(LOG_NOTICE,"return (0) when pattern>=end\n");
2843 #endif
2844  return 0;
2845  }
2846  pattern = end; /* skip and continue */
2847  break;
2848  case 'n':
2849  case 'N':
2850  if (*data < '2' || *data > '9') {
2851 #ifdef NEED_DEBUG_HERE
2852  ast_log(LOG_NOTICE,"return (0) N is not matched\n");
2853 #endif
2854  return 0;
2855  }
2856  break;
2857  case 'x':
2858  case 'X':
2859  if (*data < '0' || *data > '9') {
2860 #ifdef NEED_DEBUG_HERE
2861  ast_log(LOG_NOTICE,"return (0) X is not matched\n");
2862 #endif
2863  return 0;
2864  }
2865  break;
2866  case 'z':
2867  case 'Z':
2868  if (*data < '1' || *data > '9') {
2869 #ifdef NEED_DEBUG_HERE
2870  ast_log(LOG_NOTICE,"return (0) Z is not matched\n");
2871 #endif
2872  return 0;
2873  }
2874  break;
2875  case '.': /* Must match, even with more digits */
2876 #ifdef NEED_DEBUG_HERE
2877  ast_log(LOG_NOTICE, "return (1) when '.' is matched\n");
2878 #endif
2879  return 1;
2880  case '!': /* Early match */
2881 #ifdef NEED_DEBUG_HERE
2882  ast_log(LOG_NOTICE, "return (2) when '!' is matched\n");
2883 #endif
2884  return 2;
2885  default:
2886  if (*data != *pattern) {
2887 #ifdef NEED_DEBUG_HERE
2888  ast_log(LOG_NOTICE, "return (0) when *data(%c) != *pattern(%c)\n", *data, *pattern);
2889 #endif
2890  return 0;
2891  }
2892  break;
2893  }
2894  ++data;
2895  ++pattern;
2896  }
2897  if (*data) /* data longer than pattern, no match */ {
2898 #ifdef NEED_DEBUG_HERE
2899  ast_log(LOG_NOTICE, "return (0) when data longer than pattern\n");
2900 #endif
2901  return 0;
2902  }
2903 
2904  /*
2905  * match so far, but ran off the end of data.
2906  * Depending on what is next, determine match or not.
2907  */
2908  if (*pattern == '\0' || *pattern == '/') { /* exact match */
2909 #ifdef NEED_DEBUG_HERE
2910  ast_log(LOG_NOTICE, "at end, return (%d) in 'exact match'\n", (mode==E_MATCHMORE) ? 0 : 1);
2911 #endif
2912  return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */
2913  } else if (*pattern == '!') { /* early match */
2914 #ifdef NEED_DEBUG_HERE
2915  ast_log(LOG_NOTICE, "at end, return (2) when '!' is matched\n");
2916 #endif
2917  return 2;
2918  } else { /* partial match */
2919 #ifdef NEED_DEBUG_HERE
2920  ast_log(LOG_NOTICE, "at end, return (%d) which deps on E_MATCH\n", (mode == E_MATCH) ? 0 : 1);
2921 #endif
2922  return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */
2923  }
2924 }
#define LOG_WARNING
Definition: logger.h:144
const char pattern[0]
Definition: pbx.c:928
static int ext_cmp_exten_strlen(const char *str)
Definition: pbx.c:2368
static int ext_cmp_pattern(const char *left, const char *right)
Definition: pbx.c:2643
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static int ext_cmp_exten_partial(const char *left, const char *right)
Definition: pbx.c:2398
static int ext_cmp_exten(const char *left, const char *right)
Definition: pbx.c:2441
static int acf_exception_read ( struct ast_channel chan,
const char *  name,
char *  data,
char *  buf,
size_t  buflen 
)
static

Definition at line 3626 of file pbx.c.

References ast_channel_datastore_find(), ast_copy_string(), pbx_exception::context, ast_datastore::data, exception_store_info, pbx_exception::exten, pbx_exception::priority, and pbx_exception::reason.

3627 {
3629  struct pbx_exception *exception = NULL;
3630  if (!ds || !ds->data)
3631  return -1;
3632  exception = ds->data;
3633  if (!strcasecmp(data, "REASON"))
3634  ast_copy_string(buf, exception->reason, buflen);
3635  else if (!strcasecmp(data, "CONTEXT"))
3636  ast_copy_string(buf, exception->context, buflen);
3637  else if (!strncasecmp(data, "EXTEN", 5))
3638  ast_copy_string(buf, exception->exten, buflen);
3639  else if (!strcasecmp(data, "PRIORITY"))
3640  snprintf(buf, buflen, "%d", exception->priority);
3641  else
3642  return -1;
3643  return 0;
3644 }
const ast_string_field exten
Definition: pbx.c:1055
Structure for a data store object.
Definition: datastore.h:54
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2604
static struct ast_datastore_info exception_store_info
Definition: pbx.c:3578
const ast_string_field reason
Definition: pbx.c:1055
int priority
Definition: pbx.c:1057
void * data
Definition: datastore.h:56
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
const ast_string_field context
Definition: pbx.c:1055
static int acf_retrieve_docs ( struct ast_custom_function acf)
static

Definition at line 3901 of file pbx.c.

References ast_free, ast_module_name(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), AST_XML_DOC, ast_xmldoc_build_arguments(), ast_xmldoc_build_description(), ast_xmldoc_build_seealso(), ast_xmldoc_build_synopsis(), ast_xmldoc_build_syntax(), desc, ast_custom_function::desc, ast_custom_function::docsrc, ast_custom_function::mod, ast_custom_function::name, ast_custom_function::synopsis, and synopsis.

Referenced by __ast_custom_function_register().

3902 {
3903 #ifdef AST_XML_DOCS
3904  char *tmpxml;
3905 
3906  /* Let's try to find it in the Documentation XML */
3907  if (!ast_strlen_zero(acf->desc) || !ast_strlen_zero(acf->synopsis)) {
3908  return 0;
3909  }
3910 
3911  if (ast_string_field_init(acf, 128)) {
3912  return -1;
3913  }
3914 
3915  /* load synopsis */
3916  tmpxml = ast_xmldoc_build_synopsis("function", acf->name, ast_module_name(acf->mod));
3917  ast_string_field_set(acf, synopsis, tmpxml);
3918  ast_free(tmpxml);
3919 
3920  /* load description */
3921  tmpxml = ast_xmldoc_build_description("function", acf->name, ast_module_name(acf->mod));
3922  ast_string_field_set(acf, desc, tmpxml);
3923  ast_free(tmpxml);
3924 
3925  /* load syntax */
3926  tmpxml = ast_xmldoc_build_syntax("function", acf->name, ast_module_name(acf->mod));
3927  ast_string_field_set(acf, syntax, tmpxml);
3928  ast_free(tmpxml);
3929 
3930  /* load arguments */
3931  tmpxml = ast_xmldoc_build_arguments("function", acf->name, ast_module_name(acf->mod));
3932  ast_string_field_set(acf, arguments, tmpxml);
3933  ast_free(tmpxml);
3934 
3935  /* load seealso */
3936  tmpxml = ast_xmldoc_build_seealso("function", acf->name, ast_module_name(acf->mod));
3937  ast_string_field_set(acf, seealso, tmpxml);
3938  ast_free(tmpxml);
3939 
3940  acf->docsrc = AST_XML_DOC;
3941 #endif
3942 
3943  return 0;
3944 }
char * ast_xmldoc_build_description(const char *type, const char *name, const char *module)
Generate description documentation from XML.
Definition: xmldoc.c:1899
const ast_string_field desc
Definition: pbx.h:103
enum ast_doc_src docsrc
Definition: pbx.h:104
struct ast_module * mod
Definition: pbx.h:119
char * ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
Generate synopsis documentation from XML.
Definition: xmldoc.c:1894
char * ast_xmldoc_build_arguments(const char *type, const char *name, const char *module)
Generate the [arguments] tag based on type of node (&#39;application&#39;, &#39;function&#39; or &#39;agi&#39;) and name...
Definition: xmldoc.c:1761
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static const char desc[]
Definition: cdr_radius.c:85
static char * synopsis
Definition: func_enum.c:156
#define ast_free(a)
Definition: astmm.h:97
const ast_string_field synopsis
Definition: pbx.h:103
char * ast_xmldoc_build_syntax(const char *type, const char *name, const char *module)
Get the syntax for a specified application or function.
Definition: xmldoc.c:1156
char * ast_xmldoc_build_seealso(const char *type, const char *name, const char *module)
Parse the &lt;see-also&gt; node content.
Definition: xmldoc.c:1461
const char * ast_module_name(const struct ast_module *mod)
Get the name of a module.
Definition: loader.c:104
const char * name
Definition: pbx.h:96
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
static struct match_char * add_exten_to_pattern_tree ( struct ast_context con,
struct ast_exten e1,
int  findonly 
)
static

Definition at line 2222 of file pbx.c.

References add_pattern_node(), already_in_tree(), ARRAY_LEN, ast_copy_string(), ast_log(), pattern_node::buf, ast_exten::cidmatch, match_char::deleted, ast_exten::exten, match_char::exten, get_pattern_node(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_exten::matchcid, match_char::next_char, and ast_context::pattern_tree.

Referenced by add_priority(), ast_add_extension2_lockopt(), ast_context_remove_extension_callerid2(), and create_match_char_tree().

2223 {
2224  struct match_char *m1 = NULL;
2225  struct match_char *m2 = NULL;
2226  struct match_char **m0;
2227  const char *pos;
2228  int already;
2229  int pattern = 0;
2230  int idx_cur;
2231  int idx_next;
2232  char extenbuf[512];
2233  struct pattern_node pat_node[2];
2234 
2235  if (e1->matchcid) {
2236  if (sizeof(extenbuf) < strlen(e1->exten) + strlen(e1->cidmatch) + 2) {
2238  "The pattern %s/%s is too big to deal with: it will be ignored! Disaster!\n",
2239  e1->exten, e1->cidmatch);
2240  return NULL;
2241  }
2242  sprintf(extenbuf, "%s/%s", e1->exten, e1->cidmatch);/* Safe. We just checked. */
2243  } else {
2244  ast_copy_string(extenbuf, e1->exten, sizeof(extenbuf));
2245  }
2246 
2247 #ifdef NEED_DEBUG
2248  ast_log(LOG_DEBUG, "Adding exten %s to tree\n", extenbuf);
2249 #endif
2250  m1 = con->pattern_tree; /* each pattern starts over at the root of the pattern tree */
2251  m0 = &con->pattern_tree;
2252  already = 1;
2253 
2254  pos = extenbuf;
2255  if (*pos == '_') {
2256  pattern = 1;
2257  ++pos;
2258  }
2259  idx_cur = 0;
2260  pos = get_pattern_node(&pat_node[idx_cur], pos, pattern, extenbuf);
2261  for (; pat_node[idx_cur].buf[0]; idx_cur = idx_next) {
2262  idx_next = (idx_cur + 1) % ARRAY_LEN(pat_node);
2263  pos = get_pattern_node(&pat_node[idx_next], pos, pattern, extenbuf);
2264 
2265  /* See about adding node to tree. */
2266  m2 = NULL;
2267  if (already && (m2 = already_in_tree(m1, pat_node[idx_cur].buf, pattern))
2268  && m2->next_char) {
2269  if (!pat_node[idx_next].buf[0]) {
2270  /*
2271  * This is the end of the pattern, but not the end of the tree.
2272  * Mark this node with the exten... a shorter pattern might win
2273  * if the longer one doesn't match.
2274  */
2275  if (findonly) {
2276  return m2;
2277  }
2278  if (m2->exten) {
2279  ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n",
2280  m2->deleted ? "(deleted/invalid)" : m2->exten->exten, e1->exten);
2281  }
2282  m2->exten = e1;
2283  m2->deleted = 0;
2284  }
2285  m1 = m2->next_char; /* m1 points to the node to compare against */
2286  m0 = &m2->next_char; /* m0 points to the ptr that points to m1 */
2287  } else { /* not already OR not m2 OR nor m2->next_char */
2288  if (m2) {
2289  if (findonly) {
2290  return m2;
2291  }
2292  m1 = m2; /* while m0 stays the same */
2293  } else {
2294  if (findonly) {
2295  return m1;
2296  }
2297  m1 = add_pattern_node(con, m1, &pat_node[idx_cur], pattern, already, m0);
2298  if (!m1) { /* m1 is the node just added */
2299  return NULL;
2300  }
2301  m0 = &m1->next_char;
2302  }
2303  if (!pat_node[idx_next].buf[0]) {
2304  if (m2 && m2->exten) {
2305  ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n",
2306  m2->deleted ? "(deleted/invalid)" : m2->exten->exten, e1->exten);
2307  }
2308  m1->deleted = 0;
2309  m1->exten = e1;
2310  }
2311 
2312  /* The 'already' variable is a mini-optimization designed to make it so that we
2313  * don't have to call already_in_tree when we know it will return false.
2314  */
2315  already = 0;
2316  }
2317  }
2318  return m1;
2319 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_exten * exten
Definition: pbx.c:939
#define LOG_WARNING
Definition: logger.h:144
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)
Definition: pbx.c:2024
#define LOG_DEBUG
Definition: logger.h:122
int matchcid
Definition: pbx.c:886
static struct match_char * already_in_tree(struct match_char *current, char *pat, int is_pattern)
Definition: pbx.c:1962
char * exten
Definition: pbx.c:885
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * cidmatch
Definition: pbx.c:887
static const char * get_pattern_node(struct pattern_node *node, const char *src, int pattern, const char *extenbuf)
Definition: pbx.c:2078
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct match_char * next_char
Definition: pbx.c:938
char buf[256]
Definition: pbx.c:2021
struct match_char * pattern_tree
Definition: pbx.c:959
int deleted
Definition: pbx.c:935
match_char: forms a syntax tree for quick matching of extension patterns
Definition: pbx.c:932
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 
)
static

Definition at line 2024 of file pbx.c.

References ast_calloc, pattern_node::buf, insert_in_next_chars_alt_char_list(), match_char::is_pattern, match_char::next_char, ast_context::pattern_tree, pattern_node::specif, match_char::specificity, and match_char::x.

Referenced by add_exten_to_pattern_tree().

2025 {
2026  struct match_char *m;
2027 
2028  if (!(m = ast_calloc(1, sizeof(*m) + strlen(pattern->buf)))) {
2029  return NULL;
2030  }
2031 
2032  /* strcpy is safe here since we know its size and have allocated
2033  * just enough space for when we allocated m
2034  */
2035  strcpy(m->x, pattern->buf);
2036 
2037  /* the specificity scores are the same as used in the old
2038  pattern matcher. */
2039  m->is_pattern = is_pattern;
2040  if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'N') {
2041  m->specificity = 0x0832;
2042  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'Z') {
2043  m->specificity = 0x0931;
2044  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == 'X') {
2045  m->specificity = 0x0a30;
2046  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == '.') {
2047  m->specificity = 0x18000;
2048  } else if (pattern->specif == 1 && is_pattern && pattern->buf[0] == '!') {
2049  m->specificity = 0x28000;
2050  } else {
2051  m->specificity = pattern->specif;
2052  }
2053 
2054  if (!con->pattern_tree) {
2056  } else {
2057  if (already) { /* switch to the new regime (traversing vs appending)*/
2058  insert_in_next_chars_alt_char_list(nextcharptr, m);
2059  } else {
2061  }
2062  }
2063 
2064  return m;
2065 }
int specificity
Definition: pbx.c:936
char x[1]
Definition: pbx.c:940
int is_pattern
Definition: pbx.c:934
#define ast_calloc(a, b)
Definition: astmm.h:82
struct match_char * next_char
Definition: pbx.c:938
int specif
Definition: pbx.c:2019
char buf[256]
Definition: pbx.c:2021
struct match_char * pattern_tree
Definition: pbx.c:959
match_char: forms a syntax tree for quick matching of extension patterns
Definition: pbx.c:932
static void insert_in_next_chars_alt_char_list(struct match_char **parent_ptr, struct match_char *node)
Definition: pbx.c:1983
static int add_priority ( struct ast_context con,
struct ast_exten tmp,
struct ast_exten el,
struct ast_exten e,
int  replace 
)
static

add the extension in the priority chain.

Return values
0on success.
-1on failure.

Definition at line 8856 of file pbx.c.

References add_exten_to_pattern_tree(), ast_add_hint(), ast_change_hint(), ast_free, ast_hashtab_insert_safe(), ast_hashtab_remove_object_via_lookup(), ast_log(), ast_exten::data, ast_exten::datad, ast_exten::exten, match_char::exten, ast_exten::label, LOG_ERROR, LOG_WARNING, ast_context::name, ast_exten::next, ast_exten::peer, ast_exten::peer_label_table, ast_exten::peer_table, ast_exten::priority, PRIORITY_HINT, ast_context::root, ast_context::root_table, and match_char::x.

Referenced by ast_add_extension2_lockopt().

8858 {
8859  struct ast_exten *ep;
8860  struct ast_exten *eh=e;
8861  int repeated_label = 0; /* Track if this label is a repeat, assume no. */
8862 
8863  for (ep = NULL; e ; ep = e, e = e->peer) {
8864  if (e->label && tmp->label && e->priority != tmp->priority && !strcmp(e->label, tmp->label)) {
8865  if (strcmp(e->exten, tmp->exten)) {
8867  "Extension '%s' priority %d in '%s', label '%s' already in use at aliased extension '%s' priority %d\n",
8868  tmp->exten, tmp->priority, con->name, tmp->label, e->exten, e->priority);
8869  } else {
8871  "Extension '%s' priority %d in '%s', label '%s' already in use at priority %d\n",
8872  tmp->exten, tmp->priority, con->name, tmp->label, e->priority);
8873  }
8874  repeated_label = 1;
8875  }
8876  if (e->priority >= tmp->priority) {
8877  break;
8878  }
8879  }
8880 
8881  if (repeated_label) { /* Discard the label since it's a repeat. */
8882  tmp->label = NULL;
8883  }
8884 
8885  if (!e) { /* go at the end, and ep is surely set because the list is not empty */
8887 
8888  if (tmp->label) {
8890  }
8891  ep->peer = tmp;
8892  return 0; /* success */
8893  }
8894  if (e->priority == tmp->priority) {
8895  /* Can't have something exactly the same. Is this a
8896  replacement? If so, replace, otherwise, bonk. */
8897  if (!replace) {
8898  if (strcmp(e->exten, tmp->exten)) {
8900  "Unable to register extension '%s' priority %d in '%s', already in use by aliased extension '%s'\n",
8901  tmp->exten, tmp->priority, con->name, e->exten);
8902  } else {
8904  "Unable to register extension '%s' priority %d in '%s', already in use\n",
8905  tmp->exten, tmp->priority, con->name);
8906  }
8907  if (tmp->datad) {
8908  tmp->datad(tmp->data);
8909  /* if you free this, null it out */
8910  tmp->data = NULL;
8911  }
8912 
8913  ast_free(tmp);
8914  return -1;
8915  }
8916  /* we are replacing e, so copy the link fields and then update
8917  * whoever pointed to e to point to us
8918  */
8919  tmp->next = e->next; /* not meaningful if we are not first in the peer list */
8920  tmp->peer = e->peer; /* always meaningful */
8921  if (ep) { /* We're in the peer list, just insert ourselves */
8923 
8924  if (e->label) {
8926  }
8927 
8929  if (tmp->label) {
8931  }
8932 
8933  ep->peer = tmp;
8934  } else if (el) { /* We're the first extension. Take over e's functions */
8935  struct match_char *x = add_exten_to_pattern_tree(con, e, 1);
8936  tmp->peer_table = e->peer_table;
8937  tmp->peer_label_table = e->peer_label_table;
8940  if (e->label) {
8942  }
8943  if (tmp->label) {
8945  }
8946 
8949  el->next = tmp;
8950  /* The pattern trie points to this exten; replace the pointer,
8951  and all will be well */
8952  if (x) { /* if the trie isn't formed yet, don't sweat this */
8953  if (x->exten) { /* this test for safety purposes */
8954  x->exten = tmp; /* replace what would become a bad pointer */
8955  } else {
8956  ast_log(LOG_ERROR,"Trying to delete an exten from a context, but the pattern tree node returned isn't an extension\n");
8957  }
8958  }
8959  } else { /* We're the very first extension. */
8960  struct match_char *x = add_exten_to_pattern_tree(con, e, 1);
8963  tmp->peer_table = e->peer_table;
8964  tmp->peer_label_table = e->peer_label_table;
8967  if (e->label) {
8969  }
8970  if (tmp->label) {
8972  }
8973 
8976  con->root = tmp;
8977  /* The pattern trie points to this exten; replace the pointer,
8978  and all will be well */
8979  if (x) { /* if the trie isn't formed yet; no problem */
8980  if (x->exten) { /* this test for safety purposes */
8981  x->exten = tmp; /* replace what would become a bad pointer */
8982  } else {
8983  ast_log(LOG_ERROR,"Trying to delete an exten from a context, but the pattern tree node returned isn't an extension\n");
8984  }
8985  }
8986  }
8987  if (tmp->priority == PRIORITY_HINT)
8988  ast_change_hint(e,tmp);
8989  /* Destroy the old one */
8990  if (e->datad)
8991  e->datad(e->data);
8992  ast_free(e);
8993  } else { /* Slip ourselves in just before e */
8994  tmp->peer = e;
8995  tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */
8996  if (ep) { /* Easy enough, we're just in the peer list */
8997  if (tmp->label) {
8999  }
9001  ep->peer = tmp;
9002  } else { /* we are the first in some peer list, so link in the ext list */
9003  tmp->peer_table = e->peer_table;
9004  tmp->peer_label_table = e->peer_label_table;
9005  e->peer_table = 0;
9006  e->peer_label_table = 0;
9008  if (tmp->label) {
9010  }
9013  if (el)
9014  el->next = tmp; /* in the middle... */
9015  else
9016  con->root = tmp; /* ... or at the head */
9017  e->next = NULL; /* e is no more at the head, so e->next must be reset */
9018  }
9019  /* And immediately return success. */
9020  if (tmp->priority == PRIORITY_HINT) {
9021  ast_add_hint(tmp);
9022  }
9023  }
9024  return 0;
9025 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
static int ast_add_hint(struct ast_exten *e)
Add hint to hint list, check initial extension state.
Definition: pbx.c:5270
static int ast_change_hint(struct ast_exten *oe, struct ast_exten *ne)
Change hint for an extension.
Definition: pbx.c:5328
struct ast_exten * exten
Definition: pbx.c:939
static struct match_char * add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly)
Definition: pbx.c:2222
#define LOG_WARNING
Definition: logger.h:144
const char * label
Definition: pbx.c:889
struct ast_hashtab * peer_table
Definition: pbx.c:896
char x[1]
Definition: pbx.c:940
int priority
Definition: pbx.c:888
char * exten
Definition: pbx.c:885
struct ast_exten * peer
Definition: pbx.c:895
void(* datad)(void *)
Definition: pbx.c:894
char name[0]
Definition: pbx.c:967
#define PRIORITY_HINT
Definition: pbx.h:53
struct ast_hashtab * peer_label_table
Definition: pbx.c:897
#define LOG_ERROR
Definition: logger.h:155
void * data
Definition: pbx.c:893
void * ast_hashtab_remove_object_via_lookup(struct ast_hashtab *tab, void *obj)
Looks up the object, removes the corresponding bucket.
Definition: hashtab.c:816
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
struct ast_exten * next
Definition: pbx.c:899
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:775
int ast_hashtab_insert_safe(struct ast_hashtab *tab, const void *obj)
Check and insert new object only if it is not there.
Definition: hashtab.c:503
struct ast_hashtab * root_table
Definition: pbx.c:958
struct ast_exten * root
Definition: pbx.c:957
match_char: forms a syntax tree for quick matching of extension patterns
Definition: pbx.c:932
static struct match_char * already_in_tree ( struct match_char current,
char *  pat,
int  is_pattern 
)
static

Definition at line 1962 of file pbx.c.

References match_char::alt_char, match_char::is_pattern, and match_char::x.

Referenced by add_exten_to_pattern_tree().

1963 {
1964  struct match_char *t;
1965 
1966  if (!current) {
1967  return 0;
1968  }
1969 
1970  for (t = current; t; t = t->alt_char) {
1971  if (is_pattern == t->is_pattern && !strcmp(pat, t->x)) {/* uh, we may want to sort exploded [] contents to make matching easy */
1972  return t;
1973  }
1974  }
1975 
1976  return 0;
1977 }
struct match_char * alt_char
Definition: pbx.c:937
char x[1]
Definition: pbx.c:940
int is_pattern
Definition: pbx.c:934
match_char: forms a syntax tree for quick matching of extension patterns
Definition: pbx.c:932
int ast_active_calls ( void  )

Retrieve the number of active calls.

Definition at line 5931 of file pbx.c.

References countcalls.

Referenced by ast_var_Config(), handle_chanlist(), handle_showcalls(), and sysinfo_helper().

5932 {
5933  return countcalls;
5934 }
static int countcalls
Definition: pbx.c:1228
int ast_add_extension ( const char *  context,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar 
)

Add and extension to an extension context.

Parameters
contextcontext to add the extension to
replace
extensionextension to add
prioritypriority level of extension addition
labelextension label
calleridpattern to match CallerID, or NULL to match any CallerID
applicationapplication to run on the extension with that priority level
datadata to pass to the application
datad
registrarwho registered the extension
Return values
0success
-1failure

Definition at line 8691 of file pbx.c.

References ast_add_extension2(), ast_unlock_contexts(), and find_context_locked().

Referenced by ast_extension_state(), ast_extension_state_add_destroy(), handle_cli_dialplan_add_extension(), manage_parked_call(), park_add_hints(), park_call_full(), parkinglot_activate(), register_exten(), register_peer_exten(), and RegisterExtension().

8694 {
8695  int ret = -1;
8696  struct ast_context *c;
8697 
8699  if (c) {
8700  ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
8701  application, data, datad, registrar);
8703  }
8704 
8705  return ret;
8706 }
int ast_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add an extension to an extension context, this time with an ast_context *.
Definition: pbx.c:9052
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:5985
static char * registrar
Definition: features.c:623
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:775
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
int ast_add_extension2 ( struct ast_context con,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar 
)

Main interface to add extensions to the list for out context.

Add an extension to an extension context, this time with an ast_context *.

We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.

The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.

EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set

Definition at line 9052 of file pbx.c.

References ast_add_extension2_lockopt().

Referenced by add_extensions(), ast_add_extension(), context_merge(), load_module(), pbx_load_config(), pbx_load_users(), sla_build_station(), and sla_build_trunk().

9056 {
9057  return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid,
9058  application, data, datad, registrar, 1);
9059 }
static int ast_add_extension2_lockopt(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, int lock_context)
Same as ast_add_extension2() but controls the context locking.
Definition: pbx.c:9068
static char * registrar
Definition: features.c:623
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:775
static int ast_add_extension2_lockopt ( struct ast_context con,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar,
int  lock_context 
)
static

Same as ast_add_extension2() but controls the context locking.

Does all the work of ast_add_extension2, but adds an arg to determine if context locking should be done.

Definition at line 9068 of file pbx.c.

References add_exten_to_pattern_tree(), add_priority(), ast_exten::app, ast_add_hint(), ast_calloc, ast_channel_unref, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), AST_EXT_MATCHCID_OFF, AST_EXT_MATCHCID_ON, ast_hashtab_create(), ast_hashtab_insert_safe(), ast_hashtab_lookup(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_log(), ast_strlen_zero(), ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_exten::cidmatch, ast_channel::context, ast_exten::data, ast_sw::data, ast_exten::datad, el, errno, ext_cmp(), ext_strncpy(), ast_channel::exten, ast_exten::exten, hashtab_compare_exten_labels(), hashtab_compare_exten_numbers(), hashtab_compare_extens(), hashtab_hash_extens(), hashtab_hash_labels(), hashtab_hash_priority(), ast_exten::label, LOG_ERROR, ast_exten::matchcid, ast_context::name, ast_exten::next, option_debug, ast_exten::parent, ast_context::pattern_tree, pbx_substitute_variables_helper(), ast_exten::peer_label_table, ast_exten::peer_table, ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_sw::registrar, ast_context::root, ast_context::root_table, ast_exten::stuff, and VAR_BUF_SIZE.

Referenced by ast_add_extension2(), and ast_add_extension_nolock().

9072 {
9073  /*
9074  * Sort extensions (or patterns) according to the rules indicated above.
9075  * These are implemented by the function ext_cmp()).
9076  * All priorities for the same ext/pattern/cid are kept in a list,
9077  * using the 'peer' field as a link field..
9078  */
9079  struct ast_exten *tmp, *tmp2, *e, *el = NULL;
9080  int res;
9081  int length;
9082  char *p;
9083  char expand_buf[VAR_BUF_SIZE];
9084  struct ast_exten dummy_exten = {0};
9085  char dummy_name[1024];
9086 
9087  if (ast_strlen_zero(extension)) {
9088  ast_log(LOG_ERROR,"You have to be kidding-- add exten '' to context %s? Figure out a name and call me back. Action ignored.\n",
9089  con->name);
9090  return -1;
9091  }
9092 
9093  /* If we are adding a hint evalulate in variables and global variables */
9094  if (priority == PRIORITY_HINT && strstr(application, "${") && extension[0] != '_') {
9095  struct ast_channel *c = ast_dummy_channel_alloc();
9096 
9097  if (c) {
9098  ast_copy_string(c->exten, extension, sizeof(c->exten));
9099  ast_copy_string(c->context, con->name, sizeof(c->context));
9100  }
9101  pbx_substitute_variables_helper(c, application, expand_buf, sizeof(expand_buf));
9102  application = expand_buf;
9103  if (c) {
9104  ast_channel_unref(c);
9105  }
9106  }
9107 
9108  length = sizeof(struct ast_exten);
9109  length += strlen(extension) + 1;
9110  length += strlen(application) + 1;
9111  if (label)
9112  length += strlen(label) + 1;
9113  if (callerid)
9114  length += strlen(callerid) + 1;
9115  else
9116  length ++; /* just the '\0' */
9117 
9118  /* Be optimistic: Build the extension structure first */
9119  if (!(tmp = ast_calloc(1, length)))
9120  return -1;
9121 
9122  if (ast_strlen_zero(label)) /* let's turn empty labels to a null ptr */
9123  label = 0;
9124 
9125  /* use p as dst in assignments, as the fields are const char * */
9126  p = tmp->stuff;
9127  if (label) {
9128  tmp->label = p;
9129  strcpy(p, label);
9130  p += strlen(label) + 1;
9131  }
9132  tmp->exten = p;
9133  p += ext_strncpy(p, extension, strlen(extension) + 1) + 1;
9134  tmp->priority = priority;
9135  tmp->cidmatch = p; /* but use p for assignments below */
9136 
9137  /* Blank callerid and NULL callerid are two SEPARATE things. Do NOT confuse the two!!! */
9138  if (callerid) {
9139  p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1;
9141  } else {
9142  *p++ = '\0';
9144  }
9145  tmp->app = p;
9146  strcpy(p, application);
9147  tmp->parent = con;
9148  tmp->data = data;
9149  tmp->datad = datad;
9150  tmp->registrar = registrar;
9151 
9152  if (lock_context) {
9153  ast_wrlock_context(con);
9154  }
9155 
9156  if (con->pattern_tree) { /* usually, on initial load, the pattern_tree isn't formed until the first find_exten; so if we are adding
9157  an extension, and the trie exists, then we need to incrementally add this pattern to it. */
9158  ast_copy_string(dummy_name, extension, sizeof(dummy_name));
9159  dummy_exten.exten = dummy_name;
9160  dummy_exten.matchcid = AST_EXT_MATCHCID_OFF;
9161  dummy_exten.cidmatch = 0;
9162  tmp2 = ast_hashtab_lookup(con->root_table, &dummy_exten);
9163  if (!tmp2) {
9164  /* hmmm, not in the trie; */
9165  add_exten_to_pattern_tree(con, tmp, 0);
9166  ast_hashtab_insert_safe(con->root_table, tmp); /* for the sake of completeness */
9167  }
9168  }
9169  res = 0; /* some compilers will think it is uninitialized otherwise */
9170  for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */
9171  res = ext_cmp(e->exten, tmp->exten);
9172  if (res == 0) { /* extension match, now look at cidmatch */
9174  res = 0;
9175  else if (tmp->matchcid == AST_EXT_MATCHCID_ON && e->matchcid == AST_EXT_MATCHCID_OFF)
9176  res = 1;
9177  else if (e->matchcid == AST_EXT_MATCHCID_ON && tmp->matchcid == AST_EXT_MATCHCID_OFF)
9178  res = -1;
9179  else
9180  res = ext_cmp(e->cidmatch, tmp->cidmatch);
9181  }
9182  if (res >= 0)
9183  break;
9184  }
9185  if (e && res == 0) { /* exact match, insert in the priority chain */
9186  res = add_priority(con, tmp, el, e, replace);
9187  if (lock_context) {
9188  ast_unlock_context(con);
9189  }
9190  if (res < 0) {
9191  errno = EEXIST; /* XXX do we care ? */
9192  return 0; /* XXX should we return -1 maybe ? */
9193  }
9194  } else {
9195  /*
9196  * not an exact match, this is the first entry with this pattern,
9197  * so insert in the main list right before 'e' (if any)
9198  */
9199  tmp->next = e;
9200  if (el) { /* there is another exten already in this context */
9201  el->next = tmp;
9202  tmp->peer_table = ast_hashtab_create(13,
9207  0);
9213  0);
9214  if (label) {
9216  }
9218  } else { /* this is the first exten in this context */
9219  if (!con->root_table)
9220  con->root_table = ast_hashtab_create(27,
9225  0);
9226  con->root = tmp;
9227  con->root->peer_table = ast_hashtab_create(13,
9232  0);
9238  0);
9239  if (label) {
9241  }
9243 
9244  }
9246  if (lock_context) {
9247  ast_unlock_context(con);
9248  }
9249  if (tmp->priority == PRIORITY_HINT) {
9250  ast_add_hint(tmp);
9251  }
9252  }
9253  if (option_debug) {
9254  if (tmp->matchcid == AST_EXT_MATCHCID_ON) {
9255  ast_debug(1, "Added extension '%s' priority %d (CID match '%s') to %s (%p)\n",
9256  tmp->exten, tmp->priority, tmp->cidmatch, con->name, con);
9257  } else {
9258  ast_debug(1, "Added extension '%s' priority %d to %s (%p)\n",
9259  tmp->exten, tmp->priority, con->name, con);
9260  }
9261  }
9262 
9263  if (tmp->matchcid == AST_EXT_MATCHCID_ON) {
9264  ast_verb(3, "Added extension '%s' priority %d (CID match '%s') to %s\n",
9265  tmp->exten, tmp->priority, tmp->cidmatch, con->name);
9266  } else {
9267  ast_verb(3, "Added extension '%s' priority %d to %s\n",
9268  tmp->exten, tmp->priority, con->name);
9269  }
9270 
9271  return 0;
9272 }
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: pbx.c:4676
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
Main Channel structure associated with a channel.
Definition: channel.h:742
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
Definition: hashtab.c:534
int ast_hashtab_newsize_java(struct ast_hashtab *tab)
Create a prime number roughly 2x the current table size.
Definition: hashtab.c:131
static int ast_add_hint(struct ast_exten *e)
Add hint to hint list, check initial extension state.
Definition: pbx.c:5270
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
int option_debug
Definition: asterisk.c:182
static struct match_char * add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly)
Definition: pbx.c:2222
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
static int hashtab_compare_extens(const void *ha_a, const void *ah_b)
Definition: pbx.c:1146
static EditLine * el
Definition: asterisk.c:222
const char * label
Definition: pbx.c:889
static int hashtab_compare_exten_labels(const void *ah_a, const void *ah_b)
Definition: pbx.c:1181
static unsigned int hashtab_hash_labels(const void *obj)
Definition: pbx.c:1210
struct ast_hashtab * peer_table
Definition: pbx.c:896
#define ast_verb(level,...)
Definition: logger.h:243
int ast_hashtab_resize_java(struct ast_hashtab *tab)
Determines if a table resize should occur using the Java algorithm (if the table load factor is 75% o...
Definition: hashtab.c:88
int matchcid
Definition: pbx.c:886
char stuff[0]
Definition: pbx.c:900
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int priority
Definition: pbx.c:888
static int ext_cmp(const char *left, const char *right)
Definition: pbx.c:2691
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * exten
Definition: pbx.c:885
void(* datad)(void *)
Definition: pbx.c:894
char name[0]
Definition: pbx.c:967
struct ast_hashtab * ast_hashtab_create(int initial_buckets, int(*compare)(const void *a, const void *b), int(*resize)(struct ast_hashtab *), int(*newsize)(struct ast_hashtab *tab), unsigned int(*hash)(const void *obj), int do_locking)
Create the hashtable list.
Definition: hashtab.c:226
#define PRIORITY_HINT
Definition: pbx.h:53
struct ast_hashtab * peer_label_table
Definition: pbx.c:897
static unsigned int hashtab_hash_priority(const void *obj)
Definition: pbx.c:1204
#define LOG_ERROR
Definition: logger.h:155
void * data
Definition: pbx.c:893
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:11055
static int hashtab_compare_exten_numbers(const void *ah_a, const void *ah_b)
Definition: pbx.c:1174
int errno
static char * registrar
Definition: features.c:623
const char * registrar
Definition: pbx.c:898
struct ast_exten * next
Definition: pbx.c:899
const char * cidmatch
Definition: pbx.c:887
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:775
struct ast_context * parent
Definition: pbx.c:890
#define ast_calloc(a, b)
Definition: astmm.h:82
const char * app
Definition: pbx.c:891
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_hashtab_insert_safe(struct ast_hashtab *tab, const void *obj)
Check and insert new object only if it is not there.
Definition: hashtab.c:503
static unsigned int hashtab_hash_extens(const void *obj)
Definition: pbx.c:1194
static int add_priority(struct ast_context *con, struct ast_exten *tmp, struct ast_exten *el, struct ast_exten *e, int replace)
add the extension in the priority chain.
Definition: pbx.c:8856
struct ast_hashtab * root_table
Definition: pbx.c:958
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
static int ext_strncpy(char *dst, const char *src, int len)
copy a string skipping whitespace
Definition: pbx.c:8827
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
struct ast_exten * root
Definition: pbx.c:957
struct match_char * pattern_tree
Definition: pbx.c:959
#define VAR_BUF_SIZE
Definition: pbx.c:833
static int ast_add_extension_nolock ( const char *  context,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar 
)
static

Definition at line 8671 of file pbx.c.

References ast_add_extension2_lockopt(), and find_context().

Referenced by ast_merge_contexts_and_delete().

8674 {
8675  int ret = -1;
8676  struct ast_context *c;
8677 
8678  c = find_context(context);
8679  if (c) {
8680  ret = ast_add_extension2_lockopt(c, replace, extension, priority, label, callerid,
8681  application, data, datad, registrar, 1);
8682  }
8683 
8684  return ret;
8685 }
static int ast_add_extension2_lockopt(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, int lock_context)
Same as ast_add_extension2() but controls the context locking.
Definition: pbx.c:9068
static char * registrar
Definition: features.c:623
struct pval * find_context(char *name)
Definition: pval.c:1960
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:775
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
static int ast_add_hint ( struct ast_exten e)
static

Add hint to hint list, check initial extension state.

Definition at line 5270 of file pbx.c.

References ao2_alloc, ao2_container_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_exten::app, ast_debug, AST_DEVICE_INVALID, ast_extension_state2(), ast_get_extension_app(), ast_get_extension_name(), ast_hint::callbacks, destroy_hint(), ast_exten::exten, ast_hint::exten, hint_id_cmp(), hints, and ast_hint::laststate.

Referenced by add_priority(), and ast_add_extension2_lockopt().

5271 {
5272  struct ast_hint *hint_new;
5273  struct ast_hint *hint_found;
5274 
5275  if (!e) {
5276  return -1;
5277  }
5278 
5279  /*
5280  * We must create the hint we wish to add before determining if
5281  * it is already in the hints container to avoid possible
5282  * deadlock when getting the current extension state.
5283  */
5284  hint_new = ao2_alloc(sizeof(*hint_new), destroy_hint);
5285  if (!hint_new) {
5286  return -1;
5287  }
5288 
5289  /* Initialize new hint. */
5290  hint_new->callbacks = ao2_container_alloc(1, NULL, hint_id_cmp);
5291  if (!hint_new->callbacks) {
5292  ao2_ref(hint_new, -1);
5293  return -1;
5294  }
5295  hint_new->exten = e;
5296  if (strstr(e->app, "${") && e->exten[0] == '_') {
5297  hint_new->laststate = AST_DEVICE_INVALID;
5298  } else {
5299  hint_new->laststate = ast_extension_state2(e);
5300  }
5301 
5302  /* Prevent multiple add hints from adding the same hint at the same time. */
5303  ao2_lock(hints);
5304 
5305  /* Search if hint exists, do nothing */
5306  hint_found = ao2_find(hints, e, 0);
5307  if (hint_found) {
5308  ao2_ref(hint_found, -1);
5309  ao2_unlock(hints);
5310  ao2_ref(hint_new, -1);
5311  ast_debug(2, "HINTS: Not re-adding existing hint %s: %s\n",
5313  return -1;
5314  }
5315 
5316  /* Add new hint to the hints container */
5317  ast_debug(2, "HINTS: Adding hint %s: %s\n",
5319  ao2_link(hints, hint_new);
5320 
5321  ao2_unlock(hints);
5322  ao2_ref(hint_new, -1);
5323 
5324  return 0;
5325 }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
static int ast_extension_state2(struct ast_exten *e)
Check state of extension by using hints.
Definition: pbx.c:4889
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:11141
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
static void destroy_hint(void *obj)
Definition: pbx.c:5207
#define ao2_unlock(a)
Definition: astobj2.h:497
static struct ao2_container * hints
Definition: pbx.c:1314
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
char * exten
Definition: pbx.c:885
int laststate
Definition: pbx.c:1019
Structure for dial plan hints.
Definition: pbx.c:1010
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
const char * app
Definition: pbx.c:891
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
static int hint_id_cmp(void *obj, void *arg, int flags)
Definition: pbx.c:5191
struct ao2_container * callbacks
Definition: pbx.c:1018
int ast_async_goto ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)

Set the channel to next execute the specified dialplan location.

See Also
ast_async_parseable_goto, ast_async_goto_if_exists
Note
Do NOT hold any channel locks when calling this function.

Definition at line 8731 of file pbx.c.

References ast_channel::_state, accountcode, ast_channel::accountcode, amaflags, ast_channel::amaflags, ast_cdr_discard(), ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_strdupa, ast_channel::cdr, context, ast_channel::context, exten, ast_channel::exten, ast_channel::linkedid, LOG_WARNING, ast_channel::name, ast_sw::name, ast_channel::pbx, ast_channel::readformat, S_OR, state, and ast_channel::writeformat.

Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), dahdi_handle_dtmf(), handle_request_bye(), handle_request_refer(), my_handle_dtmf(), pbx_parseable_goto(), process_ast_dsp(), process_sdp(), sip_read(), and socket_process().

8732 {
8733  int res = 0;
8734  struct ast_channel *tmpchan;
8735  struct {
8736  char *accountcode;
8737  char *exten;
8738  char *context;
8739  char *linkedid;
8740  char *name;
8741  struct ast_cdr *cdr;
8742  int amaflags;
8743  int state;
8746  } tmpvars = { 0, };
8747 
8748  ast_channel_lock(chan);
8749  if (chan->pbx) { /* This channel is currently in the PBX */
8750  ast_explicit_goto(chan, context, exten, priority + 1);
8752  ast_channel_unlock(chan);
8753  return res;
8754  }
8755 
8756  /* In order to do it when the channel doesn't really exist within
8757  * the PBX, we have to make a new channel, masquerade, and start the PBX
8758  * at the new location */
8759  tmpvars.accountcode = ast_strdupa(chan->accountcode);
8760  tmpvars.exten = ast_strdupa(chan->exten);
8761  tmpvars.context = ast_strdupa(chan->context);
8762  tmpvars.linkedid = ast_strdupa(chan->linkedid);
8763  tmpvars.name = ast_strdupa(chan->name);
8764  tmpvars.amaflags = chan->amaflags;
8765  tmpvars.state = chan->_state;
8766  tmpvars.writeformat = chan->writeformat;
8767  tmpvars.readformat = chan->readformat;
8768  tmpvars.cdr = chan->cdr ? ast_cdr_dup(chan->cdr) : NULL;
8769 
8770  ast_channel_unlock(chan);
8771 
8772  /* Do not hold any channel locks while calling channel_alloc() since the function
8773  * locks the channel container when linking the new channel in. */
8774  if (!(tmpchan = ast_channel_alloc(0, tmpvars.state, 0, 0, tmpvars.accountcode, tmpvars.exten, tmpvars.context, tmpvars.linkedid, tmpvars.amaflags, "AsyncGoto/%s", tmpvars.name))) {
8775  ast_cdr_discard(tmpvars.cdr);
8776  return -1;
8777  }
8778 
8779  /* copy the cdr info over */
8780  if (tmpvars.cdr) {
8781  ast_cdr_discard(tmpchan->cdr);
8782  tmpchan->cdr = tmpvars.cdr;
8783  tmpvars.cdr = NULL;
8784  }
8785 
8786  /* Make formats okay */
8787  tmpchan->readformat = tmpvars.readformat;
8788  tmpchan->writeformat = tmpvars.writeformat;
8789 
8790  /* Setup proper location. Never hold another channel lock while calling this function. */
8791  ast_explicit_goto(tmpchan, S_OR(context, tmpvars.context), S_OR(exten, tmpvars.exten), priority);
8792 
8793  /* Masquerade into tmp channel */
8794  if (ast_channel_masquerade(tmpchan, chan)) {
8795  /* Failed to set up the masquerade. It's probably chan_local
8796  * in the middle of optimizing itself out. Sad. :( */
8797  ast_hangup(tmpchan);
8798  tmpchan = NULL;
8799  res = -1;
8800  } else {
8801  ast_do_masquerade(tmpchan);
8802  /* Start the PBX going on our stolen channel */
8803  if (ast_pbx_start(tmpchan)) {
8804  ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
8805  ast_hangup(tmpchan);
8806  res = -1;
8807  }
8808  }
8809 
8810  return res;
8811 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
enum sip_cc_notify_state state
Definition: chan_sip.c:842
#define ast_channel_lock(chan)
Definition: channel.h:2466
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
Weird function made for call transfers.
Definition: channel.c:6110
format_t writeformat
Definition: channel.h:854
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:5879
struct ast_cdr * ast_cdr_dup(struct ast_cdr *cdr)
Duplicate a record.
Definition: cdr.c:213
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:8708
struct ast_cdr * cdr
Definition: channel.h:766
const ast_string_field linkedid
Definition: channel.h:787
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
Definition: channel.c:9825
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
Responsible for call detail data.
Definition: cdr.h:82
int64_t format_t
Definition: frame_defs.h:32
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2733
#define ast_channel_unlock(chan)
Definition: channel.h:2467
void ast_cdr_discard(struct ast_cdr *cdr)
Discard and free a CDR record.
Definition: cdr.c:488
format_t readformat
Definition: channel.h:853
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const ast_string_field accountcode
Definition: channel.h:787
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int amaflags
Definition: channel.h:843
int ast_do_masquerade(struct ast_channel *chan)
Start masquerading a channel.
Definition: channel.c:6546
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
struct ast_pbx * pbx
Definition: channel.h:761
int ast_async_goto_by_name ( const char *  channame,
const char *  context,
const char *  exten,
int  priority 
)

Set the channel to next execute the specified dialplan location.

Definition at line 8813 of file pbx.c.

References ast_async_goto(), ast_channel_get_by_name(), and ast_channel_unref.

8814 {
8815  struct ast_channel *chan;
8816  int res = -1;
8817 
8818  if ((chan = ast_channel_get_by_name(channame))) {
8819  res = ast_async_goto(chan, context, exten, priority);
8820  chan = ast_channel_unref(chan);
8821  }
8822 
8823  return res;
8824 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
int priority
Definition: channel.h:841
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:8731
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
int ast_async_goto_if_exists ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)
Note
This function will handle locking the channel as needed.

Definition at line 11266 of file pbx.c.

References __ast_goto_if_exists().

11267 {
11268  return __ast_goto_if_exists(chan, context, exten, priority, 1);
11269 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static int __ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, int async)
Definition: pbx.c:11240
int priority
Definition: channel.h:841
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_async_parseable_goto ( struct ast_channel chan,
const char *  goto_string 
)
Note
This function will handle locking the channel as needed.

Definition at line 11331 of file pbx.c.

References pbx_parseable_goto().

Referenced by asyncgoto_exec(), and handle_redirect().

11332 {
11333  return pbx_parseable_goto(chan, goto_string, 1);
11334 }
static int pbx_parseable_goto(struct ast_channel *chan, const char *goto_string, int async)
Definition: pbx.c:11271
int ast_build_timing ( struct ast_timing i,
const char *  info 
)

Construct a timing bitmap, for use in time-based conditionals.

Parameters
iPointer to an ast_timing structure.
infoStandard string containing a timerange, weekday range, monthday range, and month range, as well as an optional timezone.
Return values
Returns1 on success or 0 on failure.

Definition at line 8314 of file pbx.c.

References ast_strdup, ast_strdupa, ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, months, strsep(), and ast_timing::timezone.

Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().

8315 {
8316  char *info;
8317  int j, num_fields, last_sep = -1;
8318 
8319  i->timezone = NULL;
8320 
8321  /* Check for empty just in case */
8322  if (ast_strlen_zero(info_in)) {
8323  return 0;
8324  }
8325 
8326  /* make a copy just in case we were passed a static string */
8327  info = ast_strdupa(info_in);
8328 
8329  /* count the number of fields in the timespec */
8330  for (j = 0, num_fields = 1; info[j] != '\0'; j++) {
8331  if (info[j] == ',') {
8332  last_sep = j;
8333  num_fields++;
8334  }
8335  }
8336 
8337  /* save the timezone, if it is specified */
8338  if (num_fields == 5) {
8339  i->timezone = ast_strdup(info + last_sep + 1);
8340  }
8341 
8342  /* Assume everything except time */
8343  i->monthmask = 0xfff; /* 12 bits */
8344  i->daymask = 0x7fffffffU; /* 31 bits */
8345  i->dowmask = 0x7f; /* 7 bits */
8346  /* on each call, use strsep() to move info to the next argument */
8347  get_timerange(i, strsep(&info, "|,"));
8348  if (info)
8349  i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
8350  if (info)
8351  i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
8352  if (info)
8353  i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
8354  return 1;
8355 }
unsigned int daymask
Definition: pbx.h:142
char * strsep(char **str, const char *delims)
#define ast_strdup(a)
Definition: astmm.h:109
unsigned int monthmask
Definition: pbx.h:141
char * timezone
Definition: pbx.h:145
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static const char *const months[]
Definition: pbx.c:8297
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
unsigned int dowmask
Definition: pbx.h:143
static const char *const days[]
Definition: pbx.c:8285
static unsigned get_range(char *src, int max, const char *const names[], const char *msg)
helper function to return a range up to max (7, 12, 31 respectively). names, if supplied, is an array of names that should be mapped to numbers.
Definition: pbx.c:8182
static void get_timerange(struct ast_timing *i, char *times)
store a bitmask of valid times, one bit each 1 minute
Definition: pbx.c:8225
int ast_canmatch_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid 
)

Looks for a valid matching extension.

Parameters
cnot really important
contextcontext to serach within
extenextension to check
prioritypriority of extension path
calleridcallerid of extension being searched for
Note
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns
If "exten" could be a valid extension in this context with or without some more digits, return non-zero. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 5415 of file pbx.c.

References E_CANMATCH, and pbx_extension_helper().

Referenced by __analog_ss_thread(), analog_ss_thread(), background_detect_exec(), cb_events(), do_immediate_setup(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), leave_voicemail(), loopback_canmatch(), mgcp_ss(), pbx_builtin_background(), phone_check_exception(), pri_dchannel(), skinny_ss(), and valid_exit().

5416 {
5417  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
5418 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
int priority
Definition: channel.h:841
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
The return value depends on the action:
Definition: pbx.c:4706
static int ast_change_hint ( struct ast_exten oe,
struct ast_exten ne 
)
static

Change hint for an extension.

Definition at line 5328 of file pbx.c.

References ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_hint::exten, hints, and OBJ_UNLINK.

Referenced by add_priority().

5329 {
5330  struct ast_hint *hint;
5331 
5332  if (!oe || !ne) {
5333  return -1;
5334  }
5335 
5336  ao2_lock(hints);/* Locked to hold off others while we move the hint around. */
5337 
5338  /*
5339  * Unlink the hint from the hints container as the extension
5340  * name (which is the hash value) could change.
5341  */
5342  hint = ao2_find(hints, oe, OBJ_UNLINK);
5343  if (!hint) {
5344  ao2_unlock(hints);
5345  return -1;
5346  }
5347 
5348  /* Update the hint and put it back in the hints container. */
5349  ao2_lock(hint);
5350  hint->exten = ne;
5351  ao2_unlock(hint);
5352  ao2_link(hints, hint);
5353 
5354  ao2_unlock(hints);
5355  ao2_ref(hint, -1);
5356 
5357  return 0;
5358 }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
#define ao2_unlock(a)
Definition: astobj2.h:497
static struct ao2_container * hints
Definition: pbx.c:1314
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
Structure for dial plan hints.
Definition: pbx.c:1010
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
int ast_check_timing ( const struct ast_timing i)

Evaluate a pre-constructed bitmap as to whether the current time falls within the range specified.

Parameters
iPointer to an ast_timing structure.
Return values
Returns1, if the time matches or 0, if the current time falls outside of the specified range.

Definition at line 8357 of file pbx.c.

References ast_check_timing2(), and ast_tvnow().

Referenced by iftime(), include_valid(), and pbx_builtin_execiftime().

8358 {
8359  return ast_check_timing2(i, ast_tvnow());
8360 }
int ast_check_timing2(const struct ast_timing *i, const struct timeval tv)
Evaluate a pre-constructed bitmap as to whether a particular time falls within the range specified...
Definition: pbx.c:8362
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int ast_check_timing2 ( const struct ast_timing i,
const struct timeval  tv 
)

Evaluate a pre-constructed bitmap as to whether a particular time falls within the range specified.

Parameters
iPointer to an ast_timing structure.
tvSpecified time
Return values
Returns1, if the time matches or 0, if the time falls outside of the specified range.

Definition at line 8362 of file pbx.c.

References ast_localtime(), ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, ast_timing::timezone, ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, and ast_tm::tm_wday.

Referenced by ast_check_timing(), and pbx_builtin_gotoiftime().

8363 {
8364  struct ast_tm tm;
8365 
8366  ast_localtime(&tv, &tm, i->timezone);
8367 
8368  /* If it's not the right month, return */
8369  if (!(i->monthmask & (1 << tm.tm_mon)))
8370  return 0;
8371 
8372  /* If it's not that time of the month.... */
8373  /* Warning, tm_mday has range 1..31! */
8374  if (!(i->daymask & (1 << (tm.tm_mday-1))))
8375  return 0;
8376 
8377  /* If it's not the right day of the week */
8378  if (!(i->dowmask & (1 << tm.tm_wday)))
8379  return 0;
8380 
8381  /* Sanity check the hour just to be safe */
8382  if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
8383  ast_log(LOG_WARNING, "Insane time...\n");
8384  return 0;
8385  }
8386 
8387  /* Now the tough part, we calculate if it fits
8388  in the right time based on min/hour */
8389  if (!(i->minmask[tm.tm_hour * 2 + (tm.tm_min >= 30 ? 1 : 0)] & (1 << (tm.tm_min >= 30 ? tm.tm_min - 30 : tm.tm_min))))
8390  return 0;
8391 
8392  /* If we got this far, then we're good */
8393  return 1;
8394 }
unsigned int daymask
Definition: pbx.h:142
#define LOG_WARNING
Definition: logger.h:144
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
unsigned int monthmask
Definition: pbx.h:141
char * timezone
Definition: pbx.h:145
unsigned int dowmask
Definition: pbx.h:143
unsigned int minmask[48]
Definition: pbx.h:144
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct timeval tv
char* ast_complete_applications ( const char *  line,
const char *  word,
int  state 
)

Command completion for the list of installed applications.

This can be called from a CLI command completion function that wants to complete from the list of available applications.

Definition at line 11336 of file pbx.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and ast_strdup.

Referenced by handle_orig(), and handle_show_application().

11337 {
11338  struct ast_app *app = NULL;
11339  int which = 0;
11340  char *ret = NULL;
11341  size_t wordlen = strlen(word);
11342 
11344  AST_RWLIST_TRAVERSE(&apps, app, list) {
11345  if (!strncasecmp(word, app->name, wordlen) && ++which > state) {
11346  ret = ast_strdup(app->name);
11347  break;
11348  }
11349  }
11351 
11352  return ret;
11353 }
#define ast_strdup(a)
Definition: astmm.h:109
Definition: pbx.c:1301
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: ael.tab.c:203
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static const char app[]
Definition: app_adsiprog.c:49
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
ast_app: A registered application
Definition: pbx.c:971
int ast_context_add_ignorepat ( const char *  context,
const char *  ignorepat,
const char *  registrar 
)

Add an ignorepat.

Parameters
contextwhich context to add the ignorpattern to
ignorepatignorepattern to set up for the extension
registrarregistrar of the ignore pattern

Adds an ignore pattern to a particular context.

Return values
0on success
-1on failure

Definition at line 8598 of file pbx.c.

References ast_context_add_ignorepat2(), ast_unlock_contexts(), and find_context_locked().

Referenced by handle_cli_dialplan_add_ignorepat().

8599 {
8600  int ret = -1;
8601  struct ast_context *c;
8602 
8604  if (c) {
8607  }
8608  return ret;
8609 }
int value
Definition: syslog.c:39
int ast_context_add_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
Definition: pbx.c:8611
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:5985
static char * registrar
Definition: features.c:623
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
int ast_context_add_ignorepat2 ( struct ast_context con,
const char *  value,
const char *  registrar 
)

Definition at line 8611 of file pbx.c.

References ast_calloc, ast_free, ast_unlock_context(), ast_wrlock_context(), errno, ast_context::ignorepats, ast_ignorepat::next, ast_ignorepat::pattern, ast_sw::registrar, and ast_ignorepat::registrar.

Referenced by ast_compile_ael2(), ast_context_add_ignorepat(), context_merge_incls_swits_igps_other_registrars(), and pbx_load_config().

8612 {
8613  struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
8614  int length;
8615  char *pattern;
8616  length = sizeof(struct ast_ignorepat);
8617  length += strlen(value) + 1;
8618  if (!(ignorepat = ast_calloc(1, length)))
8619  return -1;
8620  /* The cast to char * is because we need to write the initial value.
8621  * The field is not supposed to be modified otherwise. Also, gcc 4.2
8622  * sees the cast as dereferencing a type-punned pointer and warns about
8623  * it. This is the workaround (we're telling gcc, yes, that's really
8624  * what we wanted to do).
8625  */
8626  pattern = (char *) ignorepat->pattern;
8627  strcpy(pattern, value);
8628  ignorepat->next = NULL;
8629  ignorepat->registrar = registrar;
8630  ast_wrlock_context(con);
8631  for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
8632  ignorepatl = ignorepatc;
8633  if (!strcasecmp(ignorepatc->pattern, value)) {
8634  /* Already there */
8635  ast_unlock_context(con);
8636  ast_free(ignorepat);
8637  errno = EEXIST;
8638  return -1;
8639  }
8640  }
8641  if (ignorepatl)
8642  ignorepatl->next = ignorepat;
8643  else
8644  con->ignorepats = ignorepat;
8645  ast_unlock_context(con);
8646  return 0;
8647 
8648 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
struct ast_ignorepat * ignorepats
Definition: pbx.c:962
const char * registrar
Definition: pbx.c:926
const char pattern[0]
Definition: pbx.c:928
int value
Definition: syslog.c:39
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx.c:925
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:11055
int errno
#define ast_free(a)
Definition: astmm.h:97
static char * registrar
Definition: features.c:623
#define ast_calloc(a, b)
Definition: astmm.h:82
struct ast_ignorepat * next
Definition: pbx.c:927
int ast_context_add_include ( const char *  context,
const char *  include,
const char *  registrar 
)

Add a context include.

Parameters
contextcontext to add include to
includenew include to add
registrarwho's registering it

Adds an include taking a char * string as the context parameter

Return values
0on success
-1on error

Definition at line 8142 of file pbx.c.

References ast_context_add_include2(), ast_unlock_contexts(), and find_context_locked().

Referenced by handle_cli_dialplan_add_include().

8143 {
8144  int ret = -1;
8145  struct ast_context *c;
8146 
8148  if (c) {
8149  ret = ast_context_add_include2(c, include, registrar);
8151  }
8152  return ret;
8153 }
int ast_context_add_include2(struct ast_context *con, const char *include, const char *registrar)
Add a context include.
Definition: pbx.c:8411
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:5985
static char * registrar
Definition: features.c:623
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
int ast_context_add_include2 ( struct ast_context con,
const char *  include,
const char *  registrar 
)

Add a context include.

Parameters
concontext to add the include to
includeinclude to add
registrarwho registered the context

Adds an include taking a struct ast_context as the first parameter

Return values
0on success
-1on failure

Definition at line 8411 of file pbx.c.

References ast_build_timing(), ast_calloc, ast_destroy_timing(), ast_free, ast_get_context_name(), ast_unlock_context(), ast_verb, ast_wrlock_context(), errno, ast_include::hastime, ast_context::includes, ast_include::name, ast_include::next, ast_include::registrar, ast_sw::registrar, ast_include::rname, ast_include::stuff, and ast_include::timing.

Referenced by ast_compile_ael2(), ast_context_add_include(), context_merge_incls_swits_igps_other_registrars(), and pbx_load_config().

8413 {
8414  struct ast_include *new_include;
8415  char *c;
8416  struct ast_include *i, *il = NULL; /* include, include_last */
8417  int length;
8418  char *p;
8419 
8420  length = sizeof(struct ast_include);
8421  length += 2 * (strlen(value) + 1);
8422 
8423  /* allocate new include structure ... */
8424  if (!(new_include = ast_calloc(1, length)))
8425  return -1;
8426  /* Fill in this structure. Use 'p' for assignments, as the fields
8427  * in the structure are 'const char *'
8428  */
8429  p = new_include->stuff;
8430  new_include->name = p;
8431  strcpy(p, value);
8432  p += strlen(value) + 1;
8433  new_include->rname = p;
8434  strcpy(p, value);
8435  /* Strip off timing info, and process if it is there */
8436  if ( (c = strchr(p, ',')) ) {
8437  *c++ = '\0';
8438  new_include->hastime = ast_build_timing(&(new_include->timing), c);
8439  }
8440  new_include->next = NULL;
8441  new_include->registrar = registrar;
8442 
8443  ast_wrlock_context(con);
8444 
8445  /* ... go to last include and check if context is already included too... */
8446  for (i = con->includes; i; i = i->next) {
8447  if (!strcasecmp(i->name, new_include->name)) {
8448  ast_destroy_timing(&(new_include->timing));
8449  ast_free(new_include);
8450  ast_unlock_context(con);
8451  errno = EEXIST;
8452  return -1;
8453  }
8454  il = i;
8455  }
8456 
8457  /* ... include new context into context list, unlock, return */
8458  if (il)
8459  il->next = new_include;
8460  else
8461  con->includes = new_include;
8462  ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
8463 
8464  ast_unlock_context(con);
8465 
8466  return 0;
8467 }
ast_include: include= support in extensions.conf
Definition: pbx.c:904
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
int hastime
Definition: pbx.c:908
struct ast_include * next
Definition: pbx.c:910
struct ast_include * includes
Definition: pbx.c:961
const char * rname
Definition: pbx.c:906
int value
Definition: syslog.c:39
struct ast_timing timing
Definition: pbx.c:909
#define ast_verb(level,...)
Definition: logger.h:243
const char * registrar
Definition: pbx.c:907
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
char stuff[0]
Definition: pbx.c:911
const char * name
Definition: pbx.c:905
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:11055
int ast_destroy_timing(struct ast_timing *i)
Deallocates memory structures associated with a timing bitmap.
Definition: pbx.c:8396
int errno
#define ast_free(a)
Definition: astmm.h:97
static char * registrar
Definition: features.c:623
int ast_build_timing(struct ast_timing *i, const char *info)
Construct a timing bitmap, for use in time-based conditionals.
Definition: pbx.c:8314
#define ast_calloc(a, b)
Definition: astmm.h:82
int ast_context_add_switch ( const char *  context,
const char *  sw,
const char *  data,
int  eval,
const char *  registrar 
)

Add a switch.

Parameters
contextcontext to which to add the switch
swswitch to add
datadata to pass to switch
evalwhether to evaluate variables when running switch
registrarwhoever registered the switch

This function registers a switch with the asterisk switch architecture

Return values
0on success
-1on failure

Definition at line 8474 of file pbx.c.

References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().

8475 {
8476  int ret = -1;
8477  struct ast_context *c;
8478 
8480  if (c) { /* found, add switch to this context */
8481  ret = ast_context_add_switch2(c, sw, data, eval, registrar);
8483  }
8484  return ret;
8485 }
int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
Adds a switch (first param is a ast_context)
Definition: pbx.c:8494
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:5985
static char * registrar
Definition: features.c:623
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
int ast_context_add_switch2 ( struct ast_context con,
const char *  sw,
const char *  data,
int  eval,
const char *  registrar 
)

Adds a switch (first param is a ast_context)

Note
See ast_context_add_switch() for argument information, with the exception of the first argument. In this case, it's a pointer to an ast_context structure as opposed to the name.

Definition at line 8494 of file pbx.c.

References ast_context::alts, ast_calloc, ast_free, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_sw::data, errno, ast_sw::eval, ast_sw::name, ast_sw::registrar, and ast_sw::stuff.

Referenced by ast_compile_ael2(), ast_context_add_switch(), context_merge_incls_swits_igps_other_registrars(), lua_register_switches(), and pbx_load_config().

8496 {
8497  struct ast_sw *new_sw;
8498  struct ast_sw *i;
8499  int length;
8500  char *p;
8501 
8502  length = sizeof(struct ast_sw);
8503  length += strlen(value) + 1;
8504  if (data)
8505  length += strlen(data);
8506  length++;
8507 
8508  /* allocate new sw structure ... */
8509  if (!(new_sw = ast_calloc(1, length)))
8510  return -1;
8511  /* ... fill in this structure ... */
8512  p = new_sw->stuff;
8513  new_sw->name = p;
8514  strcpy(new_sw->name, value);
8515  p += strlen(value) + 1;
8516  new_sw->data = p;
8517  if (data) {
8518  strcpy(new_sw->data, data);
8519  p += strlen(data) + 1;
8520  } else {
8521  strcpy(new_sw->data, "");
8522  p++;
8523  }
8524  new_sw->eval = eval;
8525  new_sw->registrar = registrar;
8526 
8527  /* ... try to lock this context ... */
8528  ast_wrlock_context(con);
8529 
8530  /* ... go to last sw and check if context is already swd too... */
8531  AST_LIST_TRAVERSE(&con->alts, i, list) {
8532  if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
8533  ast_free(new_sw);
8534  ast_unlock_context(con);
8535  errno = EEXIST;
8536  return -1;
8537  }
8538  }
8539 
8540  /* ... sw new context into context list, unlock, return */
8541  AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
8542 
8543  ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
8544 
8545  ast_unlock_context(con);
8546 
8547  return 0;
8548 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
int value
Definition: syslog.c:39
#define ast_verb(level,...)
Definition: logger.h:243
ast_sw: Switch statement in extensions.conf
Definition: pbx.c:915
char stuff[0]
Definition: pbx.c:921
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
int eval
Definition: pbx.c:919
char * data
Definition: pbx.c:918
struct ast_sw::@289 list
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:11055
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
int errno
#define ast_free(a)
Definition: astmm.h:97
static char * registrar
Definition: features.c:623
#define ast_calloc(a, b)
Definition: astmm.h:82
struct ast_context::@290 alts
const char * registrar
Definition: pbx.c:917
char * name
Definition: pbx.c:916
void ast_context_destroy ( struct ast_context con,
const char *  registrar 
)

Destroy a context (matches the specified context (or ANY context if NULL)

Parameters
concontext to destroy
registrarwho registered it

You can optionally leave out either parameter. It will find it based on either the ast_context or the registrar name.

Returns
nothing

Definition at line 9875 of file pbx.c.

References __ast_context_destroy(), ast_unlock_contexts(), ast_wrlock_contexts(), contexts, and contexts_table.

Referenced by __unload_module(), ast_features_reload(), cleanup_stale_contexts(), features_shutdown(), remove_dead_dialplan_useage(), sla_destroy(), and unload_module().

9876 {
9880 }
void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *contexttab, struct ast_context *con, const char *registrar)
Definition: pbx.c:9718
static struct ast_hashtab * contexts_table
Definition: pbx.c:1286
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:11037
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static char * registrar
Definition: features.c:623
static struct ast_context * contexts
Definition: pbx.c:1285
struct ast_context* ast_context_find ( const char *  name)

Find a context.

Parameters
namename of the context to find

Will search for the context with the given name.

Returns
the ast_context on success, NULL on failure.

Definition at line 2971 of file pbx.c.

References ast_copy_string(), ast_hashtab_lookup(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::name, and fake_context::name.

Referenced by __unload_module(), _macro_exec(), ast_context_verify_includes(), ast_features_reload(), ast_ignore_pattern(), cleanup_stale_contexts(), isexten_function_read(), manage_parkinglot(), parked_call_exec(), register_exten(), register_peer_exten(), remove_dead_dialplan_useage(), unload_module(), and unregister_exten().

2972 {
2973  struct ast_context *tmp;
2974  struct fake_context item;
2975 
2976  if (!name) {
2977  return NULL;
2978  }
2980  if (contexts_table) {
2981  ast_copy_string(item.name, name, sizeof(item.name));
2982  tmp = ast_hashtab_lookup(contexts_table, &item);
2983  } else {
2984  tmp = NULL;
2985  while ((tmp = ast_walk_contexts(tmp))) {
2986  if (!strcasecmp(name, tmp->name)) {
2987  break;
2988  }
2989  }
2990  }
2992  return tmp;
2993 }
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
Definition: hashtab.c:534
static struct ast_hashtab * contexts_table
Definition: pbx.c:1286
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:11042
char name[0]
Definition: pbx.c:967
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: pbx.c:11174
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static const char name[]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
ast_context: An extension context
Definition: pbx.c:955
struct ast_context* ast_context_find_or_create ( struct ast_context **  extcontexts,
struct ast_hashtab exttable,
const char *  name,
const char *  registrar 
)

Register a new context or find an existing one.

Parameters
extcontextspointer to the ast_context structure pointer
exttablepointer to the hashtable that contains all the elements in extcontexts
namename of the new context
registrarregistrar of the context

This function allows you to play in two environments: the global contexts (active dialplan) or an external context set of your choosing. To act on the external set, make sure extcontexts and exttable are set; for the globals, make sure both extcontexts and exttable are NULL.

This will first search for a context with your name. If it exists already, it will not create a new one. If it does not exist, it will create a new one with the given name and registrar.

Returns
NULL on failure, and an ast_context structure on success

Definition at line 7726 of file pbx.c.

References ast_calloc, ast_copy_string(), ast_debug, ast_hashtab_compare_contexts(), ast_hashtab_create(), ast_hashtab_hash_contexts(), ast_hashtab_insert_immediate(), ast_hashtab_insert_safe(), ast_hashtab_lookup(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_log(), ast_mutex_init, ast_rdlock_contexts(), ast_rwlock_init, ast_strdup, ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), contexts, contexts_table, ast_context::ignorepats, ast_context::includes, local_contexts, ast_context::lock, LOG_ERROR, ast_context::macrolock, ast_context::name, fake_context::name, ast_context::next, ast_context::refcount, ast_context::registrar, ast_context::root, and ast_context::root_table.

Referenced by ast_compile_ael2(), config_parse_variables(), context_merge(), load_module(), lua_register_switches(), manage_parked_call(), parkinglot_activate(), pbx_load_config(), pbx_load_users(), reload_config(), set_config(), sla_build_station(), and sla_build_trunk().

7727 {
7728  struct ast_context *tmp, **local_contexts;
7729  struct fake_context search;
7730  int length = sizeof(struct ast_context) + strlen(name) + 1;
7731 
7732  if (!contexts_table) {
7733  /* Protect creation of contexts_table from reentrancy. */
7735  if (!contexts_table) {
7741  0);
7742  }
7744  }
7745 
7746  ast_copy_string(search.name, name, sizeof(search.name));
7747  if (!extcontexts) {
7749  local_contexts = &contexts;
7750  tmp = ast_hashtab_lookup(contexts_table, &search);
7752  if (tmp) {
7753  tmp->refcount++;
7754  return tmp;
7755  }
7756  } else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */
7757  local_contexts = extcontexts;
7758  tmp = ast_hashtab_lookup(exttable, &search);
7759  if (tmp) {
7760  tmp->refcount++;
7761  return tmp;
7762  }
7763  }
7764 
7765  if ((tmp = ast_calloc(1, length))) {
7766  ast_rwlock_init(&tmp->lock);
7767  ast_mutex_init(&tmp->macrolock);
7768  strcpy(tmp->name, name);
7769  tmp->root = NULL;
7770  tmp->root_table = NULL;
7771  tmp->registrar = ast_strdup(registrar);
7772  tmp->includes = NULL;
7773  tmp->ignorepats = NULL;
7774  tmp->refcount = 1;
7775  } else {
7776  ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
7777  return NULL;
7778  }
7779 
7780  if (!extcontexts) {
7782  tmp->next = *local_contexts;
7783  *local_contexts = tmp;
7784  ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */
7786  ast_debug(1, "Registered context '%s'(%p) in table %p registrar: %s\n", tmp->name, tmp, contexts_table, registrar);
7787  ast_verb(3, "Registered extension context '%s'; registrar: %s\n", tmp->name, registrar);
7788  } else {
7789  tmp->next = *local_contexts;
7790  if (exttable)
7791  ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */
7792 
7793  *local_contexts = tmp;
7794  ast_debug(1, "Registered context '%s'(%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar);
7795  ast_verb(3, "Registered extension context '%s'; registrar: %s\n", tmp->name, registrar);
7796  }
7797  return tmp;
7798 }
int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
hashtable functions for contexts
Definition: pbx.c:1136
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
Definition: hashtab.c:534
int ast_hashtab_newsize_java(struct ast_hashtab *tab)
Create a prime number roughly 2x the current table size.
Definition: hashtab.c:131
struct ast_include * includes
Definition: pbx.c:961
#define ast_strdup(a)
Definition: astmm.h:109
static struct ast_hashtab * contexts_table
Definition: pbx.c:1286
struct ast_ignorepat * ignorepats
Definition: pbx.c:962
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:11042
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:11037
#define ast_verb(level,...)
Definition: logger.h:243
int ast_hashtab_resize_java(struct ast_hashtab *tab)
Determines if a table resize should occur using the Java algorithm (if the table load factor is 75% o...
Definition: hashtab.c:88
ast_mutex_t macrolock
Definition: pbx.c:966
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_hashtab_insert_immediate(struct ast_hashtab *tab, const void *obj)
Insert without checking.
Definition: hashtab.c:432
char * registrar
Definition: pbx.c:963
char name[0]
Definition: pbx.c:967
struct ast_hashtab * ast_hashtab_create(int initial_buckets, int(*compare)(const void *a, const void *b), int(*resize)(struct ast_hashtab *), int(*newsize)(struct ast_hashtab *tab), unsigned int(*hash)(const void *obj), int do_locking)
Create the hashtable list.
Definition: hashtab.c:226
ast_rwlock_t lock
Definition: pbx.c:956
#define LOG_ERROR
Definition: logger.h:155
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
Definition: lock.h:190
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_context * next
Definition: pbx.c:960
static const char name[]
unsigned int ast_hashtab_hash_contexts(const void *obj)
Definition: pbx.c:1188
static char * registrar
Definition: features.c:623
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_hashtab_insert_safe(struct ast_hashtab *tab, const void *obj)
Check and insert new object only if it is not there.
Definition: hashtab.c:503
static struct ast_context * local_contexts
Definition: pbx_config.c:60
int refcount
Definition: pbx.c:964
struct ast_hashtab * root_table
Definition: pbx.c:958
static struct ast_context * contexts
Definition: pbx.c:1285
#define ast_mutex_init(pmutex)
Definition: lock.h:152
ast_context: An extension context
Definition: pbx.c:955
struct ast_exten * root
Definition: pbx.c:957
int ast_context_lockmacro ( const char *  context)

locks the macrolock in the given given context

Note
This function locks contexts list by &conlist, searches for the right context structure, and locks the macrolock mutex in that context. macrolock is used to limit a macro to be executed by one call at a time.

Definition at line 6306 of file pbx.c.

References ast_mutex_lock, ast_unlock_contexts(), find_context_locked(), and ast_context::macrolock.

Referenced by _macro_exec().

6307 {
6308  struct ast_context *c;
6309  int ret = -1;
6310 
6312  if (c) {
6314 
6315  /* if we found context, lock macrolock */
6316  ret = ast_mutex_lock(&c->macrolock);
6317  }
6318 
6319  return ret;
6320 }
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t macrolock
Definition: pbx.c:966
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:5985
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
int ast_context_remove_extension ( const char *  context,
const char *  extension,
int  priority,
const char *  registrar 
)

Simply remove extension from context.

Note
This function will lock conlock.

Definition at line 6114 of file pbx.c.

References ast_context_remove_extension_callerid(), and AST_EXT_MATCHCID_ANY.

Referenced by register_peer_exten(), remove_exten_if_exist(), sla_station_destructor(), sla_trunk_destructor(), unregister_exten(), and UnregisterExtension().

6115 {
6117 }
int ast_context_remove_extension_callerid(const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar)
Definition: pbx.c:6119
static char * registrar
Definition: features.c:623
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_context_remove_extension2 ( struct ast_context con,
const char *  extension,
int  priority,
const char *  registrar,
int  already_locked 
)

This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return.

Note
When do you want to call this function, make sure that &conlock is locked, because some process can handle with your *con context before you lock it.

Definition at line 6144 of file pbx.c.

References ast_context_remove_extension_callerid2(), and AST_EXT_MATCHCID_ANY.

Referenced by manage_parkinglot(), parked_call_exec(), and unload_module().

6145 {
6146  return ast_context_remove_extension_callerid2(con, extension, priority, NULL, AST_EXT_MATCHCID_ANY, registrar, already_locked);
6147 }
int ast_context_remove_extension_callerid2(struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar, int already_locked)
Definition: pbx.c:6149
static char * registrar
Definition: features.c:623
int ast_context_remove_extension_callerid ( const char *  context,
const char *  extension,
int  priority,
const char *  callerid,
int  matchcallerid,
const char *  registrar 
)

Definition at line 6119 of file pbx.c.

References ast_context_remove_extension_callerid2(), ast_unlock_contexts(), and find_context_locked().

Referenced by ast_context_remove_extension(), and handle_cli_dialplan_remove_extension().

6120 {
6121  int ret = -1; /* default error return */
6122  struct ast_context *c;
6123 
6125  if (c) { /* ... remove extension ... */
6126  ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid,
6127  matchcallerid, registrar, 0);
6129  }
6130 
6131  return ret;
6132 }
int ast_context_remove_extension_callerid2(struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar, int already_locked)
Definition: pbx.c:6149
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:5985
static char * registrar
Definition: features.c:623
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
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 
)

Definition at line 6149 of file pbx.c.

References add_exten_to_pattern_tree(), ast_copy_string(), ast_hashtab_insert_immediate(), ast_hashtab_lookup(), ast_hashtab_remove_this_object(), ast_hashtab_size(), ast_log(), ast_strlen_zero(), ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_exten::cidmatch, match_char::deleted, destroy_exten(), exten, ast_exten::exten, match_char::exten, ast_exten::label, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_exten::matchcid, ast_context::name, ast_exten::next, ast_context::pattern_tree, ast_exten::peer, ast_exten::peer_label_table, ast_exten::peer_table, ast_exten::priority, ast_exten::registrar, ast_context::root, ast_context::root_table, and match_char::x.

Referenced by __ast_context_destroy(), ast_context_remove_extension2(), and ast_context_remove_extension_callerid().

6150 {
6151  struct ast_exten *exten, *prev_exten = NULL;
6152  struct ast_exten *peer;
6153  struct ast_exten ex, *exten2, *exten3;
6154  char dummy_name[1024];
6155  struct ast_exten *previous_peer = NULL;
6156  struct ast_exten *next_peer = NULL;
6157  int found = 0;
6158 
6159  if (!already_locked)
6160  ast_wrlock_context(con);
6161 
6162 #ifdef NEED_DEBUG
6163  ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcallerid ? "/" : "", matchcallerid ? callerid : "", registrar);
6164 #endif
6165 #ifdef CONTEXT_DEBUG
6166  check_contexts(__FILE__, __LINE__);
6167 #endif
6168  /* find this particular extension */
6169  ex.exten = dummy_name;
6170  ex.matchcid = matchcallerid;
6171  ex.cidmatch = callerid;
6172  ast_copy_string(dummy_name, extension, sizeof(dummy_name));
6173  exten = ast_hashtab_lookup(con->root_table, &ex);
6174  if (exten) {
6175  if (priority == 0) {
6176  exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
6177  if (!exten2)
6178  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);
6179  if (con->pattern_tree) {
6180  struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
6181 
6182  if (x->exten) { /* this test for safety purposes */
6183  x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
6184  x->exten = 0; /* get rid of what will become a bad pointer */
6185  } else {
6186  ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n");
6187  }
6188  }
6189  } else {
6190  ex.priority = priority;
6191  exten2 = ast_hashtab_lookup(exten->peer_table, &ex);
6192  if (exten2) {
6193  if (exten2->label) { /* if this exten has a label, remove that, too */
6194  exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2);
6195  if (!exten3)
6196  ast_log(LOG_ERROR,"Did not remove this priority label (%d/%s) from the peer_label_table of context %s, extension %s!\n", priority, exten2->label, con->name, exten2->exten);
6197  }
6198 
6199  exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2);
6200  if (!exten3)
6201  ast_log(LOG_ERROR,"Did not remove this priority (%d) from the peer_table of context %s, extension %s!\n", priority, con->name, exten2->exten);
6202  if (exten2 == exten && exten2->peer) {
6203  exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
6205  }
6206  if (ast_hashtab_size(exten->peer_table) == 0) {
6207  /* well, if the last priority of an exten is to be removed,
6208  then, the extension is removed, too! */
6209  exten3 = ast_hashtab_remove_this_object(con->root_table, exten);
6210  if (!exten3)
6211  ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_table (%s) (priority %d)\n", exten->exten, con->name, priority);
6212  if (con->pattern_tree) {
6213  struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
6214  if (x->exten) { /* this test for safety purposes */
6215  x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
6216  x->exten = 0; /* get rid of what will become a bad pointer */
6217  }
6218  }
6219  }
6220  } else {
6221  ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n",
6222  priority, exten->exten, con->name);
6223  }
6224  }
6225  } else {
6226  /* hmmm? this exten is not in this pattern tree? */
6227  ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n",
6228  extension, con->name);
6229  }
6230 #ifdef NEED_DEBUG
6231  if (con->pattern_tree) {
6232  ast_log(LOG_NOTICE,"match char tree after exten removal:\n");
6233  log_match_char_tree(con->pattern_tree, " ");
6234  }
6235 #endif
6236 
6237  /* scan the extension list to find first matching extension-registrar */
6238  for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
6239  if (!strcmp(exten->exten, extension) &&
6240  (!registrar || !strcmp(exten->registrar, registrar)) &&
6241  (!matchcallerid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(exten->cidmatch))))
6242  break;
6243  }
6244  if (!exten) {
6245  /* we can't find right extension */
6246  if (!already_locked)
6247  ast_unlock_context(con);
6248  return -1;
6249  }
6250 
6251  /* scan the priority list to remove extension with exten->priority == priority */
6252  for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
6253  peer && !strcmp(peer->exten, extension) &&
6254  (!callerid || (!matchcallerid && !peer->matchcid) || (matchcallerid && peer->matchcid && !strcmp(peer->cidmatch, callerid))) ;
6255  peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
6256 
6257  if ((priority == 0 || peer->priority == priority) &&
6258  (!registrar || !strcmp(peer->registrar, registrar) )) {
6259  found = 1;
6260 
6261  /* we are first priority extension? */
6262  if (!previous_peer) {
6263  /*
6264  * We are first in the priority chain, so must update the extension chain.
6265  * The next node is either the next priority or the next extension
6266  */
6267  struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
6268  if (peer->peer) {
6269  /* move the peer_table and peer_label_table down to the next peer, if
6270  it is there */
6271  peer->peer->peer_table = peer->peer_table;
6272  peer->peer->peer_label_table = peer->peer_label_table;
6273  peer->peer_table = NULL;
6274  peer->peer_label_table = NULL;
6275  }
6276  if (!prev_exten) { /* change the root... */
6277  con->root = next_node;
6278  } else {
6279  prev_exten->next = next_node; /* unlink */
6280  }
6281  if (peer->peer) { /* update the new head of the pri list */
6282  peer->peer->next = peer->next;
6283  }
6284  } else { /* easy, we are not first priority in extension */
6285  previous_peer->peer = peer->peer;
6286  }
6287 
6288 
6289  /* now, free whole priority extension */
6290  destroy_exten(peer);
6291  } else {
6292  previous_peer = peer;
6293  }
6294  }
6295  if (!already_locked)
6296  ast_unlock_context(con);
6297  return found ? 0 : -1;
6298 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
Definition: hashtab.c:534
struct ast_exten * exten
Definition: pbx.c:939
static struct match_char * add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly)
Definition: pbx.c:2222
#define LOG_WARNING
Definition: logger.h:144
const char * label
Definition: pbx.c:889
struct ast_hashtab * peer_table
Definition: pbx.c:896
char x[1]
Definition: pbx.c:940
#define ast_verb(level,...)
Definition: logger.h:243
int matchcid
Definition: pbx.c:886
int priority
Definition: pbx.c:888
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_hashtab_insert_immediate(struct ast_hashtab *tab, const void *obj)
Insert without checking.
Definition: hashtab.c:432
char * exten
Definition: pbx.c:885
struct ast_exten * peer
Definition: pbx.c:895
char name[0]
Definition: pbx.c:967
struct ast_hashtab * peer_label_table
Definition: pbx.c:897
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:11055
static char * registrar
Definition: features.c:623
const char * registrar
Definition: pbx.c:898
struct ast_exten * next
Definition: pbx.c:899
const char * cidmatch
Definition: pbx.c:887
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_hashtab * root_table
Definition: pbx.c:958
int ast_hashtab_size(struct ast_hashtab *tab)
Returns the number of elements stored in the hashtab.
Definition: hashtab.c:625
struct ast_exten * root
Definition: pbx.c:957
struct match_char * pattern_tree
Definition: pbx.c:959
static void destroy_exten(struct ast_exten *e)
Definition: pbx.c:5845
int deleted
Definition: pbx.c:935
match_char: forms a syntax tree for quick matching of extension patterns
Definition: pbx.c:932
void * ast_hashtab_remove_this_object(struct ast_hashtab *tab, void *obj)
Hash the object and then compare ptrs in bucket list instead of calling the compare routine...
Definition: hashtab.c:859
int ast_context_remove_ignorepat ( const char *  context,
const char *  ignorepat,
const char *  registrar 
)

Definition at line 8554 of file pbx.c.

References ast_context_remove_ignorepat2(), ast_unlock_contexts(), and find_context_locked().

Referenced by handle_cli_dialplan_remove_ignorepat().

8555 {
8556  int ret = -1;
8557  struct ast_context *c;
8558 
8560  if (c) {
8561  ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
8563  }
8564  return ret;
8565 }
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:5985
static char * registrar
Definition: features.c:623
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
Definition: pbx.c:8567
int ast_context_remove_ignorepat2 ( struct ast_context con,
const char *  ignorepat,
const char *  registrar 
)

Definition at line 8567 of file pbx.c.

References ast_free, ast_unlock_context(), ast_wrlock_context(), errno, ast_context::ignorepats, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.

Referenced by ast_context_remove_ignorepat().

8568 {
8569  struct ast_ignorepat *ip, *ipl = NULL;
8570 
8571  ast_wrlock_context(con);
8572 
8573  for (ip = con->ignorepats; ip; ip = ip->next) {
8574  if (!strcmp(ip->pattern, ignorepat) &&
8575  (!registrar || (registrar == ip->registrar))) {
8576  if (ipl) {
8577  ipl->next = ip->next;
8578  ast_free(ip);
8579  } else {
8580  con->ignorepats = ip->next;
8581  ast_free(ip);
8582  }
8583  ast_unlock_context(con);
8584  return 0;
8585  }
8586  ipl = ip;
8587  }
8588 
8589  ast_unlock_context(con);
8590  errno = EINVAL;
8591  return -1;
8592 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
struct ast_ignorepat * ignorepats
Definition: pbx.c:962
const char * registrar
Definition: pbx.c:926
const char pattern[0]
Definition: pbx.c:928
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx.c:925
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:11055
int errno
#define ast_free(a)
Definition: astmm.h:97
static char * registrar
Definition: features.c:623
struct ast_ignorepat * next
Definition: pbx.c:927
int ast_context_remove_include ( const char *  context,
const char *  include,
const char *  registrar 
)

Remove included contexts. This function locks contexts list by &conlist, search for the right context structure, leave context list locked and call ast_context_remove_include2 which removes include, unlock contexts list and return ...

Remove a context include.

Definition at line 6007 of file pbx.c.

References ast_context_remove_include2(), ast_unlock_contexts(), and find_context_locked().

Referenced by handle_cli_dialplan_remove_include().

6008 {
6009  int ret = -1;
6010  struct ast_context *c;
6011 
6013  if (c) {
6014  /* found, remove include from this context ... */
6015  ret = ast_context_remove_include2(c, include, registrar);
6017  }
6018  return ret;
6019 }
int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
Removes an include by an ast_context structure.
Definition: pbx.c:6030
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:5985
static char * registrar
Definition: features.c:623
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
int ast_context_remove_include2 ( struct ast_context con,
const char *  include,
const char *  registrar 
)

Locks context, remove included contexts, unlocks context. When we call this function, &conlock lock must be locked, because when we giving *con argument, some process can remove/change this context and after that there can be segfault.

Removes an include by an ast_context structure.

Return values
0on success.
-1on failure.

Definition at line 6030 of file pbx.c.

References ast_destroy_timing(), ast_free, ast_get_context_name(), ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_context::includes, ast_include::name, ast_include::next, ast_include::registrar, and ast_include::timing.

Referenced by ast_context_remove_include().

6031 {
6032  struct ast_include *i, *pi = NULL;
6033  int ret = -1;
6034 
6035  ast_wrlock_context(con);
6036 
6037  /* find our include */
6038  for (i = con->includes; i; pi = i, i = i->next) {
6039  if (!strcmp(i->name, include) &&
6040  (!registrar || !strcmp(i->registrar, registrar))) {
6041  /* remove from list */
6042  ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar);
6043  if (pi)
6044  pi->next = i->next;
6045  else
6046  con->includes = i->next;
6047  /* free include and return */
6048  ast_destroy_timing(&(i->timing));
6049  ast_free(i);
6050  ret = 0;
6051  break;
6052  }
6053  }
6054 
6055  ast_unlock_context(con);
6056 
6057  return ret;
6058 }
ast_include: include= support in extensions.conf
Definition: pbx.c:904
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
struct ast_include * next
Definition: pbx.c:910
struct ast_include * includes
Definition: pbx.c:961
struct ast_timing timing
Definition: pbx.c:909
#define ast_verb(level,...)
Definition: logger.h:243
const char * registrar
Definition: pbx.c:907
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
const char * name
Definition: pbx.c:905
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:11055
int ast_destroy_timing(struct ast_timing *i)
Deallocates memory structures associated with a timing bitmap.
Definition: pbx.c:8396
#define ast_free(a)
Definition: astmm.h:97
static char * registrar
Definition: features.c:623
int ast_context_remove_switch ( const char *  context,
const char *  sw,
const char *  data,
const char *  registrar 
)

Remove a switch.

Note
This function locks contexts list by &conlist, search for the rigt context structure, leave context list locked and call ast_context_remove_switch2 which removes switch, unlock contexts list and return ...

Definition at line 6065 of file pbx.c.

References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().

6066 {
6067  int ret = -1; /* default error return */
6068  struct ast_context *c;
6069 
6071  if (c) {
6072  /* remove switch from this context ... */
6073  ret = ast_context_remove_switch2(c, sw, data, registrar);
6075  }
6076  return ret;
6077 }
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:5985
static char * registrar
Definition: features.c:623
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
This function locks given context, removes switch, unlock context and return.
Definition: pbx.c:6087
ast_context: An extension context
Definition: pbx.c:955
int ast_context_remove_switch2 ( struct ast_context con,
const char *  sw,
const char *  data,
const char *  registrar 
)

This function locks given context, removes switch, unlock context and return.

Note
When we call this function, &conlock lock must be locked, because when we giving *con argument, some process can remove/change this context and after that there can be segfault.

Definition at line 6087 of file pbx.c.

References ast_context::alts, ast_free, ast_get_context_name(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_unlock_context(), ast_verb, ast_wrlock_context(), ast_sw::data, ast_sw::name, and ast_sw::registrar.

Referenced by ast_context_remove_switch().

6088 {
6089  struct ast_sw *i;
6090  int ret = -1;
6091 
6092  ast_wrlock_context(con);
6093 
6094  /* walk switches */
6096  if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
6097  (!registrar || !strcmp(i->registrar, registrar))) {
6098  /* found, remove from list */
6099  ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar);
6101  ast_free(i); /* free switch and return */
6102  ret = 0;
6103  break;
6104  }
6105  }
6107 
6108  ast_unlock_context(con);
6109 
6110  return ret;
6111 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define ast_verb(level,...)
Definition: logger.h:243
ast_sw: Switch statement in extensions.conf
Definition: pbx.c:915
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
char * data
Definition: pbx.c:918
struct ast_sw::@289 list
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:11055
#define ast_free(a)
Definition: astmm.h:97
static char * registrar
Definition: features.c:623
struct ast_context::@290 alts
const char * registrar
Definition: pbx.c:917
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
char * name
Definition: pbx.c:916
int ast_context_unlockmacro ( const char *  context)

Unlocks the macrolock in the given context.

Note
This function locks contexts list by &conlist, searches for the right context structure, and unlocks the macrolock mutex in that context. macrolock is used to limit a macro to be executed by one call at a time.

Definition at line 6327 of file pbx.c.

References ast_mutex_unlock, ast_unlock_contexts(), find_context_locked(), and ast_context::macrolock.

Referenced by _macro_exec().

6328 {
6329  struct ast_context *c;
6330  int ret = -1;
6331 
6333  if (c) {
6335 
6336  /* if we found context, unlock macrolock */
6337  ret = ast_mutex_unlock(&c->macrolock);
6338  }
6339 
6340  return ret;
6341 }
ast_mutex_t macrolock
Definition: pbx.c:966
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:5985
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
#define ast_mutex_unlock(a)
Definition: lock.h:156
int ast_context_verify_includes ( struct ast_context con)

Verifies includes in an ast_contect structure.

Parameters
concontext in which to verify the includes
Return values
0if no problems found
-1if there were any missing context

Definition at line 11221 of file pbx.c.

References ast_context_find(), ast_get_context_name(), ast_log(), ast_walk_context_includes(), LOG_WARNING, and ast_include::rname.

Referenced by pbx_load_module().

11222 {
11223  struct ast_include *inc = NULL;
11224  int res = 0;
11225 
11226  while ( (inc = ast_walk_context_includes(con, inc)) ) {
11227  if (ast_context_find(inc->rname))
11228  continue;
11229 
11230  res = -1;
11231  ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
11232  ast_get_context_name(con), inc->rname);
11233  break;
11234  }
11235 
11236  return res;
11237 }
struct ast_include * ast_walk_context_includes(struct ast_context *con, struct ast_include *inc)
Definition: pbx.c:11203
ast_include: include= support in extensions.conf
Definition: pbx.c:904
const char * rname
Definition: pbx.c:906
#define LOG_WARNING
Definition: logger.h:144
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_context * ast_context_find(const char *name)
Find a context.
Definition: pbx.c:2971
struct ast_custom_function* ast_custom_function_find ( const char *  name)

Definition at line 3800 of file pbx.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and ast_custom_function::name.

Referenced by ast_compile_ael2(), ast_func_read(), ast_func_read2(), ast_func_write(), config_curl(), destroy_curl(), handle_show_function(), op_func(), realtime_curl(), realtime_multi_curl(), require_curl(), store_curl(), update2_curl(), and update_curl().

3801 {
3802  struct ast_custom_function *acf = NULL;
3803 
3805  AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
3806  if (!strcmp(name, acf->name))
3807  break;
3808  }
3810 
3811  return acf;
3812 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Definition: pbx.c:1231
static const char name[]
const char * name
Definition: pbx.h:96
int ast_custom_function_unregister ( struct ast_custom_function acf)

Unregister a custom function.

Definition at line 3814 of file pbx.c.

References ast_free, AST_RWLIST_REMOVE, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_string_field_free_memory, ast_verb, AST_XML_DOC, ast_custom_function::docsrc, and ast_custom_function::name.

Referenced by __ast_custom_function_register_escalating(), _unload_module(), load_module(), reload(), unload_module(), and unload_pbx().

3815 {
3816  struct ast_custom_function *cur;
3817  struct ast_custom_escalating_function *cur_escalation;
3818 
3819  if (!acf) {
3820  return -1;
3821  }
3822 
3824  if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist))) {
3825 #ifdef AST_XML_DOCS
3826  if (cur->docsrc == AST_XML_DOC) {
3828  }
3829 #endif
3830  ast_verb(2, "Unregistered custom function %s\n", cur->name);
3831  }
3833 
3834  /* Remove from the escalation list */
3836  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&escalation_root, cur_escalation, list) {
3837  if (cur_escalation->acf == acf) {
3839  ast_free(cur_escalation);
3840  break;
3841  }
3842  }
3845 
3846  return cur ? 0 : -1;
3847 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
enum ast_doc_src docsrc
Definition: pbx.h:104
#define ast_verb(level,...)
Definition: logger.h:243
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
Definition: pbx.c:1231
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
#define ast_free(a)
Definition: astmm.h:97
Extra information for an ast_custom_function holding privilege escalation information. Kept in a separate structure for ABI compatibility.
Definition: pbx.c:1237
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:870
const char * name
Definition: pbx.h:96
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
int ast_destroy_timing ( struct ast_timing i)

Deallocates memory structures associated with a timing bitmap.

Parameters
iPointer to an ast_timing structure.
Return values
0success
non-zerofailure (number suitable to pass to
See Also
strerror)

Definition at line 8396 of file pbx.c.

References ast_free, and ast_timing::timezone.

Referenced by ast_context_add_include2(), ast_context_remove_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().

8397 {
8398  if (i->timezone) {
8399  ast_free(i->timezone);
8400  i->timezone = NULL;
8401  }
8402  return 0;
8403 }
char * timezone
Definition: pbx.h:145
#define ast_free(a)
Definition: astmm.h:97
enum ast_extension_states ast_devstate_to_extenstate ( enum ast_device_state  devstate)

Map devstate to an extension state.

Parameters
[in]devstatedevice state
Returns
the extension state mapping.

Definition at line 4844 of file pbx.c.

References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_TOTAL, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, and AST_EXTENSION_UNAVAILABLE.

Referenced by ast_extension_state3().

4845 {
4846  switch (devstate) {
4847  case AST_DEVICE_ONHOLD:
4848  return AST_EXTENSION_ONHOLD;
4849  case AST_DEVICE_BUSY:
4850  return AST_EXTENSION_BUSY;
4851  case AST_DEVICE_UNKNOWN:
4852  return AST_EXTENSION_NOT_INUSE;
4854  case AST_DEVICE_INVALID:
4856  case AST_DEVICE_RINGINUSE:
4858  case AST_DEVICE_RINGING:
4859  return AST_EXTENSION_RINGING;
4860  case AST_DEVICE_INUSE:
4861  return AST_EXTENSION_INUSE;
4862  case AST_DEVICE_NOT_INUSE:
4863  return AST_EXTENSION_NOT_INUSE;
4864  case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
4865  break;
4866  }
4867 
4868  return AST_EXTENSION_NOT_INUSE;
4869 }
int ast_exists_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid 
)

Determine whether an extension exists.

Parameters
cthis is not important
contextwhich context to look in
extenwhich extension to search for
prioritypriority of the action within the extension
calleridcallerid to search for
Note
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns
If an extension within the given context(or callerid) with the given priority is found a non zero value will be returned. Otherwise, 0 is returned.

Definition at line 5400 of file pbx.c.

References E_MATCH, and pbx_extension_helper().

Referenced by __analog_ss_thread(), __ast_goto_if_exists(), __ast_pbx_run(), _macro_exec(), acf_isexten_exec(), analog_ss_thread(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), cb_events(), cli_console_dial(), conf_run(), console_dial(), console_transfer(), dahdi_handle_dtmf(), dahdi_r2_on_call_offered(), dahdi_r2_on_dnis_digit_received(), dial_exec_full(), disa_exec(), dp_lookup(), dundi_lookup_local(), findmeexec(), get_also_info(), get_destination(), get_refer_info(), gosub_exec(), handle_gosub(), handle_stimulus_message(), isexten_function_read(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), loopback_exists(), metermaidstate(), mgcp_ss(), minivm_greet_exec(), misdn_overlap_dial_task(), my_handle_dtmf(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), pri_ss_thread(), privacy_exec(), process_ast_dsp(), process_sdp(), readexten_exec(), register_peer_exten(), show_debug_helper(), sip_new(), sip_read(), skinny_ss(), socket_process(), try_calling(), vm_authenticate(), and waitstream_core().

5401 {
5402  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
5403 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
The return value depends on the action:
Definition: pbx.c:4706
int ast_explicit_goto ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)
Note
This function will handle locking the channel as needed.

Definition at line 8708 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, ast_channel::context, ast_channel::exten, and ast_channel::priority.

Referenced by __ast_goto_if_exists(), ast_async_goto(), builtin_atxfer(), disa_exec(), do_bridge_masquerade(), handle_setpriority(), and pbx_parseable_goto().

8709 {
8710  if (!chan)
8711  return -1;
8712 
8713  ast_channel_lock(chan);
8714 
8715  if (!ast_strlen_zero(context))
8716  ast_copy_string(chan->context, context, sizeof(chan->context));
8717  if (!ast_strlen_zero(exten))
8718  ast_copy_string(chan->exten, exten, sizeof(chan->exten));
8719  if (priority > -1) {
8720  chan->priority = priority;
8721  /* see flag description in channel.h for explanation */
8723  chan->priority--;
8724  }
8725 
8726  ast_channel_unlock(chan);
8727 
8728  return 0;
8729 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
int priority
Definition: channel.h:841
#define ast_test_flag(p, flag)
Definition: utils.h:63
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_channel_unlock(chan)
Definition: channel.h:2467
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int ast_extension_close ( const char *  pattern,
const char *  data,
int  needmore 
)

Definition at line 2948 of file pbx.c.

References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.

Referenced by lua_find_extension(), and realtime_switch_common().

2949 {
2950  if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
2951  ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
2952  return extension_match_core(pattern, data, needmore);
2953 }
#define LOG_WARNING
Definition: logger.h:144
static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
Definition: pbx.c:2930
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_extension_cmp ( const char *  a,
const char *  b 
)

Determine if one extension should match before another.

Parameters
aextension to compare with b
bextension to compare with a

Checks whether or extension a should match before extension b

Return values
0if the two extensions have equal matching priority
1on a > b
-1on a < b

Definition at line 2713 of file pbx.c.

References ext_cmp().

Referenced by lua_extension_cmp().

2714 {
2715  int cmp;
2716 
2717  cmp = ext_cmp(a, b);
2718  if (cmp < 0) {
2719  return -1;
2720  }
2721  if (cmp > 0) {
2722  return 1;
2723  }
2724  return 0;
2725 }
static int ext_cmp(const char *left, const char *right)
Definition: pbx.c:2691
int ast_extension_match ( const char *  pattern,
const char *  extension 
)

Determine if a given extension matches a given pattern (in NXX format)

Parameters
patternpattern to match
extensionextension to check against the pattern.

Checks whether or not the given extension matches the given pattern.

Return values
1on match
0on failure

Definition at line 2943 of file pbx.c.

References E_MATCH, and extension_match_core().

Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), load_module(), loopback_canmatch(), loopback_exists(), loopback_matchmore(), lua_find_extension(), manager_show_dialplan_helper(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), reload(), show_dialplan_helper(), and sig_pri_msn_match().

2944 {
2945  return extension_match_core(pattern, data, E_MATCH);
2946 }
static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
Definition: pbx.c:2930
int ast_extension_state ( struct ast_channel c,
const char *  context,
const char *  exten 
)

Check extension state for an extension by using hint.

Uses hint and devicestate callback to get the state of an extension.

Definition at line 4914 of file pbx.c.

References ast_exten::app, ast_add_extension(), ast_extension_state2(), ast_free_ptr(), ast_hint_extension(), ast_strdup, ast_exten::cidmatch, ast_exten::data, ast_exten::exten, ast_exten::label, ast_exten::matchcid, ast_context::name, ast_exten::parent, ast_exten::priority, and ast_exten::registrar.

Referenced by action_extensionstate(), extstate_read(), get_queue_member_status(), and handle_request_subscribe().

4915 {
4916  struct ast_exten *e;
4917 
4918  if (!(e = ast_hint_extension(c, context, exten))) { /* Do we have a hint for this extension ? */
4919  return -1; /* No hint, return -1 */
4920  }
4921 
4922  if (e->exten[0] == '_') {
4923  /* Create this hint on-the-fly */
4924  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
4925  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
4926  e->registrar);
4927  if (!(e = ast_hint_extension(c, context, exten))) {
4928  /* Improbable, but not impossible */
4929  return -1;
4930  }
4931  }
4932 
4933  return ast_extension_state2(e); /* Check all devices in the hint */
4934 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
#define ast_strdup(a)
Definition: astmm.h:109
static int ast_extension_state2(struct ast_exten *e)
Check state of extension by using hints.
Definition: pbx.c:4889
const char * label
Definition: pbx.c:889
void ast_free_ptr(void *ptr)
int matchcid
Definition: pbx.c:886
int priority
Definition: pbx.c:888
static struct ast_exten * ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
Definition: pbx.c:4835
char * exten
Definition: pbx.c:885
char name[0]
Definition: pbx.c:967
void * data
Definition: pbx.c:893
const char * registrar
Definition: pbx.c:898
const char * cidmatch
Definition: pbx.c:887
struct ast_context * parent
Definition: pbx.c:890
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:8691
const char * app
Definition: pbx.c:891
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int ast_extension_state2 ( struct ast_exten e)
static

Check state of extension by using hints.

Definition at line 4889 of file pbx.c.

References ast_extension_state3(), ast_get_extension_app(), ast_str_set(), ast_str_thread_get(), and extensionstate_buf.

Referenced by ast_add_hint(), and ast_extension_state().

4890 {
4891  struct ast_str *hint_app = ast_str_thread_get(&extensionstate_buf, 32);
4892 
4893  if (!e || !hint_app) {
4894  return -1;
4895  }
4896 
4897  ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(e));
4898  return ast_extension_state3(hint_app);
4899 }
static struct ast_threadstorage extensionstate_buf
Definition: pbx.c:865
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:11141
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:669
static int ast_extension_state3(struct ast_str *hint_app)
Definition: pbx.c:4871
const char* ast_extension_state2str ( int  extension_state)

Return extension_state as string.

Return string representation of the state of an extension.

Definition at line 4902 of file pbx.c.

References ARRAY_LEN, extension_states, and cfextension_states::text.

Referenced by cb_extensionstate(), handle_request_subscribe(), handle_show_hint(), handle_show_hints(), hints_data_provider_get(), and show_channels_cb().

4903 {
4904  int i;
4905 
4906  for (i = 0; (i < ARRAY_LEN(extension_states)); i++) {
4907  if (extension_states[i].extension_state == extension_state)
4908  return extension_states[i].text;
4909  }
4910  return "Unknown";
4911 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
const char *const text
Definition: pbx.c:1033
static struct cfextension_states extension_states[]
static int ast_extension_state3 ( struct ast_str hint_app)
static

Definition at line 4871 of file pbx.c.

References ast_devstate_aggregate_add(), ast_devstate_aggregate_init(), ast_devstate_aggregate_result(), ast_devstate_to_extenstate(), ast_str_buffer(), and strsep().

Referenced by ast_extension_state2(), and handle_statechange().

4872 {
4873  char *cur;
4874  char *rest;
4875  struct ast_devstate_aggregate agg;
4876 
4877  /* One or more devices separated with a & character */
4878  rest = ast_str_buffer(hint_app);
4879 
4881  while ((cur = strsep(&rest, "&"))) {
4883  }
4884 
4886 }
ast_device_state
Device States.
Definition: devicestate.h:51
char * strsep(char **str, const char *delims)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
enum ast_device_state ast_devstate_aggregate_result(struct ast_devstate_aggregate *agg)
Get the aggregate device state result.
Definition: devicestate.c:791
void ast_devstate_aggregate_add(struct ast_devstate_aggregate *agg, enum ast_device_state state)
Add a device state to the aggregate device state.
Definition: devicestate.c:764
enum ast_extension_states ast_devstate_to_extenstate(enum ast_device_state devstate)
Map devstate to an extension state.
Definition: pbx.c:4844
void ast_devstate_aggregate_init(struct ast_devstate_aggregate *agg)
Initialize aggregate device state.
Definition: devicestate.c:758
You shouldn&#39;t care about the contents of this struct.
Definition: devicestate.h:265
int ast_extension_state_add ( const char *  context,
const char *  exten,
ast_state_cb_type  change_cb,
void *  data 
)

Add watcher for extension states.

Registers a state change callback.

Definition at line 5135 of file pbx.c.

References ast_extension_state_add_destroy().

Referenced by __init_manager(), load_module(), and skinny_register().

5137 {
5138  return ast_extension_state_add_destroy(context, exten, change_cb, NULL, data);
5139 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
int ast_extension_state_add_destroy(const char *context, const char *exten, ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
Registers a state change callback with destructor.
Definition: pbx.c:5048
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_extension_state_add_destroy ( const char *  context,
const char *  exten,
ast_state_cb_type  change_cb,
ast_state_cb_destroy_type  destroy_cb,
void *  data 
)

Add watcher for extension states with destructor.

Registers a state change callback with destructor.

Definition at line 5048 of file pbx.c.

References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_exten::app, ast_add_extension(), ast_free_ptr(), ast_hint_extension(), ast_strdup, ast_hint::callbacks, ast_state_cb::change_cb, ast_exten::cidmatch, ast_exten::data, ast_sw::data, ast_state_cb::data, ast_state_cb::destroy_cb, destroy_state_cb(), ast_exten::exten, hints, ast_state_cb::id, id, ast_exten::label, ast_exten::matchcid, ast_context::name, OBJ_NODATA, OBJ_UNLINK, ast_exten::parent, ast_exten::priority, ast_exten::registrar, statecbs, and stateid.

Referenced by ast_extension_state_add(), and handle_request_subscribe().

5050 {
5051  struct ast_hint *hint;
5052  struct ast_state_cb *state_cb;
5053  struct ast_exten *e;
5054  int id;
5055 
5056  /* If there's no context and extension: add callback to statecbs list */
5057  if (!context && !exten) {
5058  /* Prevent multiple adds from adding the same change_cb at the same time. */
5059  ao2_lock(statecbs);
5060 
5061  /* Remove any existing change_cb. */
5062  ao2_find(statecbs, change_cb, OBJ_UNLINK | OBJ_NODATA);
5063 
5064  /* Now insert the change_cb */
5065  if (!(state_cb = ao2_alloc(sizeof(*state_cb), destroy_state_cb))) {
5067  return -1;
5068  }
5069  state_cb->id = 0;
5070  state_cb->change_cb = change_cb;
5071  state_cb->destroy_cb = destroy_cb;
5072  state_cb->data = data;
5073  ao2_link(statecbs, state_cb);
5074 
5075  ao2_ref(state_cb, -1);
5077  return 0;
5078  }
5079 
5080  if (!context || !exten)
5081  return -1;
5082 
5083  /* This callback type is for only one hint, so get the hint */
5084  e = ast_hint_extension(NULL, context, exten);
5085  if (!e) {
5086  return -1;
5087  }
5088 
5089  /* If this is a pattern, dynamically create a new extension for this
5090  * particular match. Note that this will only happen once for each
5091  * individual extension, because the pattern will no longer match first.
5092  */
5093  if (e->exten[0] == '_') {
5094  ast_add_extension(e->parent->name, 0, exten, e->priority, e->label,
5095  e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
5096  e->registrar);
5097  e = ast_hint_extension(NULL, context, exten);
5098  if (!e || e->exten[0] == '_') {
5099  return -1;
5100  }
5101  }
5102 
5103  /* Find the hint in the hints container */
5104  ao2_lock(hints);/* Locked to hold off ast_merge_contexts_and_delete */
5105  hint = ao2_find(hints, e, 0);
5106  if (!hint) {
5107  ao2_unlock(hints);
5108  return -1;
5109  }
5110 
5111  /* Now insert the callback in the callback list */
5112  if (!(state_cb = ao2_alloc(sizeof(*state_cb), destroy_state_cb))) {
5113  ao2_ref(hint, -1);
5114  ao2_unlock(hints);
5115  return -1;
5116  }
5117  do {
5118  id = stateid++; /* Unique ID for this callback */
5119  /* Do not allow id to ever be -1 or 0. */
5120  } while (id == -1 || id == 0);
5121  state_cb->id = id;
5122  state_cb->change_cb = change_cb; /* Pointer to callback routine */
5123  state_cb->destroy_cb = destroy_cb;
5124  state_cb->data = data; /* Data for the callback */
5125  ao2_link(hint->callbacks, state_cb);
5126 
5127  ao2_ref(state_cb, -1);
5128  ao2_ref(hint, -1);
5129  ao2_unlock(hints);
5130 
5131  return id;
5132 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
#define ast_strdup(a)
Definition: astmm.h:109
ast_state_cb: An extension state notify register item
Definition: pbx.c:989
static int stateid
Definition: pbx.c:1305
#define ao2_unlock(a)
Definition: astobj2.h:497
const char * label
Definition: pbx.c:889
static struct ao2_container * hints
Definition: pbx.c:1314
void ast_free_ptr(void *ptr)
ast_state_cb_type change_cb
Definition: pbx.c:995
int matchcid
Definition: pbx.c:886
int priority
Definition: pbx.c:888
int id
Definition: pbx.c:991
static struct ast_exten * ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
Definition: pbx.c:4835
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
char * exten
Definition: pbx.c:885
char name[0]
Definition: pbx.c:967
void * data
Definition: pbx.c:893
ast_state_cb_destroy_type destroy_cb
Definition: pbx.c:997
Structure for dial plan hints.
Definition: pbx.c:1010
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
const char * registrar
Definition: pbx.c:898
static void destroy_state_cb(void *doomed)
Definition: pbx.c:5038
const char * cidmatch
Definition: pbx.c:887
struct ast_context * parent
Definition: pbx.c:890
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:8691
const char * app
Definition: pbx.c:891
static struct ao2_container * statecbs
Definition: pbx.c:1316
enum queue_result id
Definition: app_queue.c:1090
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
void * data
Definition: pbx.c:993
struct ao2_container * callbacks
Definition: pbx.c:1018
int ast_extension_state_del ( int  id,
ast_state_cb_type  change_cb 
)

ast_extension_state_del: Remove a watcher from the callback list

Deletes a registered state change callback by ID.

Definition at line 5157 of file pbx.c.

References ao2_callback, ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_hint::callbacks, find_hint_by_cb_id(), hints, OBJ_UNLINK, and statecbs.

Referenced by dialog_unlink_all(), handle_request_subscribe(), skinny_unregister(), and unload_module().

5158 {
5159  struct ast_state_cb *p_cur;
5160  int ret = -1;
5161 
5162  if (!id) { /* id == 0 is a callback without extension */
5163  if (!change_cb) {
5164  return ret;
5165  }
5167  if (p_cur) {
5168  ret = 0;
5169  ao2_ref(p_cur, -1);
5170  }
5171  } else { /* callback with extension, find the callback based on ID */
5172  struct ast_hint *hint;
5173 
5174  ao2_lock(hints);/* Locked to hold off ast_merge_contexts_and_delete */
5175  hint = ao2_callback(hints, 0, find_hint_by_cb_id, &id);
5176  if (hint) {
5177  p_cur = ao2_find(hint->callbacks, &id, OBJ_UNLINK);
5178  if (p_cur) {
5179  ret = 0;
5180  ao2_ref(p_cur, -1);
5181  }
5182  ao2_ref(hint, -1);
5183  }
5184  ao2_unlock(hints);
5185  }
5186 
5187  return ret;
5188 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
ast_state_cb: An extension state notify register item
Definition: pbx.c:989
#define ao2_unlock(a)
Definition: astobj2.h:497
static struct ao2_container * hints
Definition: pbx.c:1314
ast_state_cb_type change_cb
Definition: pbx.c:995
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
Structure for dial plan hints.
Definition: pbx.c:1010
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static int find_hint_by_cb_id(void *obj, void *arg, int flags)
Remove a watcher from the callback list.
Definition: pbx.c:5142
static struct ao2_container * statecbs
Definition: pbx.c:1316
struct ao2_container * callbacks
Definition: pbx.c:1018
int ast_findlabel_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
const char *  label,
const char *  callerid 
)

Find the priority of an extension that has the specified label.

Parameters
cthis is not important
contextwhich context to look in
extenwhich extension to search for
labellabel of the action within the extension to match to priority
calleridcallerid to search for
Note
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Return values
thepriority which matches the given label in the extension
-1if not found.

Definition at line 5405 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by action_originate(), action_redirect(), handle_gosub(), handle_setpriority(), isexten_function_read(), and pbx_parseable_goto().

5406 {
5407  return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
5408 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
The return value depends on the action:
Definition: pbx.c:4706
int ast_findlabel_extension2 ( struct ast_channel c,
struct ast_context con,
const char *  exten,
const char *  label,
const char *  callerid 
)

Find the priority of an extension that has the specified label.

Note
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
This function is the same as ast_findlabel_extension, except that it accepts a pointer to an ast_context structure to specify the context instead of the name of the context. Otherwise, the functions behave the same.

Definition at line 5410 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

5411 {
5412  return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
5413 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
The return value depends on the action:
Definition: pbx.c:4706
int ast_func_read ( struct ast_channel chan,
const char *  function,
char *  workspace,
size_t  len 
)

executes a read operation on a function

Parameters
chanChannel to execute on
functionData containing the function call string (will be modified)
workspaceA pointer to safe memory to use for a return value
lenthe number of bytes in workspace

This application executes a function in read mode on a given channel.

Return values
0success
non-zerofailure

Definition at line 4177 of file pbx.c.

References __ast_module_user_add(), __ast_module_user_remove(), args, ast_copy_string(), ast_custom_function_find(), ast_free, ast_log(), ast_str_buffer(), ast_str_create(), ast_str_size(), ast_strdupa, copy(), func_args(), is_read_allowed(), LOG_ERROR, ast_custom_function::mod, ast_custom_function::read, ast_custom_function::read2, and str.

Referenced by action_getvar(), action_status(), handle_getvariable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full().

4178 {
4179  char *copy = ast_strdupa(function);
4180  char *args = func_args(copy);
4181  struct ast_custom_function *acfptr = ast_custom_function_find(copy);
4182  int res;
4183  struct ast_module_user *u = NULL;
4184 
4185  if (acfptr == NULL) {
4186  ast_log(LOG_ERROR, "Function %s not registered\n", copy);
4187  } else if (!acfptr->read && !acfptr->read2) {
4188  ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
4189  } else if (!is_read_allowed(acfptr)) {
4190  ast_log(LOG_ERROR, "Dangerous function %s read blocked\n", copy);
4191  } else if (acfptr->read) {
4192  if (acfptr->mod) {
4193  u = __ast_module_user_add(acfptr->mod, chan);
4194  }
4195  res = acfptr->read(chan, copy, args, workspace, len);
4196  if (acfptr->mod && u) {
4197  __ast_module_user_remove(acfptr->mod, u);
4198  }
4199  return res;
4200  } else {
4201  struct ast_str *str = ast_str_create(16);
4202  if (acfptr->mod) {
4203  u = __ast_module_user_add(acfptr->mod, chan);
4204  }
4205  res = acfptr->read2(chan, copy, args, &str, 0);
4206  if (acfptr->mod && u) {
4207  __ast_module_user_remove(acfptr->mod, u);
4208  }
4209  ast_copy_string(workspace, ast_str_buffer(str), len > ast_str_size(str) ? ast_str_size(str) : len);
4210  ast_free(str);
4211  return res;
4212  }
4213  return -1;
4214 }
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:482
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
void __ast_module_user_remove(struct ast_module *, struct ast_module_user *)
Definition: loader.c:231
static int copy(char *infile, char *outfile)
Utility function to copy a file.
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
struct ast_module * mod
Definition: pbx.h:119
const char * str
Definition: app_jack.c:144
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
static int is_read_allowed(struct ast_custom_function *acfptr)
Determines whether execution of a custom function&#39;s read function is allowed.
Definition: pbx.c:4119
struct ast_module_user * __ast_module_user_add(struct ast_module *, struct ast_channel *)
Definition: loader.c:209
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct ast_custom_function * ast_custom_function_find(const char *name)
Definition: pbx.c:3800
#define LOG_ERROR
Definition: logger.h:155
ast_acf_read2_fn_t read2
Definition: pbx.h:114
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static struct @350 args
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
ast_acf_read_fn_t read
Definition: pbx.h:106
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char * func_args(char *function)
return a pointer to the arguments of the function, and terminates the function name with &#39;\0&#39; ...
Definition: pbx.c:4041
int ast_func_read2 ( struct ast_channel chan,
const char *  function,
struct ast_str **  str,
ssize_t  maxlen 
)

executes a read operation on a function

Parameters
chanChannel to execute on
functionData containing the function call string (will be modified)
strA dynamic string buffer into which to place the result.
maxlen<0 if the dynamic buffer should not grow; >0 if the dynamic buffer should be limited to that number of bytes; 0 if the dynamic buffer has no upper limit

This application executes a function in read mode on a given channel.

Return values
0success
non-zerofailure

Definition at line 4216 of file pbx.c.

References __ast_module_user_add(), __ast_module_user_remove(), args, ast_custom_function_find(), ast_log(), ast_str_buffer(), ast_str_make_space(), ast_str_reset(), ast_str_size(), ast_strdupa, copy(), func_args(), is_read_allowed(), LOG_ERROR, maxsize, ast_custom_function::mod, ast_custom_function::read, ast_custom_function::read2, ast_custom_function::read_max, and VAR_BUF_SIZE.

Referenced by append_channel_vars(), and ast_str_substitute_variables_full().

4217 {
4218  char *copy = ast_strdupa(function);
4219  char *args = func_args(copy);
4220  struct ast_custom_function *acfptr = ast_custom_function_find(copy);
4221  int res;
4222  struct ast_module_user *u = NULL;
4223 
4224  if (acfptr == NULL) {
4225  ast_log(LOG_ERROR, "Function %s not registered\n", copy);
4226  } else if (!acfptr->read && !acfptr->read2) {
4227  ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
4228  } else if (!is_read_allowed(acfptr)) {
4229  ast_log(LOG_ERROR, "Dangerous function %s read blocked\n", copy);
4230  } else {
4231  if (acfptr->mod) {
4232  u = __ast_module_user_add(acfptr->mod, chan);
4233  }
4234  ast_str_reset(*str);
4235  if (acfptr->read2) {
4236  /* ast_str enabled */
4237  res = acfptr->read2(chan, copy, args, str, maxlen);
4238  } else {
4239  /* Legacy function pointer, allocate buffer for result */
4240  int maxsize = ast_str_size(*str);
4241  if (maxlen > -1) {
4242  if (maxlen == 0) {
4243  if (acfptr->read_max) {
4244  maxsize = acfptr->read_max;
4245  } else {
4246  maxsize = VAR_BUF_SIZE;
4247  }
4248  } else {
4249  maxsize = maxlen;
4250  }
4251  ast_str_make_space(str, maxsize);
4252  }
4253  res = acfptr->read(chan, copy, args, ast_str_buffer(*str), maxsize);
4254  }
4255  if (acfptr->mod && u) {
4256  __ast_module_user_remove(acfptr->mod, u);
4257  }
4258  return res;
4259  }
4260  return -1;
4261 }
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:482
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
void __ast_module_user_remove(struct ast_module *, struct ast_module_user *)
Definition: loader.c:231
static int copy(char *infile, char *outfile)
Utility function to copy a file.
struct ast_module * mod
Definition: pbx.h:119
int ast_str_make_space(struct ast_str **buf, size_t new_len)
Definition: strings.h:588
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
static int is_read_allowed(struct ast_custom_function *acfptr)
Determines whether execution of a custom function&#39;s read function is allowed.
Definition: pbx.c:4119
size_t read_max
Definition: pbx.h:116
struct ast_module_user * __ast_module_user_add(struct ast_module *, struct ast_channel *)
Definition: loader.c:209
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct ast_custom_function * ast_custom_function_find(const char *name)
Definition: pbx.c:3800
#define LOG_ERROR
Definition: logger.h:155
ast_acf_read2_fn_t read2
Definition: pbx.h:114
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int maxsize
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:436
ast_acf_read_fn_t read
Definition: pbx.h:106
static char * func_args(char *function)
return a pointer to the arguments of the function, and terminates the function name with &#39;\0&#39; ...
Definition: pbx.c:4041
#define VAR_BUF_SIZE
Definition: pbx.c:833
int ast_func_write ( struct ast_channel chan,
const char *  function,
const char *  value 
)

executes a write operation on a function

Parameters
chanChannel to execute on
functionData containing the function call string (will be modified)
valueA value parameter to pass for writing

This application executes a function in write mode on a given channel.

Return values
0success
non-zerofailure

Definition at line 4263 of file pbx.c.

References __ast_module_user_add(), __ast_module_user_remove(), args, ast_custom_function_find(), ast_log(), ast_strdupa, copy(), func_args(), is_write_allowed(), LOG_ERROR, ast_custom_function::mod, and ast_custom_function::write.

Referenced by conf_run(), pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

4264 {
4265  char *copy = ast_strdupa(function);
4266  char *args = func_args(copy);
4267  struct ast_custom_function *acfptr = ast_custom_function_find(copy);
4268 
4269  if (acfptr == NULL) {
4270  ast_log(LOG_ERROR, "Function %s not registered\n", copy);
4271  } else if (!acfptr->write) {
4272  ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy);
4273  } else if (!is_write_allowed(acfptr)) {
4274  ast_log(LOG_ERROR, "Dangerous function %s write blocked\n", copy);
4275  } else {
4276  int res;
4277  struct ast_module_user *u = NULL;
4278  if (acfptr->mod)
4279  u = __ast_module_user_add(acfptr->mod, chan);
4280  res = acfptr->write(chan, copy, args, value);
4281  if (acfptr->mod && u)
4282  __ast_module_user_remove(acfptr->mod, u);
4283  return res;
4284  }
4285 
4286  return -1;
4287 }
void __ast_module_user_remove(struct ast_module *, struct ast_module_user *)
Definition: loader.c:231
static int is_write_allowed(struct ast_custom_function *acfptr)
Determines whether execution of a custom function&#39;s write function is allowed.
Definition: pbx.c:4152
static int copy(char *infile, char *outfile)
Utility function to copy a file.
struct ast_module * mod
Definition: pbx.h:119
int value
Definition: syslog.c:39
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
ast_acf_write_fn_t write
Definition: pbx.h:118
struct ast_module_user * __ast_module_user_add(struct ast_module *, struct ast_channel *)
Definition: loader.c:209
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct ast_custom_function * ast_custom_function_find(const char *name)
Definition: pbx.c:3800
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char * func_args(char *function)
return a pointer to the arguments of the function, and terminates the function name with &#39;\0&#39; ...
Definition: pbx.c:4041
const char* ast_get_context_registrar ( struct ast_context c)

Definition at line 11111 of file pbx.c.

References ast_context::registrar.

Referenced by handle_cli_dialplan_save(), show_debug_helper(), and show_dialplan_helper().

11112 {
11113  return c ? c->registrar : NULL;
11114 }
char * registrar
Definition: pbx.c:963
void* ast_get_extension_app_data ( struct ast_exten e)
const char* ast_get_extension_cidmatch ( struct ast_exten e)

Definition at line 11136 of file pbx.c.

References ast_exten::cidmatch.

Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().

11137 {
11138  return e ? e->cidmatch : NULL;
11139 }
const char * cidmatch
Definition: pbx.c:887
struct ast_context* ast_get_extension_context ( struct ast_exten exten)

Definition at line 11078 of file pbx.c.

References ast_exten::parent.

Referenced by ast_remove_hint(), destroy_hint(), handle_show_hint(), handle_show_hints(), handle_statechange(), and hints_data_provider_get().

11079 {
11080  return exten ? exten->parent : NULL;
11081 }
struct ast_context * parent
Definition: pbx.c:890
const char* ast_get_extension_label ( struct ast_exten exten)

Definition at line 11088 of file pbx.c.

References ast_exten::label.

Referenced by handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

11089 {
11090  return exten ? exten->label : NULL;
11091 }
const char * label
Definition: pbx.c:889
int ast_get_extension_matchcid ( struct ast_exten e)

Definition at line 11131 of file pbx.c.

References ast_exten::matchcid.

Referenced by complete_dialplan_remove_extension(), find_matching_priority(), and handle_cli_dialplan_save().

11132 {
11133  return e ? e->matchcid : 0;
11134 }
int matchcid
Definition: pbx.c:886
int ast_get_extension_priority ( struct ast_exten exten)

Definition at line 11103 of file pbx.c.

References ast_exten::priority.

Referenced by complete_dialplan_remove_extension(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and print_ext().

11104 {
11105  return exten ? exten->priority : -1;
11106 }
int priority
Definition: pbx.c:888
const char* ast_get_extension_registrar ( struct ast_exten e)

Definition at line 11116 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

11117 {
11118  return e ? e->registrar : NULL;
11119 }
const char * registrar
Definition: pbx.c:898
int ast_get_hint ( char *  hint,
int  hintsize,
char *  name,
int  namesize,
struct ast_channel c,
const char *  context,
const char *  exten 
)

Get hint for channel.

If an extension hint exists, return non-zero.

Definition at line 5362 of file pbx.c.

References ast_copy_string(), ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension().

Referenced by action_extensionstate(), get_cid_name(), get_destination(), hint_read(), manager_state_cb(), skinny_extensionstate_cb(), and state_notify_build_xml().

5363 {
5364  struct ast_exten *e = ast_hint_extension(c, context, exten);
5365 
5366  if (e) {
5367  if (hint)
5368  ast_copy_string(hint, ast_get_extension_app(e), hintsize);
5369  if (name) {
5370  const char *tmp = ast_get_extension_app_data(e);
5371  if (tmp)
5372  ast_copy_string(name, tmp, namesize);
5373  }
5374  return -1;
5375  }
5376  return 0;
5377 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:11141
void * ast_get_extension_app_data(struct ast_exten *e)
Definition: pbx.c:11146
static struct ast_exten * ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
Definition: pbx.c:4835
static const char name[]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
const char* ast_get_ignorepat_name ( struct ast_ignorepat ip)
const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip)

Definition at line 11126 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

11127 {
11128  return ip ? ip->registrar : NULL;
11129 }
const char * registrar
Definition: pbx.c:926
const char* ast_get_include_name ( struct ast_include inc)
const char* ast_get_include_registrar ( struct ast_include i)

Definition at line 11121 of file pbx.c.

References ast_include::registrar.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

11122 {
11123  return i ? i->registrar : NULL;
11124 }
const char * registrar
Definition: pbx.c:907
const char* ast_get_switch_data ( struct ast_sw sw)

Definition at line 11156 of file pbx.c.

References ast_sw::data.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

11157 {
11158  return sw ? sw->data : NULL;
11159 }
char * data
Definition: pbx.c:918
int ast_get_switch_eval ( struct ast_sw sw)

Definition at line 11161 of file pbx.c.

References ast_sw::eval.

Referenced by context_merge_incls_swits_igps_other_registrars().

11162 {
11163  return sw->eval;
11164 }
int eval
Definition: pbx.c:919
const char* ast_get_switch_name ( struct ast_sw sw)

Definition at line 11151 of file pbx.c.

References ast_sw::name.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

11152 {
11153  return sw ? sw->name : NULL;
11154 }
char * name
Definition: pbx.c:916
const char* ast_get_switch_registrar ( struct ast_sw sw)

Definition at line 11166 of file pbx.c.

References ast_sw::registrar.

Referenced by context_merge_incls_swits_igps_other_registrars(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

11167 {
11168  return sw ? sw->registrar : NULL;
11169 }
const char * registrar
Definition: pbx.c:917
int ast_goto_if_exists ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)
Note
This function will handle locking the channel as needed.

Definition at line 11261 of file pbx.c.

References __ast_goto_if_exists().

Referenced by background_detect_exec(), channel_spy(), common_exec(), conf_run(), dial_exec_full(), goto_exten(), onedigit_goto(), select_entry(), valid_exit(), vm_execmain(), and vmauthenticate().

11262 {
11263  return __ast_goto_if_exists(chan, context, exten, priority, 0);
11264 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static int __ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, int async)
Definition: pbx.c:11240
int priority
Definition: pbx.c:888
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_hashtab_compare_contexts ( const void *  ah_a,
const void *  ah_b 
)

hashtable functions for contexts

Definition at line 1136 of file pbx.c.

References ast_context::name.

Referenced by ast_context_find_or_create(), lua_register_switches(), and pbx_load_module().

1137 {
1138  const struct ast_context *ac = ah_a;
1139  const struct ast_context *bc = ah_b;
1140  if (!ac || !bc) /* safety valve, but it might prevent a crash you'd rather have happen */
1141  return 1;
1142  /* assume context names are registered in a string table! */
1143  return strcmp(ac->name, bc->name);
1144 }
char name[0]
Definition: pbx.c:967
ast_context: An extension context
Definition: pbx.c:955
unsigned int ast_hashtab_hash_contexts ( const void *  obj)

Definition at line 1188 of file pbx.c.

References ast_hashtab_hash_string(), and ast_context::name.

Referenced by ast_context_find_or_create(), lua_register_switches(), and pbx_load_module().

1189 {
1190  const struct ast_context *ac = obj;
1191  return ast_hashtab_hash_string(ac->name);
1192 }
char name[0]
Definition: pbx.c:967
unsigned int ast_hashtab_hash_string(const void *obj)
Hashes a string to a number.
Definition: hashtab.c:157
ast_context: An extension context
Definition: pbx.c:955
static struct ast_exten* ast_hint_extension ( struct ast_channel c,
const char *  context,
const char *  exten 
)
static

Definition at line 4835 of file pbx.c.

References ast_hint_extension_nolock(), ast_rdlock_contexts(), and ast_unlock_contexts().

Referenced by ast_extension_state(), ast_extension_state_add_destroy(), ast_get_hint(), and ast_str_get_hint().

4836 {
4837  struct ast_exten *e;
4841  return e;
4842 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:11042
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static struct ast_exten * ast_hint_extension_nolock(struct ast_channel *c, const char *context, const char *exten)
Find hint for given extension in context.
Definition: pbx.c:4829
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static struct ast_exten* ast_hint_extension_nolock ( struct ast_channel c,
const char *  context,
const char *  exten 
)
static

Find hint for given extension in context.

Definition at line 4829 of file pbx.c.

References E_MATCH, pbx_find_extension(), PRIORITY_HINT, and pbx_find_info::stacklen.

Referenced by ast_hint_extension(), and ast_merge_contexts_and_delete().

4830 {
4831  struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
4832  return pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH);
4833 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
#define PRIORITY_HINT
Definition: pbx.h:53
int stacklen
Definition: extconf.h:234
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition: pbx.c:3013
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_ignore_pattern ( const char *  context,
const char *  pattern 
)

Checks to see if a number should be ignored.

Parameters
contextcontext to search within
patternto check whether it should be ignored or not

Check if a number should be ignored with respect to dialtone cancellation.

Return values
0if the pattern should not be ignored
non-zeroif the pattern should be ignored

Definition at line 8650 of file pbx.c.

References ast_context_find(), ast_extension_match(), ast_context::ignorepats, ast_ignorepat::next, and ast_ignorepat::pattern.

Referenced by __analog_ss_thread(), analog_ss_thread(), ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_ss(), pri_dchannel(), pri_ss_thread(), and skinny_ss().

8651 {
8652  struct ast_context *con = ast_context_find(context);
8653 
8654  if (con) {
8655  struct ast_ignorepat *pat;
8656 
8657  for (pat = con->ignorepats; pat; pat = pat->next) {
8658  if (ast_extension_match(pat->pattern, pattern))
8659  return 1;
8660  }
8661  }
8662 
8663  return 0;
8664 }
struct ast_ignorepat * ignorepats
Definition: pbx.c:962
const char pattern[0]
Definition: pbx.c:928
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx.c:925
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
Definition: pbx.c:2943
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
struct ast_ignorepat * next
Definition: pbx.c:927
struct ast_context * ast_context_find(const char *name)
Find a context.
Definition: pbx.c:2971
int ast_matchmore_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid 
)

Looks to see if adding anything to this extension might match something. (exists ^ canmatch)

Parameters
cnot really important XXX
contextcontext to serach within
extenextension to check
prioritypriority of extension path
calleridcallerid of extension being searched for
Note
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Returns
If "exten" could match a valid extension in this context with some more digits, return non-zero. Does NOT return non-zero if this is an exact-match only. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 5420 of file pbx.c.

References E_MATCHMORE, and pbx_extension_helper().

Referenced by __analog_ss_thread(), __ast_pbx_run(), analog_ss_thread(), ast_app_dtget(), collect_digits(), dahdi_r2_on_dnis_digit_received(), disa_exec(), dp_lookup(), dundi_lookup_local(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), pri_dchannel(), pri_ss_thread(), readexten_exec(), and skinny_ss().

5421 {
5422  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
5423 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
The return value depends on the action:
Definition: pbx.c:4706
void ast_merge_contexts_and_delete ( struct ast_context **  extcontexts,
struct ast_hashtab exttable,
const char *  registrar 
)

Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.

Parameters
extcontextspointer to the ast_context structure
exttablepointer to the ast_hashtab structure that contains all the elements in extcontexts
registrarof the context; if it's set the routine will delete all contexts that belong to that registrar; if NULL only the contexts that are specified in extcontexts

Definition at line 7937 of file pbx.c.

References __ast_internal_context_destroy(), ao2_callback, ao2_container_count(), ao2_find, ao2_iterator_destroy(), AO2_ITERATOR_DONTLOCK, ao2_iterator_init(), ao2_iterator_next, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_exten::app, ast_add_extension_nolock(), ast_calloc, AST_EXTENSION_REMOVED, ast_free, ast_free_ptr(), ast_hashtab_destroy(), ast_hashtab_end_traversal(), ast_hashtab_next(), ast_hashtab_start_traversal(), ast_hint_extension_nolock(), AST_LIST_HEAD_NOLOCK_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, ast_strdup, ast_tvdiff_us(), ast_tvnow(), ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), ast_hint::callbacks, store_hint::callbacks, ast_state_cb::change_cb, store_hint::context, context_merge(), context_merge_lock, contexts, contexts_table, ast_exten::data, ast_state_cb::data, store_hint::data, E_MATCH, exten, ast_exten::exten, ast_hint::exten, store_hint::exten, hints, ast_hint::laststate, store_hint::laststate, ast_context::name, ast_sw::next, ast_context::next, OBJ_UNLINK, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_exten::registrar, and pbx_find_info::stacklen.

Referenced by lua_reload_extensions(), and pbx_load_module().

7938 {
7939  double ft;
7940  struct ast_context *tmp;
7941  struct ast_context *oldcontextslist;
7942  struct ast_hashtab *oldtable;
7943  struct store_hints hints_stored = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
7944  struct store_hints hints_removed = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
7945  struct store_hint *saved_hint;
7946  struct ast_hint *hint;
7947  struct ast_exten *exten;
7948  int length;
7949  struct ast_state_cb *thiscb;
7950  struct ast_hashtab_iter *iter;
7951  struct ao2_iterator i;
7952  struct timeval begintime;
7953  struct timeval writelocktime;
7954  struct timeval endlocktime;
7955  struct timeval enddeltime;
7956 
7957  /*
7958  * It is very important that this function hold the hints
7959  * container lock _and_ the conlock during its operation; not
7960  * only do we need to ensure that the list of contexts and
7961  * extensions does not change, but also that no hint callbacks
7962  * (watchers) are added or removed during the merge/delete
7963  * process
7964  *
7965  * In addition, the locks _must_ be taken in this order, because
7966  * there are already other code paths that use this order
7967  */
7968 
7969  begintime = ast_tvnow();
7970  ast_mutex_lock(&context_merge_lock);/* Serialize ast_merge_contexts_and_delete */
7972 
7973  if (!contexts_table) {
7974  /* Well, that's odd. There are no contexts. */
7975  contexts_table = exttable;
7976  contexts = *extcontexts;
7979  return;
7980  }
7981 
7983  while ((tmp = ast_hashtab_next(iter))) {
7984  context_merge(extcontexts, exttable, tmp, registrar);
7985  }
7987 
7988  ao2_lock(hints);
7989  writelocktime = ast_tvnow();
7990 
7991  /* preserve all watchers for hints */
7993  for (; (hint = ao2_iterator_next(&i)); ao2_ref(hint, -1)) {
7994  if (ao2_container_count(hint->callbacks)) {
7995  ao2_lock(hint);
7996  if (!hint->exten) {
7997  /* The extension has already been destroyed. (Should never happen here) */
7998  ao2_unlock(hint);
7999  continue;
8000  }
8001 
8002  length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2
8003  + sizeof(*saved_hint);
8004  if (!(saved_hint = ast_calloc(1, length))) {
8005  ao2_unlock(hint);
8006  continue;
8007  }
8008 
8009  /* This removes all the callbacks from the hint into saved_hint. */
8010  while ((thiscb = ao2_callback(hint->callbacks, OBJ_UNLINK, NULL, NULL))) {
8011  AST_LIST_INSERT_TAIL(&saved_hint->callbacks, thiscb, entry);
8012  /*
8013  * We intentionally do not unref thiscb to account for the
8014  * non-ao2 reference in saved_hint->callbacks
8015  */
8016  }
8017 
8018  saved_hint->laststate = hint->laststate;
8019  saved_hint->context = saved_hint->data;
8020  strcpy(saved_hint->data, hint->exten->parent->name);
8021  saved_hint->exten = saved_hint->data + strlen(saved_hint->context) + 1;
8022  strcpy(saved_hint->exten, hint->exten->exten);
8023  ao2_unlock(hint);
8024  AST_LIST_INSERT_HEAD(&hints_stored, saved_hint, list);
8025  }
8026  }
8028 
8029  /* save the old table and list */
8030  oldtable = contexts_table;
8031  oldcontextslist = contexts;
8032 
8033  /* move in the new table and list */
8034  contexts_table = exttable;
8035  contexts = *extcontexts;
8036 
8037  /*
8038  * Restore the watchers for hints that can be found; notify
8039  * those that cannot be restored.
8040  */
8041  while ((saved_hint = AST_LIST_REMOVE_HEAD(&hints_stored, list))) {
8042  struct pbx_find_info q = { .stacklen = 0 };
8043 
8044  exten = pbx_find_extension(NULL, NULL, &q, saved_hint->context, saved_hint->exten,
8045  PRIORITY_HINT, NULL, "", E_MATCH);
8046  /*
8047  * If this is a pattern, dynamically create a new extension for this
8048  * particular match. Note that this will only happen once for each
8049  * individual extension, because the pattern will no longer match first.
8050  */
8051  if (exten && exten->exten[0] == '_') {
8052  ast_add_extension_nolock(exten->parent->name, 0, saved_hint->exten,
8053  PRIORITY_HINT, NULL, 0, exten->app, ast_strdup(exten->data), ast_free_ptr,
8054  exten->registrar);
8055  /* rwlocks are not recursive locks */
8056  exten = ast_hint_extension_nolock(NULL, saved_hint->context,
8057  saved_hint->exten);
8058  }
8059 
8060  /* Find the hint in the hints container */
8061  hint = exten ? ao2_find(hints, exten, 0) : NULL;
8062  if (!hint) {
8063  /*
8064  * Notify watchers of this removed hint later when we aren't
8065  * encumberd by so many locks.
8066  */
8067  AST_LIST_INSERT_HEAD(&hints_removed, saved_hint, list);
8068  } else {
8069  ao2_lock(hint);
8070  while ((thiscb = AST_LIST_REMOVE_HEAD(&saved_hint->callbacks, entry))) {
8071  ao2_link(hint->callbacks, thiscb);
8072  /* Ref that we added when putting into saved_hint->callbacks */
8073  ao2_ref(thiscb, -1);
8074  }
8075  hint->laststate = saved_hint->laststate;
8076  ao2_unlock(hint);
8077  ao2_ref(hint, -1);
8078  ast_free(saved_hint);
8079  }
8080  }
8081 
8082  ao2_unlock(hints);
8084 
8085  /*
8086  * Notify watchers of all removed hints with the same lock
8087  * environment as handle_statechange().
8088  */
8089  while ((saved_hint = AST_LIST_REMOVE_HEAD(&hints_removed, list))) {
8090  /* this hint has been removed, notify the watchers */
8091  while ((thiscb = AST_LIST_REMOVE_HEAD(&saved_hint->callbacks, entry))) {
8092  thiscb->change_cb(saved_hint->context, saved_hint->exten,
8093  AST_EXTENSION_REMOVED, thiscb->data);
8094  /* Ref that we added when putting into saved_hint->callbacks */
8095  ao2_ref(thiscb, -1);
8096  }
8097  ast_free(saved_hint);
8098  }
8099 
8101  endlocktime = ast_tvnow();
8102 
8103  /*
8104  * The old list and hashtab no longer are relevant, delete them
8105  * while the rest of asterisk is now freely using the new stuff
8106  * instead.
8107  */
8108 
8109  ast_hashtab_destroy(oldtable, NULL);
8110 
8111  for (tmp = oldcontextslist; tmp; ) {
8112  struct ast_context *next; /* next starting point */
8113 
8114  next = tmp->next;
8116  tmp = next;
8117  }
8118  enddeltime = ast_tvnow();
8119 
8120  ft = ast_tvdiff_us(writelocktime, begintime);
8121  ft /= 1000000.0;
8122  ast_verb(3,"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft);
8123 
8124  ft = ast_tvdiff_us(endlocktime, writelocktime);
8125  ft /= 1000000.0;
8126  ast_verb(3,"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft);
8127 
8128  ft = ast_tvdiff_us(enddeltime, endlocktime);
8129  ft /= 1000000.0;
8130  ast_verb(3,"Time to delete the old dialplan: %8.6f sec\n", ft);
8131 
8132  ft = ast_tvdiff_us(enddeltime, begintime);
8133  ft /= 1000000.0;
8134  ast_verb(3,"Total time merge_contexts_delete: %8.6f sec\n", ft);
8135 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Definition: astobj2.c:470
static void __ast_internal_context_destroy(struct ast_context *con)
Definition: pbx.c:9670
#define ast_strdup(a)
Definition: astmm.h:109
static struct ast_hashtab * contexts_table
Definition: pbx.c:1286
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
ast_state_cb: An extension state notify register item
Definition: pbx.c:989
void * ast_hashtab_next(struct ast_hashtab_iter *it)
Gets the next object in the list, advances iter one step returns null on end of traversal.
Definition: hashtab.c:753
char * context
Definition: pbx.c:7803
struct ast_hashtab_iter * ast_hashtab_start_traversal(struct ast_hashtab *tab)
Gives an iterator to hastable.
Definition: hashtab.c:696
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:11037
static ast_mutex_t context_merge_lock
Lock to hold off restructuring of hints by ast_merge_contexts_and_delete.
Definition: pbx.c:1299
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
static struct ao2_container * hints
Definition: pbx.c:1314
void ast_free_ptr(void *ptr)
#define ast_verb(level,...)
Definition: logger.h:243
ast_state_cb_type change_cb
Definition: pbx.c:995
#define ao2_ref(o, delta)
Definition: astobj2.h:472
char * exten
Definition: pbx.c:7804
#define ao2_lock(a)
Definition: astobj2.h:488
char * exten
Definition: pbx.c:885
char name[0]
Definition: pbx.c:967
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
#define PRIORITY_HINT
Definition: pbx.h:53
void ast_hashtab_end_traversal(struct ast_hashtab_iter *it)
end the traversal, free the iterator, unlock if necc.
Definition: hashtab.c:746
static void context_merge(struct ast_context **extcontexts, struct ast_hashtab *exttable, struct ast_context *context, const char *registrar)
Definition: pbx.c:7846
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
int laststate
Definition: pbx.c:1019
void * data
Definition: pbx.c:893
int laststate
Definition: pbx.c:7806
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
Structure for dial plan hints.
Definition: pbx.c:1010
struct ast_context * next
Definition: pbx.c:960
an iterator for traversing the buckets
Definition: hashtab.h:105
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
char data[1]
Definition: pbx.c:7808
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
#define ast_free(a)
Definition: astmm.h:97
int stacklen
Definition: extconf.h:234
static char * registrar
Definition: features.c:623
const char * registrar
Definition: pbx.c:898
static int ast_add_extension_nolock(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Definition: pbx.c:8671
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
Definition: linkedlists.h:251
static struct ast_exten * ast_hint_extension_nolock(struct ast_channel *c, const char *context, const char *exten)
Find hint for given extension in context.
Definition: pbx.c:4829
struct ast_context * parent
Definition: pbx.c:890
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
#define ast_calloc(a, b)
Definition: astmm.h:82
const char * app
Definition: pbx.c:891
static struct ast_context * contexts
Definition: pbx.c:1285
int64_t ast_tvdiff_us(struct timeval end, struct timeval start)
Computes the difference (in microseconds) between two struct timeval instances.
Definition: time.h:70
struct store_hint::@294 callbacks
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition: pbx.c:3013
void * data
Definition: pbx.c:993
ast_context: An extension context
Definition: pbx.c:955
struct ao2_container * callbacks
Definition: pbx.c:1018
#define ast_mutex_unlock(a)
Definition: lock.h:156
void ast_hashtab_destroy(struct ast_hashtab *tab, void(*objdestroyfunc)(void *obj))
This func will free the hash table and all its memory.
Definition: hashtab.c:388
int ast_parseable_goto ( struct ast_channel chan,
const char *  goto_string 
)
Note
This function will handle locking the channel as needed.

Definition at line 11326 of file pbx.c.

References pbx_parseable_goto().

Referenced by _while_exec(), check_goto_on_transfer(), dial_exec_full(), gosub_exec(), ivr_dispatch(), parkandannounce_exec(), pbx_builtin_goto(), and while_continue_exec().

11327 {
11328  return pbx_parseable_goto(chan, goto_string, 0);
11329 }
static int pbx_parseable_goto(struct ast_channel *chan, const char *goto_string, int async)
Definition: pbx.c:11271
int ast_pbx_init ( void  )

Provided by pbx.c

Definition at line 11407 of file pbx.c.

References ao2_container_alloc, ast_register_atexit(), HASH_EXTENHINT_SIZE, hint_cmp(), hint_hash(), hints, pbx_shutdown(), statecbs, and statecbs_cmp().

Referenced by main().

11408 {
11411 
11413 
11414  return (hints && statecbs) ? 0 : -1;
11415 }
static int hint_cmp(void *obj, void *arg, int flags)
Definition: pbx.c:11375
static int hint_hash(const void *obj, const int flags)
Definition: pbx.c:11355
static struct ao2_container * hints
Definition: pbx.c:1314
static int statecbs_cmp(void *obj, void *arg, int flags)
Definition: pbx.c:11383
#define HASH_EXTENHINT_SIZE
Definition: pbx.c:1028
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
static void pbx_shutdown(void)
Definition: pbx.c:11391
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
static struct ao2_container * statecbs
Definition: pbx.c:1316
int ast_pbx_outgoing_app ( const char *  type,
format_t  format,
void *  data,
int  timeout,
const char *  app,
const char *  appdata,
int *  reason,
int  sync,
const char *  cid_num,
const char *  cid_name,
struct ast_variable vars,
const char *  account,
struct ast_channel **  locked_channel 
)

Synchronously or asynchronously make an outbound call and send it to a particular application with given extension

Definition at line 9544 of file pbx.c.

References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, async_stat::app, async_stat::appdata, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create_detached, ast_set_variables(), AST_STATE_UP, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), ast_channel::cdr, async_stat::chan, app_tmp::chan, errno, ast_channel::hangupcause, LOG_WARNING, ast_channel::name, async_stat::p, app_tmp::t, async_stat::timeout, and outgoing_helper::vars.

Referenced by action_originate(), attempt_thread(), fast_originate(), orig_app(), and originate_exec().

9545 {
9546  struct ast_channel *chan;
9547  struct app_tmp *tmp;
9548  int res = -1, cdr_res = -1;
9549  struct outgoing_helper oh;
9550 
9551  memset(&oh, 0, sizeof(oh));
9552  oh.vars = vars;
9553  oh.account = account;
9554 
9555  if (locked_channel)
9556  *locked_channel = NULL;
9557  if (ast_strlen_zero(app)) {
9558  res = -1;
9559  goto outgoing_app_cleanup;
9560  }
9561  if (synchronous) {
9562  chan = __ast_request_and_dial(type, format, NULL, data, timeout, reason, cid_num, cid_name, &oh);
9563  if (chan) {
9564  ast_set_variables(chan, vars);
9565  if (account)
9566  ast_cdr_setaccount(chan, account);
9567  if (chan->_state == AST_STATE_UP) {
9568  res = 0;
9569  ast_verb(4, "Channel %s was answered.\n", chan->name);
9570  tmp = ast_calloc(1, sizeof(*tmp));
9571  if (!tmp || ast_string_field_init(tmp, 252)) {
9572  if (tmp) {
9573  ast_free(tmp);
9574  }
9575  res = -1;
9576  } else {
9577  ast_string_field_set(tmp, app, app);
9578  ast_string_field_set(tmp, data, appdata);
9579  tmp->chan = chan;
9580  if (synchronous > 1) {
9581  if (locked_channel)
9582  ast_channel_unlock(chan);
9583  ast_pbx_run_app(tmp);
9584  } else {
9585  if (locked_channel)
9586  ast_channel_lock(chan);
9587  if (ast_pthread_create_detached(&tmp->t, NULL, ast_pbx_run_app, tmp)) {
9588  ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
9590  ast_free(tmp);
9591  if (locked_channel)
9592  ast_channel_unlock(chan);
9593  ast_hangup(chan);
9594  res = -1;
9595  } else {
9596  if (locked_channel)
9597  *locked_channel = chan;
9598  }
9599  }
9600  }
9601  } else {
9602  ast_verb(4, "Channel %s was never answered.\n", chan->name);
9603  if (chan->cdr) { /* update the cdr */
9604  /* here we update the status of the call, which sould be busy.
9605  * if that fails then we set the status to failed */
9606  if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
9607  ast_cdr_failed(chan->cdr);
9608  }
9609  ast_hangup(chan);
9610  }
9611  }
9612 
9613  if (res < 0) { /* the call failed for some reason */
9614  if (*reason == 0) { /* if the call failed (not busy or no answer)
9615  * update the cdr with the failed message */
9616  cdr_res = ast_pbx_outgoing_cdr_failed();
9617  if (cdr_res != 0) {
9618  res = cdr_res;
9619  goto outgoing_app_cleanup;
9620  }
9621  }
9622  }
9623 
9624  } else {
9625  struct async_stat *as;
9626  if (!(as = ast_calloc(1, sizeof(*as)))) {
9627  res = -1;
9628  goto outgoing_app_cleanup;
9629  }
9630  chan = __ast_request_and_dial(type, format, NULL, data, timeout, reason, cid_num, cid_name, &oh);
9631  if (!chan) {
9632  ast_free(as);
9633  res = -1;
9634  goto outgoing_app_cleanup;
9635  }
9636  as->chan = chan;
9637  ast_copy_string(as->app, app, sizeof(as->app));
9638  if (appdata)
9639  ast_copy_string(as->appdata, appdata, sizeof(as->appdata));
9640  as->timeout = timeout;
9641  ast_set_variables(chan, vars);
9642  if (account)
9643  ast_cdr_setaccount(chan, account);
9644  /* Start a new thread, and get something handling this channel. */
9645  if (locked_channel)
9646  ast_channel_lock(chan);
9647  if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
9648  ast_log(LOG_WARNING, "Failed to start async wait\n");
9649  ast_free(as);
9650  if (locked_channel)
9651  ast_channel_unlock(chan);
9652  ast_hangup(chan);
9653  res = -1;
9654  goto outgoing_app_cleanup;
9655  } else {
9656  if (locked_channel)
9657  *locked_channel = chan;
9658  }
9659  res = 0;
9660  }
9661 outgoing_app_cleanup:
9662  ast_variables_destroy(vars);
9663  return res;
9664 }
int ast_cdr_disposition(struct ast_cdr *cdr, int cause)
Save the result of the call based on the AST_CAUSE_*.
Definition: cdr.c:790
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
void ast_cdr_failed(struct ast_cdr *cdr)
Fail a call.
Definition: cdr.c:764
struct ast_channel * chan
Definition: pbx.c:9276
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:422
static int ast_pbx_outgoing_cdr_failed(void)
Function to post an empty cdr after a spool call fails.
Definition: pbx.c:9348
pthread_t p
Definition: pbx.c:9275
struct ast_channel * __ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *reason, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
Request a channel of a given type, with data as optional information used by the low level module and...
Definition: channel.c:5456
#define LOG_WARNING
Definition: logger.h:144
int ast_cdr_setaccount(struct ast_channel *chan, const char *account)
Set account code, will generate AMI event.
Definition: cdr.c:990
void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
adds a list of channel variables to a channel
Definition: channel.c:8261
struct ast_cdr * cdr
Definition: channel.h:766
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:157
struct ast_channel * chan
Definition: pbx.c:9519
#define ast_verb(level,...)
Definition: logger.h:243
int timeout
Definition: pbx.c:9280
struct ast_variable * vars
Definition: channel.h:1005
static const char app[]
Definition: app_adsiprog.c:49
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
const char * account
Definition: channel.h:1004
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
Definition: pbx.c:9518
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
int errno
#define ast_free(a)
Definition: astmm.h:97
char app[AST_MAX_EXTENSION]
Definition: pbx.c:9281
static const char type[]
Definition: chan_nbs.c:57
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:158
static void * async_wait(void *data)
Definition: pbx.c:9285
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static void * ast_pbx_run_app(void *data)
run the application and free the descriptor once done
Definition: pbx.c:9528
int hangupcause
Definition: channel.h:849
pthread_t t
Definition: pbx.c:9520
static snd_pcm_format_t format
Definition: chan_alsa.c:93
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
char appdata[1024]
Definition: pbx.c:9282
static int ast_pbx_outgoing_cdr_failed ( void  )
static

Function to post an empty cdr after a spool call fails.

Note
This function posts an empty cdr for a failed spool call

Definition at line 9348 of file pbx.c.

References ast_cdr_alloc(), ast_cdr_detach(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_start(), ast_channel_unref, ast_dummy_channel_alloc(), and ast_channel::cdr.

Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

9349 {
9350  /* allocate a channel */
9351  struct ast_channel *chan = ast_dummy_channel_alloc();
9352 
9353  if (!chan)
9354  return -1; /* failure */
9355 
9356  chan->cdr = ast_cdr_alloc();
9357  if (!chan->cdr) {
9358  /* allocation of the cdr failed */
9359  chan = ast_channel_unref(chan); /* free the channel */
9360  return -1; /* return failure */
9361  }
9362 
9363  /* allocation of the cdr was successful */
9364  ast_cdr_init(chan->cdr, chan); /* initialize our channel's cdr */
9365  ast_cdr_start(chan->cdr); /* record the start and stop time */
9366  ast_cdr_end(chan->cdr);
9367  ast_cdr_failed(chan->cdr); /* set the status to failed */
9368  ast_cdr_detach(chan->cdr); /* post and free the record */
9369  chan->cdr = NULL;
9370  chan = ast_channel_unref(chan); /* free the channel */
9371 
9372  return 0; /* success */
9373 }
Main Channel structure associated with a channel.
Definition: channel.h:742
void ast_cdr_failed(struct ast_cdr *cdr)
Fail a call.
Definition: cdr.c:764
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void ast_cdr_end(struct ast_cdr *cdr)
End a call.
Definition: cdr.c:933
struct ast_cdr * cdr
Definition: channel.h:766
void ast_cdr_start(struct ast_cdr *cdr)
Start a call.
Definition: cdr.c:727
void ast_cdr_detach(struct ast_cdr *cdr)
Detaches the detail record for posting (and freeing) either now or at a later time in bulk with other...
Definition: cdr.c:1328
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
int ast_cdr_init(struct ast_cdr *cdr, struct ast_channel *chan)
Initialize based on a channel.
Definition: cdr.c:897
struct ast_cdr * ast_cdr_alloc(void)
Allocate a CDR record.
Definition: cdr.c:499
int ast_pbx_outgoing_exten ( const char *  type,
format_t  format,
void *  data,
int  timeout,
const char *  context,
const char *  exten,
int  priority,
int *  reason,
int  sync,
const char *  cid_num,
const char *  cid_name,
struct ast_variable vars,
const char *  account,
struct ast_channel **  locked_channel 
)

Synchronously or asynchronously make an outbound call and send it to a particular extension

Definition at line 9375 of file pbx.c.

References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_exists_extension(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create_detached, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), ast_channel::cdr, async_stat::chan, cid_name, outgoing_helper::cid_name, cid_num, outgoing_helper::cid_num, context, ast_channel::context, outgoing_helper::context, async_stat::context, exten, outgoing_helper::exten, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, ast_channel::name, async_stat::p, outgoing_helper::parent_channel, pbx_builtin_setvar_helper(), outgoing_helper::priority, set_ext_pri(), async_stat::timeout, and outgoing_helper::vars.

Referenced by action_originate(), attempt_thread(), fast_originate(), orig_exten(), and originate_exec().

9376 {
9377  struct ast_channel *chan;
9378  struct async_stat *as;
9379  int res = -1, cdr_res = -1;
9380  struct outgoing_helper oh;
9381 
9382  if (synchronous) {
9383  oh.context = context;
9384  oh.exten = exten;
9385  oh.priority = priority;
9386  oh.cid_num = cid_num;
9387  oh.cid_name = cid_name;
9388  oh.account = account;
9389  oh.vars = vars;
9390  oh.parent_channel = NULL;
9391 
9392  chan = __ast_request_and_dial(type, format, NULL, data, timeout, reason, cid_num, cid_name, &oh);
9393  if (channel) {
9394  *channel = chan;
9395  if (chan)
9396  ast_channel_lock(chan);
9397  }
9398  if (chan) {
9399  if (chan->_state == AST_STATE_UP) {
9400  res = 0;
9401  ast_verb(4, "Channel %s was answered.\n", chan->name);
9402 
9403  if (synchronous > 1) {
9404  if (channel)
9405  ast_channel_unlock(chan);
9406  if (ast_pbx_run(chan)) {
9407  ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
9408  if (channel)
9409  *channel = NULL;
9410  ast_hangup(chan);
9411  chan = NULL;
9412  res = -1;
9413  }
9414  } else {
9415  if (ast_pbx_start(chan)) {
9416  ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
9417  if (channel) {
9418  *channel = NULL;
9419  ast_channel_unlock(chan);
9420  }
9421  ast_hangup(chan);
9422  res = -1;
9423  }
9424  chan = NULL;
9425  }
9426  } else {
9427  ast_verb(4, "Channel %s was never answered.\n", chan->name);
9428 
9429  if (chan->cdr) { /* update the cdr */
9430  /* here we update the status of the call, which sould be busy.
9431  * if that fails then we set the status to failed */
9432  if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
9433  ast_cdr_failed(chan->cdr);
9434  }
9435 
9436  if (channel) {
9437  *channel = NULL;
9438  ast_channel_unlock(chan);
9439  }
9440  ast_hangup(chan);
9441  chan = NULL;
9442  }
9443  }
9444 
9445  if (res < 0) { /* the call failed for some reason */
9446  if (*reason == 0) { /* if the call failed (not busy or no answer)
9447  * update the cdr with the failed message */
9448  cdr_res = ast_pbx_outgoing_cdr_failed();
9449  if (cdr_res != 0) {
9450  res = cdr_res;
9451  goto outgoing_exten_cleanup;
9452  }
9453  }
9454 
9455  /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
9456  /* check if "failed" exists */
9457  if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
9458  chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", NULL, 0, "OutgoingSpoolFailed");
9459  if (chan) {
9460  char failed_reason[4] = "";
9461  if (!ast_strlen_zero(context))
9462  ast_copy_string(chan->context, context, sizeof(chan->context));
9463  set_ext_pri(chan, "failed", 1);
9464  ast_set_variables(chan, vars);
9465  snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
9466  pbx_builtin_setvar_helper(chan, "REASON", failed_reason);
9467  if (account)
9468  ast_cdr_setaccount(chan, account);
9469  if (ast_pbx_run(chan)) {
9470  ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
9471  ast_hangup(chan);
9472  }
9473  chan = NULL;
9474  }
9475  }
9476  }
9477  } else {
9478  if (!(as = ast_calloc(1, sizeof(*as)))) {
9479  res = -1;
9480  goto outgoing_exten_cleanup;
9481  }
9482  chan = ast_request_and_dial(type, format, NULL, data, timeout, reason, cid_num, cid_name);
9483  if (channel) {
9484  *channel = chan;
9485  if (chan)
9486  ast_channel_lock(chan);
9487  }
9488  if (!chan) {
9489  ast_free(as);
9490  res = -1;
9491  goto outgoing_exten_cleanup;
9492  }
9493  as->chan = chan;
9494  ast_copy_string(as->context, context, sizeof(as->context));
9495  set_ext_pri(as->chan, exten, priority);
9496  as->timeout = timeout;
9497  ast_set_variables(chan, vars);
9498  if (account)
9499  ast_cdr_setaccount(chan, account);
9500  if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
9501  ast_log(LOG_WARNING, "Failed to start async wait\n");
9502  ast_free(as);
9503  if (channel) {
9504  *channel = NULL;
9505  ast_channel_unlock(chan);
9506  }
9507  ast_hangup(chan);
9508  res = -1;
9509  goto outgoing_exten_cleanup;
9510  }
9511  res = 0;
9512  }
9513 outgoing_exten_cleanup:
9514  ast_variables_destroy(vars);
9515  return res;
9516 }
int ast_cdr_disposition(struct ast_cdr *cdr, int cause)
Save the result of the call based on the AST_CAUSE_*.
Definition: cdr.c:790
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
#define ast_channel_lock(chan)
Definition: channel.h:2466
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
void ast_cdr_failed(struct ast_cdr *cdr)
Fail a call.
Definition: cdr.c:764
struct ast_channel * chan
Definition: pbx.c:9276
char context[AST_MAX_CONTEXT]
Definition: pbx.c:9277
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:422
static int ast_pbx_outgoing_cdr_failed(void)
Function to post an empty cdr after a spool call fails.
Definition: pbx.c:9348
pthread_t p
Definition: pbx.c:9275
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
struct ast_channel * __ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *reason, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
Request a channel of a given type, with data as optional information used by the low level module and...
Definition: channel.c:5456
#define LOG_WARNING
Definition: logger.h:144
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:5879
int ast_cdr_setaccount(struct ast_channel *chan, const char *account)
Set account code, will generate AMI event.
Definition: cdr.c:990
void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
adds a list of channel variables to a channel
Definition: channel.c:8261
struct ast_cdr * cdr
Definition: channel.h:766
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:157
#define ast_verb(level,...)
Definition: logger.h:243
int timeout
Definition: pbx.c:9280
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
Definition: channel.c:9825
struct ast_variable * vars
Definition: channel.h:1005
const char * account
Definition: channel.h:1004
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
#define LOG_ERROR
Definition: logger.h:155
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_free(a)
Definition: astmm.h:97
static const char type[]
Definition: chan_nbs.c:57
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:158
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
static void * async_wait(void *data)
Definition: pbx.c:9285
struct ast_channel * ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *reason, const char *cid_num, const char *cid_name)
Request a channel of a given type, with data as optional information used by the low level module and...
Definition: channel.c:5650
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
const char * context
Definition: channel.h:999
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:5926
int hangupcause
Definition: channel.h:849
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
Definition: pbx.c:5431
static snd_pcm_format_t format
Definition: chan_alsa.c:93
enum ast_pbx_result ast_pbx_run ( struct ast_channel c)

Execute the PBX in the current thread.

Parameters
cchannel to run the pbx on

This executes the PBX on a given channel. It allocates a new PBX structure for the channel, and provides all PBX functionality. See ast_pbx_start for an asynchronous function to run the PBX in a new thread as opposed to the current one.

Return values
Zeroon success
non-zeroon failure

Definition at line 5926 of file pbx.c.

References ast_pbx_run_args().

Referenced by __analog_ss_thread(), analog_ss_thread(), ast_pbx_outgoing_exten(), async_wait(), do_idle_thread(), do_notify(), mgcp_ss(), pri_ss_thread(), skinny_newcall(), and unistim_ss().

5927 {
5928  return ast_pbx_run_args(c, NULL);
5929 }
enum ast_pbx_result ast_pbx_run_args(struct ast_channel *c, struct ast_pbx_args *args)
Execute the PBX in the current thread.
Definition: pbx.c:5906
static void* ast_pbx_run_app ( void *  data)
static

run the application and free the descriptor once done

Definition at line 9528 of file pbx.c.

References app, app_tmp::app, ast_free, ast_hangup(), ast_log(), ast_string_field_free_memory, ast_verb, app_tmp::chan, ast_sw::data, app_tmp::data, LOG_WARNING, ast_channel::name, pbx_exec(), and pbx_findapp().

Referenced by ast_pbx_outgoing_app().

9529 {
9530  struct app_tmp *tmp = data;
9531  struct ast_app *app;
9532  app = pbx_findapp(tmp->app);
9533  if (app) {
9534  ast_verb(4, "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name);
9535  pbx_exec(tmp->chan, app, tmp->data);
9536  } else
9537  ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app);
9538  ast_hangup(tmp->chan);
9540  ast_free(tmp);
9541  return NULL;
9542 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: pbx.c:1537
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx.c:1497
#define LOG_WARNING
Definition: logger.h:144
struct ast_channel * chan
Definition: pbx.c:9519
#define ast_verb(level,...)
Definition: logger.h:243
static const char app[]
Definition: app_adsiprog.c:49
Definition: pbx.c:9518
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
ast_app: A registered application
Definition: pbx.c:971
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
const ast_string_field data
Definition: pbx.c:9524
const ast_string_field app
Definition: pbx.c:9524
enum ast_pbx_result ast_pbx_run_args ( struct ast_channel c,
struct ast_pbx_args args 
)

Execute the PBX in the current thread.

Parameters
cchannel to run the pbx on
argsoptions for the pbx

This executes the PBX on a given channel. It allocates a new PBX structure for the channel, and provides all PBX functionality. See ast_pbx_start for an asynchronous function to run the PBX in a new thread as opposed to the current one.

Return values
Zeroon success
non-zeroon failure

Definition at line 5906 of file pbx.c.

References __ast_pbx_run(), ast_log(), AST_OPT_FLAG_FULLY_BOOTED, ast_options, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_test_flag, decrease_call_count(), increase_call_count(), and LOG_WARNING.

Referenced by ast_pbx_run(), dial_exec_full(), handle_gosub(), and try_calling().

5907 {
5908  enum ast_pbx_result res = AST_PBX_SUCCESS;
5909 
5911  ast_log(LOG_WARNING, "PBX requires Asterisk to be fully booted\n");
5912  return AST_PBX_FAILED;
5913  }
5914 
5915  if (increase_call_count(c)) {
5916  return AST_PBX_CALL_LIMIT;
5917  }
5918 
5919  res = __ast_pbx_run(c, args);
5920 
5922 
5923  return res;
5924 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void decrease_call_count(void)
Definition: pbx.c:5837
#define LOG_WARNING
Definition: logger.h:144
static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c, struct ast_pbx_args *args)
Definition: pbx.c:5473
static int increase_call_count(const struct ast_channel *c)
Increase call count for channel.
Definition: pbx.c:5790
ast_pbx_result
The result codes when starting the PBX on a channel with ast_pbx_start.
Definition: pbx.h:299
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_flags ast_options
Definition: asterisk.c:178
enum ast_pbx_result ast_pbx_start ( struct ast_channel c)

Create a new thread and start the PBX.

Parameters
cchannel to start the pbx on
See Also
ast_pbx_run for a synchronous function to run the PBX in the current thread, as opposed to starting a new one.
Return values
Zeroon success
non-zeroon failure

Definition at line 5879 of file pbx.c.

References ast_log(), AST_OPT_FLAG_FULLY_BOOTED, ast_options, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create_detached, ast_test_flag, decrease_call_count(), increase_call_count(), LOG_WARNING, and pbx_thread().

Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_call_thread(), bridge_exec(), check_goto_on_transfer(), console_new(), dahdi_new(), dial_exec_full(), generic_recall(), gtalk_new(), gtalk_newcall(), handle_request_invite(), jingle_new(), jingle_newcall(), local_call(), manage_parked_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), pri_dchannel(), skinny_new(), and unistim_new().

5880 {
5881  pthread_t t;
5882 
5883  if (!c) {
5884  ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
5885  return AST_PBX_FAILED;
5886  }
5887 
5889  ast_log(LOG_WARNING, "PBX requires Asterisk to be fully booted\n");
5890  return AST_PBX_FAILED;
5891  }
5892 
5893  if (increase_call_count(c))
5894  return AST_PBX_CALL_LIMIT;
5895 
5896  /* Start a new thread, and get something handling this channel. */
5897  if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) {
5898  ast_log(LOG_WARNING, "Failed to create new channel thread\n");
5900  return AST_PBX_FAILED;
5901  }
5902 
5903  return AST_PBX_SUCCESS;
5904 }
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:422
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void decrease_call_count(void)
Definition: pbx.c:5837
#define LOG_WARNING
Definition: logger.h:144
static int increase_call_count(const struct ast_channel *c)
Increase call count for channel.
Definition: pbx.c:5790
static void * pbx_thread(void *data)
Definition: pbx.c:5859
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_flags ast_options
Definition: asterisk.c:178
int ast_processed_calls ( void  )

Retrieve the total number of calls processed through the PBX since last restart.

Definition at line 5936 of file pbx.c.

References totalcalls.

Referenced by ast_var_Config(), handle_chanlist(), and handle_showcalls().

5937 {
5938  return totalcalls;
5939 }
static int totalcalls
Definition: pbx.c:1229
int ast_rdlock_context ( struct ast_context con)

Read locks a given context.

Parameters
concontext to lock
Return values
0on success
-1on failure

Definition at line 11060 of file pbx.c.

References ast_rwlock_rdlock, and ast_context::lock.

Referenced by _macro_exec(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_cli_dialplan_save(), lookup_c_ip(), lookup_ci(), manager_show_dialplan_helper(), show_debug_helper(), and show_dialplan_helper().

11061 {
11062  return ast_rwlock_rdlock(&con->lock);
11063 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:201
ast_rwlock_t lock
Definition: pbx.c:956
int ast_register_application2 ( const char *  app,
int(*)(struct ast_channel *, const char *)  execute,
const char *  synopsis,
const char *  description,
void *  mod 
)

Dynamically register a new dial plan application.

Register an application.

Definition at line 6344 of file pbx.c.

References ast_app::arguments, ast_calloc, ast_free, ast_log(), ast_module_name(), AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, AST_STATIC_DOC, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_verb, AST_XML_DOC, ast_xmldoc_build_arguments(), ast_xmldoc_build_description(), ast_xmldoc_build_seealso(), ast_xmldoc_build_synopsis(), ast_xmldoc_build_syntax(), COLOR_BRCYAN, ast_app::docsrc, ast_app::execute, LOG_WARNING, ast_app::seealso, ast_app::syntax, and term_color().

Referenced by ast_cc_init(), ast_features_init(), and load_pbx().

6345 {
6346  struct ast_app *tmp, *cur = NULL;
6347  char tmps[80];
6348  int length, res;
6349 #ifdef AST_XML_DOCS
6350  char *tmpxml;
6351 #endif
6352 
6354  AST_RWLIST_TRAVERSE(&apps, tmp, list) {
6355  if (!(res = strcasecmp(app, tmp->name))) {
6356  ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
6358  return -1;
6359  } else if (res < 0)
6360  break;
6361  }
6362 
6363  length = sizeof(*tmp) + strlen(app) + 1;
6364 
6365  if (!(tmp = ast_calloc(1, length))) {
6367  return -1;
6368  }
6369 
6370  if (ast_string_field_init(tmp, 128)) {
6372  ast_free(tmp);
6373  return -1;
6374  }
6375 
6376  strcpy(tmp->name, app);
6377  tmp->execute = execute;
6378  tmp->module = mod;
6379 
6380 #ifdef AST_XML_DOCS
6381  /* Try to lookup the docs in our XML documentation database */
6383  /* load synopsis */
6384  tmpxml = ast_xmldoc_build_synopsis("application", app, ast_module_name(tmp->module));
6385  ast_string_field_set(tmp, synopsis, tmpxml);
6386  ast_free(tmpxml);
6387 
6388  /* load description */
6389  tmpxml = ast_xmldoc_build_description("application", app, ast_module_name(tmp->module));
6390  ast_string_field_set(tmp, description, tmpxml);
6391  ast_free(tmpxml);
6392 
6393  /* load syntax */
6394  tmpxml = ast_xmldoc_build_syntax("application", app, ast_module_name(tmp->module));
6395  ast_string_field_set(tmp, syntax, tmpxml);
6396  ast_free(tmpxml);
6397 
6398  /* load arguments */
6399  tmpxml = ast_xmldoc_build_arguments("application", app, ast_module_name(tmp->module));
6400  ast_string_field_set(tmp, arguments, tmpxml);
6401  ast_free(tmpxml);
6402 
6403  /* load seealso */
6404  tmpxml = ast_xmldoc_build_seealso("application", app, ast_module_name(tmp->module));
6405  ast_string_field_set(tmp, seealso, tmpxml);
6406  ast_free(tmpxml);
6407  tmp->docsrc = AST_XML_DOC;
6408  } else {
6409 #endif
6412 #ifdef AST_XML_DOCS
6413  tmp->docsrc = AST_STATIC_DOC;
6414  }
6415 #endif
6416 
6417  /* Store in alphabetical order */
6418  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
6419  if (strcasecmp(tmp->name, cur->name) < 0) {
6421  break;
6422  }
6423  }
6425  if (!cur)
6426  AST_RWLIST_INSERT_TAIL(&apps, tmp, list);
6427 
6428  ast_verb(2, "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
6429 
6431 
6432  return 0;
6433 }
const ast_string_field description
Definition: pbx.c:979
Definition: pbx.c:1301
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
char * ast_xmldoc_build_description(const char *type, const char *name, const char *module)
Generate description documentation from XML.
Definition: xmldoc.c:1899
char * ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
Generate synopsis documentation from XML.
Definition: xmldoc.c:1894
char * ast_xmldoc_build_arguments(const char *type, const char *name, const char *module)
Generate the [arguments] tag based on type of node (&#39;application&#39;, &#39;function&#39; or &#39;agi&#39;) and name...
Definition: xmldoc.c:1761
#define ast_verb(level,...)
Definition: logger.h:243
#define COLOR_BRCYAN
Definition: term.h:60
static const char app[]
Definition: app_adsiprog.c:49
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:595
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
const ast_string_field syntax
Definition: pbx.c:979
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char * synopsis
Definition: func_enum.c:156
#define ast_free(a)
Definition: astmm.h:97
enum ast_doc_src docsrc
Definition: pbx.c:981
char * ast_xmldoc_build_syntax(const char *type, const char *name, const char *module)
Get the syntax for a specified application or function.
Definition: xmldoc.c:1156
char * ast_xmldoc_build_seealso(const char *type, const char *name, const char *module)
Parse the &lt;see-also&gt; node content.
Definition: xmldoc.c:1461
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
const char * ast_module_name(const struct ast_module *mod)
Get the name of a module.
Definition: loader.c:104
#define ast_calloc(a, b)
Definition: astmm.h:82
ast_app: A registered application
Definition: pbx.c:971
const ast_string_field seealso
Definition: pbx.c:979
int(* execute)(struct ast_channel *chan, const char *data)
Definition: pbx.c:972
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
const ast_string_field arguments
Definition: pbx.c:979
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
int ast_register_switch ( struct ast_switch sw)

Register an alternative dialplan switch.

Parameters
swswitch to register

This function registers a populated ast_switch structure with the asterisk switching architecture.

Return values
0success
non-zerofailure

Definition at line 6439 of file pbx.c.

References ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, LOG_WARNING, and ast_switch::name.

Referenced by load_module().

6440 {
6441  struct ast_switch *tmp;
6442 
6445  if (!strcasecmp(tmp->name, sw->name)) {
6447  ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
6448  return -1;
6449  }
6450  }
6453 
6454  return 0;
6455 }
struct ast_switch::@191 list
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * name
Definition: pbx.h:130
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Definition: pbx.c:1303
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
static int ast_remove_hint ( struct ast_exten e)
static

Remove hint from extension.

Definition at line 5237 of file pbx.c.

References ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_copy_string(), ast_get_context_name(), ast_get_extension_context(), ast_get_extension_name(), ast_hint::context_name, ast_hint::exten, ast_hint::exten_name, hints, and OBJ_UNLINK.

Referenced by destroy_exten().

5238 {
5239  /* Cleanup the Notifys if hint is removed */
5240  struct ast_hint *hint;
5241 
5242  if (!e) {
5243  return -1;
5244  }
5245 
5246  hint = ao2_find(hints, e, OBJ_UNLINK);
5247  if (!hint) {
5248  return -1;
5249  }
5250 
5251  /*
5252  * The extension is being destroyed so we must save some
5253  * information to notify that the extension is deactivated.
5254  */
5255  ao2_lock(hint);
5258  sizeof(hint->context_name));
5260  sizeof(hint->exten_name));
5261  hint->exten = NULL;
5262  ao2_unlock(hint);
5263 
5264  ao2_ref(hint, -1);
5265 
5266  return 0;
5267 }
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
#define ao2_unlock(a)
Definition: astobj2.h:497
static struct ao2_container * hints
Definition: pbx.c:1314
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
char context_name[AST_MAX_CONTEXT]
Definition: pbx.c:1020
Structure for dial plan hints.
Definition: pbx.c:1010
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char exten_name[AST_MAX_EXTENSION]
Definition: pbx.c:1021
struct ast_context * ast_get_extension_context(struct ast_exten *exten)
Definition: pbx.c:11078
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 
)

Launch a new extension (i.e. new stack)

Parameters
cnot important
contextwhich context to generate the extension within
extennew extension to add
prioritypriority of new extension
calleridcallerid of extension
found
combined_find_spawnThis adds a new extension to the asterisk extension list.
Note
It is possible for autoservice to be started and stopped on c during this function call, it is important that c is not locked prior to calling this. Otherwise a deadlock may occur
Return values
0on success
-1on failure.

Definition at line 5425 of file pbx.c.

References E_SPAWN, and pbx_extension_helper().

Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), dial_exec_full(), gosub_run(), and loopback_exec().

5426 {
5427  return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
5428 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action, int *found, int combined_find_spawn)
The return value depends on the action:
Definition: pbx.c:4706
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 
)

Get hint for channel.

If an extension hint exists, return non-zero.

Definition at line 5380 of file pbx.c.

References ast_get_extension_app(), ast_get_extension_app_data(), ast_hint_extension(), and ast_str_set().

Referenced by ast_str_retrieve_variable().

5381 {
5382  struct ast_exten *e = ast_hint_extension(c, context, exten);
5383 
5384  if (!e) {
5385  return 0;
5386  }
5387 
5388  if (hint) {
5389  ast_str_set(hint, hintsize, "%s", ast_get_extension_app(e));
5390  }
5391  if (name) {
5392  const char *tmp = ast_get_extension_app_data(e);
5393  if (tmp) {
5394  ast_str_set(name, namesize, "%s", tmp);
5395  }
5396  }
5397  return -1;
5398 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:11141
void * ast_get_extension_app_data(struct ast_exten *e)
Definition: pbx.c:11146
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
static struct ast_exten * ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
Definition: pbx.c:4835
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
const char* ast_str_retrieve_variable ( struct ast_str **  buf,
ssize_t  maxlen,
struct ast_channel chan,
struct varshead headp,
const char *  var 
)
Parameters
bufResult will be placed in this buffer.
maxlen-1 if the buffer should not grow, 0 if the buffer may grow to any size, and >0 if the buffer should grow only to that number of bytes.
chanChannel variables from which to extract values, and channel to pass to any dialplan functions.
headpIf no channel is specified, a channel list from which to extract variable values
varVariable name to retrieve.

Definition at line 3445 of file pbx.c.

References ast_party_caller::ani2, ARRAY_LEN, ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_debug, ast_eid_default, ast_eid_to_str(), AST_LIST_TRAVERSE, ast_party_id_presentation(), ast_rwlock_rdlock, ast_rwlock_unlock, ast_str_buffer(), ast_str_get_hint(), ast_str_set(), ast_str_substring(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::caller, ast_channel::context, ast_channel::dialed, ast_var_t::entries, ast_channel::exten, globals, globalslock, ast_channel::hangupcause, ast_party_caller::id, ast_channel::name, ast_party_id::number, parse_variable_name(), ast_party_number::plan, ast_channel::priority, ast_party_dialed::transit_network_select, ast_channel::uniqueid, and ast_channel::varshead.

Referenced by ast_str_substitute_variables_full(), and pbx_retrieve_variable().

3446 {
3447  const char not_found = '\0';
3448  char *tmpvar;
3449  const char *ret;
3450  const char *s; /* the result */
3451  int offset, length;
3452  int i, need_substring;
3453  struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */
3454  char workspace[20];
3455 
3456  if (c) {
3457  ast_channel_lock(c);
3458  places[0] = &c->varshead;
3459  }
3460  /*
3461  * Make a copy of var because parse_variable_name() modifies the string.
3462  * Then if called directly, we might need to run substring() on the result;
3463  * remember this for later in 'need_substring', 'offset' and 'length'
3464  */
3465  tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
3466  need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
3467 
3468  /*
3469  * Look first into predefined variables, then into variable lists.
3470  * Variable 's' points to the result, according to the following rules:
3471  * s == &not_found (set at the beginning) means that we did not find a
3472  * matching variable and need to look into more places.
3473  * If s != &not_found, s is a valid result string as follows:
3474  * s = NULL if the variable does not have a value;
3475  * you typically do this when looking for an unset predefined variable.
3476  * s = workspace if the result has been assembled there;
3477  * typically done when the result is built e.g. with an snprintf(),
3478  * so we don't need to do an additional copy.
3479  * s != workspace in case we have a string, that needs to be copied
3480  * (the ast_copy_string is done once for all at the end).
3481  * Typically done when the result is already available in some string.
3482  */
3483  s = &not_found; /* default value */
3484  if (c) { /* This group requires a valid channel */
3485  /* Names with common parts are looked up a piece at a time using strncmp. */
3486  if (!strncmp(var, "CALL", 4)) {
3487  if (!strncmp(var + 4, "ING", 3)) {
3488  if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */
3489  ast_str_set(str, maxlen, "%d",
3491  s = ast_str_buffer(*str);
3492  } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */
3493  ast_str_set(str, maxlen, "%d", c->caller.ani2);
3494  s = ast_str_buffer(*str);
3495  } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */
3496  ast_str_set(str, maxlen, "%d", c->caller.id.number.plan);
3497  s = ast_str_buffer(*str);
3498  } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */
3499  ast_str_set(str, maxlen, "%d", c->dialed.transit_network_select);
3500  s = ast_str_buffer(*str);
3501  }
3502  }
3503  } else if (!strcmp(var, "HINT")) {
3504  s = ast_str_get_hint(str, maxlen, NULL, 0, c, c->context, c->exten) ? ast_str_buffer(*str) : NULL;
3505  } else if (!strcmp(var, "HINTNAME")) {
3506  s = ast_str_get_hint(NULL, 0, str, maxlen, c, c->context, c->exten) ? ast_str_buffer(*str) : NULL;
3507  } else if (!strcmp(var, "EXTEN")) {
3508  s = c->exten;
3509  } else if (!strcmp(var, "CONTEXT")) {
3510  s = c->context;
3511  } else if (!strcmp(var, "PRIORITY")) {
3512  ast_str_set(str, maxlen, "%d", c->priority);
3513  s = ast_str_buffer(*str);
3514  } else if (!strcmp(var, "CHANNEL")) {
3515  s = c->name;
3516  } else if (!strcmp(var, "UNIQUEID")) {
3517  s = c->uniqueid;
3518  } else if (!strcmp(var, "HANGUPCAUSE")) {
3519  ast_str_set(str, maxlen, "%d", c->hangupcause);
3520  s = ast_str_buffer(*str);
3521  }
3522  }
3523  if (s == &not_found) { /* look for more */
3524  if (!strcmp(var, "EPOCH")) {
3525  ast_str_set(str, maxlen, "%d", (int) time(NULL));
3526  s = ast_str_buffer(*str);
3527  } else if (!strcmp(var, "SYSTEMNAME")) {
3529  } else if (!strcmp(var, "ENTITYID")) {
3530  ast_eid_to_str(workspace, sizeof(workspace), &ast_eid_default);
3531  s = workspace;
3532  }
3533  }
3534  /* if not found, look into chanvars or global vars */
3535  for (i = 0; s == &not_found && i < ARRAY_LEN(places); i++) {
3536  struct ast_var_t *variables;
3537  if (!places[i])
3538  continue;
3539  if (places[i] == &globals)
3541  AST_LIST_TRAVERSE(places[i], variables, entries) {
3542  if (!strcasecmp(ast_var_name(variables), var)) {
3543  s = ast_var_value(variables);
3544  break;
3545  }
3546  }
3547  if (places[i] == &globals)
3549  }
3550  if (s == &not_found || s == NULL) {
3551  ast_debug(5, "Result of '%s' is NULL\n", var);
3552  ret = NULL;
3553  } else {
3554  ast_debug(5, "Result of '%s' is '%s'\n", var, s);
3555  if (s != ast_str_buffer(*str)) {
3556  ast_str_set(str, maxlen, "%s", s);
3557  }
3558  ret = ast_str_buffer(*str);
3559  if (need_substring) {
3560  ret = ast_str_substring(*str, offset, length);
3561  ast_debug(2, "Final result of '%s' is '%s'\n", var, ret);
3562  }
3563  }
3564 
3565  if (c) {
3566  ast_channel_unlock(c);
3567  }
3568  return ret;
3569 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:201
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int priority
Definition: channel.h:841
const ast_string_field uniqueid
Definition: channel.h:787
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Definition: netsock.c:222
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:89
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:2151
static ast_rwlock_t globalslock
Definition: pbx.c:1217
#define var
Definition: ast_expr2f.c:606
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)
If an extension hint exists, return non-zero.
Definition: pbx.c:5380
#define ast_rwlock_unlock(a)
Definition: lock.h:200
const char * ast_config_AST_SYSTEM_NAME
Definition: asterisk.c:273
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:243
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:380
const ast_string_field name
Definition: channel.h:787
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct ast_var_t::@158 entries
struct ast_eid ast_eid_default
Global EID.
Definition: asterisk.c:192
int transit_network_select
Transit Network Select.
Definition: channel.h:347
static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
extract offset:length from variable name.
Definition: pbx.c:3311
int hangupcause
Definition: channel.h:849
static struct varshead globals
Definition: pbx.c:1218
struct varshead varshead
Definition: channel.h:817
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static const char * ast_str_substring(struct ast_str *value, int offset, int length)
Definition: pbx.c:3380
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
void ast_str_substitute_variables ( struct ast_str **  buf,
ssize_t  maxlen,
struct ast_channel chan,
const char *  templ 
)
Parameters
bufResult will be placed in this buffer.
maxlen-1 if the buffer should not grow, 0 if the buffer may grow to any size, and >0 if the buffer should grow only to that number of bytes.
chanChannel variables from which to extract values, and channel to pass to any dialplan functions.
templVariable template to expand.

Definition at line 4468 of file pbx.c.

References ast_str_substitute_variables_full().

Referenced by _macro_exec(), acf_odbc_read(), acf_odbc_write(), cli_odbc_read(), cli_odbc_write(), config_curl(), custom_log(), cut_internal(), destroy_curl(), exec_exec(), func_mchan_read(), function_eval2(), function_fieldnum_helper(), function_fieldqty_helper(), handle_getvariablefull(), import_helper(), listfilter(), make_email_file(), realtime_curl(), realtime_multi_curl(), replace(), require_curl(), sendmail(), sendpage(), shift_pop(), store_curl(), syslog_log(), tryexec_exec(), unshift_push(), update2_curl(), and update_curl().

4469 {
4470  size_t used;
4471  ast_str_substitute_variables_full(buf, maxlen, chan, NULL, templ, &used);
4472 }
void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *templ, size_t *used)
Definition: pbx.c:4289
void ast_str_substitute_variables_full ( struct ast_str **  buf,
ssize_t  maxlen,
struct ast_channel c,
struct varshead headp,
const char *  templ,
size_t *  used 
)
Parameters
bufResult will be placed in this buffer.
maxlen-1 if the buffer should not grow, 0 if the buffer may grow to any size, and >0 if the buffer should grow only to that number of bytes.
cChannel variables from which to extract values, and channel to pass to any dialplan functions.
headpIf no channel is specified, a channel list from which to extract variable values
templVariable template to expand.
usedNumber of bytes read from the template.

Definition at line 4289 of file pbx.c.

References ast_channel_unref, ast_debug, ast_dummy_channel_alloc(), ast_free, ast_func_read2(), ast_log(), ast_str_append(), ast_str_append_substr(), ast_str_buffer(), ast_str_create(), ast_str_expr(), ast_str_reset(), ast_str_retrieve_variable(), ast_str_set_substr(), ast_str_strlen(), ast_str_substitute_variables_full(), ast_str_substring(), ast_strlen_zero(), len(), LOG_ERROR, LOG_WARNING, parse_variable_name(), and ast_channel::varshead.

Referenced by ast_str_substitute_variables(), ast_str_substitute_variables_full(), and ast_str_substitute_variables_varshead().

4290 {
4291  /* Substitutes variables into buf, based on string templ */
4292  char *cp4 = NULL;
4293  const char *tmp, *whereweare;
4294  int orig_size = 0;
4295  int offset, offset2, isfunction;
4296  const char *nextvar, *nextexp, *nextthing;
4297  const char *vars, *vare;
4298  char *finalvars;
4299  int pos, brackets, needsub, len;
4300  struct ast_str *substr1 = ast_str_create(16), *substr2 = NULL, *substr3 = ast_str_create(16);
4301 
4302  ast_str_reset(*buf);
4303  whereweare = tmp = templ;
4304  while (!ast_strlen_zero(whereweare)) {
4305  /* reset our buffer */
4306  ast_str_reset(substr3);
4307 
4308  /* Assume we're copying the whole remaining string */
4309  pos = strlen(whereweare);
4310  nextvar = NULL;
4311  nextexp = NULL;
4312  nextthing = strchr(whereweare, '$');
4313  if (nextthing) {
4314  switch (nextthing[1]) {
4315  case '{':
4316  nextvar = nextthing;
4317  pos = nextvar - whereweare;
4318  break;
4319  case '[':
4320  nextexp = nextthing;
4321  pos = nextexp - whereweare;
4322  break;
4323  default:
4324  pos = 1;
4325  }
4326  }
4327 
4328  if (pos) {
4329  /* Copy that many bytes */
4330  ast_str_append_substr(buf, maxlen, whereweare, pos);
4331 
4332  templ += pos;
4333  whereweare += pos;
4334  }
4335 
4336  if (nextvar) {
4337  /* We have a variable. Find the start and end, and determine
4338  if we are going to have to recursively call ourselves on the
4339  contents */
4340  vars = vare = nextvar + 2;
4341  brackets = 1;
4342  needsub = 0;
4343 
4344  /* Find the end of it */
4345  while (brackets && *vare) {
4346  if ((vare[0] == '$') && (vare[1] == '{')) {
4347  needsub++;
4348  } else if (vare[0] == '{') {
4349  brackets++;
4350  } else if (vare[0] == '}') {
4351  brackets--;
4352  } else if ((vare[0] == '$') && (vare[1] == '['))
4353  needsub++;
4354  vare++;
4355  }
4356  if (brackets)
4357  ast_log(LOG_WARNING, "Error in extension logic (missing '}')\n");
4358  len = vare - vars - 1;
4359 
4360  /* Skip totally over variable string */
4361  whereweare += (len + 3);
4362 
4363  /* Store variable name (and truncate) */
4364  ast_str_set_substr(&substr1, 0, vars, len);
4365  ast_debug(5, "Evaluating '%s' (from '%s' len %d)\n", ast_str_buffer(substr1), vars, len);
4366 
4367  /* Substitute if necessary */
4368  if (needsub) {
4369  size_t used;
4370  if (!substr2) {
4371  substr2 = ast_str_create(16);
4372  }
4373 
4374  ast_str_substitute_variables_full(&substr2, 0, c, headp, ast_str_buffer(substr1), &used);
4375  finalvars = ast_str_buffer(substr2);
4376  } else {
4377  finalvars = ast_str_buffer(substr1);
4378  }
4379 
4380  parse_variable_name(finalvars, &offset, &offset2, &isfunction);
4381  if (isfunction) {
4382  /* Evaluate function */
4383  if (c || !headp) {
4384  cp4 = ast_func_read2(c, finalvars, &substr3, 0) ? NULL : ast_str_buffer(substr3);
4385  } else {
4386  struct varshead old;
4387  struct ast_channel *bogus = ast_dummy_channel_alloc();
4388  if (bogus) {
4389  memcpy(&old, &bogus->varshead, sizeof(old));
4390  memcpy(&bogus->varshead, headp, sizeof(bogus->varshead));
4391  cp4 = ast_func_read2(c, finalvars, &substr3, 0) ? NULL : ast_str_buffer(substr3);
4392  /* Don't deallocate the varshead that was passed in */
4393  memcpy(&bogus->varshead, &old, sizeof(bogus->varshead));
4394  ast_channel_unref(bogus);
4395  } else {
4396  ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
4397  }
4398  }
4399  ast_debug(2, "Function %s result is '%s'\n", finalvars, cp4 ? cp4 : "(null)");
4400  } else {
4401  /* Retrieve variable value */
4402  ast_str_retrieve_variable(&substr3, 0, c, headp, finalvars);
4403  cp4 = ast_str_buffer(substr3);
4404  }
4405  if (cp4) {
4406  ast_str_substring(substr3, offset, offset2);
4407  ast_str_append(buf, maxlen, "%s", ast_str_buffer(substr3));
4408  }
4409  } else if (nextexp) {
4410  /* We have an expression. Find the start and end, and determine
4411  if we are going to have to recursively call ourselves on the
4412  contents */
4413  vars = vare = nextexp + 2;
4414  brackets = 1;
4415  needsub = 0;
4416 
4417  /* Find the end of it */
4418  while (brackets && *vare) {
4419  if ((vare[0] == '$') && (vare[1] == '[')) {
4420  needsub++;
4421  brackets++;
4422  vare++;
4423  } else if (vare[0] == '[') {
4424  brackets++;
4425  } else if (vare[0] == ']') {
4426  brackets--;
4427  } else if ((vare[0] == '$') && (vare[1] == '{')) {
4428  needsub++;
4429  vare++;
4430  }
4431  vare++;
4432  }
4433  if (brackets)
4434  ast_log(LOG_WARNING, "Error in extension logic (missing ']')\n");
4435  len = vare - vars - 1;
4436 
4437  /* Skip totally over expression */
4438  whereweare += (len + 3);
4439 
4440  /* Store variable name (and truncate) */
4441  ast_str_set_substr(&substr1, 0, vars, len);
4442 
4443  /* Substitute if necessary */
4444  if (needsub) {
4445  size_t used;
4446  if (!substr2) {
4447  substr2 = ast_str_create(16);
4448  }
4449 
4450  ast_str_substitute_variables_full(&substr2, 0, c, headp, ast_str_buffer(substr1), &used);
4451  finalvars = ast_str_buffer(substr2);
4452  } else {
4453  finalvars = ast_str_buffer(substr1);
4454  }
4455 
4456  if (ast_str_expr(&substr3, 0, c, finalvars)) {
4457  ast_debug(2, "Expression result is '%s'\n", ast_str_buffer(substr3));
4458  }
4459  ast_str_append(buf, maxlen, "%s", ast_str_buffer(substr3));
4460  }
4461  }
4462  *used = ast_str_strlen(*buf) - orig_size;
4463  ast_free(substr1);
4464  ast_free(substr2);
4465  ast_free(substr3);
4466 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
int ast_func_read2(struct ast_channel *chan, const char *function, struct ast_str **str, ssize_t maxlen)
executes a read operation on a function
Definition: pbx.c:4216
#define LOG_WARNING
Definition: logger.h:144
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_str_append_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Append a non-NULL terminated substring to the end of a dynamic string.
Definition: strings.h:823
void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *templ, size_t *used)
Definition: pbx.c:4289
#define LOG_ERROR
Definition: logger.h:155
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
int ast_str_expr(struct ast_str **str, ssize_t maxlen, struct ast_channel *chan, char *expr)
Evaluate the given expression.
Definition: ast_expr2f.c:2438
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:436
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
const char * ast_str_retrieve_variable(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, struct varshead *headp, const char *var)
Definition: pbx.c:3445
static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
extract offset:length from variable name.
Definition: pbx.c:3311
char * ast_str_set_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Set a dynamic string to a non-NULL terminated substring.
Definition: strings.h:816
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
struct varshead varshead
Definition: channel.h:817
static const char * ast_str_substring(struct ast_str *value, int offset, int length)
Definition: pbx.c:3380
void ast_str_substitute_variables_varshead ( struct ast_str **  buf,
ssize_t  maxlen,
struct varshead headp,
const char *  templ 
)
Parameters
bufResult will be placed in this buffer.
maxlen-1 if the buffer should not grow, 0 if the buffer may grow to any size, and >0 if the buffer should grow only to that number of bytes.
headpIf no channel is specified, a channel list from which to extract variable values
templVariable template to expand.

Definition at line 4474 of file pbx.c.

References ast_str_substitute_variables_full().

4475 {
4476  size_t used;
4477  ast_str_substitute_variables_full(buf, maxlen, NULL, headp, templ, &used);
4478 }
void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *templ, size_t *used)
Definition: pbx.c:4289
static const char* ast_str_substring ( struct ast_str value,
int  offset,
int  length 
)
static

Definition at line 3380 of file pbx.c.

References ast_str_buffer(), ast_str_reset(), ast_str_strlen(), and ast_str_update().

Referenced by ast_str_retrieve_variable(), and ast_str_substitute_variables_full().

3381 {
3382  int lr; /* length of the input string after the copy */
3383 
3384  lr = ast_str_strlen(value); /* compute length after copy, so we never go out of the workspace */
3385 
3386  /* Quick check if no need to do anything */
3387  if (offset == 0 && length >= lr) /* take the whole string */
3388  return ast_str_buffer(value);
3389 
3390  if (offset < 0) { /* translate negative offset into positive ones */
3391  offset = lr + offset;
3392  if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
3393  offset = 0;
3394  }
3395 
3396  /* too large offset result in empty string so we know what to return */
3397  if (offset >= lr) {
3398  ast_str_reset(value);
3399  return ast_str_buffer(value);
3400  }
3401 
3402  if (offset > 0) {
3403  /* Go ahead and chop off the beginning */
3404  memmove(ast_str_buffer(value), ast_str_buffer(value) + offset, ast_str_strlen(value) - offset + 1);
3405  lr -= offset;
3406  }
3407 
3408  if (length >= 0 && length < lr) { /* truncate if necessary */
3409  char *tmp = ast_str_buffer(value);
3410  tmp[length] = '\0';
3411  ast_str_update(value);
3412  } else if (length < 0) {
3413  if (lr > -length) { /* After we remove from the front and from the rear, is there anything left? */
3414  char *tmp = ast_str_buffer(value);
3415  tmp[lr + length] = '\0';
3416  ast_str_update(value);
3417  } else {
3418  ast_str_reset(value);
3419  }
3420  } else {
3421  /* Nothing to do, but update the buffer length */
3422  ast_str_update(value);
3423  }
3424 
3425  return ast_str_buffer(value);
3426 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:436
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
Definition: strings.h:446
int ast_thread_inhibit_escalations ( void  )

Inhibit (in the current thread) the execution of dialplan functions which cause privilege escalations. If pbx_live_dangerously() has been called, this function has no effect.

Returns
0 if successfuly marked current thread.
Non-zero if marking current thread failed.

Definition at line 4072 of file pbx.c.

References ast_log(), ast_threadstorage_get(), LOG_ERROR, and thread_inhibit_escalations_tl.

Referenced by handle_tcptls_connection().

4073 {
4074  int *thread_inhibit_escalations;
4075 
4076  thread_inhibit_escalations = ast_threadstorage_get(
4077  &thread_inhibit_escalations_tl, sizeof(*thread_inhibit_escalations));
4078 
4079  if (thread_inhibit_escalations == NULL) {
4080  ast_log(LOG_ERROR, "Error inhibiting privilege escalations for current thread\n");
4081  return -1;
4082  }
4083 
4084  *thread_inhibit_escalations = 1;
4085  return 0;
4086 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
static struct ast_threadstorage thread_inhibit_escalations_tl
Definition: pbx.c:870
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_unregister_application ( const char *  app)

Unregister an application.

Parameters
appname of the application (does not have to be the same string as the one that was registered)

This unregisters an application from Asterisk's internal application list.

Return values
0success
-1failure

Definition at line 7705 of file pbx.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_string_field_free_memory, ast_verb, and unreference_cached_app().

Referenced by __unload_module(), cc_shutdown(), features_shutdown(), load_module(), unload_module(), and unload_pbx().

7706 {
7707  struct ast_app *tmp;
7708 
7710  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
7711  if (!strcasecmp(app, tmp->name)) {
7714  ast_verb(2, "Unregistered application '%s'\n", tmp->name);
7716  ast_free(tmp);
7717  break;
7718  }
7719  }
7722 
7723  return tmp ? 0 : -1;
7724 }
static void unreference_cached_app(struct ast_app *app)
Definition: pbx.c:7686
Definition: pbx.c:1301
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ast_verb(level,...)
Definition: logger.h:243
static const char app[]
Definition: app_adsiprog.c:49
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
#define ast_free(a)
Definition: astmm.h:97
ast_app: A registered application
Definition: pbx.c:971
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
void ast_unregister_switch ( struct ast_switch sw)

Unregister an alternative switch.

Parameters
swswitch to unregister

Unregisters a switch from asterisk.

Returns
nothing

Definition at line 6457 of file pbx.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by __unload_module(), and unload_module().

6458 {
6460  AST_RWLIST_REMOVE(&switches, sw, list);
6462 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: pbx.c:1303
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:870
struct ast_exten* ast_walk_context_extensions ( struct ast_context con,
struct ast_exten exten 
)

Definition at line 11179 of file pbx.c.

References ast_exten::next, and ast_context::root.

Referenced by complete_dialplan_remove_extension(), context_used(), dundi_precache_full(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), show_dialplan_helper(), and unreference_cached_app().

11181 {
11182  if (!exten)
11183  return con ? con->root : NULL;
11184  else
11185  return exten->next;
11186 }
struct ast_exten * next
Definition: pbx.c:899
struct ast_exten * root
Definition: pbx.c:957
struct ast_ignorepat* ast_walk_context_ignorepats ( struct ast_context con,
struct ast_ignorepat ip 
)

Definition at line 11212 of file pbx.c.

References ast_context::ignorepats, and ast_ignorepat::next.

Referenced by complete_dialplan_remove_ignorepat(), context_merge_incls_swits_igps_other_registrars(), context_used(), handle_cli_dialplan_save(), lookup_c_ip(), manager_show_dialplan_helper(), and show_dialplan_helper().

11214 {
11215  if (!ip)
11216  return con ? con->ignorepats : NULL;
11217  else
11218  return ip->next;
11219 }
struct ast_ignorepat * ignorepats
Definition: pbx.c:962
struct ast_ignorepat * next
Definition: pbx.c:927
struct ast_include* ast_walk_context_includes ( struct ast_context con,
struct ast_include inc 
)

Definition at line 11203 of file pbx.c.

References ast_context::includes, and ast_include::next.

Referenced by ast_context_verify_includes(), complete_dialplan_remove_include(), context_merge_incls_swits_igps_other_registrars(), context_used(), find_matching_priority(), handle_cli_dialplan_save(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper().

11205 {
11206  if (!inc)
11207  return con ? con->includes : NULL;
11208  else
11209  return inc->next;
11210 }
struct ast_include * next
Definition: pbx.c:910
struct ast_include * includes
Definition: pbx.c:961
struct ast_sw* ast_walk_context_switches ( struct ast_context con,
struct ast_sw sw 
)

Definition at line 11188 of file pbx.c.

References ast_context::alts, AST_LIST_FIRST, and AST_LIST_NEXT.

Referenced by context_merge_incls_swits_igps_other_registrars(), context_used(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and show_dialplan_helper().

11190 {
11191  if (!sw)
11192  return con ? AST_LIST_FIRST(&con->alts) : NULL;
11193  else
11194  return AST_LIST_NEXT(sw, list);
11195 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
struct ast_context::@290 alts
struct ast_exten* ast_walk_extension_priorities ( struct ast_exten exten,
struct ast_exten priority 
)

Definition at line 11197 of file pbx.c.

References exten, and ast_exten::peer.

Referenced by complete_dialplan_remove_extension(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), show_dialplan_helper(), and unreference_cached_app().

11199 {
11200  return priority ? priority->peer : exten;
11201 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
struct ast_exten * peer
Definition: pbx.c:895
int ast_wrlock_context ( struct ast_context con)

Write locks a given context.

Parameters
concontext to lock
Return values
0on success
-1on failure

Definition at line 11055 of file pbx.c.

References ast_rwlock_wrlock, and ast_context::lock.

Referenced by __ast_context_destroy(), ast_add_extension2_lockopt(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_remove_extension_callerid2(), ast_context_remove_ignorepat2(), ast_context_remove_include2(), and ast_context_remove_switch2().

11056 {
11057  return ast_rwlock_wrlock(&con->lock);
11058 }
ast_rwlock_t lock
Definition: pbx.c:956
#define ast_rwlock_wrlock(a)
Definition: lock.h:202
int ast_wrlock_contexts ( void  )

Write locks the context list.

Return values
0on success
-1on error

Definition at line 11037 of file pbx.c.

References ast_mutex_lock, and conlock.

Referenced by ast_context_destroy(), ast_context_find_or_create(), ast_merge_contexts_and_delete(), and complete_dialplan_remove_include().

11038 {
11039  return ast_mutex_lock(&conlock);
11040 }
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t conlock
Lock for the ast_context list.
Definition: pbx.c:1294
static void* async_wait ( void *  data)
static

Definition at line 9285 of file pbx.c.

References ast_channel::_state, app, async_stat::app, async_stat::appdata, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, ast_copy_string(), AST_FRAME_CONTROL, ast_free, ast_frfree, ast_hangup(), ast_log(), ast_pbx_run(), ast_read(), ast_remaining_ms(), AST_STATE_UP, ast_strlen_zero(), ast_tvnow(), ast_verb, ast_waitfor(), async_stat::chan, ast_channel::context, async_stat::context, ast_sw::data, ast_channel::exten, async_stat::exten, f, ast_frame::frametype, ast_frame_subclass::integer, LOG_ERROR, LOG_WARNING, ast_channel::name, pbx_exec(), pbx_findapp(), ast_channel::priority, async_stat::priority, ast_frame::subclass, and async_stat::timeout.

Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

9286 {
9287  struct async_stat *as = data;
9288  struct ast_channel *chan = as->chan;
9289  int timeout = as->timeout;
9290  int res;
9291  struct ast_frame *f;
9292  struct ast_app *app;
9293  struct timeval start = ast_tvnow();
9294  int ms;
9295 
9296  while ((ms = ast_remaining_ms(start, timeout)) &&
9297  chan->_state != AST_STATE_UP) {
9298  res = ast_waitfor(chan, ms);
9299  if (res < 1)
9300  break;
9301 
9302  f = ast_read(chan);
9303  if (!f)
9304  break;
9305  if (f->frametype == AST_FRAME_CONTROL) {
9306  if ((f->subclass.integer == AST_CONTROL_BUSY) ||
9308  ast_frfree(f);
9309  break;
9310  }
9311  }
9312  ast_frfree(f);
9313  }
9314  if (chan->_state == AST_STATE_UP) {
9315  if (!ast_strlen_zero(as->app)) {
9316  app = pbx_findapp(as->app);
9317  if (app) {
9318  ast_verb(3, "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name);
9319  pbx_exec(chan, app, as->appdata);
9320  } else
9321  ast_log(LOG_WARNING, "No such application '%s'\n", as->app);
9322  } else {
9323  if (!ast_strlen_zero(as->context))
9324  ast_copy_string(chan->context, as->context, sizeof(chan->context));
9325  if (!ast_strlen_zero(as->exten))
9326  ast_copy_string(chan->exten, as->exten, sizeof(chan->exten));
9327  if (as->priority > 0)
9328  chan->priority = as->priority;
9329  /* Run the PBX */
9330  if (ast_pbx_run(chan)) {
9331  ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name);
9332  } else {
9333  /* PBX will have taken care of this */
9334  chan = NULL;
9335  }
9336  }
9337  }
9338  ast_free(as);
9339  if (chan)
9340  ast_hangup(chan);
9341  return NULL;
9342 }
union ast_frame_subclass subclass
Definition: frame.h:146
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: pbx.c:1537
int priority
Definition: channel.h:841
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx.c:1497
struct ast_channel * chan
Definition: pbx.c:9276
char context[AST_MAX_CONTEXT]
Definition: pbx.c:9277
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
int priority
Definition: pbx.c:9279
char exten[AST_MAX_EXTENSION]
Definition: pbx.c:9278
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_verb(level,...)
Definition: logger.h:243
int timeout
Definition: pbx.c:9280
static const char app[]
Definition: app_adsiprog.c:49
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define LOG_ERROR
Definition: logger.h:155
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:1615
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
static struct ast_format f[]
Definition: format_g726.c:181
char app[AST_MAX_EXTENSION]
Definition: pbx.c:9281
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3539
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
ast_app: A registered application
Definition: pbx.c:971
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:5926
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_frfree(fr)
Definition: frame.h:583
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
char appdata[1024]
Definition: pbx.c:9282
static void cli_match_char_tree ( struct match_char node,
char *  prefix,
int  fd 
)
static

Definition at line 1699 of file pbx.c.

References match_char::alt_char, ast_cli(), ast_str_alloca, ast_str_buffer(), ast_str_set(), match_char::deleted, ast_exten::exten, match_char::exten, match_char::is_pattern, match_char::next_char, match_char::specificity, and match_char::x.

Referenced by show_debug_helper().

1700 {
1701  char extenstr[40];
1702  struct ast_str *my_prefix = ast_str_alloca(1024);
1703 
1704  extenstr[0] = '\0';
1705 
1706  if (node->exten) {
1707  snprintf(extenstr, sizeof(extenstr), "(%p)", node->exten);
1708  }
1709 
1710  if (strlen(node->x) > 1) {
1711  ast_cli(fd, "%s[%s]:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y' : 'N',
1712  node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:" : "",
1713  node->exten ? node->exten->exten : "", extenstr);
1714  } else {
1715  ast_cli(fd, "%s%s:%c:%c:%d:%s%s%s\n", prefix, node->x, node->is_pattern ? 'Y' : 'N',
1716  node->deleted ? 'D' : '-', node->specificity, node->exten? "EXTEN:" : "",
1717  node->exten ? node->exten->exten : "", extenstr);
1718  }
1719 
1720  ast_str_set(&my_prefix, 0, "%s+ ", prefix);
1721 
1722  if (node->next_char)
1723  cli_match_char_tree(node->next_char, ast_str_buffer(my_prefix), fd);
1724 
1725  if (node->alt_char)
1726  cli_match_char_tree(node->alt_char, prefix, fd);
1727 }
struct ast_exten * exten
Definition: pbx.c:939
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int specificity
Definition: pbx.c:936
struct match_char * alt_char
Definition: pbx.c:937
#define ast_str_alloca(init_len)
Definition: strings.h:608
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
char x[1]
Definition: pbx.c:940
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
char * exten
Definition: pbx.c:885
static void cli_match_char_tree(struct match_char *node, char *prefix, int fd)
Definition: pbx.c:1699
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
int is_pattern
Definition: pbx.c:934
struct match_char * next_char
Definition: pbx.c:938
static char prefix[MAX_PREFIX]
Definition: http.c:107
int deleted
Definition: pbx.c:935
static int collect_digits ( struct ast_channel c,
int  waittime,
char *  buf,
int  buflen,
int  pos 
)
static

collect digits from the channel into the buffer.

Parameters
c,buf,buflen,pos
waittimeis in milliseconds
Return values
0on timeout or done.
-1on error.

Definition at line 5446 of file pbx.c.

References ast_channel::_softhangup, ast_channel_clear_softhangup(), ast_matchmore_extension(), AST_SOFTHANGUP_ASYNCGOTO, ast_waitfordigit(), ast_channel::caller, ast_channel::context, ast_pbx::dtimeoutms, ast_party_caller::id, ast_party_id::number, ast_channel::pbx, S_COR, ast_party_number::str, and ast_party_number::valid.

Referenced by __ast_pbx_run().

5447 {
5448  int digit;
5449 
5450  buf[pos] = '\0'; /* make sure it is properly terminated */
5451  while (ast_matchmore_extension(c, c->context, buf, 1,
5452  S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
5453  /* As long as we're willing to wait, and as long as it's not defined,
5454  keep reading digits until we can't possibly get a right answer anymore. */
5455  digit = ast_waitfordigit(c, waittime);
5458  } else {
5459  if (!digit) /* No entry */
5460  break;
5461  if (digit < 0) /* Error, maybe a hangup */
5462  return -1;
5463  if (pos < buflen - 1) { /* XXX maybe error otherwise ? */
5464  buf[pos++] = digit;
5465  buf[pos] = '\0';
5466  }
5467  waittime = c->pbx->dtimeoutms;
5468  }
5469  }
5470  return 0;
5471 }
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
Definition: pbx.c:5420
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
Clear a set of softhangup flags from a channel.
Definition: channel.c:2707
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
int _softhangup
Definition: channel.h:832
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
int dtimeoutms
Definition: pbx.h:180
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct ast_pbx * pbx
Definition: channel.h:761
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int compare_char ( const void *  a,
const void *  b 
)
static

Definition at line 1127 of file pbx.c.

Referenced by get_pattern_node().

1128 {
1129  const unsigned char *ac = a;
1130  const unsigned char *bc = b;
1131 
1132  return *ac - *bc;
1133 }
static char* complete_core_show_hint ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

autocomplete for CLI command 'core show hint'

Definition at line 6649 of file pbx.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_get_extension_name(), ast_strdup, ast_hint::exten, and hints.

Referenced by handle_show_hint().

6650 {
6651  struct ast_hint *hint;
6652  char *ret = NULL;
6653  int which = 0;
6654  int wordlen;
6655  struct ao2_iterator i;
6656 
6657  if (pos != 3)
6658  return NULL;
6659 
6660  wordlen = strlen(word);
6661 
6662  /* walk through all hints */
6663  i = ao2_iterator_init(hints, 0);
6664  for (; (hint = ao2_iterator_next(&i)); ao2_ref(hint, -1)) {
6665  ao2_lock(hint);
6666  if (!hint->exten) {
6667  /* The extension has already been destroyed */
6668  ao2_unlock(hint);
6669  continue;
6670  }
6671  if (!strncasecmp(word, ast_get_extension_name(hint->exten), wordlen) && ++which > state) {
6672  ret = ast_strdup(ast_get_extension_name(hint->exten));
6673  ao2_unlock(hint);
6674  ao2_ref(hint, -1);
6675  break;
6676  }
6677  ao2_unlock(hint);
6678  }
6680 
6681  return ret;
6682 }
#define ast_strdup(a)
Definition: astmm.h:109
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
static struct ao2_container * hints
Definition: pbx.c:1314
Definition: ael.tab.c:203
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
Structure for dial plan hints.
Definition: pbx.c:1010
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
static char* complete_show_dialplan_context ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Definition at line 6865 of file pbx.c.

References ast_get_context_name(), ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), and ast_walk_contexts().

Referenced by handle_debug_dialplan(), and handle_show_dialplan().

6867 {
6868  struct ast_context *c = NULL;
6869  char *ret = NULL;
6870  int which = 0;
6871  int wordlen;
6872 
6873  /* we are do completion of [exten@]context on second position only */
6874  if (pos != 2)
6875  return NULL;
6876 
6878 
6879  wordlen = strlen(word);
6880 
6881  /* walk through all contexts and return the n-th match */
6882  while ( (c = ast_walk_contexts(c)) ) {
6883  if (!strncasecmp(word, ast_get_context_name(c), wordlen) && ++which > state) {
6884  ret = ast_strdup(ast_get_context_name(c));
6885  break;
6886  }
6887  }
6888 
6890 
6891  return ret;
6892 }
#define ast_strdup(a)
Definition: astmm.h:109
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:11042
Definition: ael.tab.c:203
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: pbx.c:11174
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
ast_context: An extension context
Definition: pbx.c:955
static void context_merge ( struct ast_context **  extcontexts,
struct ast_hashtab exttable,
struct ast_context context,
const char *  registrar 
)
static

Definition at line 7846 of file pbx.c.

References ast_exten::app, ast_add_extension2(), ast_context_find_or_create(), ast_hashtab_end_traversal(), ast_hashtab_lookup(), ast_hashtab_next(), ast_hashtab_start_traversal(), ast_log(), ast_strdup, ast_verb, ast_exten::cidmatch, context_merge_incls_swits_igps_other_registrars(), ast_exten::data, ast_exten::datad, ast_exten::exten, first, ast_exten::label, LOG_ERROR, ast_exten::matchcid, ast_context::name, ast_exten::peer_table, ast_exten::priority, ast_context::refcount, ast_exten::registrar, ast_context::registrar, and ast_context::root_table.

Referenced by ast_merge_contexts_and_delete().

7847 {
7848  struct ast_context *new = ast_hashtab_lookup(exttable, context); /* is there a match in the new set? */
7849  struct ast_exten *exten_item, *prio_item, *new_exten_item, *new_prio_item;
7850  struct ast_hashtab_iter *exten_iter;
7851  struct ast_hashtab_iter *prio_iter;
7852  int insert_count = 0;
7853  int first = 1;
7854 
7855  /* We'll traverse all the extensions/prios, and see which are not registrar'd with
7856  the current registrar, and copy them to the new context. If the new context does not
7857  exist, we'll create it "on demand". If no items are in this context to copy, then we'll
7858  only create the empty matching context if the old one meets the criteria */
7859 
7860  if (context->root_table) {
7861  exten_iter = ast_hashtab_start_traversal(context->root_table);
7862  while ((exten_item=ast_hashtab_next(exten_iter))) {
7863  if (new) {
7864  new_exten_item = ast_hashtab_lookup(new->root_table, exten_item);
7865  } else {
7866  new_exten_item = NULL;
7867  }
7868  prio_iter = ast_hashtab_start_traversal(exten_item->peer_table);
7869  while ((prio_item=ast_hashtab_next(prio_iter))) {
7870  int res1;
7871  char *dupdstr;
7872 
7873  if (new_exten_item) {
7874  new_prio_item = ast_hashtab_lookup(new_exten_item->peer_table, prio_item);
7875  } else {
7876  new_prio_item = NULL;
7877  }
7878  if (strcmp(prio_item->registrar,registrar) == 0) {
7879  continue;
7880  }
7881  /* make sure the new context exists, so we have somewhere to stick this exten/prio */
7882  if (!new) {
7883  new = ast_context_find_or_create(extcontexts, exttable, context->name, prio_item->registrar); /* a new context created via priority from a different context in the old dialplan, gets its registrar from the prio's registrar */
7884  }
7885 
7886  /* copy in the includes, switches, and ignorepats */
7887  if (first) { /* but, only need to do this once */
7889  first = 0;
7890  }
7891 
7892  if (!new) {
7893  ast_log(LOG_ERROR,"Could not allocate a new context for %s in merge_and_delete! Danger!\n", context->name);
7894  ast_hashtab_end_traversal(prio_iter);
7895  ast_hashtab_end_traversal(exten_iter);
7896  return; /* no sense continuing. */
7897  }
7898  /* we will not replace existing entries in the new context with stuff from the old context.
7899  but, if this is because of some sort of registrar conflict, we ought to say something... */
7900 
7901  dupdstr = ast_strdup(prio_item->data);
7902 
7903  res1 = ast_add_extension2(new, 0, prio_item->exten, prio_item->priority, prio_item->label,
7904  prio_item->matchcid ? prio_item->cidmatch : NULL, prio_item->app, dupdstr, prio_item->datad, prio_item->registrar);
7905  if (!res1 && new_exten_item && new_prio_item){
7906  ast_verb(3,"Dropping old dialplan item %s/%s/%d [%s(%s)] (registrar=%s) due to conflict with new dialplan\n",
7907  context->name, prio_item->exten, prio_item->priority, prio_item->app, (char*)prio_item->data, prio_item->registrar);
7908  } else {
7909  /* we do NOT pass the priority data from the old to the new -- we pass a copy of it, so no changes to the current dialplan take place,
7910  and no double frees take place, either! */
7911  insert_count++;
7912  }
7913  }
7914  ast_hashtab_end_traversal(prio_iter);
7915  }
7916  ast_hashtab_end_traversal(exten_iter);
7917  } else if (new) {
7918  /* If the context existed but had no extensions, we still want to merge
7919  * the includes, switches and ignore patterns.
7920  */
7922  }
7923 
7924  if (!insert_count && !new && (strcmp(context->registrar, registrar) != 0 ||
7925  (strcmp(context->registrar, registrar) == 0 && context->refcount > 1))) {
7926  /* we could have given it the registrar of the other module who incremented the refcount,
7927  but that's not available, so we give it the registrar we know about */
7928  new = ast_context_find_or_create(extcontexts, exttable, context->name, context->registrar);
7929 
7930  /* copy in the includes, switches, and ignorepats */
7932  }
7933 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
Definition: hashtab.c:534
#define ast_strdup(a)
Definition: astmm.h:109
int ast_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add an extension to an extension context, this time with an ast_context *.
Definition: pbx.c:9052
static void context_merge_incls_swits_igps_other_registrars(struct ast_context *new, struct ast_context *old, const char *registrar)
Definition: pbx.c:7813
void * ast_hashtab_next(struct ast_hashtab_iter *it)
Gets the next object in the list, advances iter one step returns null on end of traversal.
Definition: hashtab.c:753
struct ast_hashtab_iter * ast_hashtab_start_traversal(struct ast_hashtab *tab)
Gives an iterator to hastable.
Definition: hashtab.c:696
const char * label
Definition: pbx.c:889
struct ast_hashtab * peer_table
Definition: pbx.c:896
#define ast_verb(level,...)
Definition: logger.h:243
int matchcid
Definition: pbx.c:886
int priority
Definition: pbx.c:888
char * exten
Definition: pbx.c:885
char * registrar
Definition: pbx.c:963
void(* datad)(void *)
Definition: pbx.c:894
char name[0]
Definition: pbx.c:967
void ast_hashtab_end_traversal(struct ast_hashtab_iter *it)
end the traversal, free the iterator, unlock if necc.
Definition: hashtab.c:746
#define LOG_ERROR
Definition: logger.h:155
void * data
Definition: pbx.c:893
struct sla_ringing_trunk * first
Definition: app_meetme.c:965
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
an iterator for traversing the buckets
Definition: hashtab.h:105
static char * registrar
Definition: features.c:623
const char * registrar
Definition: pbx.c:898
const char * cidmatch
Definition: pbx.c:887
const char * app
Definition: pbx.c:891
int refcount
Definition: pbx.c:964
struct ast_hashtab * root_table
Definition: pbx.c:958
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:7726
ast_context: An extension context
Definition: pbx.c:955
static void context_merge_incls_swits_igps_other_registrars ( struct ast_context new,
struct ast_context old,
const char *  registrar 
)
static

Definition at line 7813 of file pbx.c.

References ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_get_context_name(), ast_get_ignorepat_name(), ast_get_ignorepat_registrar(), ast_get_include_name(), ast_get_include_registrar(), ast_get_switch_data(), ast_get_switch_eval(), ast_get_switch_name(), ast_get_switch_registrar(), ast_verb, ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), and ast_sw::registrar.

Referenced by context_merge().

7814 {
7815  struct ast_include *i;
7816  struct ast_ignorepat *ip;
7817  struct ast_sw *sw;
7818 
7819  ast_verb(3, "merging incls/swits/igpats from old(%s) to new(%s) context, registrar = %s\n", ast_get_context_name(old), ast_get_context_name(new), registrar);
7820  /* copy in the includes, switches, and ignorepats */
7821  /* walk through includes */
7822  for (i = NULL; (i = ast_walk_context_includes(old, i)) ; ) {
7823  if (strcmp(ast_get_include_registrar(i), registrar) == 0)
7824  continue; /* not mine */
7826  }
7827 
7828  /* walk through switches */
7829  for (sw = NULL; (sw = ast_walk_context_switches(old, sw)) ; ) {
7830  if (strcmp(ast_get_switch_registrar(sw), registrar) == 0)
7831  continue; /* not mine */
7833  }
7834 
7835  /* walk thru ignorepats ... */
7836  for (ip = NULL; (ip = ast_walk_context_ignorepats(old, ip)); ) {
7837  if (strcmp(ast_get_ignorepat_registrar(ip), registrar) == 0)
7838  continue; /* not mine */
7840  }
7841 }
struct ast_include * ast_walk_context_includes(struct ast_context *con, struct ast_include *inc)
Definition: pbx.c:11203
ast_include: include= support in extensions.conf
Definition: pbx.c:904
int ast_context_add_include2(struct ast_context *con, const char *include, const char *registrar)
Add a context include.
Definition: pbx.c:8411
int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
Adds a switch (first param is a ast_context)
Definition: pbx.c:8494
#define ast_verb(level,...)
Definition: logger.h:243
const char * ast_get_switch_name(struct ast_sw *sw)
Definition: pbx.c:11151
const char * ast_get_include_name(struct ast_include *include)
Definition: pbx.c:11093
const char * ast_get_include_registrar(struct ast_include *i)
Definition: pbx.c:11121
ast_sw: Switch statement in extensions.conf
Definition: pbx.c:915
const char * ast_get_ignorepat_registrar(struct ast_ignorepat *ip)
Definition: pbx.c:11126
const char * ast_get_switch_data(struct ast_sw *sw)
Definition: pbx.c:11156
struct ast_ignorepat * ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip)
Definition: pbx.c:11212
int ast_context_add_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
Definition: pbx.c:8611
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
int ast_get_switch_eval(struct ast_sw *sw)
Definition: pbx.c:11161
const char * ast_get_switch_registrar(struct ast_sw *sw)
Definition: pbx.c:11166
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx.c:925
const char * ast_get_ignorepat_name(struct ast_ignorepat *ip)
Definition: pbx.c:11098
static char * registrar
Definition: features.c:623
struct ast_sw * ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw)
Definition: pbx.c:11188
static void create_match_char_tree ( struct ast_context con)
static

Definition at line 2321 of file pbx.c.

References add_exten_to_pattern_tree(), ast_hashtab_end_traversal(), ast_hashtab_get_stats(), ast_hashtab_next(), ast_hashtab_start_traversal(), ast_log(), ast_exten::exten, LOG_DEBUG, LOG_ERROR, ast_context::name, ast_context::root_table, and t1.

Referenced by pbx_find_extension().

2322 {
2323  struct ast_hashtab_iter *t1;
2324  struct ast_exten *e1;
2325 #ifdef NEED_DEBUG
2326  int biggest_bucket, resizes, numobjs, numbucks;
2327 
2328  ast_log(LOG_DEBUG,"Creating Extension Trie for context %s(%p)\n", con->name, con);
2329  ast_hashtab_get_stats(con->root_table, &biggest_bucket, &resizes, &numobjs, &numbucks);
2330  ast_log(LOG_DEBUG,"This tree has %d objects in %d bucket lists, longest list=%d objects, and has resized %d times\n",
2331  numobjs, numbucks, biggest_bucket, resizes);
2332 #endif
2334  while ((e1 = ast_hashtab_next(t1))) {
2335  if (e1->exten) {
2336  add_exten_to_pattern_tree(con, e1, 0);
2337  } else {
2338  ast_log(LOG_ERROR, "Attempt to create extension with no extension name.\n");
2339  }
2340  }
2342 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
static struct match_char * add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly)
Definition: pbx.c:2222
void * ast_hashtab_next(struct ast_hashtab_iter *it)
Gets the next object in the list, advances iter one step returns null on end of traversal.
Definition: hashtab.c:753
struct ast_hashtab_iter * ast_hashtab_start_traversal(struct ast_hashtab *tab)
Gives an iterator to hastable.
Definition: hashtab.c:696
#define LOG_DEBUG
Definition: logger.h:122
char * exten
Definition: pbx.c:885
char name[0]
Definition: pbx.c:967
void ast_hashtab_end_traversal(struct ast_hashtab_iter *it)
end the traversal, free the iterator, unlock if necc.
Definition: hashtab.c:746
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
an iterator for traversing the buckets
Definition: hashtab.h:105
struct ast_hashtab * root_table
Definition: pbx.c:958
void ast_hashtab_get_stats(struct ast_hashtab *tab, int *biggest_bucket_size, int *resize_count, int *num_objects, int *num_buckets)
Returns key stats for the table.
Definition: hashtab.c:611
static uint16_t t1
Definition: res_pktccops.c:159
static void decrease_call_count ( void  )
static

Definition at line 5837 of file pbx.c.

References ast_mutex_lock, ast_mutex_unlock, countcalls, and maxcalllock.

Referenced by ast_pbx_run_args(), ast_pbx_start(), and pbx_thread().

5838 {
5840  if (countcalls > 0)
5841  countcalls--;
5843 }
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t maxcalllock
Definition: pbx.c:1227
static int countcalls
Definition: pbx.c:1228
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void destroy_exten ( struct ast_exten e)
static

Definition at line 5845 of file pbx.c.

References ast_free, ast_hashtab_destroy(), ast_remove_hint(), ast_exten::data, ast_exten::datad, ast_exten::peer_label_table, ast_exten::peer_table, ast_exten::priority, and PRIORITY_HINT.

Referenced by __ast_internal_context_destroy(), and ast_context_remove_extension_callerid2().

5846 {
5847  if (e->priority == PRIORITY_HINT)
5848  ast_remove_hint(e);
5849 
5850  if (e->peer_table)
5852  if (e->peer_label_table)
5854  if (e->datad)
5855  e->datad(e->data);
5856  ast_free(e);
5857 }
struct ast_hashtab * peer_table
Definition: pbx.c:896
int priority
Definition: pbx.c:888
void(* datad)(void *)
Definition: pbx.c:894
#define PRIORITY_HINT
Definition: pbx.h:53
struct ast_hashtab * peer_label_table
Definition: pbx.c:897
void * data
Definition: pbx.c:893
#define ast_free(a)
Definition: astmm.h:97
static int ast_remove_hint(struct ast_exten *e)
Remove hint from extension.
Definition: pbx.c:5237
void ast_hashtab_destroy(struct ast_hashtab *tab, void(*objdestroyfunc)(void *obj))
This func will free the hash table and all its memory.
Definition: hashtab.c:388
static void destroy_hint ( void *  obj)
static

Definition at line 5207 of file pbx.c.

References ao2_callback, ao2_ref, AST_EXTENSION_DEACTIVATED, ast_get_context_name(), ast_get_extension_context(), ast_get_extension_name(), ast_hint::callbacks, ast_state_cb::change_cb, ast_hint::context_name, ast_state_cb::data, ast_hint::exten, ast_hint::exten_name, and OBJ_UNLINK.

Referenced by ast_add_hint().

5208 {
5209  struct ast_hint *hint = obj;
5210 
5211  if (hint->callbacks) {
5212  struct ast_state_cb *state_cb;
5213  const char *context_name;
5214  const char *exten_name;
5215 
5216  if (hint->exten) {
5217  context_name = ast_get_context_name(ast_get_extension_context(hint->exten));
5218  exten_name = ast_get_extension_name(hint->exten);
5219  hint->exten = NULL;
5220  } else {
5221  /* The extension has already been destroyed */
5222  context_name = hint->context_name;
5223  exten_name = hint->exten_name;
5224  }
5225  while ((state_cb = ao2_callback(hint->callbacks, OBJ_UNLINK, NULL, NULL))) {
5226  /* Notify with -1 and remove all callbacks */
5227  /* NOTE: The casts will not be needed for v1.10 and later */
5228  state_cb->change_cb((char *) context_name, (char *) exten_name,
5229  AST_EXTENSION_DEACTIVATED, state_cb->data);
5230  ao2_ref(state_cb, -1);
5231  }
5232  ao2_ref(hint->callbacks, -1);
5233  }
5234 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
ast_state_cb: An extension state notify register item
Definition: pbx.c:989
ast_state_cb_type change_cb
Definition: pbx.c:995
#define ao2_ref(o, delta)
Definition: astobj2.h:472
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
char context_name[AST_MAX_CONTEXT]
Definition: pbx.c:1020
Structure for dial plan hints.
Definition: pbx.c:1010
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
void * data
Definition: pbx.c:993
char exten_name[AST_MAX_EXTENSION]
Definition: pbx.c:1021
struct ao2_container * callbacks
Definition: pbx.c:1018
struct ast_context * ast_get_extension_context(struct ast_exten *exten)
Definition: pbx.c:11078
static void destroy_pattern_tree ( struct match_char pattern_tree)
static

Definition at line 2344 of file pbx.c.

References match_char::alt_char, ast_free, match_char::exten, and match_char::next_char.

Referenced by __ast_internal_context_destroy().

2345 {
2346  /* destroy all the alternates */
2347  if (pattern_tree->alt_char) {
2348  destroy_pattern_tree(pattern_tree->alt_char);
2349  pattern_tree->alt_char = 0;
2350  }
2351  /* destroy all the nexts */
2352  if (pattern_tree->next_char) {
2353  destroy_pattern_tree(pattern_tree->next_char);
2354  pattern_tree->next_char = 0;
2355  }
2356  pattern_tree->exten = 0; /* never hurts to make sure there's no pointers laying around */
2357  ast_free(pattern_tree);
2358 }
struct ast_exten * exten
Definition: pbx.c:939
struct match_char * alt_char
Definition: pbx.c:937
#define ast_free(a)
Definition: astmm.h:97
static void destroy_pattern_tree(struct match_char *pattern_tree)
Definition: pbx.c:2344
struct match_char * next_char
Definition: pbx.c:938
static void destroy_state_cb ( void *  doomed)
static

Definition at line 5038 of file pbx.c.

References ast_state_cb::data, ast_state_cb::destroy_cb, and ast_state_cb::id.

Referenced by ast_extension_state_add_destroy().

5039 {
5040  struct ast_state_cb *state_cb = doomed;
5041 
5042  if (state_cb->destroy_cb) {
5043  state_cb->destroy_cb(state_cb->id, state_cb->data);
5044  }
5045 }
ast_state_cb: An extension state notify register item
Definition: pbx.c:989
int id
Definition: pbx.c:991
ast_state_cb_destroy_type destroy_cb
Definition: pbx.c:997
void * data
Definition: pbx.c:993
static void device_state_cb ( const struct ast_event event,
void *  unused 
)
static

Definition at line 10905 of file pbx.c.

References ast_calloc, ast_event_get_ie_str(), AST_EVENT_IE_DEVICE, ast_free, ast_log(), ast_strlen_zero(), ast_taskprocessor_push(), statechange::dev, handle_statechange(), and LOG_ERROR.

Referenced by load_pbx().

10906 {
10907  const char *device;
10908  struct statechange *sc;
10909 
10910  device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
10911  if (ast_strlen_zero(device)) {
10912  ast_log(LOG_ERROR, "Received invalid event that had no device IE\n");
10913  return;
10914  }
10915 
10916  if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(device) + 1)))
10917  return;
10918  strcpy(sc->dev, device);
10920  ast_free(sc);
10921  }
10922 }
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap)
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char dev[0]
Definition: app_queue.c:1622
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
static int handle_statechange(void *datap)
Definition: pbx.c:4936
#define ast_calloc(a, b)
Definition: astmm.h:82
static struct ast_taskprocessor * device_state_tps
Definition: pbx.c:862
const char * ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a string payload.
Definition: event.c:1102
Device Name Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: STR.
Definition: event_defs.h:107
static void exception_store_free ( void *  data)
static

Definition at line 3571 of file pbx.c.

References ast_free, ast_string_field_free_memory, and ast_sw::data.

3572 {
3573  struct pbx_exception *exception = data;
3574  ast_string_field_free_memory(exception);
3575  ast_free(exception);
3576 }
#define ast_free(a)
Definition: astmm.h:97
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
static int ext_cmp ( const char *  left,
const char *  right 
)
static

Definition at line 2691 of file pbx.c.

References ext_cmp_exten(), and ext_cmp_pattern().

Referenced by ast_add_extension2_lockopt(), and ast_extension_cmp().

2692 {
2693  /* Make sure non-pattern extens come first. */
2694  if (left[0] != '_') {
2695  if (right[0] == '_') {
2696  return -1;
2697  }
2698  /* Compare two non-pattern extens. */
2699  return ext_cmp_exten(left, right);
2700  }
2701  if (right[0] != '_') {
2702  return 1;
2703  }
2704 
2705  /*
2706  * OK, we need full pattern sorting routine.
2707  *
2708  * Skip past the underscores
2709  */
2710  return ext_cmp_pattern(left + 1, right + 1);
2711 }
static int ext_cmp_pattern(const char *left, const char *right)
Definition: pbx.c:2643
static int ext_cmp_exten(const char *left, const char *right)
Definition: pbx.c:2441
static int ext_cmp_exten ( const char *  left,
const char *  right 
)
static

Definition at line 2441 of file pbx.c.

Referenced by _extension_match_core(), and ext_cmp().

2442 {
2443  int cmp;
2444 
2445  for (;;) {
2446  /* Ignore '-' chars as eye candy fluff. */
2447  while (*left == '-') {
2448  ++left;
2449  }
2450  while (*right == '-') {
2451  ++right;
2452  }
2453 
2454  cmp = *left - *right;
2455  if (cmp) {
2456  break;
2457  }
2458  if (!*left) {
2459  /*
2460  * Get here only if both strings ended at the same time. cmp
2461  * would be non-zero if only one string ended.
2462  */
2463  break;
2464  }
2465  ++left;
2466  ++right;
2467  }
2468  return cmp;
2469 }
static int ext_cmp_exten_partial ( const char *  left,
const char *  right 
)
static

Definition at line 2398 of file pbx.c.

Referenced by _extension_match_core().

2399 {
2400  int cmp;
2401 
2402  for (;;) {
2403  /* Ignore '-' chars as eye candy fluff. */
2404  while (*left == '-') {
2405  ++left;
2406  }
2407  while (*right == '-') {
2408  ++right;
2409  }
2410 
2411  if (!*right) {
2412  /*
2413  * Right ended first for partial match or both ended at the same
2414  * time for a match.
2415  */
2416  cmp = 0;
2417  break;
2418  }
2419 
2420  cmp = *left - *right;
2421  if (cmp) {
2422  break;
2423  }
2424  ++left;
2425  ++right;
2426  }
2427  return cmp;
2428 }
static int ext_cmp_exten_strlen ( const char *  str)
static

Definition at line 2368 of file pbx.c.

References len(), and str.

Referenced by _extension_match_core().

2369 {
2370  int len;
2371 
2372  len = 0;
2373  for (;;) {
2374  /* Ignore '-' chars as eye candy fluff. */
2375  while (*str == '-') {
2376  ++str;
2377  }
2378  if (!*str) {
2379  break;
2380  }
2381  ++str;
2382  ++len;
2383  }
2384  return len;
2385 }
const char * str
Definition: app_jack.c:144
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int ext_cmp_pattern ( const char *  left,
const char *  right 
)
static

Definition at line 2643 of file pbx.c.

References ARRAY_LEN, and ext_cmp_pattern_pos().

Referenced by _extension_match_core(), and ext_cmp().

2644 {
2645  int cmp;
2646  int left_pos;
2647  int right_pos;
2648 
2649  for (;;) {
2650  unsigned char left_bitwise[32] = { 0, };
2651  unsigned char right_bitwise[32] = { 0, };
2652 
2653  left_pos = ext_cmp_pattern_pos(&left, left_bitwise);
2654  right_pos = ext_cmp_pattern_pos(&right, right_bitwise);
2655  cmp = left_pos - right_pos;
2656  if (!cmp) {
2657  /*
2658  * Are the character sets different, even though they score the same?
2659  *
2660  * Note: Must swap left and right to get the sense of the
2661  * comparison correct. Otherwise, we would need to multiply by
2662  * -1 instead.
2663  */
2664  cmp = memcmp(right_bitwise, left_bitwise, ARRAY_LEN(left_bitwise));
2665  }
2666  if (cmp) {
2667  break;
2668  }
2669  if (!left) {
2670  /*
2671  * Get here only if both patterns ended at the same time. cmp
2672  * would be non-zero if only one pattern ended.
2673  */
2674  break;
2675  }
2676  }
2677  return cmp;
2678 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int ext_cmp_pattern_pos(const char **p, unsigned char *bitwise)
helper functions to sort extension patterns in the desired way, so that more specific patterns appear...
Definition: pbx.c:2528
static int ext_cmp_pattern_pos ( const char **  p,
unsigned char *  bitwise 
)
static

helper functions to sort extension patterns in the desired way, so that more specific patterns appear first.

The function compares individual characters (or sets of), returning an int where bits 0-7 are the ASCII code of the first char in the set, bits 8-15 are the number of characters in the set, and bits 16-20 are for special cases. This way more specific patterns (smaller character sets) appear first. Wildcards have a special value, so that we can directly compare them to sets by subtracting the two values. In particular: 0x001xx one character, character set starting with xx 0x0yyxx yy characters, character set starting with xx 0x18000 '.' (one or more of anything) 0x28000 '!' (zero or more of anything) 0x30000 NUL (end of string) 0x40000 error in set. The pointer to the string is advanced according to needs. NOTES:

  1. the empty set is ignored.
  2. given that a full set has always 0 as the first element, we could encode the special cases as 0xffXX where XX is 1, 2, 3, 4 as used above.

Definition at line 2528 of file pbx.c.

References ast_log(), BITS_PER, and LOG_WARNING.

Referenced by ext_cmp_pattern().

2529 {
2530 #define BITS_PER 8 /* Number of bits per unit (byte). */
2531  unsigned char c;
2532  unsigned char cmin;
2533  int count;
2534  const char *end;
2535 
2536  do {
2537  /* Get character and advance. (Ignore '-' chars as eye candy fluff.) */
2538  do {
2539  c = *(*p)++;
2540  } while (c == '-');
2541 
2542  /* always return unless we have a set of chars */
2543  switch (c) {
2544  default:
2545  /* ordinary character */
2546  bitwise[c / BITS_PER] = 1 << ((BITS_PER - 1) - (c % BITS_PER));
2547  return 0x0100 | c;
2548 
2549  case 'n':
2550  case 'N':
2551  /* 2..9 */
2552  bitwise[6] = 0x3f;
2553  bitwise[7] = 0xc0;
2554  return 0x0800 | '2';
2555 
2556  case 'x':
2557  case 'X':
2558  /* 0..9 */
2559  bitwise[6] = 0xff;
2560  bitwise[7] = 0xc0;
2561  return 0x0A00 | '0';
2562 
2563  case 'z':
2564  case 'Z':
2565  /* 1..9 */
2566  bitwise[6] = 0x7f;
2567  bitwise[7] = 0xc0;
2568  return 0x0900 | '1';
2569 
2570  case '.':
2571  /* wildcard */
2572  return 0x18000;
2573 
2574  case '!':
2575  /* earlymatch */
2576  return 0x28000; /* less specific than '.' */
2577 
2578  case '\0':
2579  /* empty string */
2580  *p = NULL;
2581  return 0x30000;
2582 
2583  case '[':
2584  /* char set */
2585  break;
2586  }
2587  /* locate end of set */
2588  end = strchr(*p, ']');
2589 
2590  if (!end) {
2591  ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
2592  return 0x40000; /* XXX make this entry go last... */
2593  }
2594 
2595  count = 0;
2596  cmin = 0xFF;
2597  for (; *p < end; ++*p) {
2598  unsigned char c1; /* first char in range */
2599  unsigned char c2; /* last char in range */
2600 
2601  c1 = (*p)[0];
2602  if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
2603  c2 = (*p)[2];
2604  *p += 2; /* skip a total of 3 chars */
2605  } else { /* individual character */
2606  c2 = c1;
2607  }
2608  if (c1 < cmin) {
2609  cmin = c1;
2610  }
2611  for (; c1 <= c2; ++c1) {
2612  unsigned char mask = 1 << ((BITS_PER - 1) - (c1 % BITS_PER));
2613 
2614  /*
2615  * Note: If two character sets score the same, the one with the
2616  * lowest ASCII values will compare as coming first. Must fill
2617  * in most significant bits for lower ASCII values to accomplish
2618  * the desired sort order.
2619  */
2620  if (!(bitwise[c1 / BITS_PER] & mask)) {
2621  /* Add the character to the set. */
2622  bitwise[c1 / BITS_PER] |= mask;
2623  count += 0x100;
2624  }
2625  }
2626  }
2627  ++*p;
2628  } while (!count);/* While the char set was empty. */
2629  return count | cmin;
2630 }
#define LOG_WARNING
Definition: logger.h:144
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define BITS_PER
static int ext_strncpy ( char *  dst,
const char *  src,
int  len 
)
static

copy a string skipping whitespace

Definition at line 8827 of file pbx.c.

Referenced by ast_add_extension2_lockopt().

8828 {
8829  int count = 0;
8830  int insquares = 0;
8831 
8832  while (*src && (count < len - 1)) {
8833  if (*src == '[') {
8834  insquares = 1;
8835  } else if (*src == ']') {
8836  insquares = 0;
8837  } else if (*src == ' ' && !insquares) {
8838  src++;
8839  continue;
8840  }
8841  *dst = *src;
8842  dst++;
8843  src++;
8844  count++;
8845  }
8846  *dst = '\0';
8847 
8848  return count;
8849 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int extension_match_core ( const char *  pattern,
const char *  data,
enum ext_match_t  mode 
)
static

Definition at line 2930 of file pbx.c.

References _extension_match_core(), ast_add_profile(), ast_mark(), and ast_strlen_zero().

Referenced by ast_extension_close(), ast_extension_match(), and pbx_find_extension().

2931 {
2932  int i;
2933  static int prof_id = -2; /* marker for 'unallocated' id */
2934  if (prof_id == -2) {
2935  prof_id = ast_add_profile("ext_match", 0);
2936  }
2937  ast_mark(prof_id, 1);
2938  i = _extension_match_core(ast_strlen_zero(pattern) ? "" : pattern, ast_strlen_zero(data) ? "" : data, mode);
2939  ast_mark(prof_id, 0);
2940  return i;
2941 }
int64_t ast_mark(int, int start1_stop0)
Definition: asterisk.c:775
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_add_profile(const char *, uint64_t scale)
support for event profiling
Definition: asterisk.c:710
static int _extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
Definition: pbx.c:2739
static struct ast_context * find_context ( const char *  context)
static

lookup for a context with a given name,

Return values
foundcontext or NULL if not found.

Definition at line 5971 of file pbx.c.

References ast_copy_string(), ast_hashtab_lookup(), contexts_table, and fake_context::name.

5972 {
5973  struct fake_context item;
5974 
5975  ast_copy_string(item.name, context, sizeof(item.name));
5976 
5977  return ast_hashtab_lookup(contexts_table, &item);
5978 }
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
Definition: hashtab.c:534
static struct ast_hashtab * contexts_table
Definition: pbx.c:1286
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static struct ast_context * find_context_locked ( const char *  context)
static

lookup for a context with a given name,

Return values
withconlock held if found.
NULLif not found.

Definition at line 5985 of file pbx.c.

References ast_copy_string(), ast_hashtab_lookup(), ast_rdlock_contexts(), ast_unlock_contexts(), contexts_table, and fake_context::name.

Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), and ast_context_unlockmacro().

5986 {
5987  struct ast_context *c;
5988  struct fake_context item;
5989 
5990  ast_copy_string(item.name, context, sizeof(item.name));
5991 
5993  c = ast_hashtab_lookup(contexts_table, &item);
5994  if (!c) {
5996  }
5997 
5998  return c;
5999 }
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
Definition: hashtab.c:534
static struct ast_hashtab * contexts_table
Definition: pbx.c:1286
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:11042
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
static int find_hint_by_cb_id ( void *  obj,
void *  arg,
int  flags 
)
static

Remove a watcher from the callback list.

Definition at line 5142 of file pbx.c.

References ao2_find, ao2_ref, ast_hint::callbacks, CMP_MATCH, and CMP_STOP.

Referenced by ast_extension_state_del().

5143 {
5144  struct ast_state_cb *state_cb;
5145  const struct ast_hint *hint = obj;
5146  int *id = arg;
5147 
5148  if ((state_cb = ao2_find(hint->callbacks, id, 0))) {
5149  ao2_ref(state_cb, -1);
5150  return CMP_MATCH | CMP_STOP;
5151  }
5152 
5153  return 0;
5154 }
ast_state_cb: An extension state notify register item
Definition: pbx.c:989
#define ao2_ref(o, delta)
Definition: astobj2.h:472
Structure for dial plan hints.
Definition: pbx.c:1010
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
struct ao2_container * callbacks
Definition: pbx.c:1018
static char* func_args ( char *  function)
static

return a pointer to the arguments of the function, and terminates the function name with '\0'

Definition at line 4041 of file pbx.c.

References args, ast_log(), and LOG_WARNING.

Referenced by ast_func_read(), ast_func_read2(), and ast_func_write().

4042 {
4043  char *args = strchr(function, '(');
4044 
4045  if (!args) {
4046  ast_log(LOG_WARNING, "Function '%s' doesn't contain parentheses. Assuming null argument.\n", function);
4047  } else {
4048  char *p;
4049  *args++ = '\0';
4050  if ((p = strrchr(args, ')'))) {
4051  *p = '\0';
4052  } else {
4053  ast_log(LOG_WARNING, "Can't find trailing parenthesis for function '%s(%s'?\n", function, args);
4054  }
4055  }
4056  return args;
4057 }
#define LOG_WARNING
Definition: logger.h:144
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_exten * get_canmatch_exten ( struct match_char node)
static

Definition at line 1729 of file pbx.c.

References ast_log(), ast_exten::exten, match_char::exten, LOG_NOTICE, match_char::next_char, and match_char::x.

1730 {
1731  /* find the exten at the end of the rope */
1732  struct match_char *node2 = node;
1733 
1734  for (node2 = node; node2; node2 = node2->next_char) {
1735  if (node2->exten) {
1736 #ifdef NEED_DEBUG_HERE
1737  ast_log(LOG_NOTICE,"CanMatch_exten returns exten %s(%p)\n", node2->exten->exten, node2->exten);
1738 #endif
1739  return node2->exten;
1740  }
1741  }
1742 #ifdef NEED_DEBUG_HERE
1743  ast_log(LOG_NOTICE,"CanMatch_exten returns NULL, match_char=%s\n", node->x);
1744 #endif
1745  return 0;
1746 }
struct ast_exten * exten
Definition: pbx.c:939
char x[1]
Definition: pbx.c:940
char * exten
Definition: pbx.c:885
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
struct match_char * next_char
Definition: pbx.c:938
match_char: forms a syntax tree for quick matching of extension patterns
Definition: pbx.c:932
static const char* get_pattern_node ( struct pattern_node node,
const char *  src,
int  pattern,
const char *  extenbuf 
)
static

Definition at line 2078 of file pbx.c.

References ast_log(), pattern_node::buf, compare_char(), first, INC_DST_OVERFLOW_CHECK, last, LOG_ERROR, LOG_WARNING, and pattern_node::specif.

Referenced by add_exten_to_pattern_tree().

2079 {
2080 #define INC_DST_OVERFLOW_CHECK \
2081  do { \
2082  if (dst - node->buf < sizeof(node->buf) - 1) { \
2083  ++dst; \
2084  } else { \
2085  overflow = 1; \
2086  } \
2087  } while (0)
2088 
2089  node->specif = 0;
2090  node->buf[0] = '\0';
2091  while (*src) {
2092  if (*src == '[' && pattern) {
2093  char *dst = node->buf;
2094  const char *src_next;
2095  int length;
2096  int overflow = 0;
2097 
2098  /* get past the '[' */
2099  ++src;
2100  for (;;) {
2101  if (*src == '\\') {
2102  /* Escaped character. */
2103  ++src;
2104  if (*src == '[' || *src == '\\' || *src == '-' || *src == ']') {
2105  *dst = *src++;
2107  }
2108  } else if (*src == '-') {
2109  unsigned char first;
2110  unsigned char last;
2111 
2112  src_next = src;
2113  first = *(src_next - 1);
2114  last = *++src_next;
2115 
2116  if (last == '\\') {
2117  /* Escaped character. */
2118  last = *++src_next;
2119  }
2120 
2121  /* Possible char range. */
2122  if (node->buf[0] && last) {
2123  /* Expand the char range. */
2124  while (++first <= last) {
2125  *dst = first;
2127  }
2128  src = src_next + 1;
2129  } else {
2130  /*
2131  * There was no left or right char for the range.
2132  * It is just a '-'.
2133  */
2134  *dst = *src++;
2136  }
2137  } else if (*src == '\0') {
2139  "A matching ']' was not found for '[' in exten pattern '%s'\n",
2140  extenbuf);
2141  break;
2142  } else if (*src == ']') {
2143  ++src;
2144  break;
2145  } else {
2146  *dst = *src++;
2148  }
2149  }
2150  /* null terminate the exploded range */
2151  *dst = '\0';
2152 
2153  if (overflow) {
2155  "Expanded character set too large to deal with in exten pattern '%s'. Ignoring character set.\n",
2156  extenbuf);
2157  node->buf[0] = '\0';
2158  continue;
2159  }
2160 
2161  /* Sort the characters in character set. */
2162  length = strlen(node->buf);
2163  if (!length) {
2164  ast_log(LOG_WARNING, "Empty character set in exten pattern '%s'. Ignoring.\n",
2165  extenbuf);
2166  node->buf[0] = '\0';
2167  continue;
2168  }
2169  qsort(node->buf, length, 1, compare_char);
2170 
2171  /* Remove duplicate characters from character set. */
2172  dst = node->buf;
2173  src_next = node->buf;
2174  while (*src_next++) {
2175  if (*dst != *src_next) {
2176  *++dst = *src_next;
2177  }
2178  }
2179 
2180  length = strlen(node->buf);
2181  length <<= 8;
2182  node->specif = length | (unsigned char) node->buf[0];
2183  break;
2184  } else if (*src == '-') {
2185  /* Skip dashes in all extensions. */
2186  ++src;
2187  } else {
2188  if (*src == '\\') {
2189  /*
2190  * XXX The escape character here does not remove any special
2191  * meaning to characters except the '[', '\\', and '-'
2192  * characters since they are special only in this function.
2193  */
2194  node->buf[0] = *++src;
2195  if (!node->buf[0]) {
2196  break;
2197  }
2198  } else {
2199  node->buf[0] = *src;
2200  if (pattern) {
2201  /* make sure n,x,z patterns are canonicalized to N,X,Z */
2202  if (node->buf[0] == 'n') {
2203  node->buf[0] = 'N';
2204  } else if (node->buf[0] == 'x') {
2205  node->buf[0] = 'X';
2206  } else if (node->buf[0] == 'z') {
2207  node->buf[0] = 'Z';
2208  }
2209  }
2210  }
2211  node->buf[1] = '\0';
2212  node->specif = 1;
2213  ++src;
2214  break;
2215  }
2216  }
2217  return src;
2218 
2219 #undef INC_DST_OVERFLOW_CHECK
2220 }
#define LOG_WARNING
Definition: logger.h:144
#define INC_DST_OVERFLOW_CHECK
struct sla_ringing_trunk * last
Definition: app_meetme.c:965
#define LOG_ERROR
Definition: logger.h:155
static int compare_char(const void *a, const void *b)
Definition: pbx.c:1127
struct sla_ringing_trunk * first
Definition: app_meetme.c:965
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int specif
Definition: pbx.c:2019
char buf[256]
Definition: pbx.c:2021
static unsigned get_range ( char *  src,
int  max,
const char *const  names[],
const char *  msg 
)
static

helper function to return a range up to max (7, 12, 31 respectively). names, if supplied, is an array of names that should be mapped to numbers.

Definition at line 8182 of file pbx.c.

References ast_log(), ast_strlen_zero(), LOG_WARNING, lookup_name(), and strsep().

Referenced by ast_build_timing().

8183 {
8184  int start, end; /* start and ending position */
8185  unsigned int mask = 0;
8186  char *part;
8187 
8188  /* Check for whole range */
8189  if (ast_strlen_zero(src) || !strcmp(src, "*")) {
8190  return (1 << max) - 1;
8191  }
8192 
8193  while ((part = strsep(&src, "&"))) {
8194  /* Get start and ending position */
8195  char *endpart = strchr(part, '-');
8196  if (endpart) {
8197  *endpart++ = '\0';
8198  }
8199  /* Find the start */
8200  if ((start = lookup_name(part, names, max)) < 0) {
8201  ast_log(LOG_WARNING, "Invalid %s '%s', skipping element\n", msg, part);
8202  continue;
8203  }
8204  if (endpart) { /* find end of range */
8205  if ((end = lookup_name(endpart, names, max)) < 0) {
8206  ast_log(LOG_WARNING, "Invalid end %s '%s', skipping element\n", msg, endpart);
8207  continue;
8208  }
8209  } else {
8210  end = start;
8211  }
8212  /* Fill the mask. Remember that ranges are cyclic */
8213  mask |= (1 << end); /* initialize with last element */
8214  while (start != end) {
8215  mask |= (1 << start);
8216  if (++start >= max) {
8217  start = 0;
8218  }
8219  }
8220  }
8221  return mask;
8222 }
char * strsep(char **str, const char *delims)
#define LOG_WARNING
Definition: logger.h:144
static int lookup_name(const char *s, const char *const names[], int max)
Helper for get_range. return the index of the matching entry, starting from 1. If names is not suppli...
Definition: pbx.c:8159
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void get_timerange ( struct ast_timing i,
char *  times 
)
static

store a bitmask of valid times, one bit each 1 minute

Definition at line 8225 of file pbx.c.

References ast_log(), ast_strlen_zero(), LOG_WARNING, ast_timing::minmask, and strsep().

Referenced by ast_build_timing().

8226 {
8227  char *endpart, *part;
8228  int x;
8229  int st_h, st_m;
8230  int endh, endm;
8231  int minute_start, minute_end;
8232 
8233  /* start disabling all times, fill the fields with 0's, as they may contain garbage */
8234  memset(i->minmask, 0, sizeof(i->minmask));
8235 
8236  /* 1-minute per bit */
8237  /* Star is all times */
8238  if (ast_strlen_zero(times) || !strcmp(times, "*")) {
8239  /* 48, because each hour takes 2 integers; 30 bits each */
8240  for (x = 0; x < 48; x++) {
8241  i->minmask[x] = 0x3fffffff; /* 30 bits */
8242  }
8243  return;
8244  }
8245  /* Otherwise expect a range */
8246  while ((part = strsep(&times, "&"))) {
8247  if (!(endpart = strchr(part, '-'))) {
8248  if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
8249  ast_log(LOG_WARNING, "%s isn't a valid time.\n", part);
8250  continue;
8251  }
8252  i->minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30));
8253  continue;
8254  }
8255  *endpart++ = '\0';
8256  /* why skip non digits? Mostly to skip spaces */
8257  while (*endpart && !isdigit(*endpart)) {
8258  endpart++;
8259  }
8260  if (!*endpart) {
8261  ast_log(LOG_WARNING, "Invalid time range starting with '%s-'.\n", part);
8262  continue;
8263  }
8264  if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) {
8265  ast_log(LOG_WARNING, "'%s' isn't a valid start time.\n", part);
8266  continue;
8267  }
8268  if (sscanf(endpart, "%2d:%2d", &endh, &endm) != 2 || endh < 0 || endh > 23 || endm < 0 || endm > 59) {
8269  ast_log(LOG_WARNING, "'%s' isn't a valid end time.\n", endpart);
8270  continue;
8271  }
8272  minute_start = st_h * 60 + st_m;
8273  minute_end = endh * 60 + endm;
8274  /* Go through the time and enable each appropriate bit */
8275  for (x = minute_start; x != minute_end; x = (x + 1) % (24 * 60)) {
8276  i->minmask[x / 30] |= (1 << (x % 30));
8277  }
8278  /* Do the last one */
8279  i->minmask[x / 30] |= (1 << (x % 30));
8280  }
8281  /* All done */
8282  return;
8283 }
char * strsep(char **str, const char *delims)
#define LOG_WARNING
Definition: logger.h:144
char x[1]
Definition: pbx.c:940
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
unsigned int minmask[48]
Definition: pbx.h:144
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char* handle_debug_dialplan ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Send ack once.

Definition at line 7196 of file pbx.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_PBX_MAX_STACK, ast_strdupa, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_show_dialplan_context(), dialplan_counters::context_existence, exten, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, show_debug_helper(), strsep(), dialplan_counters::total_context, ast_cli_entry::usage, and ast_cli_args::word.

7197 {
7198  char *exten = NULL, *context = NULL;
7199  /* Variables used for different counters */
7200  struct dialplan_counters counters;
7201  const char *incstack[AST_PBX_MAX_STACK];
7202 
7203  switch (cmd) {
7204  case CLI_INIT:
7205  e->command = "dialplan debug";
7206  e->usage =
7207  "Usage: dialplan debug [context]\n"
7208  " Show dialplan context Trie(s). Usually only useful to folks debugging the deep internals of the fast pattern matcher\n";
7209  return NULL;
7210  case CLI_GENERATE:
7211  return complete_show_dialplan_context(a->line, a->word, a->pos, a->n);
7212  }
7213 
7214  memset(&counters, 0, sizeof(counters));
7215 
7216  if (a->argc != 2 && a->argc != 3)
7217  return CLI_SHOWUSAGE;
7218 
7219  /* we obtain [exten@]context? if yes, split them ... */
7220  /* note: we ignore the exten totally here .... */
7221  if (a->argc == 3) {
7222  if (strchr(a->argv[2], '@')) { /* split into exten & context */
7223  context = ast_strdupa(a->argv[2]);
7224  exten = strsep(&context, "@");
7225  /* change empty strings to NULL */
7226  if (ast_strlen_zero(exten))
7227  exten = NULL;
7228  } else { /* no '@' char, only context given */
7229  context = ast_strdupa(a->argv[2]);
7230  }
7231  if (ast_strlen_zero(context))
7232  context = NULL;
7233  }
7234  /* else Show complete dial plan, context and exten are NULL */
7235  show_debug_helper(a->fd, context, exten, &counters, NULL, 0, incstack);
7236 
7237  /* check for input failure and throw some error messages */
7238  if (context && !counters.context_existence) {
7239  ast_cli(a->fd, "There is no existence of '%s' context\n", context);
7240  return CLI_FAILURE;
7241  }
7242 
7243 
7244  ast_cli(a->fd,"-= %d %s. =-\n",
7245  counters.total_context, counters.total_context == 1 ? "context" : "contexts");
7246 
7247  /* everything ok */
7248  return CLI_SUCCESS;
7249 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
char * strsep(char **str, const char *delims)
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const int n
Definition: cli.h:159
static int show_debug_helper(int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[])
Definition: pbx.c:7074
const char *const * argv
Definition: cli.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define AST_PBX_MAX_STACK
Definition: extconf.h:223
#define CLI_FAILURE
Definition: cli.h:45
static char * complete_show_dialplan_context(const char *line, const char *word, int pos, int state)
Definition: pbx.c:6865
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
Counters for the show dialplan manager command.
Definition: pbx.c:6895
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char* handle_set_chanvar ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 7569 of file pbx.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_get_by_name(), ast_channel_unref, ast_cli(), ast_complete_channels(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, pbx_builtin_setvar_helper(), ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

7570 {
7571  struct ast_channel *chan;
7572  const char *chan_name, *var_name, *var_value;
7573 
7574  switch (cmd) {
7575  case CLI_INIT:
7576  e->command = "dialplan set chanvar";
7577  e->usage =
7578  "Usage: dialplan set chanvar <channel> <varname> <value>\n"
7579  " Set channel variable <varname> to <value>\n";
7580  return NULL;
7581  case CLI_GENERATE:
7582  return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
7583  }
7584 
7585  if (a->argc != e->args + 3)
7586  return CLI_SHOWUSAGE;
7587 
7588  chan_name = a->argv[e->args];
7589  var_name = a->argv[e->args + 1];
7590  var_value = a->argv[e->args + 2];
7591 
7592  if (!(chan = ast_channel_get_by_name(chan_name))) {
7593  ast_cli(a->fd, "Channel '%s' not found\n", chan_name);
7594  return CLI_FAILURE;
7595  }
7596 
7597  pbx_builtin_setvar_helper(chan, var_name, var_value);
7598 
7599  chan = ast_channel_unref(chan);
7600 
7601  ast_cli(a->fd, "\n -- Channel variable '%s' set to '%s' for '%s'\n", var_name, var_value, chan_name);
7602 
7603  return CLI_SUCCESS;
7604 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition: cli.c:1547
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
static char* handle_set_extenpatternmatchnew ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 7606 of file pbx.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, pbx_set_extenpatternmatchnew(), and ast_cli_entry::usage.

7607 {
7608  int oldval = 0;
7609 
7610  switch (cmd) {
7611  case CLI_INIT:
7612  e->command = "dialplan set extenpatternmatchnew true";
7613  e->usage =
7614  "Usage: dialplan set extenpatternmatchnew true|false\n"
7615  " Use the NEW extension pattern matching algorithm, true or false.\n";
7616  return NULL;
7617  case CLI_GENERATE:
7618  return NULL;
7619  }
7620 
7621  if (a->argc != 4)
7622  return CLI_SHOWUSAGE;
7623 
7624  oldval = pbx_set_extenpatternmatchnew(1);
7625 
7626  if (oldval)
7627  ast_cli(a->fd, "\n -- Still using the NEW pattern match algorithm for extension names in the dialplan.\n");
7628  else
7629  ast_cli(a->fd, "\n -- Switched to using the NEW pattern match algorithm for extension names in the dialplan.\n");
7630 
7631  return CLI_SUCCESS;
7632 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
int pbx_set_extenpatternmatchnew(int newval)
Definition: pbx.c:5948
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_set_global ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 7547 of file pbx.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, pbx_builtin_setvar_helper(), and ast_cli_entry::usage.

7548 {
7549  switch (cmd) {
7550  case CLI_INIT:
7551  e->command = "dialplan set global";
7552  e->usage =
7553  "Usage: dialplan set global <name> <value>\n"
7554  " Set global dialplan variable <name> to <value>\n";
7555  return NULL;
7556  case CLI_GENERATE:
7557  return NULL;
7558  }
7559 
7560  if (a->argc != e->args + 2)
7561  return CLI_SHOWUSAGE;
7562 
7563  pbx_builtin_setvar_helper(NULL, a->argv[3], a->argv[4]);
7564  ast_cli(a->fd, "\n -- Global variable '%s' set to '%s'\n", a->argv[3], a->argv[4]);
7565 
7566  return CLI_SUCCESS;
7567 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_show_application ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 6543 of file pbx.c.

References app, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_complete_applications(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, print_app_docs(), ast_cli_entry::usage, and ast_cli_args::word.

6544 {
6545  struct ast_app *aa;
6546  int app, no_registered_app = 1;
6547 
6548  switch (cmd) {
6549  case CLI_INIT:
6550  e->command = "core show application";
6551  e->usage =
6552  "Usage: core show application <application> [<application> [<application> [...]]]\n"
6553  " Describes a particular application.\n";
6554  return NULL;
6555  case CLI_GENERATE:
6556  /*
6557  * There is a possibility to show informations about more than one
6558  * application at one time. You can type 'show application Dial Echo' and
6559  * you will see informations about these two applications ...
6560  */
6561  return ast_complete_applications(a->line, a->word, a->n);
6562  }
6563 
6564  if (a->argc < 4) {
6565  return CLI_SHOWUSAGE;
6566  }
6567 
6569  AST_RWLIST_TRAVERSE(&apps, aa, list) {
6570  /* Check for each app that was supplied as an argument */
6571  for (app = 3; app < a->argc; app++) {
6572  if (strcasecmp(aa->name, a->argv[app])) {
6573  continue;
6574  }
6575 
6576  /* We found it! */
6577  no_registered_app = 0;
6578 
6579  print_app_docs(aa, a->fd);
6580  }
6581  }
6583 
6584  /* we found at least one app? no? */
6585  if (no_registered_app) {
6586  ast_cli(a->fd, "Your application(s) is (are) not registered\n");
6587  return CLI_FAILURE;
6588  }
6589 
6590  return CLI_SUCCESS;
6591 }
Definition: pbx.c:1301
const int argc
Definition: cli.h:154
char * ast_complete_applications(const char *line, const char *word, int state)
Command completion for the list of installed applications.
Definition: pbx.c:11336
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static const char app[]
Definition: app_adsiprog.c:49
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
ast_app: A registered application
Definition: pbx.c:971
static void print_app_docs(struct ast_app *aa, int fd)
Definition: pbx.c:6468
static char* handle_show_applications ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 6779 of file pbx.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_app::description, ast_cli_args::fd, ast_cli_args::n, ast_cli_args::pos, strcasestr(), ast_app::synopsis, ast_cli_entry::usage, and ast_cli_args::word.

6780 {
6781  struct ast_app *aa;
6782  int like = 0, describing = 0;
6783  int total_match = 0; /* Number of matches in like clause */
6784  int total_apps = 0; /* Number of apps registered */
6785  static const char * const choices[] = { "like", "describing", NULL };
6786 
6787  switch (cmd) {
6788  case CLI_INIT:
6789  e->command = "core show applications [like|describing]";
6790  e->usage =
6791  "Usage: core show applications [{like|describing} <text>]\n"
6792  " List applications which are currently available.\n"
6793  " If 'like', <text> will be a substring of the app name\n"
6794  " If 'describing', <text> will be a substring of the description\n";
6795  return NULL;
6796  case CLI_GENERATE:
6797  return (a->pos != 3) ? NULL : ast_cli_complete(a->word, choices, a->n);
6798  }
6799 
6801 
6802  if (AST_RWLIST_EMPTY(&apps)) {
6803  ast_cli(a->fd, "There are no registered applications\n");
6805  return CLI_SUCCESS;
6806  }
6807 
6808  /* core list applications like <keyword> */
6809  if ((a->argc == 5) && (!strcmp(a->argv[3], "like"))) {
6810  like = 1;
6811  } else if ((a->argc > 4) && (!strcmp(a->argv[3], "describing"))) {
6812  describing = 1;
6813  }
6814 
6815  /* core list applications describing <keyword1> [<keyword2>] [...] */
6816  if ((!like) && (!describing)) {
6817  ast_cli(a->fd, " -= Registered Asterisk Applications =-\n");
6818  } else {
6819  ast_cli(a->fd, " -= Matching Asterisk Applications =-\n");
6820  }
6821 
6822  AST_RWLIST_TRAVERSE(&apps, aa, list) {
6823  int printapp = 0;
6824  total_apps++;
6825  if (like) {
6826  if (strcasestr(aa->name, a->argv[4])) {
6827  printapp = 1;
6828  total_match++;
6829  }
6830  } else if (describing) {
6831  if (aa->description) {
6832  /* Match all words on command line */
6833  int i;
6834  printapp = 1;
6835  for (i = 4; i < a->argc; i++) {
6836  if (!strcasestr(aa->description, a->argv[i])) {
6837  printapp = 0;
6838  } else {
6839  total_match++;
6840  }
6841  }
6842  }
6843  } else {
6844  printapp = 1;
6845  }
6846 
6847  if (printapp) {
6848  ast_cli(a->fd," %20s: %s\n", aa->name, aa->synopsis ? aa->synopsis : "<Synopsis not available>");
6849  }
6850  }
6851  if ((!like) && (!describing)) {
6852  ast_cli(a->fd, " -= %d Applications Registered =-\n",total_apps);
6853  } else {
6854  ast_cli(a->fd, " -= %d Applications Matching =-\n",total_match);
6855  }
6856 
6858 
6859  return CLI_SUCCESS;
6860 }
const ast_string_field description
Definition: pbx.c:979
const ast_string_field synopsis
Definition: pbx.c:979
Definition: pbx.c:1301
const int argc
Definition: cli.h:154
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: cli.c:1535
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
const char *const * argv
Definition: cli.h:155
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
ast_app: A registered application
Definition: pbx.c:971
const int pos
Definition: cli.h:158
char * strcasestr(const char *, const char *)
static char* handle_show_chanvar ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

CLI support for listing chanvar's variables in a parseable way.

Definition at line 7512 of file pbx.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_get_by_name(), ast_channel_unref, ast_cli(), ast_complete_channels(), ast_str_alloca, ast_str_buffer(), ast_str_strlen(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, pbx_builtin_serialize_variables(), ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

7513 {
7514  struct ast_channel *chan = NULL;
7515  struct ast_str *vars = ast_str_alloca(BUFSIZ * 4); /* XXX large because we might have lots of channel vars */
7516 
7517  switch (cmd) {
7518  case CLI_INIT:
7519  e->command = "dialplan show chanvar";
7520  e->usage =
7521  "Usage: dialplan show chanvar <channel>\n"
7522  " List current channel variables and their values\n";
7523  return NULL;
7524  case CLI_GENERATE:
7525  return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
7526  }
7527 
7528  if (a->argc != e->args + 1)
7529  return CLI_SHOWUSAGE;
7530 
7531  if (!(chan = ast_channel_get_by_name(a->argv[e->args]))) {
7532  ast_cli(a->fd, "Channel '%s' not found\n", a->argv[e->args]);
7533  return CLI_FAILURE;
7534  }
7535 
7536  pbx_builtin_serialize_variables(chan, &vars);
7537 
7538  if (ast_str_strlen(vars)) {
7539  ast_cli(a->fd, "\nVariables for channel %s:\n%s\n", a->argv[e->args], ast_str_buffer(vars));
7540  }
7541 
7542  chan = ast_channel_unref(chan);
7543 
7544  return CLI_SUCCESS;
7545 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
const int argc
Definition: cli.h:154
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
Definition: cli.h:146
#define ast_str_alloca(init_len)
Definition: strings.h:608
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
const char *const * argv
Definition: cli.h:155
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
const int pos
Definition: cli.h:158
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition: cli.c:1547
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
int pbx_builtin_serialize_variables(struct ast_channel *chan, struct ast_str **buf)
Create a human-readable string, specifying all variables and their corresponding values.
Definition: pbx.c:10444
static char* handle_show_dialplan ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 7129 of file pbx.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_PBX_MAX_STACK, ast_strdupa, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_show_dialplan_context(), dialplan_counters::context_existence, exten, dialplan_counters::extension_existence, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, show_dialplan_helper(), strsep(), dialplan_counters::total_context, dialplan_counters::total_exten, dialplan_counters::total_prio, ast_cli_entry::usage, and ast_cli_args::word.

7130 {
7131  char *exten = NULL, *context = NULL;
7132  /* Variables used for different counters */
7133  struct dialplan_counters counters;
7134  const char *incstack[AST_PBX_MAX_STACK];
7135 
7136  switch (cmd) {
7137  case CLI_INIT:
7138  e->command = "dialplan show";
7139  e->usage =
7140  "Usage: dialplan show [[exten@]context]\n"
7141  " Show dialplan\n";
7142  return NULL;
7143  case CLI_GENERATE:
7144  return complete_show_dialplan_context(a->line, a->word, a->pos, a->n);
7145  }
7146 
7147  memset(&counters, 0, sizeof(counters));
7148 
7149  if (a->argc != 2 && a->argc != 3)
7150  return CLI_SHOWUSAGE;
7151 
7152  /* we obtain [exten@]context? if yes, split them ... */
7153  if (a->argc == 3) {
7154  if (strchr(a->argv[2], '@')) { /* split into exten & context */
7155  context = ast_strdupa(a->argv[2]);
7156  exten = strsep(&context, "@");
7157  /* change empty strings to NULL */
7158  if (ast_strlen_zero(exten))
7159  exten = NULL;
7160  } else { /* no '@' char, only context given */
7161  context = ast_strdupa(a->argv[2]);
7162  }
7163  if (ast_strlen_zero(context))
7164  context = NULL;
7165  }
7166  /* else Show complete dial plan, context and exten are NULL */
7167  show_dialplan_helper(a->fd, context, exten, &counters, NULL, 0, incstack);
7168 
7169  /* check for input failure and throw some error messages */
7170  if (context && !counters.context_existence) {
7171  ast_cli(a->fd, "There is no existence of '%s' context\n", context);
7172  return CLI_FAILURE;
7173  }
7174 
7175  if (exten && !counters.extension_existence) {
7176  if (context)
7177  ast_cli(a->fd, "There is no existence of %s@%s extension\n",
7178  exten, context);
7179  else
7180  ast_cli(a->fd,
7181  "There is no existence of '%s' extension in all contexts\n",
7182  exten);
7183  return CLI_FAILURE;
7184  }
7185 
7186  ast_cli(a->fd,"-= %d %s (%d %s) in %d %s. =-\n",
7187  counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions",
7188  counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities",
7189  counters.total_context, counters.total_context == 1 ? "context" : "contexts");
7190 
7191  /* everything ok */
7192  return CLI_SUCCESS;
7193 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
char * strsep(char **str, const char *delims)
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
static int show_dialplan_helper(int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[])
Definition: pbx.c:6919
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const int n
Definition: cli.h:159
const char *const * argv
Definition: cli.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define AST_PBX_MAX_STACK
Definition: extconf.h:223
#define CLI_FAILURE
Definition: cli.h:45
static char * complete_show_dialplan_context(const char *line, const char *word, int pos, int state)
Definition: pbx.c:6865
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
Counters for the show dialplan manager command.
Definition: pbx.c:6895
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char* handle_show_function ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3693 of file pbx.c.

References ast_cli_args::argc, ast_custom_function::arguments, ast_cli_args::argv, ast_cli(), ast_custom_function_find(), ast_free, ast_malloc, AST_MAX_APP, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, AST_TERM_MAX_ESCAPE_CHARS, AST_XML_DOC, ast_xmldoc_printable(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, COLOR_CYAN, COLOR_MAGENTA, ast_cli_entry::command, ast_custom_function::desc, ast_custom_function::docsrc, ast_cli_args::fd, ast_cli_args::n, ast_custom_function::name, S_OR, ast_custom_function::seealso, ast_custom_function::synopsis, synopsis, ast_custom_function::syntax, term_color(), ast_cli_entry::usage, and ast_cli_args::word.

3694 {
3695  struct ast_custom_function *acf;
3696  /* Maximum number of characters added by terminal coloring is 22 */
3697  char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40], argtitle[40], seealsotitle[40];
3698  char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL, *seealso = NULL;
3699  char stxtitle[40], *syntax = NULL, *arguments = NULL;
3700  int syntax_size, description_size, synopsis_size, arguments_size, seealso_size;
3701  char *ret = NULL;
3702  int which = 0;
3703  int wordlen;
3704 
3705  switch (cmd) {
3706  case CLI_INIT:
3707  e->command = "core show function";
3708  e->usage =
3709  "Usage: core show function <function>\n"
3710  " Describe a particular dialplan function.\n";
3711  return NULL;
3712  case CLI_GENERATE:
3713  wordlen = strlen(a->word);
3714  /* case-insensitive for convenience in this 'complete' function */
3716  AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
3717  if (!strncasecmp(a->word, acf->name, wordlen) && ++which > a->n) {
3718  ret = ast_strdup(acf->name);
3719  break;
3720  }
3721  }
3723 
3724  return ret;
3725  }
3726 
3727  if (a->argc < 4) {
3728  return CLI_SHOWUSAGE;
3729  }
3730 
3731  if (!(acf = ast_custom_function_find(a->argv[3]))) {
3732  ast_cli(a->fd, "No function by that name registered.\n");
3733  return CLI_FAILURE;
3734  }
3735 
3736  syntax_size = strlen(S_OR(acf->syntax, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
3737  if (!(syntax = ast_malloc(syntax_size))) {
3738  ast_cli(a->fd, "Memory allocation failure!\n");
3739  return CLI_FAILURE;
3740  }
3741 
3742  snprintf(info, sizeof(info), "\n -= Info about function '%s' =- \n\n", acf->name);
3743  term_color(infotitle, info, COLOR_MAGENTA, 0, sizeof(infotitle));
3744  term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
3745  term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
3746  term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
3747  term_color(argtitle, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
3748  term_color(seealsotitle, "[See Also]\n", COLOR_MAGENTA, 0, 40);
3749  term_color(syntax, S_OR(acf->syntax, "Not available"), COLOR_CYAN, 0, syntax_size);
3750 #ifdef AST_XML_DOCS
3751  if (acf->docsrc == AST_XML_DOC) {
3752  arguments = ast_xmldoc_printable(S_OR(acf->arguments, "Not available"), 1);
3753  synopsis = ast_xmldoc_printable(S_OR(acf->synopsis, "Not available"), 1);
3754  description = ast_xmldoc_printable(S_OR(acf->desc, "Not available"), 1);
3755  seealso = ast_xmldoc_printable(S_OR(acf->seealso, "Not available"), 1);
3756  } else
3757 #endif
3758  {
3759  synopsis_size = strlen(S_OR(acf->synopsis, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
3760  synopsis = ast_malloc(synopsis_size);
3761 
3762  description_size = strlen(S_OR(acf->desc, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
3763  description = ast_malloc(description_size);
3764 
3765  arguments_size = strlen(S_OR(acf->arguments, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
3766  arguments = ast_malloc(arguments_size);
3767 
3768  seealso_size = strlen(S_OR(acf->seealso, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
3769  seealso = ast_malloc(seealso_size);
3770 
3771  /* check allocated memory. */
3772  if (!synopsis || !description || !arguments || !seealso) {
3773  ast_free(synopsis);
3774  ast_free(description);
3775  ast_free(arguments);
3776  ast_free(seealso);
3777  ast_free(syntax);
3778  return CLI_FAILURE;
3779  }
3780 
3781  term_color(arguments, S_OR(acf->arguments, "Not available"), COLOR_CYAN, 0, arguments_size);
3782  term_color(synopsis, S_OR(acf->synopsis, "Not available"), COLOR_CYAN, 0, synopsis_size);
3783  term_color(description, S_OR(acf->desc, "Not available"), COLOR_CYAN, 0, description_size);
3784  term_color(seealso, S_OR(acf->seealso, "Not available"), COLOR_CYAN, 0, seealso_size);
3785  }
3786 
3787  ast_cli(a->fd, "%s%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n",
3788  infotitle, syntitle, synopsis, destitle, description,
3789  stxtitle, syntax, argtitle, arguments, seealsotitle, seealso);
3790 
3791  ast_free(arguments);
3792  ast_free(synopsis);
3793  ast_free(description);
3794  ast_free(seealso);
3795  ast_free(syntax);
3796 
3797  return CLI_SUCCESS;
3798 }
#define ast_strdup(a)
Definition: astmm.h:109
const ast_string_field syntax
Definition: pbx.h:103
const int argc
Definition: cli.h:154
#define COLOR_CYAN
Definition: term.h:59
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const ast_string_field desc
Definition: pbx.h:103
enum ast_doc_src docsrc
Definition: pbx.h:104
Definition: cli.h:146
const ast_string_field arguments
Definition: pbx.h:103
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_TERM_MAX_ESCAPE_CHARS
Maximum number of characters needed for a color escape sequence, plus a null char.
Definition: term.h:67
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Definition: pbx.c:1231
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
const char *const * argv
Definition: cli.h:155
struct ast_custom_function * ast_custom_function_find(const char *name)
Definition: pbx.c:3800
#define AST_MAX_APP
Definition: pbx.h:39
#define CLI_SHOWUSAGE
Definition: cli.h:44
static char * synopsis
Definition: func_enum.c:156
#define CLI_FAILURE
Definition: cli.h:45
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
char * ast_xmldoc_printable(const char *bwinput, int withcolors)
Colorize and put delimiters (instead of tags) to the xmldoc output.
Definition: xmldoc.c:315
const ast_string_field synopsis
Definition: pbx.h:103
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const char * name
Definition: pbx.h:96
const ast_string_field seealso
Definition: pbx.h:103
#define ast_malloc(a)
Definition: astmm.h:91
#define COLOR_MAGENTA
Definition: term.h:57
static char* handle_show_functions ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3651 of file pbx.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_custom_function::name, S_OR, ast_custom_function::synopsis, ast_custom_function::syntax, and ast_cli_entry::usage.

3652 {
3653  struct ast_custom_function *acf;
3654  int count_acf = 0;
3655  int like = 0;
3656 
3657  switch (cmd) {
3658  case CLI_INIT:
3659  e->command = "core show functions [like]";
3660  e->usage =
3661  "Usage: core show functions [like <text>]\n"
3662  " List builtin functions, optionally only those matching a given string\n";
3663  return NULL;
3664  case CLI_GENERATE:
3665  return NULL;
3666  }
3667 
3668  if (a->argc == 5 && (!strcmp(a->argv[3], "like")) ) {
3669  like = 1;
3670  } else if (a->argc != 3) {
3671  return CLI_SHOWUSAGE;
3672  }
3673 
3674  ast_cli(a->fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed");
3675 
3677  AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
3678  if (!like || strstr(acf->name, a->argv[4])) {
3679  count_acf++;
3680  ast_cli(a->fd, "%-20.20s %-35.35s %s\n",
3681  S_OR(acf->name, ""),
3682  S_OR(acf->syntax, ""),
3683  S_OR(acf->synopsis, ""));
3684  }
3685  }
3687 
3688  ast_cli(a->fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : "");
3689 
3690  return CLI_SUCCESS;
3691 }
const ast_string_field syntax
Definition: pbx.h:103
const int argc
Definition: cli.h:154
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Definition: pbx.c:1231
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const ast_string_field synopsis
Definition: pbx.h:103
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const char * name
Definition: pbx.h:96
static char* handle_show_globals ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

CLI support for listing global variables in a parseable way.

Definition at line 7454 of file pbx.c.

References ast_cli(), AST_LIST_TRAVERSE, ast_rwlock_rdlock, ast_rwlock_unlock, ast_var_name(), ast_var_value(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_var_t::entries, ast_cli_args::fd, globals, globalslock, and ast_cli_entry::usage.

7455 {
7456  int i = 0;
7457  struct ast_var_t *newvariable;
7458 
7459  switch (cmd) {
7460  case CLI_INIT:
7461  e->command = "dialplan show globals";
7462  e->usage =
7463  "Usage: dialplan show globals\n"
7464  " List current global dialplan variables and their values\n";
7465  return NULL;
7466  case CLI_GENERATE:
7467  return NULL;
7468  }
7469 
7471  AST_LIST_TRAVERSE (&globals, newvariable, entries) {
7472  i++;
7473  ast_cli(a->fd, " %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable));
7474  }
7476  ast_cli(a->fd, "\n -- %d variable(s)\n", i);
7477 
7478  return CLI_SUCCESS;
7479 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:201
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:89
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
static ast_rwlock_t globalslock
Definition: pbx.c:1217
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define ast_rwlock_unlock(a)
Definition: lock.h:200
const int fd
Definition: cli.h:153
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_var_t::@158 entries
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static struct varshead globals
Definition: pbx.c:1218
static char* handle_show_hint ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

handle_show_hint: CLI support for listing registered dial plan hint

Definition at line 6685 of file pbx.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_extension_state2str(), ast_get_context_name(), ast_get_extension_app(), ast_get_extension_context(), ast_get_extension_name(), ast_hint::callbacks, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_core_show_hint(), ast_hint::exten, ast_cli_args::fd, hints, ast_hint::laststate, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

6686 {
6687  struct ast_hint *hint;
6688  int watchers;
6689  int num = 0, extenlen;
6690  struct ao2_iterator i;
6691 
6692  switch (cmd) {
6693  case CLI_INIT:
6694  e->command = "core show hint";
6695  e->usage =
6696  "Usage: core show hint <exten>\n"
6697  " List registered hint.\n"
6698  " Hint details are shown in four columns. In order from left to right, they are:\n"
6699  " 1. Hint extension URI.\n"
6700  " 2. Mapped device state identifiers.\n"
6701  " 3. Current extension state. The aggregate of mapped device states.\n"
6702  " 4. Watchers - number of subscriptions and other entities watching this hint.\n";
6703 
6704  return NULL;
6705  case CLI_GENERATE:
6706  return complete_core_show_hint(a->line, a->word, a->pos, a->n);
6707  }
6708 
6709  if (a->argc < 4)
6710  return CLI_SHOWUSAGE;
6711 
6712  if (ao2_container_count(hints) == 0) {
6713  ast_cli(a->fd, "There are no registered dialplan hints\n");
6714  return CLI_SUCCESS;
6715  }
6716 
6717  extenlen = strlen(a->argv[3]);
6718  i = ao2_iterator_init(hints, 0);
6719  for (; (hint = ao2_iterator_next(&i)); ao2_ref(hint, -1)) {
6720  ao2_lock(hint);
6721  if (!hint->exten) {
6722  /* The extension has already been destroyed */
6723  ao2_unlock(hint);
6724  continue;
6725  }
6726  if (!strncasecmp(ast_get_extension_name(hint->exten), a->argv[3], extenlen)) {
6727  watchers = ao2_container_count(hint->callbacks);
6728  ast_cli(a->fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n",
6732  ast_extension_state2str(hint->laststate), watchers);
6733  num++;
6734  }
6735  ao2_unlock(hint);
6736  }
6738  if (!num)
6739  ast_cli(a->fd, "No hints matching extension %s\n", a->argv[3]);
6740  else
6741  ast_cli(a->fd, "%d hint%s matching extension %s\n", num, (num!=1 ? "s":""), a->argv[3]);
6742  return CLI_SUCCESS;
6743 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Definition: astobj2.c:470
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
const int argc
Definition: cli.h:154
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:11141
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
Definition: cli.h:146
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static struct ao2_container * hints
Definition: pbx.c:1314
const char * line
Definition: cli.h:156
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:472
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition: pbx.c:4902
#define ao2_lock(a)
Definition: astobj2.h:488
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
const char *const * argv
Definition: cli.h:155
int laststate
Definition: pbx.c:1019
#define CLI_SHOWUSAGE
Definition: cli.h:44
Structure for dial plan hints.
Definition: pbx.c:1010
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
static char * complete_core_show_hint(const char *line, const char *word, int pos, int state)
autocomplete for CLI command &#39;core show hint&#39;
Definition: pbx.c:6649
const int pos
Definition: cli.h:158
struct ao2_container * callbacks
Definition: pbx.c:1018
struct ast_context * ast_get_extension_context(struct ast_exten *exten)
Definition: pbx.c:11078
static char* handle_show_hints ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

handle_show_hints: CLI support for listing registered dial plan hints

Definition at line 6594 of file pbx.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli(), ast_extension_state2str(), ast_get_context_name(), ast_get_extension_app(), ast_get_extension_context(), ast_get_extension_name(), ast_hint::callbacks, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_hint::exten, ast_cli_args::fd, hints, ast_hint::laststate, and ast_cli_entry::usage.

6595 {
6596  struct ast_hint *hint;
6597  int num = 0;
6598  int watchers;
6599  struct ao2_iterator i;
6600 
6601  switch (cmd) {
6602  case CLI_INIT:
6603  e->command = "core show hints";
6604  e->usage =
6605  "Usage: core show hints\n"
6606  " List registered hints.\n"
6607  " Hint details are shown in four columns. In order from left to right, they are:\n"
6608  " 1. Hint extension URI.\n"
6609  " 2. Mapped device state identifiers.\n"
6610  " 3. Current extension state. The aggregate of mapped device states.\n"
6611  " 4. Watchers - number of subscriptions and other entities watching this hint.\n";
6612  return NULL;
6613  case CLI_GENERATE:
6614  return NULL;
6615  }
6616 
6617  if (ao2_container_count(hints) == 0) {
6618  ast_cli(a->fd, "There are no registered dialplan hints\n");
6619  return CLI_SUCCESS;
6620  }
6621  /* ... we have hints ... */
6622  ast_cli(a->fd, "\n -= Registered Asterisk Dial Plan Hints =-\n");
6623 
6624  i = ao2_iterator_init(hints, 0);
6625  for (; (hint = ao2_iterator_next(&i)); ao2_ref(hint, -1)) {
6626  ao2_lock(hint);
6627  if (!hint->exten) {
6628  /* The extension has already been destroyed */
6629  ao2_unlock(hint);
6630  continue;
6631  }
6632  watchers = ao2_container_count(hint->callbacks);
6633  ast_cli(a->fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n",
6637  ast_extension_state2str(hint->laststate), watchers);
6638  ao2_unlock(hint);
6639  num++;
6640  }
6642 
6643  ast_cli(a->fd, "----------------\n");
6644  ast_cli(a->fd, "- %d hints registered\n", num);
6645  return CLI_SUCCESS;
6646 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Definition: astobj2.c:470
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:11141
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
Definition: cli.h:146
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static struct ao2_container * hints
Definition: pbx.c:1314
const int fd
Definition: cli.h:153
#define ao2_ref(o, delta)
Definition: astobj2.h:472
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition: pbx.c:4902
#define ao2_lock(a)
Definition: astobj2.h:488
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
int laststate
Definition: pbx.c:1019
Structure for dial plan hints.
Definition: pbx.c:1010
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
char * command
Definition: cli.h:180
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
struct ao2_container * callbacks
Definition: pbx.c:1018
struct ast_context * ast_get_extension_context(struct ast_exten *exten)
Definition: pbx.c:11078
static char* handle_show_switches ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

handle_show_switches: CLI support for listing registered dial plan switches

Definition at line 6747 of file pbx.c.

References ast_cli(), AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_switch::description, ast_cli_args::fd, ast_switch::name, and ast_cli_entry::usage.

6748 {
6749  struct ast_switch *sw;
6750 
6751  switch (cmd) {
6752  case CLI_INIT:
6753  e->command = "core show switches";
6754  e->usage =
6755  "Usage: core show switches\n"
6756  " List registered switches\n";
6757  return NULL;
6758  case CLI_GENERATE:
6759  return NULL;
6760  }
6761 
6763 
6764  if (AST_RWLIST_EMPTY(&switches)) {
6766  ast_cli(a->fd, "There are no registered alternative switches\n");
6767  return CLI_SUCCESS;
6768  }
6769 
6770  ast_cli(a->fd, "\n -= Registered Asterisk Alternative Switches =-\n");
6772  ast_cli(a->fd, "%s: %s\n", sw->name, sw->description);
6773 
6775 
6776  return CLI_SUCCESS;
6777 }
struct ast_switch::@191 list
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
const char * description
Definition: pbx.h:131
static const char name[]
char * command
Definition: cli.h:180
Definition: pbx.c:1303
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static int handle_statechange ( void *  datap)
static

Definition at line 4936 of file pbx.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_copy_string(), ast_extension_state3(), ast_free, ast_get_context_name(), ast_get_extension_app(), ast_get_extension_context(), ast_get_extension_name(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_mutex_lock, ast_mutex_unlock, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_hint::callbacks, ast_state_cb::change_cb, context_merge_lock, ast_state_cb::data, statechange::dev, ast_hint::exten, hints, ast_hint::laststate, parse(), state, statecbs, and strsep().

Referenced by device_state_cb().

4937 {
4938  struct ast_hint *hint;
4939  struct ast_str *hint_app;
4940  struct statechange *sc = datap;
4941  struct ao2_iterator i;
4942  struct ao2_iterator cb_iter;
4943  char context_name[AST_MAX_CONTEXT];
4944  char exten_name[AST_MAX_EXTENSION];
4945 
4946  hint_app = ast_str_create(1024);
4947  if (!hint_app) {
4948  ast_free(sc);
4949  return -1;
4950  }
4951 
4952  ast_mutex_lock(&context_merge_lock);/* Hold off ast_merge_contexts_and_delete */
4953  i = ao2_iterator_init(hints, 0);
4954  for (; (hint = ao2_iterator_next(&i)); ao2_ref(hint, -1)) {
4955  struct ast_state_cb *state_cb;
4956  char *cur, *parse;
4957  int state;
4958 
4959  ao2_lock(hint);
4960  if (!hint->exten) {
4961  /* The extension has already been destroyed */
4962  ao2_unlock(hint);
4963  continue;
4964  }
4965 
4966  /* Does this hint monitor the device that changed state? */
4967  ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(hint->exten));
4968  parse = ast_str_buffer(hint_app);
4969  while ((cur = strsep(&parse, "&"))) {
4970  if (!strcasecmp(cur, sc->dev)) {
4971  /* The hint monitors the device. */
4972  break;
4973  }
4974  }
4975  if (!cur) {
4976  /* The hint does not monitor the device. */
4977  ao2_unlock(hint);
4978  continue;
4979  }
4980 
4981  /*
4982  * Save off strings in case the hint extension gets destroyed
4983  * while we are notifying the watchers.
4984  */
4985  ast_copy_string(context_name,
4987  sizeof(context_name));
4988  ast_copy_string(exten_name, ast_get_extension_name(hint->exten),
4989  sizeof(exten_name));
4990  ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(hint->exten));
4991  ao2_unlock(hint);
4992 
4993  /*
4994  * Get device state for this hint.
4995  *
4996  * NOTE: We cannot hold any locks while determining the hint
4997  * device state or notifying the watchers without causing a
4998  * deadlock. (conlock, hints, and hint)
4999  */
5000  state = ast_extension_state3(hint_app);
5001  if (state == hint->laststate) {
5002  continue;
5003  }
5004 
5005  /* Device state changed since last check - notify the watchers. */
5006  hint->laststate = state; /* record we saw the change */
5007 
5008  /* For general callbacks */
5009  cb_iter = ao2_iterator_init(statecbs, 0);
5010  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
5011  state_cb->change_cb(context_name, exten_name, state, state_cb->data);
5012  }
5013  ao2_iterator_destroy(&cb_iter);
5014 
5015  /* For extension callbacks */
5016  cb_iter = ao2_iterator_init(hint->callbacks, 0);
5017  for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) {
5018  state_cb->change_cb(context_name, exten_name, state, state_cb->data);
5019  }
5020  ao2_iterator_destroy(&cb_iter);
5021  }
5024 
5025  ast_free(hint_app);
5026  ast_free(sc);
5027  return 0;
5028 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
char * strsep(char **str, const char *delims)
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:11141
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
ast_state_cb: An extension state notify register item
Definition: pbx.c:989
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t context_merge_lock
Lock to hold off restructuring of hints by ast_merge_contexts_and_delete.
Definition: pbx.c:1299
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
static struct ao2_container * hints
Definition: pbx.c:1314
ast_state_cb_type change_cb
Definition: pbx.c:995
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
char dev[0]
Definition: app_queue.c:1622
int laststate
Definition: pbx.c:1019
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
Structure for dial plan hints.
Definition: pbx.c:1010
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
#define AST_MAX_CONTEXT
Definition: channel.h:136
#define ast_free(a)
Definition: astmm.h:97
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static struct ao2_container * statecbs
Definition: pbx.c:1316
void * data
Definition: pbx.c:993
static int ast_extension_state3(struct ast_str *hint_app)
Definition: pbx.c:4871
struct ao2_container * callbacks
Definition: pbx.c:1018
struct ast_context * ast_get_extension_context(struct ast_exten *exten)
Definition: pbx.c:11078
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* handle_unset_extenpatternmatchnew ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 7634 of file pbx.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, pbx_set_extenpatternmatchnew(), and ast_cli_entry::usage.

7635 {
7636  int oldval = 0;
7637 
7638  switch (cmd) {
7639  case CLI_INIT:
7640  e->command = "dialplan set extenpatternmatchnew false";
7641  e->usage =
7642  "Usage: dialplan set extenpatternmatchnew true|false\n"
7643  " Use the NEW extension pattern matching algorithm, true or false.\n";
7644  return NULL;
7645  case CLI_GENERATE:
7646  return NULL;
7647  }
7648 
7649  if (a->argc != 4)
7650  return CLI_SHOWUSAGE;
7651 
7652  oldval = pbx_set_extenpatternmatchnew(0);
7653 
7654  if (!oldval)
7655  ast_cli(a->fd, "\n -- Still using the OLD pattern match algorithm for extension names in the dialplan.\n");
7656  else
7657  ast_cli(a->fd, "\n -- Switched to using the OLD pattern match algorithm for extension names in the dialplan.\n");
7658 
7659  return CLI_SUCCESS;
7660 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
int pbx_set_extenpatternmatchnew(int newval)
Definition: pbx.c:5948
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static int hashtab_compare_exten_labels ( const void *  ah_a,
const void *  ah_b 
)
static

Definition at line 1181 of file pbx.c.

References ast_exten::label, and S_OR.

Referenced by ast_add_extension2_lockopt().

1182 {
1183  const struct ast_exten *ac = ah_a;
1184  const struct ast_exten *bc = ah_b;
1185  return strcmp(S_OR(ac->label, ""), S_OR(bc->label, ""));
1186 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
const char * label
Definition: pbx.c:889
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static int hashtab_compare_exten_numbers ( const void *  ah_a,
const void *  ah_b 
)
static

Definition at line 1174 of file pbx.c.

References ast_exten::priority.

Referenced by ast_add_extension2_lockopt().

1175 {
1176  const struct ast_exten *ac = ah_a;
1177  const struct ast_exten *bc = ah_b;
1178  return ac->priority != bc->priority;
1179 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
int priority
Definition: pbx.c:888
static int hashtab_compare_extens ( const void *  ha_a,
const void *  ah_b 
)
static

Definition at line 1146 of file pbx.c.

References AST_EXT_MATCHCID_ANY, AST_EXT_MATCHCID_OFF, ast_strlen_zero(), ast_exten::cidmatch, ast_exten::exten, and ast_exten::matchcid.

Referenced by ast_add_extension2_lockopt().

1147 {
1148  const struct ast_exten *ac = ah_a;
1149  const struct ast_exten *bc = ah_b;
1150  int x = strcmp(ac->exten, bc->exten);
1151  if (x) { /* if exten names are diff, then return */
1152  return x;
1153  }
1154 
1155  /* but if they are the same, do the cidmatch values match? */
1156  /* not sure which side may be using ast_ext_matchcid_types, so check both */
1158  return 0;
1159  }
1161  return 0;
1162  }
1163  if (ac->matchcid != bc->matchcid) {
1164  return 1;
1165  }
1166  /* all other cases already disposed of, match now required on callerid string (cidmatch) */
1167  /* although ast_add_extension2_lockopt() enforces non-zero ptr, caller may not have */
1168  if (ast_strlen_zero(ac->cidmatch) && ast_strlen_zero(bc->cidmatch)) {
1169  return 0;
1170  }
1171  return strcmp(ac->cidmatch, bc->cidmatch);
1172 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
int matchcid
Definition: pbx.c:886
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * exten
Definition: pbx.c:885
const char * cidmatch
Definition: pbx.c:887
static unsigned int hashtab_hash_extens ( const void *  obj)
static

Definition at line 1194 of file pbx.c.

References AST_EXT_MATCHCID_ON, ast_hashtab_hash_string(), ast_exten::cidmatch, ast_exten::exten, and ast_exten::matchcid.

Referenced by ast_add_extension2_lockopt().

1195 {
1196  const struct ast_exten *ac = obj;
1197  unsigned int x = ast_hashtab_hash_string(ac->exten);
1198  unsigned int y = 0;
1199  if (ac->matchcid == AST_EXT_MATCHCID_ON)
1201  return x+y;
1202 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
int matchcid
Definition: pbx.c:886
char * exten
Definition: pbx.c:885
unsigned int ast_hashtab_hash_string(const void *obj)
Hashes a string to a number.
Definition: hashtab.c:157
const char * cidmatch
Definition: pbx.c:887
static unsigned int hashtab_hash_labels ( const void *  obj)
static

Definition at line 1210 of file pbx.c.

References ast_hashtab_hash_string(), ast_exten::label, and S_OR.

Referenced by ast_add_extension2_lockopt().

1211 {
1212  const struct ast_exten *ac = obj;
1213  return ast_hashtab_hash_string(S_OR(ac->label, ""));
1214 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
const char * label
Definition: pbx.c:889
unsigned int ast_hashtab_hash_string(const void *obj)
Hashes a string to a number.
Definition: hashtab.c:157
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static unsigned int hashtab_hash_priority ( const void *  obj)
static

Definition at line 1204 of file pbx.c.

References ast_hashtab_hash_int(), and ast_exten::priority.

Referenced by ast_add_extension2_lockopt().

1205 {
1206  const struct ast_exten *ac = obj;
1207  return ast_hashtab_hash_int(ac->priority);
1208 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
int priority
Definition: pbx.c:888
unsigned int ast_hashtab_hash_int(const int num)
Definition: hashtab.c:209
static int hint_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 11375 of file pbx.c.

References CMP_MATCH, CMP_STOP, and ast_hint::exten.

Referenced by ast_pbx_init().

11376 {
11377  const struct ast_hint *hint = obj;
11378  const struct ast_exten *exten = arg;
11379 
11380  return (hint->exten == exten) ? CMP_MATCH | CMP_STOP : 0;
11381 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
Structure for dial plan hints.
Definition: pbx.c:1010
static int hint_hash ( const void *  obj,
const int  flags 
)
static

Definition at line 11355 of file pbx.c.

References ast_get_extension_name(), ast_str_case_hash(), ast_strlen_zero(), ast_hint::exten, and ast_hint::exten_name.

Referenced by ast_pbx_init().

11356 {
11357  const struct ast_hint *hint = obj;
11358  const char *exten_name;
11359  int res;
11360 
11361  exten_name = ast_get_extension_name(hint->exten);
11362  if (ast_strlen_zero(exten_name)) {
11363  /*
11364  * If the exten or extension name isn't set, return 0 so that
11365  * the ao2_find() search will start in the first bucket.
11366  */
11367  res = 0;
11368  } else {
11369  res = ast_str_case_hash(exten_name);
11370  }
11371 
11372  return res;
11373 }
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
Structure for dial plan hints.
Definition: pbx.c:1010
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
char exten_name[AST_MAX_EXTENSION]
Definition: pbx.c:1021
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:989
static int hint_id_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 5191 of file pbx.c.

References CMP_MATCH, CMP_STOP, and ast_state_cb::id.

Referenced by ast_add_hint().

5192 {
5193  const struct ast_state_cb *cb = obj;
5194  int *id = arg;
5195 
5196  return (cb->id == *id) ? CMP_MATCH | CMP_STOP : 0;
5197 }
ast_state_cb: An extension state notify register item
Definition: pbx.c:989
int id
Definition: pbx.c:991
static int hints_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
)
static

Definition at line 10928 of file pbx.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_remove_node(), ast_data_search_match(), ast_extension_state2str(), ast_get_context_name(), ast_get_extension_app(), ast_get_extension_context(), ast_get_extension_name(), ast_hint::callbacks, ast_hint::exten, hints, and ast_hint::laststate.

10930 {
10931  struct ast_data *data_hint;
10932  struct ast_hint *hint;
10933  int watchers;
10934  struct ao2_iterator i;
10935 
10936  if (ao2_container_count(hints) == 0) {
10937  return 0;
10938  }
10939 
10940  i = ao2_iterator_init(hints, 0);
10941  for (; (hint = ao2_iterator_next(&i)); ao2_ref(hint, -1)) {
10942  watchers = ao2_container_count(hint->callbacks);
10943  data_hint = ast_data_add_node(data_root, "hint");
10944  if (!data_hint) {
10945  continue;
10946  }
10947  ast_data_add_str(data_hint, "extension", ast_get_extension_name(hint->exten));
10949  ast_data_add_str(data_hint, "application", ast_get_extension_app(hint->exten));
10950  ast_data_add_str(data_hint, "state", ast_extension_state2str(hint->laststate));
10951  ast_data_add_int(data_hint, "watchers", watchers);
10952 
10953  if (!ast_data_search_match(search, data_hint)) {
10954  ast_data_remove_node(data_root, data_hint);
10955  }
10956  }
10958 
10959  return 0;
10960 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Definition: astobj2.c:470
The data tree to be returned by the callbacks and managed by functions local to this file...
Definition: data.c:85
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:11141
struct ast_exten * exten
Hint extension.
Definition: pbx.c:1017
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
static struct ao2_container * hints
Definition: pbx.c:1314
struct ast_data * ast_data_add_node(struct ast_data *root, const char *childname)
Add a container child.
Definition: data.c:2317
#define ao2_ref(o, delta)
Definition: astobj2.h:472
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition: pbx.c:4902
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
int laststate
Definition: pbx.c:1019
void ast_data_remove_node(struct ast_data *root, struct ast_data *child)
Remove a node that was added using ast_data_add_.
Definition: data.c:2486
Structure for dial plan hints.
Definition: pbx.c:1010
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
struct ast_data * ast_data_add_str(struct ast_data *root, const char *childname, const char *string)
Add a string node type.
Definition: data.c:2401
struct ast_data * ast_data_add_int(struct ast_data *root, const char *childname, int value)
Add an integer node type.
Definition: data.c:2322
struct ao2_container * callbacks
Definition: pbx.c:1018
int ast_data_search_match(const struct ast_data_search *search, struct ast_data *data)
Check the current generated node to know if it matches the search condition.
Definition: data.c:1458
struct ast_context * ast_get_extension_context(struct ast_exten *exten)
Definition: pbx.c:11078
static int include_valid ( struct ast_include i)
inlinestatic

Definition at line 1565 of file pbx.c.

References ast_check_timing(), ast_include::hastime, and ast_include::timing.

Referenced by pbx_find_extension().

1566 {
1567  if (!i->hastime)
1568  return 1;
1569 
1570  return ast_check_timing(&(i->timing));
1571 }
int hastime
Definition: pbx.c:908
struct ast_timing timing
Definition: pbx.c:909
int ast_check_timing(const struct ast_timing *i)
Evaluate a pre-constructed bitmap as to whether the current time falls within the range specified...
Definition: pbx.c:8357
static int increase_call_count ( const struct ast_channel c)
static

Increase call count for channel.

Return values
0on success
non-zeroif a configured limit (maxcalls, maxload, minmemfree) was reached

Definition at line 5790 of file pbx.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, countcalls, getloadavg(), LOG_WARNING, maxcalllock, ast_channel::name, option_maxcalls, option_maxload, option_minmemfree, and totalcalls.

Referenced by ast_pbx_run_args(), and ast_pbx_start().

5791 {
5792  int failed = 0;
5793  double curloadavg;
5794 #if defined(HAVE_SYSINFO)
5795  long curfreemem;
5796  struct sysinfo sys_info;
5797 #endif
5798 
5800  if (option_maxcalls) {
5801  if (countcalls >= option_maxcalls) {
5802  ast_log(LOG_WARNING, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name);
5803  failed = -1;
5804  }
5805  }
5806  if (option_maxload) {
5807  getloadavg(&curloadavg, 1);
5808  if (curloadavg >= option_maxload) {
5809  ast_log(LOG_WARNING, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg);
5810  failed = -1;
5811  }
5812  }
5813 #if defined(HAVE_SYSINFO)
5814  if (option_minmemfree) {
5815  if (!sysinfo(&sys_info)) {
5816  /* make sure that the free system memory is above the configured low watermark
5817  * convert the amount of freeram from mem_units to MB */
5818  curfreemem = sys_info.freeram * sys_info.mem_unit;
5819  curfreemem /= 1024 * 1024;
5820  if (curfreemem < option_minmemfree) {
5821  ast_log(LOG_WARNING, "Available system memory (~%ldMB) is below the configured low watermark (%ldMB)\n", curfreemem, option_minmemfree);
5822  failed = -1;
5823  }
5824  }
5825  }
5826 #endif
5827 
5828  if (!failed) {
5829  countcalls++;
5830  totalcalls++;
5831  }
5833 
5834  return failed;
5835 }
#define LOG_WARNING
Definition: logger.h:144
#define ast_mutex_lock(a)
Definition: lock.h:155
long option_minmemfree
Definition: asterisk.c:187
static ast_mutex_t maxcalllock
Definition: pbx.c:1227
double option_maxload
Definition: asterisk.c:183
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int totalcalls
Definition: pbx.c:1229
static int countcalls
Definition: pbx.c:1228
int option_maxcalls
Definition: asterisk.c:184
int getloadavg(double *list, int nelem)
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void insert_in_next_chars_alt_char_list ( struct match_char **  parent_ptr,
struct match_char node 
)
static

Definition at line 1983 of file pbx.c.

References match_char::alt_char, and match_char::specificity.

Referenced by add_pattern_node().

1984 {
1985  struct match_char *curr, *lcurr;
1986 
1987  /* insert node into the tree at "current", so the alt_char list from current is
1988  sorted in increasing value as you go to the leaves */
1989  if (!(*parent_ptr)) {
1990  *parent_ptr = node;
1991  return;
1992  }
1993 
1994  if ((*parent_ptr)->specificity > node->specificity) {
1995  /* insert at head */
1996  node->alt_char = (*parent_ptr);
1997  *parent_ptr = node;
1998  return;
1999  }
2000 
2001  lcurr = *parent_ptr;
2002  for (curr = (*parent_ptr)->alt_char; curr; curr = curr->alt_char) {
2003  if (curr->specificity > node->specificity) {
2004  node->alt_char = curr;
2005  lcurr->alt_char = node;
2006  break;
2007  }
2008  lcurr = curr;
2009  }
2010 
2011  if (!curr) {
2012  lcurr->alt_char = node;
2013  }
2014 
2015 }
int specificity
Definition: pbx.c:936
struct match_char * alt_char
Definition: pbx.c:937
match_char: forms a syntax tree for quick matching of extension patterns
Definition: pbx.c:932
static int is_read_allowed ( struct ast_custom_function acfptr)
static

Determines whether execution of a custom function's read function is allowed.

Parameters
acfptrCustom function to check
Returns
True (non-zero) if reading is allowed.
False (zero) if reading is not allowed.

Definition at line 4119 of file pbx.c.

References ast_debug, ast_custom_function::name, read_escalates(), and thread_inhibits_escalations().

Referenced by ast_func_read(), and ast_func_read2().

4120 {
4121  if (!acfptr) {
4122  return 1;
4123  }
4124 
4125  if (!read_escalates(acfptr)) {
4126  return 1;
4127  }
4128 
4129  if (!thread_inhibits_escalations()) {
4130  return 1;
4131  }
4132 
4133  if (live_dangerously) {
4134  /* Global setting overrides the thread's preference */
4135  ast_debug(2, "Reading %s from a dangerous context\n",
4136  acfptr->name);
4137  return 1;
4138  }
4139 
4140  /* We have no reason to allow this function to execute */
4141  return 0;
4142 }
static int live_dangerously
Set to true (non-zero) to globally allow all dangerous dialplan functions to run. ...
Definition: pbx.c:870
static int thread_inhibits_escalations(void)
Indicates whether the current thread inhibits the execution of dangerous functions.
Definition: pbx.c:4095
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int read_escalates(const struct ast_custom_function *acf)
Returns true if given custom function escalates privileges on read.
Definition: pbx.c:3856
const char * name
Definition: pbx.h:96
static int is_write_allowed ( struct ast_custom_function acfptr)
static

Determines whether execution of a custom function's write function is allowed.

Parameters
acfptrCustom function to check
Returns
True (non-zero) if writing is allowed.
False (zero) if writing is not allowed.

Definition at line 4152 of file pbx.c.

References ast_debug, ast_custom_function::name, thread_inhibits_escalations(), and write_escalates().

Referenced by ast_func_write().

4153 {
4154  if (!acfptr) {
4155  return 1;
4156  }
4157 
4158  if (!write_escalates(acfptr)) {
4159  return 1;
4160  }
4161 
4162  if (!thread_inhibits_escalations()) {
4163  return 1;
4164  }
4165 
4166  if (live_dangerously) {
4167  /* Global setting overrides the thread's preference */
4168  ast_debug(2, "Writing %s from a dangerous context\n",
4169  acfptr->name);
4170  return 1;
4171  }
4172 
4173  /* We have no reason to allow this function to execute */
4174  return 0;
4175 }
static int live_dangerously
Set to true (non-zero) to globally allow all dangerous dialplan functions to run. ...
Definition: pbx.c:870
static int thread_inhibits_escalations(void)
Indicates whether the current thread inhibits the execution of dangerous functions.
Definition: pbx.c:4095
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * name
Definition: pbx.h:96
static int write_escalates(const struct ast_custom_function *acf)
Returns true if given custom function escalates privileges on write.
Definition: pbx.c:3878
int load_pbx ( void  )

Provided by pbx.c

Definition at line 10996 of file pbx.c.

References __ast_custom_function_register(), ARRAY_LEN, ast_cli_register_multiple(), ast_data_register_multiple_core, AST_EVENT_DEVICE_STATE, AST_EVENT_IE_END, ast_event_subscribe(), ast_log(), ast_manager_register_xml, ast_register_application2(), ast_register_atexit(), ast_taskprocessor_get(), ast_verb, builtins, device_state_cb(), device_state_sub, EVENT_FLAG_CONFIG, EVENT_FLAG_REPORTING, exception_function, LOG_ERROR, LOG_WARNING, manager_show_dialplan(), pbx_cli, pbx_data_providers, testtime_function, and unload_pbx().

Referenced by main().

10997 {
10998  int x;
10999 
11001 
11002  /* Initialize the PBX */
11003  ast_verb(1, "Asterisk PBX Core Initializing\n");
11004  if (!(device_state_tps = ast_taskprocessor_get("pbx-core", 0))) {
11005  ast_log(LOG_WARNING, "failed to create pbx-core taskprocessor\n");
11006  }
11007 
11008  ast_verb(1, "Registering builtin applications:\n");
11013 
11014  /* Register builtin applications */
11015  for (x = 0; x < ARRAY_LEN(builtins); x++) {
11016  ast_verb(1, "[%s]\n", builtins[x].name);
11017  if (ast_register_application2(builtins[x].name, builtins[x].execute, NULL, NULL, NULL)) {
11018  ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
11019  return -1;
11020  }
11021  }
11022 
11023  /* Register manager application */
11025 
11026  if (!(device_state_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE, device_state_cb, "pbx Device State Change", NULL,
11027  AST_EVENT_IE_END))) {
11028  return -1;
11029  }
11030 
11031  return 0;
11032 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:144
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary...
static struct ast_cli_entry pbx_cli[]
Definition: pbx.c:7665
char x[1]
Definition: pbx.c:940
#define ast_verb(level,...)
Definition: logger.h:243
#define ast_data_register_multiple_core(data_entries, entries)
Definition: data.h:379
#define ast_manager_register_xml(a, b, c)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:172
static struct ast_event_sub * device_state_sub
Subscription for device state change events.
Definition: pbx.c:1225
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
static struct ast_custom_function testtime_function
Definition: pbx.c:10114
static void unload_pbx(void)
Definition: pbx.c:10973
#define LOG_ERROR
Definition: logger.h:155
#define EVENT_FLAG_CONFIG
Definition: manager.h:78
static int manager_show_dialplan(struct mansession *s, const struct message *m)
Manager listing of dial plan.
Definition: pbx.c:7397
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_data_entry pbx_data_providers[]
Definition: pbx.c:10967
static const char name[]
static struct ast_custom_function exception_function
Definition: pbx.c:3646
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
struct ast_event_sub * ast_event_subscribe(enum ast_event_type event_type, ast_event_cb_t cb, const char *description, void *userdata,...)
Subscribe to events.
Definition: event.c:909
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
Register a custom function.
Definition: pbx.c:3946
static struct ast_taskprocessor * device_state_tps
Definition: pbx.c:862
int ast_register_application2(const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
Register an application.
Definition: pbx.c:6344
static void device_state_cb(const struct ast_event *event, void *unused)
Definition: pbx.c:10905
static struct pbx_builtin builtins[]
static int lookup_name ( const char *  s,
const char *const  names[],
int  max 
)
static

Helper for get_range. return the index of the matching entry, starting from 1. If names is not supplied, try numeric values.

Definition at line 8159 of file pbx.c.

Referenced by get_range().

8160 {
8161  int i;
8162 
8163  if (names && *s > '9') {
8164  for (i = 0; names[i]; i++) {
8165  if (!strcasecmp(s, names[i])) {
8166  return i;
8167  }
8168  }
8169  }
8170 
8171  /* Allow months and weekdays to be specified as numbers, as well */
8172  if (sscanf(s, "%2d", &i) == 1 && i >= 1 && i <= max) {
8173  /* What the array offset would have been: "1" would be at offset 0 */
8174  return i - 1;
8175  }
8176  return -1; /* error return */
8177 }
static void manager_dpsendack ( struct mansession s,
const struct message m 
)
static

Send ack once.

Definition at line 7252 of file pbx.c.

References astman_send_listack().

Referenced by manager_show_dialplan(), and manager_show_dialplan_helper().

7253 {
7254  astman_send_listack(s, m, "DialPlan list will follow", "start");
7255 }
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager list transaction.
Definition: manager.c:2145
static int manager_show_dialplan ( struct mansession s,
const struct message m 
)
static

Manager listing of dial plan.

Definition at line 7397 of file pbx.c.

References ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), context, dialplan_counters::context_existence, exten, dialplan_counters::extension_existence, manager_dpsendack(), manager_show_dialplan_helper(), dialplan_counters::total_context, dialplan_counters::total_exten, dialplan_counters::total_items, and dialplan_counters::total_prio.

Referenced by load_pbx().

7398 {
7399  const char *exten, *context;
7400  const char *id = astman_get_header(m, "ActionID");
7401  char idtext[256];
7402 
7403  /* Variables used for different counters */
7404  struct dialplan_counters counters;
7405 
7406  if (!ast_strlen_zero(id))
7407  snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
7408  else
7409  idtext[0] = '\0';
7410 
7411  memset(&counters, 0, sizeof(counters));
7412 
7413  exten = astman_get_header(m, "Extension");
7414  context = astman_get_header(m, "Context");
7415 
7416  manager_show_dialplan_helper(s, m, idtext, context, exten, &counters, NULL);
7417 
7418  if (!ast_strlen_zero(context) && !counters.context_existence) {
7419  char errorbuf[BUFSIZ];
7420 
7421  snprintf(errorbuf, sizeof(errorbuf), "Did not find context %s", context);
7422  astman_send_error(s, m, errorbuf);
7423  return 0;
7424  }
7425  if (!ast_strlen_zero(exten) && !counters.extension_existence) {
7426  char errorbuf[BUFSIZ];
7427 
7428  if (!ast_strlen_zero(context))
7429  snprintf(errorbuf, sizeof(errorbuf), "Did not find extension %s@%s", exten, context);
7430  else
7431  snprintf(errorbuf, sizeof(errorbuf), "Did not find extension %s in any context", exten);
7432  astman_send_error(s, m, errorbuf);
7433  return 0;
7434  }
7435 
7436  if (!counters.total_items) {
7437  manager_dpsendack(s, m);
7438  }
7439 
7440  astman_append(s, "Event: ShowDialPlanComplete\r\n"
7441  "EventList: Complete\r\n"
7442  "ListItems: %d\r\n"
7443  "ListExtensions: %d\r\n"
7444  "ListPriorities: %d\r\n"
7445  "ListContexts: %d\r\n"
7446  "%s"
7447  "\r\n", counters.total_items, counters.total_exten, counters.total_prio, counters.total_context, idtext);
7448 
7449  /* everything ok */
7450  return 0;
7451 }
static void manager_dpsendack(struct mansession *s, const struct message *m)
Send ack once.
Definition: pbx.c:7252
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int manager_show_dialplan_helper(struct mansession *s, const struct message *m, const char *actionidtext, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude)
Show dialplan extensions XXX this function is similar but not exactly the same as the CLI&#39;s show dial...
Definition: pbx.c:7261
Counters for the show dialplan manager command.
Definition: pbx.c:6895
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int manager_show_dialplan_helper ( struct mansession s,
const struct message m,
const char *  actionidtext,
const char *  context,
const char *  exten,
struct dialplan_counters dpc,
struct ast_include rinclude 
)
static

Show dialplan extensions XXX this function is similar but not exactly the same as the CLI's show dialplan. Must check whether the difference is intentional or not.

Definition at line 7261 of file pbx.c.

References ast_debug, ast_extension_match(), ast_get_context_name(), ast_get_extension_app(), ast_get_extension_app_data(), ast_get_extension_label(), ast_get_extension_name(), ast_get_extension_priority(), ast_get_extension_registrar(), ast_get_ignorepat_name(), ast_get_ignorepat_registrar(), ast_get_include_name(), ast_get_include_registrar(), ast_get_switch_data(), ast_get_switch_name(), ast_get_switch_registrar(), ast_log(), AST_MAX_EXTENSION, ast_rdlock_context(), ast_rdlock_contexts(), ast_strlen_zero(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), ast_walk_contexts(), ast_walk_extension_priorities(), astman_append(), astman_send_error(), dialplan_counters::context_existence, dialplan_counters::extension_existence, LOG_WARNING, manager_dpsendack(), PRIORITY_HINT, dialplan_counters::total_context, dialplan_counters::total_exten, dialplan_counters::total_items, and dialplan_counters::total_prio.

Referenced by manager_show_dialplan().

7265 {
7266  struct ast_context *c;
7267  int res = 0, old_total_exten = dpc->total_exten;
7268 
7269  if (ast_strlen_zero(exten))
7270  exten = NULL;
7271  if (ast_strlen_zero(context))
7272  context = NULL;
7273 
7274  ast_debug(3, "manager_show_dialplan: Context: -%s- Extension: -%s-\n", context, exten);
7275 
7276  /* try to lock contexts */
7277  if (ast_rdlock_contexts()) {
7278  astman_send_error(s, m, "Failed to lock contexts");
7279  ast_log(LOG_WARNING, "Failed to lock contexts list for manager: listdialplan\n");
7280  return -1;
7281  }
7282 
7283  c = NULL; /* walk all contexts ... */
7284  while ( (c = ast_walk_contexts(c)) ) {
7285  struct ast_exten *e;
7286  struct ast_include *i;
7287  struct ast_ignorepat *ip;
7288 
7289  if (context && strcmp(ast_get_context_name(c), context) != 0)
7290  continue; /* not the name we want */
7291 
7292  dpc->context_existence = 1;
7293  dpc->total_context++;
7294 
7295  ast_debug(3, "manager_show_dialplan: Found Context: %s \n", ast_get_context_name(c));
7296 
7297  if (ast_rdlock_context(c)) { /* failed to lock */
7298  ast_debug(3, "manager_show_dialplan: Failed to lock context\n");
7299  continue;
7300  }
7301 
7302  /* XXX note- an empty context is not printed */
7303  e = NULL; /* walk extensions in context */
7304  while ( (e = ast_walk_context_extensions(c, e)) ) {
7305  struct ast_exten *p;
7306 
7307  /* looking for extension? is this our extension? */
7309  /* not the one we are looking for, continue */
7310  ast_debug(3, "manager_show_dialplan: Skipping extension %s\n", ast_get_extension_name(e));
7311  continue;
7312  }
7313  ast_debug(3, "manager_show_dialplan: Found Extension: %s \n", ast_get_extension_name(e));
7314 
7315  dpc->extension_existence = 1;
7316 
7317  dpc->total_exten++;
7318 
7319  p = NULL; /* walk next extension peers */
7320  while ( (p = ast_walk_extension_priorities(e, p)) ) {
7321  int prio = ast_get_extension_priority(p);
7322 
7323  dpc->total_prio++;
7324  if (!dpc->total_items++)
7325  manager_dpsendack(s, m);
7326  astman_append(s, "Event: ListDialplan\r\n%s", actionidtext);
7327  astman_append(s, "Context: %s\r\nExtension: %s\r\n", ast_get_context_name(c), ast_get_extension_name(e) );
7328 
7329  /* XXX maybe make this conditional, if p != e ? */
7330  if (ast_get_extension_label(p))
7331  astman_append(s, "ExtensionLabel: %s\r\n", ast_get_extension_label(p));
7332 
7333  if (prio == PRIORITY_HINT) {
7334  astman_append(s, "Priority: hint\r\nApplication: %s\r\n", ast_get_extension_app(p));
7335  } else {
7336  astman_append(s, "Priority: %d\r\nApplication: %s\r\nAppData: %s\r\n", prio, ast_get_extension_app(p), (char *) ast_get_extension_app_data(p));
7337  }
7338  astman_append(s, "Registrar: %s\r\n\r\n", ast_get_extension_registrar(e));
7339  }
7340  }
7341 
7342  i = NULL; /* walk included and write info ... */
7343  while ( (i = ast_walk_context_includes(c, i)) ) {
7344  if (exten) {
7345  /* Check all includes for the requested extension */
7346  manager_show_dialplan_helper(s, m, actionidtext, ast_get_include_name(i), exten, dpc, i);
7347  } else {
7348  if (!dpc->total_items++)
7349  manager_dpsendack(s, m);
7350  astman_append(s, "Event: ListDialplan\r\n%s", actionidtext);
7351  astman_append(s, "Context: %s\r\nIncludeContext: %s\r\nRegistrar: %s\r\n", ast_get_context_name(c), ast_get_include_name(i), ast_get_include_registrar(i));
7352  astman_append(s, "\r\n");
7353  ast_debug(3, "manager_show_dialplan: Found Included context: %s \n", ast_get_include_name(i));
7354  }
7355  }
7356 
7357  ip = NULL; /* walk ignore patterns and write info ... */
7358  while ( (ip = ast_walk_context_ignorepats(c, ip)) ) {
7359  const char *ipname = ast_get_ignorepat_name(ip);
7360  char ignorepat[AST_MAX_EXTENSION];
7361 
7362  snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname);
7363  if (!exten || ast_extension_match(ignorepat, exten)) {
7364  if (!dpc->total_items++)
7365  manager_dpsendack(s, m);
7366  astman_append(s, "Event: ListDialplan\r\n%s", actionidtext);
7367  astman_append(s, "Context: %s\r\nIgnorePattern: %s\r\nRegistrar: %s\r\n", ast_get_context_name(c), ipname, ast_get_ignorepat_registrar(ip));
7368  astman_append(s, "\r\n");
7369  }
7370  }
7371  if (!rinclude) {
7372  struct ast_sw *sw = NULL;
7373  while ( (sw = ast_walk_context_switches(c, sw)) ) {
7374  if (!dpc->total_items++)
7375  manager_dpsendack(s, m);
7376  astman_append(s, "Event: ListDialplan\r\n%s", actionidtext);
7377  astman_append(s, "Context: %s\r\nSwitch: %s/%s\r\nRegistrar: %s\r\n", ast_get_context_name(c), ast_get_switch_name(sw), ast_get_switch_data(sw), ast_get_switch_registrar(sw));
7378  astman_append(s, "\r\n");
7379  ast_debug(3, "manager_show_dialplan: Found Switch : %s \n", ast_get_switch_name(sw));
7380  }
7381  }
7382 
7383  ast_unlock_context(c);
7384  }
7386 
7387  if (dpc->total_exten == old_total_exten) {
7388  ast_debug(3, "manager_show_dialplan: Found nothing new\n");
7389  /* Nothing new under the sun */
7390  return -1;
7391  } else {
7392  return res;
7393  }
7394 }
struct ast_include * ast_walk_context_includes(struct ast_context *con, struct ast_include *inc)
Definition: pbx.c:11203
static void manager_dpsendack(struct mansession *s, const struct message *m)
Send ack once.
Definition: pbx.c:7252
ast_include: include= support in extensions.conf
Definition: pbx.c:904
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
int ast_get_extension_priority(struct ast_exten *exten)
Definition: pbx.c:11103
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
const char * ast_get_extension_registrar(struct ast_exten *e)
Definition: pbx.c:11116
int total_items
Definition: pbx.c:6896
int total_exten
Definition: pbx.c:6898
#define LOG_WARNING
Definition: logger.h:144
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:11141
void * ast_get_extension_app_data(struct ast_exten *e)
Definition: pbx.c:11146
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:11042
int context_existence
Definition: pbx.c:6900
const char * ast_get_extension_label(struct ast_exten *e)
Definition: pbx.c:11088
const char * ast_get_switch_name(struct ast_sw *sw)
Definition: pbx.c:11151
const char * ast_get_include_name(struct ast_include *include)
Definition: pbx.c:11093
const char * ast_get_include_registrar(struct ast_include *i)
Definition: pbx.c:11121
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
ast_sw: Switch statement in extensions.conf
Definition: pbx.c:915
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority)
Definition: pbx.c:11179
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_MAX_EXTENSION
Definition: channel.h:135
const char * ast_get_ignorepat_registrar(struct ast_ignorepat *ip)
Definition: pbx.c:11126
const char * ast_get_switch_data(struct ast_sw *sw)
Definition: pbx.c:11156
static int manager_show_dialplan_helper(struct mansession *s, const struct message *m, const char *actionidtext, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude)
Show dialplan extensions XXX this function is similar but not exactly the same as the CLI&#39;s show dial...
Definition: pbx.c:7261
struct ast_ignorepat * ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip)
Definition: pbx.c:11212
#define PRIORITY_HINT
Definition: pbx.h:53
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: pbx.c:11174
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
const char * ast_get_switch_registrar(struct ast_sw *sw)
Definition: pbx.c:11166
struct ast_exten * ast_walk_extension_priorities(struct ast_exten *exten, struct ast_exten *priority)
Definition: pbx.c:11197
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx.c:925
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
const char * ast_get_ignorepat_name(struct ast_ignorepat *ip)
Definition: pbx.c:11098
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
Definition: pbx.c:2943
struct ast_sw * ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw)
Definition: pbx.c:11188
int total_prio
Definition: pbx.c:6899
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
int total_context
Definition: pbx.c:6897
ast_context: An extension context
Definition: pbx.c:955
int extension_existence
Definition: pbx.c:6901
int ast_rdlock_context(struct ast_context *con)
Read locks a given context.
Definition: pbx.c:11060
static int matchcid ( const char *  cidpattern,
const char *  callerid 
)
static

Definition at line 3001 of file pbx.c.

References ast_extension_match(), and ast_strlen_zero().

Referenced by pbx_find_extension().

3002 {
3003  /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
3004  failing to get a number should count as a match, otherwise not */
3005 
3006  if (ast_strlen_zero(callerid)) {
3007  return ast_strlen_zero(cidpattern) ? 1 : 0;
3008  }
3009 
3010  return ast_extension_match(cidpattern, callerid);
3011 }
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
Definition: pbx.c:2943
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 
)
static

Definition at line 1807 of file pbx.c.

References match_char::alt_char, ast_debug, ast_log(), scoreboard::canmatch, match_char::deleted, E_CANMATCH, E_MATCHMORE, ast_exten::exten, match_char::exten, scoreboard::exten, match_char::is_pattern, ast_exten::label, LOG_NOTICE, NEW_MATCHER_CHK_MATCH, NEW_MATCHER_RECURSE, match_char::next_char, match_char::specificity, str, update_scoreboard(), and match_char::x.

Referenced by pbx_find_extension().

1808 {
1809  struct match_char *p; /* note minimal stack storage requirements */
1810  struct ast_exten pattern = { .label = label };
1811 #ifdef DEBUG_THIS
1812  if (tree)
1813  ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree %s action=%s\n", str, tree->x, action2str(action));
1814  else
1815  ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree NULL action=%s\n", str, action2str(action));
1816 #endif
1817  for (p = tree; p; p = p->alt_char) {
1818  if (p->is_pattern) {
1819  if (p->x[0] == 'N') {
1820  if (p->x[1] == 0 && *str >= '2' && *str <= '9' ) {
1821 #define NEW_MATCHER_CHK_MATCH \
1822  if (p->exten && !(*(str + 1))) { /* if a shorter pattern matches along the way, might as well report it */ \
1823  if (action == E_MATCH || action == E_SPAWN || action == E_FINDLABEL) { /* if in CANMATCH/MATCHMORE, don't let matches get in the way */ \
1824  update_scoreboard(score, length + 1, spec + p->specificity, p->exten, 0, callerid, p->deleted, p); \
1825  if (!p->deleted) { \
1826  if (action == E_FINDLABEL) { \
1827  if (ast_hashtab_lookup(score->exten->peer_label_table, &pattern)) { \
1828  ast_debug(4, "Found label in preferred extension\n"); \
1829  return; \
1830  } \
1831  } else { \
1832  ast_debug(4, "returning an exact match-- first found-- %s\n", p->exten->exten); \
1833  return; /* the first match, by definition, will be the best, because of the sorted tree */ \
1834  } \
1835  } \
1836  } \
1837  }
1838 
1839 #define NEW_MATCHER_RECURSE \
1840  if (p->next_char && (*(str + 1) || (p->next_char->x[0] == '/' && p->next_char->x[1] == 0) \
1841  || p->next_char->x[0] == '!')) { \
1842  if (*(str + 1) || p->next_char->x[0] == '!') { \
1843  new_find_extension(str + 1, score, p->next_char, length + 1, spec + p->specificity, callerid, label, action); \
1844  if (score->exten) { \
1845  ast_debug(4 ,"returning an exact match-- %s\n", score->exten->exten); \
1846  return; /* the first match is all we need */ \
1847  } \
1848  } else { \
1849  new_find_extension("/", score, p->next_char, length + 1, spec + p->specificity, callerid, label, action); \
1850  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) { \
1851  ast_debug(4,"returning a (can/more) match--- %s\n", score->exten ? score->exten->exten : \
1852  "NULL"); \
1853  return; /* the first match is all we need */ \
1854  } \
1855  } \
1856  } else if ((p->next_char || action == E_CANMATCH) && !*(str + 1)) { \
1857  score->canmatch = 1; \
1858  score->canmatch_exten = get_canmatch_exten(p); \
1859  if (action == E_CANMATCH || action == E_MATCHMORE) { \
1860  ast_debug(4, "returning a canmatch/matchmore--- str=%s\n", str); \
1861  return; \
1862  } \
1863  }
1864 
1867  }
1868  } else if (p->x[0] == 'Z') {
1869  if (p->x[1] == 0 && *str >= '1' && *str <= '9' ) {
1872  }
1873  } else if (p->x[0] == 'X') {
1874  if (p->x[1] == 0 && *str >= '0' && *str <= '9' ) {
1877  }
1878  } else if (p->x[0] == '.' && p->x[1] == 0) {
1879  /* how many chars will the . match against? */
1880  int i = 0;
1881  const char *str2 = str;
1882  while (*str2 && *str2 != '/') {
1883  str2++;
1884  i++;
1885  }
1886  if (p->exten && *str2 != '/') {
1887  update_scoreboard(score, length + i, spec + (i * p->specificity), p->exten, '.', callerid, p->deleted, p);
1888  if (score->exten) {
1889  ast_debug(4,"return because scoreboard has a match with '/'--- %s\n", score->exten->exten);
1890  return; /* the first match is all we need */
1891  }
1892  }
1893  if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
1894  new_find_extension("/", score, p->next_char, length + i, spec+(p->specificity*i), callerid, label, action);
1895  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
1896  ast_debug(4, "return because scoreboard has exact match OR CANMATCH/MATCHMORE & canmatch set--- %s\n", score->exten ? score->exten->exten : "NULL");
1897  return; /* the first match is all we need */
1898  }
1899  }
1900  } else if (p->x[0] == '!' && p->x[1] == 0) {
1901  /* how many chars will the . match against? */
1902  int i = 1;
1903  const char *str2 = str;
1904  while (*str2 && *str2 != '/') {
1905  str2++;
1906  i++;
1907  }
1908  if (p->exten && *str2 != '/') {
1909  update_scoreboard(score, length + 1, spec + (p->specificity * i), p->exten, '!', callerid, p->deleted, p);
1910  if (score->exten) {
1911  ast_debug(4, "return because scoreboard has a '!' match--- %s\n", score->exten->exten);
1912  return; /* the first match is all we need */
1913  }
1914  }
1915  if (p->next_char && p->next_char->x[0] == '/' && p->next_char->x[1] == 0) {
1916  new_find_extension("/", score, p->next_char, length + i, spec + (p->specificity * i), callerid, label, action);
1917  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
1918  ast_debug(4, "return because scoreboard has exact match OR CANMATCH/MATCHMORE & canmatch set with '/' and '!'--- %s\n", score->exten ? score->exten->exten : "NULL");
1919  return; /* the first match is all we need */
1920  }
1921  }
1922  } else if (p->x[0] == '/' && p->x[1] == 0) {
1923  /* the pattern in the tree includes the cid match! */
1924  if (p->next_char && callerid && *callerid) {
1925  new_find_extension(callerid, score, p->next_char, length + 1, spec, callerid, label, action);
1926  if (score->exten || ((action == E_CANMATCH || action == E_MATCHMORE) && score->canmatch)) {
1927  ast_debug(4, "return because scoreboard has exact match OR CANMATCH/MATCHMORE & canmatch set with '/'--- %s\n", score->exten ? score->exten->exten : "NULL");
1928  return; /* the first match is all we need */
1929  }
1930  }
1931  } else if (strchr(p->x, *str)) {
1932  ast_debug(4, "Nothing strange about this match\n");
1935  }
1936  } else if (strchr(p->x, *str)) {
1937  ast_debug(4, "Nothing strange about this match\n");
1940  }
1941  }
1942  ast_debug(4, "return at end of func\n");
1943 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
struct ast_exten * exten
Definition: pbx.c:939
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)
Definition: pbx.c:1807
#define NEW_MATCHER_RECURSE
int specificity
Definition: pbx.c:936
struct match_char * alt_char
Definition: pbx.c:937
const char * str
Definition: app_jack.c:144
const char * label
Definition: pbx.c:889
char x[1]
Definition: pbx.c:940
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char * exten
Definition: pbx.c:885
#define NEW_MATCHER_CHK_MATCH
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int is_pattern
Definition: pbx.c:934
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)
Definition: pbx.c:1652
int canmatch
Definition: pbx.c:948
struct match_char * next_char
Definition: pbx.c:938
struct ast_exten * exten
Definition: pbx.c:951
int deleted
Definition: pbx.c:935
match_char: forms a syntax tree for quick matching of extension patterns
Definition: pbx.c:932
static int parse_variable_name ( char *  var,
int *  offset,
int *  length,
int *  isfunc 
)
static

extract offset:length from variable name.

Returns
1 if there is a offset:length part, which is trimmed off (values go into variables)

Definition at line 3311 of file pbx.c.

References var.

Referenced by ast_str_retrieve_variable(), ast_str_substitute_variables_full(), and pbx_substitute_variables_helper_full().

3312 {
3313  int parens = 0;
3314 
3315  *offset = 0;
3316  *length = INT_MAX;
3317  *isfunc = 0;
3318  for (; *var; var++) {
3319  if (*var == '(') {
3320  (*isfunc)++;
3321  parens++;
3322  } else if (*var == ')') {
3323  parens--;
3324  } else if (*var == ':' && parens == 0) {
3325  *var++ = '\0';
3326  sscanf(var, "%30d:%30d", offset, length);
3327  return 1; /* offset:length valid */
3328  }
3329  }
3330  return 0;
3331 }
#define var
Definition: ast_expr2f.c:606
void pbx_builtin_clear_globals ( void  )

Definition at line 10709 of file pbx.c.

References AST_LIST_REMOVE_HEAD, ast_rwlock_unlock, ast_rwlock_wrlock, ast_var_delete(), ast_var_t::entries, globals, and globalslock.

Referenced by handle_cli_dialplan_reload(), pbx_shutdown(), and reload().

10710 {
10711  struct ast_var_t *vardata;
10712 
10714  while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
10715  ast_var_delete(vardata);
10717 }
static ast_rwlock_t globalslock
Definition: pbx.c:1217
#define ast_rwlock_unlock(a)
Definition: lock.h:200
void ast_var_delete(struct ast_var_t *var)
Definition: chanvars.c:63
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
struct ast_var_t::@158 entries
#define ast_rwlock_wrlock(a)
Definition: lock.h:202
static struct varshead globals
Definition: pbx.c:1218
const char* pbx_builtin_getvar_helper ( struct ast_channel chan,
const char *  name 
)

Return a pointer to the value of the corresponding channel variable.

Note
Will lock the channel.
This function will return a pointer to the buffer inside the channel variable. This value should only be accessed with the channel locked. If the value needs to be kept around, it should be done by using the following thread-safe code:
* const char *var;
*
* if ((var = pbx_builtin_getvar_helper(chan, "MYVAR"))) {
* var = ast_strdupa(var);
* }
*

Definition at line 10475 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_rwlock_rdlock, ast_rwlock_unlock, ast_var_name(), ast_var_value(), globals, globalslock, and ast_channel::varshead.

Referenced by __ast_pbx_run(), _macro_exec(), _while_exec(), agentmonitoroutgoing_exec(), analog_call(), append_channel_vars(), array(), ast_bridge_call(), ast_bridge_timelimit(), ast_call_forward(), ast_channel_connected_line_macro(), ast_channel_redirecting_macro(), ast_eivr_getvariable(), ast_hangup(), ast_monitor_stop(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_run(), confbridge_exec(), create_dynamic_parkinglot(), crement_function_read(), dahdi_hangup(), dahdi_r2_answer(), dahdi_r2_get_channel_category(), dial_exec_full(), do_forward(), dundi_exec(), dundi_helper(), feature_check(), feature_interpret(), find_by_mark(), find_conf_realtime(), findparkinglotname(), func_channel_read(), generic_fax_exec(), get_also_info(), get_index(), get_refer_info(), global_read(), gosub_run(), handle_gosub(), hash_read(), iax2_call(), iax2_exec(), import_ch(), leave_voicemail(), local_attended_transfer(), local_hangup(), local_read(), login_exec(), macro_fixup(), meetme_menu_admin_extended(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_exec(), park_call_full(), park_space_reserve(), pbx_builtin_background(), pbx_builtin_gotoiftime(), queue_exec(), real_ctx(), receivefax_exec(), retrydial_exec(), ring_entry(), run_agi(), sendfax_exec(), set_config_flags(), set_local_info(), sig_pri_call(), sig_pri_hangup(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), update_bridge_vars(), and wait_for_answer().

10476 {
10477  struct ast_var_t *variables;
10478  const char *ret = NULL;
10479  int i;
10480  struct varshead *places[2] = { NULL, &globals };
10481 
10482  if (!name)
10483  return NULL;
10484 
10485  if (chan) {
10486  ast_channel_lock(chan);
10487  places[0] = &chan->varshead;
10488  }
10489 
10490  for (i = 0; i < 2; i++) {
10491  if (!places[i])
10492  continue;
10493  if (places[i] == &globals)
10495  AST_LIST_TRAVERSE(places[i], variables, entries) {
10496  if (!strcmp(name, ast_var_name(variables))) {
10497  ret = ast_var_value(variables);
10498  break;
10499  }
10500  }
10501  if (places[i] == &globals)
10503  if (ret)
10504  break;
10505  }
10506 
10507  if (chan)
10508  ast_channel_unlock(chan);
10509 
10510  return ret;
10511 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:201
#define ast_channel_lock(chan)
Definition: channel.h:2466
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:89
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
static ast_rwlock_t globalslock
Definition: pbx.c:1217
#define ast_rwlock_unlock(a)
Definition: lock.h:200
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static const char name[]
static struct varshead globals
Definition: pbx.c:1218
struct varshead varshead
Definition: channel.h:817
static int pbx_builtin_gotoif ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 10731 of file pbx.c.

References ast_debug, ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_goto(), pbx_checkcondition(), and strsep().

10732 {
10733  char *condition, *branch1, *branch2, *branch;
10734  char *stringp;
10735 
10736  if (ast_strlen_zero(data)) {
10737  ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n");
10738  return 0;
10739  }
10740 
10741  stringp = ast_strdupa(data);
10742  condition = strsep(&stringp,"?");
10743  branch1 = strsep(&stringp,":");
10744  branch2 = strsep(&stringp,"");
10745  branch = pbx_checkcondition(condition) ? branch1 : branch2;
10746 
10747  if (ast_strlen_zero(branch)) {
10748  ast_debug(1, "Not taking any branch\n");
10749  return 0;
10750  }
10751 
10752  return pbx_builtin_goto(chan, branch);
10753 }
char * strsep(char **str, const char *delims)
#define LOG_WARNING
Definition: logger.h:144
static int pbx_builtin_goto(struct ast_channel *, const char *)
Definition: pbx.c:10435
int pbx_checkcondition(const char *condition)
Evaluate a condition.
Definition: pbx.c:10719
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int pbx_builtin_importvar ( struct ast_channel chan,
const char *  data 
)
static
Todo:
XXX should do !ast_strlen_zero(..) of the args ?

Definition at line 10669 of file pbx.c.

References ast_alloca, ast_channel_get_by_name(), ast_channel_unref, ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, ast_sw::name, pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), strsep(), value, and VAR_BUF_SIZE.

10670 {
10671  char *name;
10672  char *value;
10673  char *channel;
10674  char tmp[VAR_BUF_SIZE];
10675  static int deprecation_warning = 0;
10676 
10677  if (ast_strlen_zero(data)) {
10678  ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
10679  return 0;
10680  }
10681  tmp[0] = 0;
10682  if (!deprecation_warning) {
10683  ast_log(LOG_WARNING, "ImportVar is deprecated. Please use Set(varname=${IMPORT(channel,variable)}) instead.\n");
10684  deprecation_warning = 1;
10685  }
10686 
10687  value = ast_strdupa(data);
10688  name = strsep(&value,"=");
10689  channel = strsep(&value,",");
10690  if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */
10691  struct ast_channel *chan2 = ast_channel_get_by_name(channel);
10692  if (chan2) {
10693  char *s = ast_alloca(strlen(value) + 4);
10694  sprintf(s, "${%s}", value);
10695  pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1);
10696  chan2 = ast_channel_unref(chan2);
10697  }
10698  pbx_builtin_setvar_helper(chan, name, tmp);
10699  }
10700 
10701  return(0);
10702 }
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: pbx.c:4676
Main Channel structure associated with a channel.
Definition: channel.h:742
char * strsep(char **str, const char *delims)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define LOG_WARNING
Definition: logger.h:144
int value
Definition: syslog.c:39
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
#define VAR_BUF_SIZE
Definition: pbx.c:833
static int pbx_builtin_incomplete ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 9996 of file pbx.c.

References __ast_answer(), ast_channel::_state, ast_check_hangup(), AST_CONTROL_INCOMPLETE, ast_indicate(), AST_PBX_INCOMPLETE, AST_STATE_UP, ast_strlen_zero(), and ast_sw::data.

9997 {
9998  const char *options = data;
9999  int answer = 1;
10000 
10001  /* Some channels can receive DTMF in unanswered state; some cannot */
10002  if (!ast_strlen_zero(options) && strchr(options, 'n')) {
10003  answer = 0;
10004  }
10005 
10006  /* If the channel is hungup, stop waiting */
10007  if (ast_check_hangup(chan)) {
10008  return -1;
10009  } else if (chan->_state != AST_STATE_UP && answer) {
10010  __ast_answer(chan, 0, 1);
10011  }
10012 
10014 
10015  return AST_PBX_INCOMPLETE;
10016 }
int __ast_answer(struct ast_channel *chan, unsigned int delay, int cdr_answer)
Answer a channel, with a selectable delay before returning.
Definition: channel.c:2982
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
const char * data
Definition: channel.h:755
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
#define AST_PBX_INCOMPLETE
Definition: pbx.h:50
enum ast_channel_state _state
Definition: channel.h:839
static int pbx_builtin_noop ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 10704 of file pbx.c.

10705 {
10706  return 0;
10707 }
void pbx_builtin_pushvar_helper ( struct ast_channel chan,
const char *  name,
const char *  value 
)

Add a variable to the channel variable stack, without removing any previously set value.

Note
Will lock the channel.

Definition at line 10513 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_rwlock_unlock, ast_rwlock_wrlock, ast_strdupa, ast_var_assign(), ast_verb, globals, globalslock, LOG_WARNING, and ast_channel::varshead.

Referenced by acf_odbc_read(), acf_odbc_write(), cli_odbc_read(), cli_odbc_write(), and frame_set_var().

10514 {
10515  struct ast_var_t *newvariable;
10516  struct varshead *headp;
10517 
10518  if (name[strlen(name)-1] == ')') {
10519  char *function = ast_strdupa(name);
10520 
10521  ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
10522  ast_func_write(chan, function, value);
10523  return;
10524  }
10525 
10526  if (chan) {
10527  ast_channel_lock(chan);
10528  headp = &chan->varshead;
10529  } else {
10531  headp = &globals;
10532  }
10533 
10534  if (value && (newvariable = ast_var_assign(name, value))) {
10535  if (headp == &globals)
10536  ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
10537  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
10538  }
10539 
10540  if (chan)
10541  ast_channel_unlock(chan);
10542  else
10544 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
struct ast_var_t * ast_var_assign(const char *name, const char *value)
Definition: chanvars.c:41
#define LOG_WARNING
Definition: logger.h:144
static ast_rwlock_t globalslock
Definition: pbx.c:1217
int value
Definition: syslog.c:39
#define ast_rwlock_unlock(a)
Definition: lock.h:200
#define ast_verb(level,...)
Definition: logger.h:243
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static const char name[]
#define ast_rwlock_wrlock(a)
Definition: lock.h:202
static struct varshead globals
Definition: pbx.c:1218
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
Definition: pbx.c:4263
struct varshead varshead
Definition: channel.h:817
int pbx_builtin_raise_exception ( struct ast_channel chan,
const char *  reason 
)

Definition at line 3620 of file pbx.c.

References raise_exception().

3621 {
3622  /* Priority will become 1, next time through the AUTOLOOP */
3623  return raise_exception(chan, reason, 0);
3624 }
static int raise_exception(struct ast_channel *chan, const char *reason, int priority)
Definition: pbx.c:3594
static int pbx_builtin_saycharacters ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 10792 of file pbx.c.

References ast_say_character_str(), and ast_channel::language.

10793 {
10794  int res = 0;
10795 
10796  if (data)
10797  res = ast_say_character_str(chan, data, "", chan->language);
10798  return res;
10799 }
int ast_say_character_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
Definition: channel.c:8421
const ast_string_field language
Definition: channel.h:787
static int pbx_builtin_saydate ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 10810 of file pbx.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_say_date, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::language, LOG_WARNING, parse(), and pbx_builtin_setvar_helper().

10811 {
10812  int res = 0;
10813  char *parse;
10814  int unixdate = 0;
10815  char charascii[2];
10816 
10818  AST_APP_ARG(datestr);
10819  AST_APP_ARG(digits);
10820  );
10821 
10822 
10823  if (ast_strlen_zero(data)) {
10824  ast_log(LOG_WARNING, "SayDate requires an argument (date)\n");
10825  return -1;
10826  }
10827 
10828  if (!(parse = ast_strdupa(data))) {
10829  ast_log(LOG_WARNING, "Memory Error!\n");
10830  return -1;
10831  }
10832 
10833  AST_STANDARD_APP_ARGS(args, parse);
10834 
10835  if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) {
10836  ast_log(LOG_WARNING, "SayDate escape digits must be a subset from '0123456789*#'\n");
10837  args.digits = "";
10838  }
10839 
10840  if (sscanf(args.datestr, "%d", &unixdate) != 1) {
10841  ast_log(LOG_WARNING, "Firt argument to SayDate must be numeric (date)\n");
10842  return -1;
10843  }
10844 
10845  res = ast_say_date(chan, (time_t)unixdate, args.digits, chan->language);
10846  if (res > 0) {
10847  if (isdigit(res) || (res == '*') || (res == '#')) {
10848  snprintf(charascii, 2, "%c", res);
10849  pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii);
10850  res = 0;
10851  } else {
10852  ast_log(LOG_WARNING, "SayDate: invalid return value (%d) detected\n", res);
10853  }
10854  }
10855  return res;
10856 }
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
SAY_EXTERN int(* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date)
Definition: say.h:164
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
const ast_string_field language
Definition: channel.h:787
static int pbx_builtin_saydigits ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 10783 of file pbx.c.

References ast_say_digit_str(), and ast_channel::language.

10784 {
10785  int res = 0;
10786 
10787  if (data)
10788  res = ast_say_digit_str(chan, data, "", chan->language);
10789  return res;
10790 }
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
Definition: channel.c:8415
const ast_string_field language
Definition: channel.h:787
static int pbx_builtin_saynumber ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 10755 of file pbx.c.

References ast_copy_string(), ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, LOG_WARNING, and strsep().

10756 {
10757  char tmp[256];
10758  char *number = tmp;
10759  char *options;
10760 
10761  if (ast_strlen_zero(data)) {
10762  ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
10763  return -1;
10764  }
10765  ast_copy_string(tmp, data, sizeof(tmp));
10766  strsep(&number, ",");
10767  options = strsep(&number, ",");
10768  if (options) {
10769  if ( strcasecmp(options, "f") && strcasecmp(options, "m") &&
10770  strcasecmp(options, "c") && strcasecmp(options, "n") ) {
10771  ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
10772  return -1;
10773  }
10774  }
10775 
10776  if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) {
10777  ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
10778  }
10779 
10780  return 0;
10781 }
char * strsep(char **str, const char *delims)
#define LOG_WARNING
Definition: logger.h:144
Number structure.
Definition: app_followme.c:109
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8397
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
const ast_string_field language
Definition: channel.h:787
static int pbx_builtin_sayphonetic ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 10801 of file pbx.c.

References ast_say_phonetic_str(), and ast_channel::language.

10802 {
10803  int res = 0;
10804 
10805  if (data)
10806  res = ast_say_phonetic_str(chan, data, "", chan->language);
10807  return res;
10808 }
int ast_say_phonetic_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
Definition: channel.c:8427
const ast_string_field language
Definition: channel.h:787
static int pbx_builtin_saytime ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 10858 of file pbx.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_say_time, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::language, LOG_WARNING, parse(), and pbx_builtin_setvar_helper().

10859 {
10860  int res = 0;
10861  char *parse;
10862  int secs = 0;
10863  char charascii[2];
10864 
10866  AST_APP_ARG(timestr);
10867  AST_APP_ARG(digits);
10868  );
10869 
10870  if (ast_strlen_zero(data)) {
10871  ast_log(LOG_WARNING, "SayTime requires an argument (time in seconds)\n");
10872  return -1;
10873  }
10874 
10875  if (!(parse = ast_strdupa(data))) {
10876  ast_log(LOG_WARNING, "Memory Error!\n");
10877  return -1;
10878  }
10879 
10880  AST_STANDARD_APP_ARGS(args, parse);
10881 
10882  if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) {
10883  ast_log(LOG_WARNING, "SayTime escape digits must be a subset from '0123456789*#'\n");
10884  args.digits = "";
10885  }
10886 
10887  if (sscanf(args.timestr, "%d", &secs) != 1) {
10888  ast_log(LOG_WARNING, "Firt argument to SayTime must be numeric (time in seconds)\n");
10889  return -1;
10890  }
10891 
10892  res = ast_say_time(chan, (time_t)secs, args.digits, chan->language);
10893  if (res > 0) {
10894  if (isdigit(res) || (res == '*') || (res == '#')) {
10895  snprintf(charascii, 2, "%c", res);
10896  pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii);
10897  res = 0;
10898  } else {
10899  ast_log(LOG_WARNING, "SayTime: invalid return value (%d) detected\n", res);
10900  }
10901  }
10902  return res;
10903 }
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition: say.h:162
const ast_string_field language
Definition: channel.h:787
int pbx_builtin_serialize_variables ( struct ast_channel chan,
struct ast_str **  buf 
)

Create a human-readable string, specifying all variables and their corresponding values.

Parameters
chanChannel from which to read variables
bufDynamic string in which to place the result (should be allocated with ast_str_create).
See Also
ast_str_create
Note
Will lock the channel.

Definition at line 10444 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_str_append(), ast_str_reset(), ast_var_name(), ast_var_value(), ast_var_t::entries, LOG_ERROR, total, var, and ast_channel::varshead.

Referenced by ast_var_channels_table(), dumpchan_exec(), handle_show_chanvar(), handle_showchan(), and vars2manager().

10445 {
10446  struct ast_var_t *variables;
10447  const char *var, *val;
10448  int total = 0;
10449 
10450  if (!chan)
10451  return 0;
10452 
10453  ast_str_reset(*buf);
10454 
10455  ast_channel_lock(chan);
10456 
10457  AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
10458  if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))
10459  /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
10460  ) {
10461  if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) {
10462  ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
10463  break;
10464  } else
10465  total++;
10466  } else
10467  break;
10468  }
10469 
10470  ast_channel_unlock(chan);
10471 
10472  return total;
10473 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Definition: ast_expr2.c:325
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:89
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
#define var
Definition: ast_expr2f.c:606
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct ast_var_t::@158 entries
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:436
static int total
Definition: res_adsi.c:967
struct varshead varshead
Definition: channel.h:817
int pbx_builtin_setvar ( struct ast_channel chan,
const char *  data 
)

Parse and set a single channel variable, where the name and value are separated with an '=' character.

Note
Will lock the channel.

Definition at line 10603 of file pbx.c.

References ast_compat_app_set, ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, ast_sw::name, pbx_builtin_setvar_helper(), pbx_builtin_setvar_multiple(), strsep(), and value.

Referenced by ast_compile_ael2().

10604 {
10605  char *name, *value, *mydata;
10606 
10607  if (ast_compat_app_set) {
10608  return pbx_builtin_setvar_multiple(chan, data);
10609  }
10610 
10611  if (ast_strlen_zero(data)) {
10612  ast_log(LOG_WARNING, "Set requires one variable name/value pair.\n");
10613  return 0;
10614  }
10615 
10616  mydata = ast_strdupa(data);
10617  name = strsep(&mydata, "=");
10618  value = mydata;
10619  if (!value) {
10620  ast_log(LOG_WARNING, "Set requires an '=' to be a valid assignment.\n");
10621  return 0;
10622  }
10623 
10624  if (strchr(name, ' ')) {
10625  ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", name, mydata);
10626  }
10627 
10628  pbx_builtin_setvar_helper(chan, name, value);
10629 
10630  return 0;
10631 }
char * strsep(char **str, const char *delims)
#define LOG_WARNING
Definition: logger.h:144
#define ast_compat_app_set
Definition: options.h:144
int value
Definition: syslog.c:39
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int pbx_builtin_setvar_multiple(struct ast_channel *chan, const char *data)
Parse and set multiple channel variables, where the pairs are separated by the &#39;,&#39; character...
Definition: pbx.c:10633
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
int pbx_builtin_setvar_helper ( struct ast_channel chan,
const char *  name,
const char *  value 
)

Add a variable to the channel variable stack, removing the most recently set value for the same name.

Note
Will lock the channel. May also be used to set a channel dialplan function to a particular value.
See Also
ast_func_write
Returns
-1 if the dialplan function fails to be set
Version
1.8 changed the function to return an error code

Definition at line 10546 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_rwlock_unlock, ast_rwlock_wrlock, ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verb, EVENT_FLAG_DIALPLAN, globals, globalslock, manager_event, ast_channel::name, ast_sw::name, ast_channel::uniqueid, and ast_channel::varshead.

Referenced by __analog_ss_thread(), __ast_pbx_run(), __oh323_new(), _macro_exec(), _while_exec(), acf_curl_helper(), acf_fetch(), acf_odbc_read(), acf_odbc_write(), acf_transaction_write(), action_atxfer(), action_setvar(), admin_exec(), agi_exec_full(), aji_status_exec(), analog_ss_thread(), aqm_exec(), array(), ast_bridge_call(), ast_cc_agent_set_interfaces_chanvar(), ast_eivr_setvariable(), ast_iax2_new(), ast_monitor_start(), ast_monitor_stop(), ast_pbx_outgoing_exten(), ast_pickup_call(), ast_rtp_instance_set_stats_vars(), ast_set_cc_interfaces_chanvar(), ast_set_variables(), asyncgoto_exec(), background_detect_exec(), bridge_exec(), bridge_play_sounds(), builtin_atxfer(), builtin_automixmonitor(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), cccancel_exec(), ccreq_exec(), chanavail_exec(), channel_spy(), commit_exec(), conf_run(), controlplayback_exec(), count_exec(), crement_function_read(), dahdi_handle_dtmf(), dahdi_new(), dial_exec_full(), disa_exec(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), feature_exec_app(), feature_request_and_dial(), frame_set_var(), func_mchan_write(), function_db_delete(), function_db_exists(), function_db_read(), function_realtime_store(), generic_recall(), get_rdnis(), get_refer_info(), global_write(), gosub_release_frame(), gosub_run(), handle_gosub(), handle_incoming(), handle_request_bye(), handle_request_refer(), handle_set_chanvar(), handle_set_global(), handle_setvariable(), hash_read(), hash_write(), isAnsweringMachine(), leave_queue(), leave_voicemail(), local_hangup(), lua_set_variable(), lua_set_variable_value(), macro_fixup(), manage_parked_call(), mgcp_new(), minivm_accmess_exec(), minivm_delete_exec(), minivm_greet_exec(), minivm_notify_exec(), minivm_record_exec(), misdn_call(), mixmonitor_exec(), my_handle_dtmf(), originate_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_call_full(), parked_call_exec(), parse_moved_contact(), pbx_builtin_background(), pbx_builtin_gotoiftime(), pbx_builtin_importvar(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_setvar(), pbx_builtin_setvar_multiple(), pbx_load_config(), phase_e_handler(), play_message_datetime(), playback_exec(), pqm_exec(), prep_email_sub_vars(), pri_dchannel(), privacy_exec(), process_ast_dsp(), process_sdp(), read_exec(), readexten_exec(), readfile_exec(), realtimefield_read(), receivefax_exec(), record_exec(), reload_module(), return_exec(), ring_entry(), rollback_exec(), rotate_file(), rqm_exec(), sendfax_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_channel_variables(), set_queue_result(), shift_pop(), sig_pri_new_ast_channel(), sip_addheader(), sip_hangup(), sip_new(), sip_read(), skinny_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), start_monitor_exec(), system_exec_helper(), testtime_write(), transfer_exec(), transmit(), tryexec_exec(), unshift_push(), update_bridge_vars(), update_qe_rule(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), waituntil_exec(), and zapateller_exec().

10547 {
10548  struct ast_var_t *newvariable;
10549  struct varshead *headp;
10550  const char *nametail = name;
10551 
10552  if (name[strlen(name) - 1] == ')') {
10553  char *function = ast_strdupa(name);
10554 
10555  return ast_func_write(chan, function, value);
10556  }
10557 
10558  if (chan) {
10559  ast_channel_lock(chan);
10560  headp = &chan->varshead;
10561  } else {
10563  headp = &globals;
10564  }
10565 
10566  /* For comparison purposes, we have to strip leading underscores */
10567  if (*nametail == '_') {
10568  nametail++;
10569  if (*nametail == '_')
10570  nametail++;
10571  }
10572 
10573  AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
10574  if (strcmp(ast_var_name(newvariable), nametail) == 0) {
10575  /* there is already such a variable, delete it */
10576  AST_LIST_REMOVE_CURRENT(entries);
10577  ast_var_delete(newvariable);
10578  break;
10579  }
10580  }
10582 
10583  if (value && (newvariable = ast_var_assign(name, value))) {
10584  if (headp == &globals)
10585  ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
10586  AST_LIST_INSERT_HEAD(headp, newvariable, entries);
10588  "Channel: %s\r\n"
10589  "Variable: %s\r\n"
10590  "Value: %s\r\n"
10591  "Uniqueid: %s\r\n",
10592  chan ? chan->name : "none", name, value,
10593  chan ? chan->uniqueid : "none");
10594  }
10595 
10596  if (chan)
10597  ast_channel_unlock(chan);
10598  else
10600  return 0;
10601 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
const ast_string_field uniqueid
Definition: channel.h:787
struct ast_var_t * ast_var_assign(const char *name, const char *value)
Definition: chanvars.c:41
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:69
static ast_rwlock_t globalslock
Definition: pbx.c:1217
int value
Definition: syslog.c:39
#define ast_rwlock_unlock(a)
Definition: lock.h:200
#define EVENT_FLAG_DIALPLAN
Definition: manager.h:82
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
void ast_var_delete(struct ast_var_t *var)
Definition: chanvars.c:63
#define ast_verb(level,...)
Definition: logger.h:243
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
const ast_string_field name
Definition: channel.h:787
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static const char name[]
#define ast_rwlock_wrlock(a)
Definition: lock.h:202
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
static struct varshead globals
Definition: pbx.c:1218
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
Definition: pbx.c:4263
struct varshead varshead
Definition: channel.h:817
int pbx_builtin_setvar_multiple ( struct ast_channel chan,
const char *  data 
)

Parse and set multiple channel variables, where the pairs are separated by the ',' character, and name and value are separated with an '=' character.

Note
Will lock the channel.

Definition at line 10633 of file pbx.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::context, ast_sw::data, ast_channel::exten, LOG_WARNING, ast_channel::name, pbx_builtin_setvar_helper(), ast_channel::priority, and value.

Referenced by pbx_builtin_setvar(), queue_function_var(), set_queue_variables(), and try_calling().

10634 {
10635  char *data;
10636  int x;
10638  AST_APP_ARG(pair)[24];
10639  );
10640  AST_DECLARE_APP_ARGS(pair,
10641  AST_APP_ARG(name);
10642  AST_APP_ARG(value);
10643  );
10644 
10645  if (ast_strlen_zero(vdata)) {
10646  ast_log(LOG_WARNING, "MSet requires at least one variable name/value pair.\n");
10647  return 0;
10648  }
10649 
10650  data = ast_strdupa(vdata);
10651  AST_STANDARD_APP_ARGS(args, data);
10652 
10653  for (x = 0; x < args.argc; x++) {
10654  AST_NONSTANDARD_APP_ARGS(pair, args.pair[x], '=');
10655  if (pair.argc == 2) {
10656  pbx_builtin_setvar_helper(chan, pair.name, pair.value);
10657  if (strchr(pair.name, ' '))
10658  ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", pair.name, pair.value);
10659  } else if (!chan) {
10660  ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '='\n", pair.name);
10661  } else {
10662  ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '=' (in %s@%s:%d\n", pair.name, chan->exten, chan->context, chan->priority);
10663  }
10664  }
10665 
10666  return 0;
10667 }
int priority
Definition: channel.h:841
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
int value
Definition: syslog.c:39
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int pbx_checkcondition ( const char *  condition)

Evaluate a condition.

Return values
0if the condition is NULL or of zero length
intIf the string is an integer, the integer representation of the integer is returned
1Any other non-empty string

Definition at line 10719 of file pbx.c.

References ast_strlen_zero().

Referenced by _macro_exec(), _while_exec(), acf_if(), execif_exec(), gosubif_exec(), macroif_exec(), pbx_builtin_gotoif(), and testtime_write().

10720 {
10721  int res;
10722  if (ast_strlen_zero(condition)) { /* NULL or empty strings are false */
10723  return 0;
10724  } else if (sscanf(condition, "%30d", &res) == 1) { /* Numbers are evaluated for truth */
10725  return res;
10726  } else { /* Strings are true */
10727  return 1;
10728  }
10729 }
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static void pbx_destroy ( struct ast_pbx p)
static

Definition at line 1573 of file pbx.c.

References ast_free.

Referenced by __ast_pbx_run().

1574 {
1575  ast_free(p);
1576 }
#define ast_free(a)
Definition: astmm.h:97
int pbx_exec ( struct ast_channel c,
struct ast_app app,
const char *  data 
)

Execute an application.

Parameters
cchannel to execute on
appwhich app to execute
datathe data passed into the app

This application executes an application on a given channel. It saves the stack and executes the given application passing in the given data.

Return values
0success
-1failure
Parameters
cChannel
appApplication
dataData for execution

Definition at line 1497 of file pbx.c.

References __ast_module_user_add(), __ast_module_user_remove(), ast_channel::appl, ast_cdr_setapp(), AST_CEL_APP_END, AST_CEL_APP_START, ast_cel_report_event(), ast_check_hangup(), ast_log(), ast_opt_dont_warn, ast_strlen_zero(), ast_channel::cdr, ast_channel::data, ast_sw::data, ast_app::execute, LOG_WARNING, and S_OR.

Referenced by aelsub_exec(), answer_exec_run(), ast_app_exec_macro(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), do_magic_pickup(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), lua_pbx_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().

1500 {
1501  int res;
1502  struct ast_module_user *u = NULL;
1503  const char *saved_c_appl;
1504  const char *saved_c_data;
1505 
1506  if (c->cdr && !ast_check_hangup(c))
1507  ast_cdr_setapp(c->cdr, app->name, data);
1508 
1509  /* save channel values */
1510  saved_c_appl= c->appl;
1511  saved_c_data= c->data;
1512 
1513  c->appl = app->name;
1514  c->data = data;
1515  ast_cel_report_event(c, AST_CEL_APP_START, NULL, NULL, NULL);
1516 
1517  if (app->module)
1518  u = __ast_module_user_add(app->module, c);
1519  if (strcasecmp(app->name, "system") && !ast_strlen_zero(data) &&
1520  strchr(data, '|') && !strchr(data, ',') && !ast_opt_dont_warn) {
1521  ast_log(LOG_WARNING, "The application delimiter is now the comma, not "
1522  "the pipe. Did you forget to convert your dialplan? (%s(%s))\n",
1523  app->name, (char *) data);
1524  }
1525  res = app->execute(c, S_OR(data, ""));
1526  if (app->module && u)
1527  __ast_module_user_remove(app->module, u);
1528  ast_cel_report_event(c, AST_CEL_APP_END, NULL, NULL, NULL);
1529  /* restore channel values */
1530  c->appl = saved_c_appl;
1531  c->data = saved_c_data;
1532  return res;
1533 }
#define LOG_WARNING
Definition: logger.h:144
int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event_type, const char *userdefevname, const char *extra, struct ast_channel *peer2)
Report a channel event.
Definition: cel.c:645
void __ast_module_user_remove(struct ast_module *, struct ast_module_user *)
Definition: loader.c:231
struct ast_cdr * cdr
Definition: channel.h:766
const char * data
Definition: channel.h:755
const char * appl
Definition: channel.h:754
#define ast_opt_dont_warn
Definition: options.h:121
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
an app ends
Definition: cel.h:60
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
struct ast_module_user * __ast_module_user_add(struct ast_module *, struct ast_channel *)
Definition: loader.c:209
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_cdr_setapp(struct ast_cdr *cdr, const char *app, const char *data)
Set the last executed application.
Definition: cdr.c:822
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
int(* execute)(struct ast_channel *chan, const char *data)
Definition: pbx.c:972
an app starts
Definition: cel.h:58
static int pbx_extension_helper ( struct ast_channel c,
struct ast_context con,
const char *  context,
const char *  exten,
int  priority,
const char *  label,
const char *  callerid,
enum ext_match_t  action,
int *  found,
int  combined_find_spawn 
)
static

The return value depends on the action:

E_MATCH, E_CANMATCH, E_MATCHMORE require a real match, and return 0 on failure, -1 on match; E_FINDLABEL maps the label to a priority, and returns the priority on success, ... XXX E_SPAWN, spawn an application,

Return values
0on success.
-1on failure.
Note
The channel is auto-serviced in this function, because doing an extension match may block for a long time. For example, if the lookup has to use a network dialplan switch, such as DUNDi or IAX2, it may take a while. However, the channel auto-service code will queue up any important signalling frames to be processed after this is done.

Definition at line 4706 of file pbx.c.

References app, ast_exten::app, ast_copy_string(), ast_debug, ast_log(), ast_rdlock_contexts(), ast_strdupa, ast_strlen_zero(), ast_unlock_contexts(), ast_verb, ast_exten::cached_app, COLOR_BRCYAN, COLOR_BRMAGENTA, ast_channel::context, pbx_find_info::data, ast_exten::data, E_CANMATCH, E_FINDLABEL, E_MATCH, E_MATCHMORE, EVENT_FLAG_DIALPLAN, ast_switch::exec, EXT_DATA_SIZE, ast_channel::exten, pbx_find_info::foundcontext, LOG_NOTICE, LOG_WARNING, manager_event, ast_switch::name, ast_channel::name, pbx_exec(), pbx_find_extension(), pbx_findapp(), pbx_substitute_variables_helper(), ast_channel::priority, ast_exten::priority, S_OR, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, pbx_find_info::swo, term_color(), ast_channel::uniqueid, and VERBOSITY_ATLEAST.

Referenced by ast_canmatch_extension(), ast_exists_extension(), ast_findlabel_extension(), ast_findlabel_extension2(), ast_matchmore_extension(), and ast_spawn_extension().

4709 {
4710  struct ast_exten *e;
4711  struct ast_app *app;
4712  char *substitute = NULL;
4713  int res;
4714  struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
4715  char passdata[EXT_DATA_SIZE];
4716 
4717  int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
4718 
4720  if (found)
4721  *found = 0;
4722 
4723  e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
4724  if (e) {
4725  if (found)
4726  *found = 1;
4727  if (matching_action) {
4729  return -1; /* success, we found it */
4730  } else if (action == E_FINDLABEL) { /* map the label to a priority */
4731  res = e->priority;
4733  return res; /* the priority we were looking for */
4734  } else { /* spawn */
4735  if (!e->cached_app)
4736  e->cached_app = pbx_findapp(e->app);
4737  app = e->cached_app;
4738  if (ast_strlen_zero(e->data)) {
4739  *passdata = '\0';
4740  } else {
4741  const char *tmp;
4742  if ((!(tmp = strchr(e->data, '$'))) || (!strstr(tmp, "${") && !strstr(tmp, "$["))) {
4743  /* no variables to substitute, copy on through */
4744  ast_copy_string(passdata, e->data, sizeof(passdata));
4745  } else {
4746  /* save e->data on stack for later processing after lock released */
4747  substitute = ast_strdupa(e->data);
4748  }
4749  }
4751  if (!app) {
4752  ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
4753  return -1;
4754  }
4755  if (c->context != context)
4756  ast_copy_string(c->context, context, sizeof(c->context));
4757  if (c->exten != exten)
4758  ast_copy_string(c->exten, exten, sizeof(c->exten));
4759  c->priority = priority;
4760  if (substitute) {
4761  pbx_substitute_variables_helper(c, substitute, passdata, sizeof(passdata)-1);
4762  }
4763 #ifdef CHANNEL_TRACE
4764  ast_channel_trace_update(c);
4765 #endif
4766  ast_debug(1, "Launching '%s'\n", app->name);
4767  if (VERBOSITY_ATLEAST(3)) {
4768  char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE];
4769  ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n",
4770  exten, context, priority,
4771  term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
4772  term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
4773  term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)),
4774  "in new stack");
4775  }
4776  manager_event(EVENT_FLAG_DIALPLAN, "Newexten",
4777  "Channel: %s\r\n"
4778  "Context: %s\r\n"
4779  "Extension: %s\r\n"
4780  "Priority: %d\r\n"
4781  "Application: %s\r\n"
4782  "AppData: %s\r\n"
4783  "Uniqueid: %s\r\n",
4784  c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid);
4785  return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */
4786  }
4787  } else if (q.swo) { /* not found here, but in another switch */
4788  if (found)
4789  *found = 1;
4791  if (matching_action) {
4792  return -1;
4793  } else {
4794  if (!q.swo->exec) {
4795  ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
4796  res = -1;
4797  }
4798  return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
4799  }
4800  } else { /* not found anywhere, see what happened */
4802  /* Using S_OR here because Solaris doesn't like NULL being passed to ast_log */
4803  switch (q.status) {
4804  case STATUS_NO_CONTEXT:
4805  if (!matching_action && !combined_find_spawn)
4806  ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", S_OR(context, ""));
4807  break;
4808  case STATUS_NO_EXTENSION:
4809  if (!matching_action && !combined_find_spawn)
4810  ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, S_OR(context, ""));
4811  break;
4812  case STATUS_NO_PRIORITY:
4813  if (!matching_action && !combined_find_spawn)
4814  ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, S_OR(context, ""));
4815  break;
4816  case STATUS_NO_LABEL:
4817  if (context && !combined_find_spawn)
4818  ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, S_OR(context, ""));
4819  break;
4820  default:
4821  ast_debug(1, "Shouldn't happen!\n");
4822  }
4823 
4824  return (matching_action) ? 0 : -1;
4825  }
4826 }
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: pbx.c:4676
struct ast_app * cached_app
Definition: pbx.c:892
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: pbx.c:1537
int priority
Definition: channel.h:841
#define EXT_DATA_SIZE
Definition: pbx.c:828
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx.c:1497
const ast_string_field uniqueid
Definition: channel.h:787
#define STATUS_NO_PRIORITY
Definition: pbx.c:2997
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
#define VERBOSITY_ATLEAST(level)
Definition: logger.h:241
#define STATUS_NO_EXTENSION
Definition: pbx.c:2996
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:11042
#define EVENT_FLAG_DIALPLAN
Definition: manager.h:82
#define ast_verb(level,...)
Definition: logger.h:243
#define COLOR_BRCYAN
Definition: term.h:60
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int priority
Definition: pbx.c:888
const char * name
Definition: pbx.h:130
static const char app[]
Definition: app_adsiprog.c:49
const char * data
Definition: extconf.h:237
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define STATUS_NO_LABEL
Definition: pbx.c:2998
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
#define COLOR_BRMAGENTA
Definition: term.h:58
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void * data
Definition: pbx.c:893
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
#define STATUS_NO_CONTEXT
Definition: pbx.c:2995
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
ast_switch_f * exec
Definition: pbx.h:135
#define LOG_NOTICE
Definition: logger.h:133
const char * foundcontext
Definition: extconf.h:238
int stacklen
Definition: extconf.h:234
const char * app
Definition: pbx.c:891
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
ast_app: A registered application
Definition: pbx.c:971
struct ast_switch * swo
Definition: extconf.h:236
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition: pbx.c:3013
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
struct ast_exten* pbx_find_extension ( struct ast_channel chan,
struct ast_context bypass,
struct pbx_find_info q,
const char *  context,
const char *  exten,
int  priority,
const char *  label,
const char *  callerid,
enum ext_match_t  action 
)

Definition at line 3013 of file pbx.c.

References ast_context::alts, ast_autoservice_start(), ast_autoservice_stop(), ast_hashtab_lookup(), AST_LIST_TRAVERSE, ast_log(), AST_PBX_MAX_STACK, ast_str_buffer(), ast_str_size(), ast_str_thread_get(), ast_strdupa, ast_strlen_zero(), ast_walk_context_extensions(), ast_switch::canmatch, scoreboard::canmatch_exten, context, create_match_char_tree(), pbx_find_info::data, ast_sw::data, E_CANMATCH, E_FINDLABEL, E_MATCHMORE, ast_sw::eval, ast_switch::exists, ast_exten::exten, scoreboard::exten, extenpatternmatchnew, extension_match_core(), find_context(), pbx_find_info::foundcontext, include_valid(), ast_context::includes, pbx_find_info::incstack, ast_exten::label, scoreboard::last_char, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, match(), matchcid(), ast_switch::matchmore, ast_sw::name, ast_context::name, new_find_extension(), ast_include::next, scoreboard::node, overrideswitch, ast_context::pattern_tree, pbx_find_extension(), pbx_findswitch(), pbx_substitute_variables_helper(), ast_exten::priority, ast_include::rname, ast_context::root_table, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, STATUS_SUCCESS, strsep(), switch_data, pbx_find_info::swo, scoreboard::total_length, scoreboard::total_specificity, and trie_find_next_match().

Referenced by ast_hint_extension_nolock(), ast_merge_contexts_and_delete(), check_goto(), check_pval_item(), get_parking_exten(), pbx_extension_helper(), pbx_find_extension(), register_peer_exten(), and remove_exten_if_exist().

3017 {
3018  int x, res;
3019  struct ast_context *tmp = NULL;
3020  struct ast_exten *e = NULL, *eroot = NULL;
3021  struct ast_include *i = NULL;
3022  struct ast_sw *sw = NULL;
3023  struct ast_exten pattern = {NULL, };
3024  struct scoreboard score = {0, };
3025  struct ast_str *tmpdata = NULL;
3026 
3027  pattern.label = label;
3028  pattern.priority = priority;
3029 #ifdef NEED_DEBUG_HERE
3030  ast_log(LOG_NOTICE, "Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int) action);
3031 #endif
3032 
3033  /* Initialize status if appropriate */
3034  if (q->stacklen == 0) {
3036  q->swo = NULL;
3037  q->data = NULL;
3038  q->foundcontext = NULL;
3039  } else if (q->stacklen >= AST_PBX_MAX_STACK) {
3040  ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
3041  return NULL;
3042  }
3043 
3044  /* Check first to see if we've already been checked */
3045  for (x = 0; x < q->stacklen; x++) {
3046  if (!strcasecmp(q->incstack[x], context))
3047  return NULL;
3048  }
3049 
3050  if (bypass) { /* bypass means we only look there */
3051  tmp = bypass;
3052  } else { /* look in contexts */
3053  tmp = find_context(context);
3054  if (!tmp) {
3055  return NULL;
3056  }
3057  }
3058 
3059  if (q->status < STATUS_NO_EXTENSION)
3061 
3062  /* Do a search for matching extension */
3063 
3064  eroot = NULL;
3065  score.total_specificity = 0;
3066  score.exten = 0;
3067  score.total_length = 0;
3068  if (!tmp->pattern_tree && tmp->root_table) {
3070 #ifdef NEED_DEBUG
3071  ast_log(LOG_DEBUG, "Tree Created in context %s:\n", context);
3072  log_match_char_tree(tmp->pattern_tree," ");
3073 #endif
3074  }
3075 #ifdef NEED_DEBUG
3076  ast_log(LOG_NOTICE, "The Trie we are searching in:\n");
3077  log_match_char_tree(tmp->pattern_tree, ":: ");
3078 #endif
3079 
3080  do {
3082  char *osw = ast_strdupa(overrideswitch), *name;
3083  struct ast_switch *asw;
3084  ast_switch_f *aswf = NULL;
3085  char *datap;
3086  int eval = 0;
3087 
3088  name = strsep(&osw, "/");
3089  asw = pbx_findswitch(name);
3090 
3091  if (!asw) {
3092  ast_log(LOG_WARNING, "No such switch '%s'\n", name);
3093  break;
3094  }
3095 
3096  if (osw && strchr(osw, '$')) {
3097  eval = 1;
3098  }
3099 
3100  if (eval && !(tmpdata = ast_str_thread_get(&switch_data, 512))) {
3101  ast_log(LOG_WARNING, "Can't evaluate overrideswitch?!\n");
3102  break;
3103  } else if (eval) {
3104  /* Substitute variables now */
3105  pbx_substitute_variables_helper(chan, osw, ast_str_buffer(tmpdata), ast_str_size(tmpdata));
3106  datap = ast_str_buffer(tmpdata);
3107  } else {
3108  datap = osw;
3109  }
3110 
3111  /* equivalent of extension_match_core() at the switch level */
3112  if (action == E_CANMATCH)
3113  aswf = asw->canmatch;
3114  else if (action == E_MATCHMORE)
3115  aswf = asw->matchmore;
3116  else /* action == E_MATCH */
3117  aswf = asw->exists;
3118  if (!aswf) {
3119  res = 0;
3120  } else {
3121  if (chan) {
3122  ast_autoservice_start(chan);
3123  }
3124  res = aswf(chan, context, exten, priority, callerid, datap);
3125  if (chan) {
3126  ast_autoservice_stop(chan);
3127  }
3128  }
3129  if (res) { /* Got a match */
3130  q->swo = asw;
3131  q->data = datap;
3132  q->foundcontext = context;
3133  /* XXX keep status = STATUS_NO_CONTEXT ? */
3134  return NULL;
3135  }
3136  }
3137  } while (0);
3138 
3139  if (extenpatternmatchnew) {
3140  new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid, label, action);
3141  eroot = score.exten;
3142 
3143  if (score.last_char == '!' && action == E_MATCHMORE) {
3144  /* We match an extension ending in '!'.
3145  * The decision in this case is final and is NULL (no match).
3146  */
3147 #ifdef NEED_DEBUG_HERE
3148  ast_log(LOG_NOTICE,"Returning MATCHMORE NULL with exclamation point.\n");
3149 #endif
3150  return NULL;
3151  }
3152 
3153  if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) {
3154  q->status = STATUS_SUCCESS;
3155 #ifdef NEED_DEBUG_HERE
3156  ast_log(LOG_NOTICE,"Returning CANMATCH exten %s\n", score.canmatch_exten->exten);
3157 #endif
3158  return score.canmatch_exten;
3159  }
3160 
3161  if ((action == E_MATCHMORE || action == E_CANMATCH) && eroot) {
3162  if (score.node) {
3163  struct ast_exten *z = trie_find_next_match(score.node);
3164  if (z) {
3165 #ifdef NEED_DEBUG_HERE
3166  ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten %s\n", z->exten);
3167 #endif
3168  } else {
3169  if (score.canmatch_exten) {
3170 #ifdef NEED_DEBUG_HERE
3171  ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE canmatchmatch exten %s(%p)\n", score.canmatch_exten->exten, score.canmatch_exten);
3172 #endif
3173  return score.canmatch_exten;
3174  } else {
3175 #ifdef NEED_DEBUG_HERE
3176  ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten NULL\n");
3177 #endif
3178  }
3179  }
3180  return z;
3181  }
3182 #ifdef NEED_DEBUG_HERE
3183  ast_log(LOG_NOTICE, "Returning CANMATCH/MATCHMORE NULL (no next_match)\n");
3184 #endif
3185  return NULL; /* according to the code, complete matches are null matches in MATCHMORE mode */
3186  }
3187 
3188  if (eroot) {
3189  /* found entry, now look for the right priority */
3190  if (q->status < STATUS_NO_PRIORITY)
3192  e = NULL;
3193  if (action == E_FINDLABEL && label ) {
3194  if (q->status < STATUS_NO_LABEL)
3195  q->status = STATUS_NO_LABEL;
3196  e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
3197  } else {
3198  e = ast_hashtab_lookup(eroot->peer_table, &pattern);
3199  }
3200  if (e) { /* found a valid match */
3201  q->status = STATUS_SUCCESS;
3202  q->foundcontext = context;
3203 #ifdef NEED_DEBUG_HERE
3204  ast_log(LOG_NOTICE,"Returning complete match of exten %s\n", e->exten);
3205 #endif
3206  return e;
3207  }
3208  }
3209  } else { /* the old/current default exten pattern match algorithm */
3210 
3211  /* scan the list trying to match extension and CID */
3212  eroot = NULL;
3213  while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
3214  int match = extension_match_core(eroot->exten, exten, action);
3215  /* 0 on fail, 1 on match, 2 on earlymatch */
3216 
3217  if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
3218  continue; /* keep trying */
3219  if (match == 2 && action == E_MATCHMORE) {
3220  /* We match an extension ending in '!'.
3221  * The decision in this case is final and is NULL (no match).
3222  */
3223  return NULL;
3224  }
3225  /* found entry, now look for the right priority */
3226  if (q->status < STATUS_NO_PRIORITY)
3228  e = NULL;
3229  if (action == E_FINDLABEL && label ) {
3230  if (q->status < STATUS_NO_LABEL)
3231  q->status = STATUS_NO_LABEL;
3232  e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
3233  } else {
3234  e = ast_hashtab_lookup(eroot->peer_table, &pattern);
3235  }
3236  if (e) { /* found a valid match */
3237  q->status = STATUS_SUCCESS;
3238  q->foundcontext = context;
3239  return e;
3240  }
3241  }
3242  }
3243 
3244  /* Check alternative switches */
3245  AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
3246  struct ast_switch *asw = pbx_findswitch(sw->name);
3247  ast_switch_f *aswf = NULL;
3248  char *datap;
3249 
3250  if (!asw) {
3251  ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
3252  continue;
3253  }
3254 
3255  /* Substitute variables now */
3256  if (sw->eval) {
3257  if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) {
3258  ast_log(LOG_WARNING, "Can't evaluate switch?!\n");
3259  continue;
3260  }
3261  pbx_substitute_variables_helper(chan, sw->data, ast_str_buffer(tmpdata), ast_str_size(tmpdata));
3262  }
3263 
3264  /* equivalent of extension_match_core() at the switch level */
3265  if (action == E_CANMATCH)
3266  aswf = asw->canmatch;
3267  else if (action == E_MATCHMORE)
3268  aswf = asw->matchmore;
3269  else /* action == E_MATCH */
3270  aswf = asw->exists;
3271  datap = sw->eval ? ast_str_buffer(tmpdata) : sw->data;
3272  if (!aswf)
3273  res = 0;
3274  else {
3275  if (chan)
3276  ast_autoservice_start(chan);
3277  res = aswf(chan, context, exten, priority, callerid, datap);
3278  if (chan)
3279  ast_autoservice_stop(chan);
3280  }
3281  if (res) { /* Got a match */
3282  q->swo = asw;
3283  q->data = datap;
3284  q->foundcontext = context;
3285  /* XXX keep status = STATUS_NO_CONTEXT ? */
3286  return NULL;
3287  }
3288  }
3289  q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
3290  /* Now try any includes we have in this context */
3291  for (i = tmp->includes; i; i = i->next) {
3292  if (include_valid(i)) {
3293  if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) {
3294 #ifdef NEED_DEBUG_HERE
3295  ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten);
3296 #endif
3297  return e;
3298  }
3299  if (q->swo)
3300  return NULL;
3301  }
3302  }
3303  return NULL;
3304 }
ast_include: include= support in extensions.conf
Definition: pbx.c:904
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: pbx.c:4676
int( ast_switch_f)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
All switch functions have the same interface, so define a type for them.
Definition: pbx.h:124
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
Definition: hashtab.c:534
struct ast_include * next
Definition: pbx.c:910
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:179
char * strsep(char **str, const char *delims)
struct ast_include * includes
Definition: pbx.c:961
#define STATUS_NO_PRIORITY
Definition: pbx.c:2997
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:482
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)
Definition: pbx.c:1807
const char * rname
Definition: pbx.c:906
#define LOG_WARNING
Definition: logger.h:144
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
char last_char
Definition: pbx.c:947
#define STATUS_NO_EXTENSION
Definition: pbx.c:2996
const char * label
Definition: pbx.c:889
char * incstack[AST_PBX_MAX_STACK]
Definition: extconf.h:233
#define LOG_DEBUG
Definition: logger.h:122
static struct ast_exten * trie_find_next_match(struct match_char *node)
Definition: pbx.c:1748
ast_switch_f * matchmore
Definition: pbx.h:136
int priority
Definition: pbx.c:888
ast_sw: Switch statement in extensions.conf
Definition: pbx.c:915
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority)
Definition: pbx.c:11179
const char * data
Definition: extconf.h:237
static void create_match_char_tree(struct ast_context *con)
Definition: pbx.c:2321
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_exten * canmatch_exten
Definition: pbx.c:950
static struct ast_threadstorage switch_data
Definition: pbx.c:864
char * exten
Definition: pbx.c:885
#define STATUS_SUCCESS
Definition: pbx.c:2999
char name[0]
Definition: pbx.c:967
int total_specificity
Definition: pbx.c:945
#define STATUS_NO_LABEL
Definition: pbx.c:2998
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:238
static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
Definition: pbx.c:2930
ast_switch_f * canmatch
Definition: pbx.h:134
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
int eval
Definition: pbx.c:919
char * data
Definition: pbx.c:918
#define STATUS_NO_CONTEXT
Definition: pbx.c:2995
#define AST_PBX_MAX_STACK
Definition: extconf.h:223
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static int extenpatternmatchnew
Definition: pbx.c:1221
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static int matchcid(const char *cidpattern, const char *callerid)
Definition: pbx.c:3001
static const char name[]
const char * foundcontext
Definition: extconf.h:238
int stacklen
Definition: extconf.h:234
struct pval * find_context(char *name)
Definition: pval.c:1960
struct match_char * node
Definition: pbx.c:949
static struct ast_switch * pbx_findswitch(const char *sw)
Definition: pbx.c:1551
struct ast_context::@290 alts
static char * overrideswitch
Definition: pbx.c:1222
struct ast_switch * swo
Definition: extconf.h:236
static int include_valid(struct ast_include *i)
Definition: pbx.c:1565
struct ast_hashtab * root_table
Definition: pbx.c:958
ast_switch_f * exists
Definition: pbx.h:133
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition: pbx.c:3013
int total_length
Definition: pbx.c:946
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:669
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_exten * exten
Definition: pbx.c:951
char * name
Definition: pbx.c:916
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2069
ast_context: An extension context
Definition: pbx.c:955
struct match_char * pattern_tree
Definition: pbx.c:959
struct ast_app* pbx_findapp ( const char *  app)

Find application handle in linked list.

Look up an application.

Definition at line 1537 of file pbx.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.

Referenced by aelsub_exec(), answer_exec_run(), ast_app_exec_macro(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), do_magic_pickup(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), lua_pbx_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().

1538 {
1539  struct ast_app *tmp;
1540 
1542  AST_RWLIST_TRAVERSE(&apps, tmp, list) {
1543  if (!strcasecmp(tmp->name, app))
1544  break;
1545  }
1547 
1548  return tmp;
1549 }
Definition: pbx.c:1301
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static const char app[]
Definition: app_adsiprog.c:49
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
ast_app: A registered application
Definition: pbx.c:971
static struct ast_switch* pbx_findswitch ( const char *  sw)
static

Definition at line 1551 of file pbx.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and ast_switch::name.

Referenced by pbx_find_extension().

1552 {
1553  struct ast_switch *asw;
1554 
1557  if (!strcasecmp(asw->name, sw))
1558  break;
1559  }
1561 
1562  return asw;
1563 }
struct ast_switch::@191 list
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const char * name
Definition: pbx.h:130
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Definition: pbx.c:1303
void pbx_live_dangerously ( int  new_live_dangerously)

Enable/disable the execution of 'dangerous' functions from external protocols (AMI, etc.).

These dialplan functions (such as SHELL) provide an opportunity for privilege escalation. They are okay to invoke from the dialplan, but external protocols with permission controls should not normally invoke them.

This function can globally enable/disable the execution of dangerous functions from external protocols.

Parameters
new_live_dangerouslyIf true, enable the execution of escalating functions from external protocols.

Definition at line 4059 of file pbx.c.

References ast_log(), LOG_NOTICE, and LOG_WARNING.

Referenced by ast_readconfig().

4060 {
4061  if (new_live_dangerously && !live_dangerously) {
4062  ast_log(LOG_WARNING, "Privilege escalation protection disabled!\n"
4063  "See https://wiki.asterisk.org/wiki/x/1gKfAQ for more details.\n");
4064  }
4065 
4066  if (!new_live_dangerously && live_dangerously) {
4067  ast_log(LOG_NOTICE, "Privilege escalation protection enabled.\n");
4068  }
4069  live_dangerously = new_live_dangerously;
4070 }
#define LOG_WARNING
Definition: logger.h:144
static int live_dangerously
Set to true (non-zero) to globally allow all dangerous dialplan functions to run. ...
Definition: pbx.c:870
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static int pbx_parseable_goto ( struct ast_channel chan,
const char *  goto_string,
int  async 
)
static

Definition at line 11271 of file pbx.c.

References ast_async_goto(), ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::caller, context, ast_channel::context, exten, ast_channel::exten, ast_party_caller::id, LOG_WARNING, ast_party_id::number, ast_channel::priority, S_COR, ast_party_number::str, strsep(), and ast_party_number::valid.

Referenced by ast_async_parseable_goto(), and ast_parseable_goto().

11272 {
11273  char *exten, *pri, *context;
11274  char *stringp;
11275  int ipri;
11276  int mode = 0;
11277 
11278  if (ast_strlen_zero(goto_string)) {
11279  ast_log(LOG_WARNING, "Goto requires an argument ([[context,]extension,]priority)\n");
11280  return -1;
11281  }
11282  stringp = ast_strdupa(goto_string);
11283  context = strsep(&stringp, ","); /* guaranteed non-null */
11284  exten = strsep(&stringp, ",");
11285  pri = strsep(&stringp, ",");
11286  if (!exten) { /* Only a priority in this one */
11287  pri = context;
11288  exten = NULL;
11289  context = NULL;
11290  } else if (!pri) { /* Only an extension and priority in this one */
11291  pri = exten;
11292  exten = context;
11293  context = NULL;
11294  }
11295  if (*pri == '+') {
11296  mode = 1;
11297  pri++;
11298  } else if (*pri == '-') {
11299  mode = -1;
11300  pri++;
11301  }
11302  if (sscanf(pri, "%30d", &ipri) != 1) {
11303  ipri = ast_findlabel_extension(chan, context ? context : chan->context,
11304  exten ? exten : chan->exten, pri,
11305  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
11306  if (ipri < 1) {
11307  ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
11308  return -1;
11309  } else
11310  mode = 0;
11311  }
11312  /* At this point we have a priority and maybe an extension and a context */
11313 
11314  if (mode)
11315  ipri = chan->priority + (ipri * mode);
11316 
11317  if (async)
11318  ast_async_goto(chan, context, exten, ipri);
11319  else
11320  ast_explicit_goto(chan, context, exten, ipri);
11321 
11322  return 0;
11323 
11324 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
char * strsep(char **str, const char *delims)
int priority
Definition: channel.h:841
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:8708
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
Find the priority of an extension that has the specified label.
Definition: pbx.c:5405
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:8731
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
void pbx_retrieve_variable ( struct ast_channel c,
const char *  var,
char **  ret,
char *  workspace,
int  workspacelen,
struct varshead headp 
)

Support for Asterisk built-in variables in the dialplan.

Retrieve the value of a builtin variable or variable from the channel variable stack.

Note
See also

Definition at line 3434 of file pbx.c.

References ast_copy_string(), ast_free, ast_str_buffer(), ast_str_create(), ast_str_retrieve_variable(), and str.

Referenced by action_getvar(), action_status(), handle_getvariable(), lua_get_variable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full().

3435 {
3436  struct ast_str *str = ast_str_create(16);
3437  const char *cret;
3438 
3439  cret = ast_str_retrieve_variable(&str, 0, c, headp, var);
3440  ast_copy_string(workspace, ast_str_buffer(str), workspacelen);
3441  *ret = cret ? workspace : NULL;
3442  ast_free(str);
3443 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
#define var
Definition: ast_expr2f.c:606
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
const char * str
Definition: app_jack.c:144
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define ast_free(a)
Definition: astmm.h:97
const char * ast_str_retrieve_variable(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, struct varshead *headp, const char *var)
Definition: pbx.c:3445
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int pbx_set_autofallthrough ( int  newval)

Set "autofallthrough" flag, if newval is <0, does not actually set. If set to 1, sets to auto fall through. If newval set to 0, sets to no auto fall through (reads extension instead). Returns previous value.

Definition at line 5941 of file pbx.c.

References autofallthrough.

Referenced by pbx_load_module().

5942 {
5943  int oldval = autofallthrough;
5944  autofallthrough = newval;
5945  return oldval;
5946 }
static int autofallthrough
Definition: pbx.c:1220
int pbx_set_extenpatternmatchnew ( int  newval)

Set "extenpatternmatchnew" flag, if newval is <0, does not actually set. If set to 1, sets to use the new Trie-based pattern matcher. If newval set to 0, sets to use the old linear-search algorithm. Returns previous value.

Definition at line 5948 of file pbx.c.

References extenpatternmatchnew.

Referenced by handle_set_extenpatternmatchnew(), handle_unset_extenpatternmatchnew(), and pbx_load_module().

5949 {
5950  int oldval = extenpatternmatchnew;
5951  extenpatternmatchnew = newval;
5952  return oldval;
5953 }
static int extenpatternmatchnew
Definition: pbx.c:1221
void pbx_set_overrideswitch ( const char *  newval)

Set "overrideswitch" field. If set and of nonzero length, all contexts will be tried directly through the named switch prior to any other matching within that context.

Since
1.6.1

Definition at line 5955 of file pbx.c.

References ast_free, ast_strdup, ast_strlen_zero(), and overrideswitch.

Referenced by pbx_load_module().

5956 {
5957  if (overrideswitch) {
5959  }
5960  if (!ast_strlen_zero(newval)) {
5961  overrideswitch = ast_strdup(newval);
5962  } else {
5963  overrideswitch = NULL;
5964  }
5965 }
#define ast_strdup(a)
Definition: astmm.h:109
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_free(a)
Definition: astmm.h:97
static char * overrideswitch
Definition: pbx.c:1222
static void pbx_shutdown ( void  )
static

Definition at line 11391 of file pbx.c.

References ao2_ref, ast_hashtab_destroy(), contexts_table, hints, pbx_builtin_clear_globals(), and statecbs.

Referenced by ast_pbx_init().

11392 {
11393  if (hints) {
11394  ao2_ref(hints, -1);
11395  hints = NULL;
11396  }
11397  if (statecbs) {
11398  ao2_ref(statecbs, -1);
11399  statecbs = NULL;
11400  }
11401  if (contexts_table) {
11403  }
11405 }
void pbx_builtin_clear_globals(void)
Definition: pbx.c:10709
static struct ast_hashtab * contexts_table
Definition: pbx.c:1286
static struct ao2_container * hints
Definition: pbx.c:1314
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static struct ao2_container * statecbs
Definition: pbx.c:1316
void ast_hashtab_destroy(struct ast_hashtab *tab, void(*objdestroyfunc)(void *obj))
This func will free the hash table and all its memory.
Definition: hashtab.c:388
void pbx_substitute_variables_helper ( struct ast_channel c,
const char *  cp1,
char *  cp2,
int  count 
)

Definition at line 4676 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

Referenced by add_extensions(), ast_add_extension2_lockopt(), function_eval(), get_manager_event_info(), get_mapping_weight(), import_helper(), launch_monitor_thread(), manager_log(), pbx_builtin_importvar(), pbx_extension_helper(), pbx_find_extension(), pbx_load_config(), realtime_exec(), rotate_file(), substituted(), and try_calling().

4677 {
4678  size_t used;
4679  pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count, &used);
4680 }
void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used)
Definition: pbx.c:4480
struct varshead varshead
Definition: channel.h:817
void pbx_substitute_variables_helper_full ( struct ast_channel c,
struct varshead headp,
const char *  cp1,
char *  cp2,
int  count,
size_t *  used 
)

Definition at line 4480 of file pbx.c.

References ast_alloca, ast_channel_unref, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_expr(), ast_func_read(), ast_log(), ast_strlen_zero(), len(), LOG_ERROR, LOG_WARNING, parse_variable_name(), pbx_retrieve_variable(), pbx_substitute_variables_helper_full(), substring(), var, VAR_BUF_SIZE, and ast_channel::varshead.

Referenced by pbx_substitute_variables_helper(), pbx_substitute_variables_helper_full(), and pbx_substitute_variables_varshead().

4481 {
4482  /* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!! */
4483  char *cp4 = NULL;
4484  const char *tmp, *whereweare, *orig_cp2 = cp2;
4485  int length, offset, offset2, isfunction;
4486  char *workspace = NULL;
4487  char *ltmp = NULL, *var = NULL;
4488  char *nextvar, *nextexp, *nextthing;
4489  char *vars, *vare;
4490  int pos, brackets, needsub, len;
4491 
4492  *cp2 = 0; /* just in case nothing ends up there */
4493  whereweare=tmp=cp1;
4494  while (!ast_strlen_zero(whereweare) && count) {
4495  /* Assume we're copying the whole remaining string */
4496  pos = strlen(whereweare);
4497  nextvar = NULL;
4498  nextexp = NULL;
4499  nextthing = strchr(whereweare, '$');
4500  if (nextthing) {
4501  switch (nextthing[1]) {
4502  case '{':
4503  nextvar = nextthing;
4504  pos = nextvar - whereweare;
4505  break;
4506  case '[':
4507  nextexp = nextthing;
4508  pos = nextexp - whereweare;
4509  break;
4510  default:
4511  pos = 1;
4512  }
4513  }
4514 
4515  if (pos) {
4516  /* Can't copy more than 'count' bytes */
4517  if (pos > count)
4518  pos = count;
4519 
4520  /* Copy that many bytes */
4521  memcpy(cp2, whereweare, pos);
4522 
4523  count -= pos;
4524  cp2 += pos;
4525  whereweare += pos;
4526  *cp2 = 0;
4527  }
4528 
4529  if (nextvar) {
4530  /* We have a variable. Find the start and end, and determine
4531  if we are going to have to recursively call ourselves on the
4532  contents */
4533  vars = vare = nextvar + 2;
4534  brackets = 1;
4535  needsub = 0;
4536 
4537  /* Find the end of it */
4538  while (brackets && *vare) {
4539  if ((vare[0] == '$') && (vare[1] == '{')) {
4540  needsub++;
4541  } else if (vare[0] == '{') {
4542  brackets++;
4543  } else if (vare[0] == '}') {
4544  brackets--;
4545  } else if ((vare[0] == '$') && (vare[1] == '['))
4546  needsub++;
4547  vare++;
4548  }
4549  if (brackets)
4550  ast_log(LOG_WARNING, "Error in extension logic (missing '}')\n");
4551  len = vare - vars - 1;
4552 
4553  /* Skip totally over variable string */
4554  whereweare += (len + 3);
4555 
4556  if (!var)
4557  var = ast_alloca(VAR_BUF_SIZE);
4558 
4559  /* Store variable name (and truncate) */
4560  ast_copy_string(var, vars, len + 1);
4561 
4562  /* Substitute if necessary */
4563  if (needsub) {
4564  size_t used;
4565  if (!ltmp)
4566  ltmp = ast_alloca(VAR_BUF_SIZE);
4567 
4568  pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1, &used);
4569  vars = ltmp;
4570  } else {
4571  vars = var;
4572  }
4573 
4574  if (!workspace)
4575  workspace = ast_alloca(VAR_BUF_SIZE);
4576 
4577  workspace[0] = '\0';
4578 
4579  parse_variable_name(vars, &offset, &offset2, &isfunction);
4580  if (isfunction) {
4581  /* Evaluate function */
4582  if (c || !headp)
4583  cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
4584  else {
4585  struct varshead old;
4586  struct ast_channel *c = ast_dummy_channel_alloc();
4587  if (c) {
4588  memcpy(&old, &c->varshead, sizeof(old));
4589  memcpy(&c->varshead, headp, sizeof(c->varshead));
4590  cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
4591  /* Don't deallocate the varshead that was passed in */
4592  memcpy(&c->varshead, &old, sizeof(c->varshead));
4593  c = ast_channel_unref(c);
4594  } else {
4595  ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
4596  }
4597  }
4598  ast_debug(2, "Function %s result is '%s'\n", vars, cp4 ? cp4 : "(null)");
4599  } else {
4600  /* Retrieve variable value */
4601  pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);
4602  }
4603  if (cp4) {
4604  cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);
4605 
4606  length = strlen(cp4);
4607  if (length > count)
4608  length = count;
4609  memcpy(cp2, cp4, length);
4610  count -= length;
4611  cp2 += length;
4612  *cp2 = 0;
4613  }
4614  } else if (nextexp) {
4615  /* We have an expression. Find the start and end, and determine
4616  if we are going to have to recursively call ourselves on the
4617  contents */
4618  vars = vare = nextexp + 2;
4619  brackets = 1;
4620  needsub = 0;
4621 
4622  /* Find the end of it */
4623  while (brackets && *vare) {
4624  if ((vare[0] == '$') && (vare[1] == '[')) {
4625  needsub++;
4626  brackets++;
4627  vare++;
4628  } else if (vare[0] == '[') {
4629  brackets++;
4630  } else if (vare[0] == ']') {
4631  brackets--;
4632  } else if ((vare[0] == '$') && (vare[1] == '{')) {
4633  needsub++;
4634  vare++;
4635  }
4636  vare++;
4637  }
4638  if (brackets)
4639  ast_log(LOG_WARNING, "Error in extension logic (missing ']')\n");
4640  len = vare - vars - 1;
4641 
4642  /* Skip totally over expression */
4643  whereweare += (len + 3);
4644 
4645  if (!var)
4646  var = ast_alloca(VAR_BUF_SIZE);
4647 
4648  /* Store variable name (and truncate) */
4649  ast_copy_string(var, vars, len + 1);
4650 
4651  /* Substitute if necessary */
4652  if (needsub) {
4653  size_t used;
4654  if (!ltmp)
4655  ltmp = ast_alloca(VAR_BUF_SIZE);
4656 
4657  pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1, &used);
4658  vars = ltmp;
4659  } else {
4660  vars = var;
4661  }
4662 
4663  length = ast_expr(vars, cp2, count, c);
4664 
4665  if (length) {
4666  ast_debug(1, "Expression result is '%s'\n", cp2);
4667  count -= length;
4668  cp2 += length;
4669  *cp2 = 0;
4670  }
4671  }
4672  }
4673  *used = cp2 - orig_cp2;
4674 }
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
Definition: pbx.c:4177
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
static char * substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
takes a substring. It is ok to call with value == workspace.
Definition: pbx.c:3344
#define LOG_WARNING
Definition: logger.h:144
#define var
Definition: ast_expr2f.c:606
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define LOG_ERROR
Definition: logger.h:155
void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
Retrieve the value of a builtin variable or variable from the channel variable stack.
Definition: pbx.c:3434
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
extract offset:length from variable name.
Definition: pbx.c:3311
void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used)
Definition: pbx.c:4480
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan)
Evaluate the given expression.
Definition: ast_expr2f.c:2396
struct varshead varshead
Definition: channel.h:817
#define VAR_BUF_SIZE
Definition: pbx.c:833
void pbx_substitute_variables_varshead ( struct varshead headp,
const char *  cp1,
char *  cp2,
int  count 
)

Definition at line 4682 of file pbx.c.

References pbx_substitute_variables_helper_full().

Referenced by do_say(), dundi_lookup_local(), and loopback_subst().

4683 {
4684  size_t used;
4685  pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count, &used);
4686 }
void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used)
Definition: pbx.c:4480
static void* pbx_thread ( void *  data)
static

Definition at line 5859 of file pbx.c.

References __ast_pbx_run(), ast_sw::data, and decrease_call_count().

Referenced by ast_pbx_start().

5860 {
5861  /* Oh joyeous kernel, we're a new thread, with nothing to do but
5862  answer this channel and get it going.
5863  */
5864  /* NOTE:
5865  The launcher of this function _MUST_ increment 'countcalls'
5866  before invoking the function; it will be decremented when the
5867  PBX has finished running on the channel
5868  */
5869  struct ast_channel *c = data;
5870 
5871  __ast_pbx_run(c, NULL);
5873 
5874  pthread_exit(NULL);
5875 
5876  return NULL;
5877 }
Main Channel structure associated with a channel.
Definition: channel.h:742
static void decrease_call_count(void)
Definition: pbx.c:5837
static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c, struct ast_pbx_args *args)
Definition: pbx.c:5473
const char * data
Definition: channel.h:755
static void print_app_docs ( struct ast_app aa,
int  fd 
)
static

Definition at line 6468 of file pbx.c.

References ast_app::arguments, ast_cli(), ast_free, ast_malloc, AST_MAX_APP, AST_TERM_MAX_ESCAPE_CHARS, AST_XML_DOC, ast_xmldoc_printable(), COLOR_CYAN, COLOR_MAGENTA, ast_switch::description, ast_app::description, ast_app::docsrc, S_OR, ast_app::seealso, synopsis, ast_app::synopsis, ast_app::syntax, and term_color().

Referenced by handle_show_application().

6469 {
6470  /* Maximum number of characters added by terminal coloring is 22 */
6471  char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40], stxtitle[40], argtitle[40];
6472  char seealsotitle[40];
6473  char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL, *syntax = NULL, *arguments = NULL;
6474  char *seealso = NULL;
6475  int syntax_size, synopsis_size, description_size, arguments_size, seealso_size;
6476 
6477  snprintf(info, sizeof(info), "\n -= Info about application '%s' =- \n\n", aa->name);
6478  term_color(infotitle, info, COLOR_MAGENTA, 0, sizeof(infotitle));
6479 
6480  term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
6481  term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
6482  term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
6483  term_color(argtitle, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
6484  term_color(seealsotitle, "[See Also]\n", COLOR_MAGENTA, 0, 40);
6485 
6486 #ifdef AST_XML_DOCS
6487  if (aa->docsrc == AST_XML_DOC) {
6488  description = ast_xmldoc_printable(S_OR(aa->description, "Not available"), 1);
6489  arguments = ast_xmldoc_printable(S_OR(aa->arguments, "Not available"), 1);
6490  synopsis = ast_xmldoc_printable(S_OR(aa->synopsis, "Not available"), 1);
6491  seealso = ast_xmldoc_printable(S_OR(aa->seealso, "Not available"), 1);
6492 
6493  if (!synopsis || !description || !arguments || !seealso) {
6494  goto return_cleanup;
6495  }
6496  } else
6497 #endif
6498  {
6499  synopsis_size = strlen(S_OR(aa->synopsis, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
6500  synopsis = ast_malloc(synopsis_size);
6501 
6502  description_size = strlen(S_OR(aa->description, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
6503  description = ast_malloc(description_size);
6504 
6505  arguments_size = strlen(S_OR(aa->arguments, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
6506  arguments = ast_malloc(arguments_size);
6507 
6508  seealso_size = strlen(S_OR(aa->seealso, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
6509  seealso = ast_malloc(seealso_size);
6510 
6511  if (!synopsis || !description || !arguments || !seealso) {
6512  goto return_cleanup;
6513  }
6514 
6515  term_color(synopsis, S_OR(aa->synopsis, "Not available"), COLOR_CYAN, 0, synopsis_size);
6516  term_color(description, S_OR(aa->description, "Not available"), COLOR_CYAN, 0, description_size);
6517  term_color(arguments, S_OR(aa->arguments, "Not available"), COLOR_CYAN, 0, arguments_size);
6518  term_color(seealso, S_OR(aa->seealso, "Not available"), COLOR_CYAN, 0, seealso_size);
6519  }
6520 
6521  /* Handle the syntax the same for both XML and raw docs */
6522  syntax_size = strlen(S_OR(aa->syntax, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
6523  if (!(syntax = ast_malloc(syntax_size))) {
6524  goto return_cleanup;
6525  }
6526  term_color(syntax, S_OR(aa->syntax, "Not available"), COLOR_CYAN, 0, syntax_size);
6527 
6528  ast_cli(fd, "%s%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n",
6529  infotitle, syntitle, synopsis, destitle, description,
6530  stxtitle, syntax, argtitle, arguments, seealsotitle, seealso);
6531 
6532 return_cleanup:
6533  ast_free(description);
6534  ast_free(arguments);
6535  ast_free(synopsis);
6536  ast_free(seealso);
6537  ast_free(syntax);
6538 }
const ast_string_field description
Definition: pbx.c:979
const ast_string_field synopsis
Definition: pbx.c:979
#define COLOR_CYAN
Definition: term.h:59
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_TERM_MAX_ESCAPE_CHARS
Maximum number of characters needed for a color escape sequence, plus a null char.
Definition: term.h:67
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
#define AST_MAX_APP
Definition: pbx.h:39
const ast_string_field syntax
Definition: pbx.c:979
static char * synopsis
Definition: func_enum.c:156
#define ast_free(a)
Definition: astmm.h:97
enum ast_doc_src docsrc
Definition: pbx.c:981
char * ast_xmldoc_printable(const char *bwinput, int withcolors)
Colorize and put delimiters (instead of tags) to the xmldoc output.
Definition: xmldoc.c:315
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const ast_string_field seealso
Definition: pbx.c:979
#define ast_malloc(a)
Definition: astmm.h:91
#define COLOR_MAGENTA
Definition: term.h:57
const ast_string_field arguments
Definition: pbx.c:979
static void print_ext ( struct ast_exten e,
char *  buf,
int  buflen 
)
static

helper function to print an extension

Definition at line 6905 of file pbx.c.

References ast_get_extension_app(), ast_get_extension_app_data(), ast_get_extension_priority(), ast_strlen_zero(), and PRIORITY_HINT.

Referenced by show_dialplan_helper().

6906 {
6907  int prio = ast_get_extension_priority(e);
6908  if (prio == PRIORITY_HINT) {
6909  snprintf(buf, buflen, "hint: %s",
6911  } else {
6912  snprintf(buf, buflen, "%d. %s(%s)",
6913  prio, ast_get_extension_app(e),
6915  }
6916 }
int ast_get_extension_priority(struct ast_exten *exten)
Definition: pbx.c:11103
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:11141
void * ast_get_extension_app_data(struct ast_exten *e)
Definition: pbx.c:11146
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define PRIORITY_HINT
Definition: pbx.h:53
static int raise_exception ( struct ast_channel chan,
const char *  reason,
int  priority 
)
static

Definition at line 3594 of file pbx.c.

References ast_calloc_with_stringfields, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc(), ast_datastore_free(), ast_string_field_set, ast_channel::context, ast_datastore::data, exception_store_info, exten, ast_channel::exten, ast_channel::priority, pbx_exception::priority, and set_ext_pri().

Referenced by __ast_pbx_run(), pbx_builtin_raise_exception(), and pbx_builtin_waitexten().

3595 {
3597  struct pbx_exception *exception = NULL;
3598 
3599  if (!ds) {
3601  if (!ds)
3602  return -1;
3603  if (!(exception = ast_calloc_with_stringfields(1, struct pbx_exception, 128))) {
3604  ast_datastore_free(ds);
3605  return -1;
3606  }
3607  ds->data = exception;
3608  ast_channel_datastore_add(chan, ds);
3609  } else
3610  exception = ds->data;
3611 
3612  ast_string_field_set(exception, reason, reason);
3613  ast_string_field_set(exception, context, chan->context);
3614  ast_string_field_set(exception, exten, chan->exten);
3615  exception->priority = chan->priority;
3616  set_ext_pri(chan, "e", priority);
3617  return 0;
3618 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
int priority
Definition: channel.h:841
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define ast_calloc_with_stringfields(n, type, size)
Allocate a structure with embedded stringfields in a single allocation.
Definition: stringfields.h:275
Structure for a data store object.
Definition: datastore.h:54
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2604
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
static struct ast_datastore_info exception_store_info
Definition: pbx.c:3578
const ast_string_field reason
Definition: pbx.c:1055
int priority
Definition: pbx.c:1057
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
void * data
Definition: datastore.h:56
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static void set_ext_pri(struct ast_channel *c, const char *exten, int pri)
Definition: pbx.c:5431
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2590
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
static int read_escalates ( const struct ast_custom_function acf)
static

Returns true if given custom function escalates privileges on read.

Parameters
acfCustom function to query.
Returns
True (non-zero) if reads escalate privileges.
False (zero) if reads just read.

Definition at line 3856 of file pbx.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.

Referenced by is_read_allowed().

3856  {
3857  int res = 0;
3858  struct ast_custom_escalating_function *cur_escalation;
3859 
3861  AST_RWLIST_TRAVERSE(&escalation_root, cur_escalation, list) {
3862  if (cur_escalation->acf == acf) {
3863  res = cur_escalation->read_escalates;
3864  break;
3865  }
3866  }
3868  return res;
3869 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Extra information for an ast_custom_function holding privilege escalation information. Kept in a separate structure for ABI compatibility.
Definition: pbx.c:1237
static void set_ext_pri ( struct ast_channel c,
const char *  exten,
int  pri 
)
static

helper function to set extension and priority

Definition at line 5431 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_channel::exten, and ast_channel::priority.

Referenced by __ast_pbx_run(), ast_pbx_outgoing_exten(), pbx_builtin_waitexten(), and raise_exception().

5432 {
5433  ast_channel_lock(c);
5434  ast_copy_string(c->exten, exten, sizeof(c->exten));
5435  c->priority = pri;
5436  ast_channel_unlock(c);
5437 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
int priority
Definition: channel.h:841
#define ast_channel_unlock(chan)
Definition: channel.h:2467
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static int show_debug_helper ( int  fd,
const char *  context,
const char *  exten,
struct dialplan_counters dpc,
struct ast_include rinclude,
int  includecount,
const char *  includes[] 
)
static

Definition at line 7074 of file pbx.c.

References ast_cli(), ast_exists_extension(), ast_get_context_name(), ast_get_context_registrar(), ast_rdlock_context(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_contexts(), cli_match_char_tree(), dialplan_counters::context_existence, ast_context::name, ast_context::pattern_tree, dialplan_counters::total_context, and dialplan_counters::total_exten.

Referenced by handle_debug_dialplan().

7075 {
7076  struct ast_context *c = NULL;
7077  int res = 0, old_total_exten = dpc->total_exten;
7078 
7079  ast_cli(fd,"\n In-mem exten Trie for Fast Extension Pattern Matching:\n\n");
7080 
7081  ast_cli(fd,"\n Explanation: Node Contents Format = <char(s) to match>:<pattern?>:<specif>:[matched extension]\n");
7082  ast_cli(fd, " Where <char(s) to match> is a set of chars, any one of which should match the current character\n");
7083  ast_cli(fd, " <pattern?>: Y if this a pattern match (eg. _XZN[5-7]), N otherwise\n");
7084  ast_cli(fd, " <specif>: an assigned 'exactness' number for this matching char. The lower the number, the more exact the match\n");
7085  ast_cli(fd, " [matched exten]: If all chars matched to this point, which extension this matches. In form: EXTEN:<exten string>\n");
7086  ast_cli(fd, " In general, you match a trie node to a string character, from left to right. All possible matching chars\n");
7087  ast_cli(fd, " are in a string vertically, separated by an unbroken string of '+' characters.\n\n");
7089 
7090  /* walk all contexts ... */
7091  while ( (c = ast_walk_contexts(c)) ) {
7092  int context_info_printed = 0;
7093 
7094  if (context && strcmp(ast_get_context_name(c), context))
7095  continue; /* skip this one, name doesn't match */
7096 
7097  dpc->context_existence = 1;
7098 
7099  if (!c->pattern_tree) {
7100  /* Ignore check_return warning from Coverity for ast_exists_extension below */
7101  ast_exists_extension(NULL, c->name, "s", 1, ""); /* do this to force the trie to built, if it is not already */
7102  }
7103 
7104  ast_rdlock_context(c);
7105 
7106  dpc->total_context++;
7107  ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
7109  context_info_printed = 1;
7110 
7111  if (c->pattern_tree)
7112  {
7113  cli_match_char_tree(c->pattern_tree, " ", fd);
7114  } else {
7115  ast_cli(fd,"\n No Pattern Trie present. Perhaps the context is empty...or there is trouble...\n\n");
7116  }
7117 
7118  ast_unlock_context(c);
7119 
7120  /* if we print something in context, make an empty line */
7121  if (context_info_printed)
7122  ast_cli(fd, "\n");
7123  }
7125 
7126  return (dpc->total_exten == old_total_exten) ? -1 : res;
7127 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
int total_exten
Definition: pbx.c:6898
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:11042
int context_existence
Definition: pbx.c:6900
const char * ast_get_context_registrar(struct ast_context *c)
Definition: pbx.c:11111
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
char name[0]
Definition: pbx.c:967
static void cli_match_char_tree(struct match_char *node, char *prefix, int fd)
Definition: pbx.c:1699
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: pbx.c:11174
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int total_context
Definition: pbx.c:6897
ast_context: An extension context
Definition: pbx.c:955
struct match_char * pattern_tree
Definition: pbx.c:959
int ast_rdlock_context(struct ast_context *con)
Read locks a given context.
Definition: pbx.c:11060
static int show_dialplan_helper ( int  fd,
const char *  context,
const char *  exten,
struct dialplan_counters dpc,
struct ast_include rinclude,
int  includecount,
const char *  includes[] 
)
static

Definition at line 6919 of file pbx.c.

References ast_cli(), AST_EXT_MATCHCID_ON, ast_extension_match(), ast_get_context_name(), ast_get_context_registrar(), ast_get_extension_label(), ast_get_extension_name(), ast_get_extension_registrar(), ast_get_ignorepat_name(), ast_get_ignorepat_registrar(), ast_get_include_name(), ast_get_include_registrar(), ast_get_switch_data(), ast_get_switch_name(), ast_get_switch_registrar(), ast_log(), AST_MAX_EXTENSION, AST_PBX_MAX_STACK, ast_rdlock_context(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), ast_walk_contexts(), ast_walk_extension_priorities(), buf2, ast_exten::cidmatch, dialplan_counters::context_existence, el, dialplan_counters::extension_existence, LOG_WARNING, ast_exten::matchcid, print_ext(), dialplan_counters::total_context, dialplan_counters::total_exten, and dialplan_counters::total_prio.

Referenced by handle_show_dialplan().

6920 {
6921  struct ast_context *c = NULL;
6922  int res = 0, old_total_exten = dpc->total_exten;
6923 
6925 
6926  /* walk all contexts ... */
6927  while ( (c = ast_walk_contexts(c)) ) {
6928  struct ast_exten *e;
6929  struct ast_include *i;
6930  struct ast_ignorepat *ip;
6931 #ifndef LOW_MEMORY
6932  char buf[1024], buf2[1024];
6933 #else
6934  char buf[256], buf2[256];
6935 #endif
6936  int context_info_printed = 0;
6937 
6938  if (context && strcmp(ast_get_context_name(c), context))
6939  continue; /* skip this one, name doesn't match */
6940 
6941  dpc->context_existence = 1;
6942 
6943  ast_rdlock_context(c);
6944 
6945  /* are we looking for exten too? if yes, we print context
6946  * only if we find our extension.
6947  * Otherwise print context even if empty ?
6948  * XXX i am not sure how the rinclude is handled.
6949  * I think it ought to go inside.
6950  */
6951  if (!exten) {
6952  dpc->total_context++;
6953  ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
6955  context_info_printed = 1;
6956  }
6957 
6958  /* walk extensions ... */
6959  e = NULL;
6960  while ( (e = ast_walk_context_extensions(c, e)) ) {
6961  struct ast_exten *p;
6962 
6964  continue; /* skip, extension match failed */
6965 
6966  dpc->extension_existence = 1;
6967 
6968  /* may we print context info? */
6969  if (!context_info_printed) {
6970  dpc->total_context++;
6971  if (rinclude) { /* TODO Print more info about rinclude */
6972  ast_cli(fd, "[ Included context '%s' created by '%s' ]\n",
6974  } else {
6975  ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
6977  }
6978  context_info_printed = 1;
6979  }
6980  dpc->total_prio++;
6981 
6982  /* write extension name and first peer */
6983  if (e->matchcid == AST_EXT_MATCHCID_ON)
6984  snprintf(buf, sizeof(buf), "'%s' (CID match '%s') => ", ast_get_extension_name(e), e->cidmatch);
6985  else
6986  snprintf(buf, sizeof(buf), "'%s' =>", ast_get_extension_name(e));
6987 
6988  print_ext(e, buf2, sizeof(buf2));
6989 
6990  ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2,
6992 
6993  dpc->total_exten++;
6994  /* walk next extension peers */
6995  p = e; /* skip the first one, we already got it */
6996  while ( (p = ast_walk_extension_priorities(e, p)) ) {
6997  const char *el = ast_get_extension_label(p);
6998  dpc->total_prio++;
6999  if (el)
7000  snprintf(buf, sizeof(buf), " [%s]", el);
7001  else
7002  buf[0] = '\0';
7003  print_ext(p, buf2, sizeof(buf2));
7004 
7005  ast_cli(fd," %-17s %-45s [%s]\n", buf, buf2,
7007  }
7008  }
7009 
7010  /* walk included and write info ... */
7011  i = NULL;
7012  while ( (i = ast_walk_context_includes(c, i)) ) {
7013  snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i));
7014  if (exten) {
7015  /* Check all includes for the requested extension */
7016  if (includecount >= AST_PBX_MAX_STACK) {
7017  ast_log(LOG_WARNING, "Maximum include depth exceeded!\n");
7018  } else {
7019  int dupe = 0;
7020  int x;
7021  for (x = 0; x < includecount; x++) {
7022  if (!strcasecmp(includes[x], ast_get_include_name(i))) {
7023  dupe++;
7024  break;
7025  }
7026  }
7027  if (!dupe) {
7028  includes[includecount] = ast_get_include_name(i);
7029  show_dialplan_helper(fd, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes);
7030  } else {
7031  ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context);
7032  }
7033  }
7034  } else {
7035  ast_cli(fd, " Include => %-45s [%s]\n",
7036  buf, ast_get_include_registrar(i));
7037  }
7038  }
7039 
7040  /* walk ignore patterns and write info ... */
7041  ip = NULL;
7042  while ( (ip = ast_walk_context_ignorepats(c, ip)) ) {
7043  const char *ipname = ast_get_ignorepat_name(ip);
7044  char ignorepat[AST_MAX_EXTENSION];
7045  snprintf(buf, sizeof(buf), "'%s'", ipname);
7046  snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname);
7047  if (!exten || ast_extension_match(ignorepat, exten)) {
7048  ast_cli(fd, " Ignore pattern => %-45s [%s]\n",
7049  buf, ast_get_ignorepat_registrar(ip));
7050  }
7051  }
7052  if (!rinclude) {
7053  struct ast_sw *sw = NULL;
7054  while ( (sw = ast_walk_context_switches(c, sw)) ) {
7055  snprintf(buf, sizeof(buf), "'%s/%s'",
7056  ast_get_switch_name(sw),
7057  ast_get_switch_data(sw));
7058  ast_cli(fd, " Alt. Switch => %-45s [%s]\n",
7059  buf, ast_get_switch_registrar(sw));
7060  }
7061  }
7062 
7063  ast_unlock_context(c);
7064 
7065  /* if we print something in context, make an empty line */
7066  if (context_info_printed)
7067  ast_cli(fd, "\n");
7068  }
7070 
7071  return (dpc->total_exten == old_total_exten) ? -1 : res;
7072 }
struct ast_include * ast_walk_context_includes(struct ast_context *con, struct ast_include *inc)
Definition: pbx.c:11203
ast_include: include= support in extensions.conf
Definition: pbx.c:904
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:11065
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
const char * ast_get_extension_registrar(struct ast_exten *e)
Definition: pbx.c:11116
int total_exten
Definition: pbx.c:6898
#define LOG_WARNING
Definition: logger.h:144
static EditLine * el
Definition: asterisk.c:222
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:11042
static struct ast_threadstorage buf2
int context_existence
Definition: pbx.c:6900
const char * ast_get_extension_label(struct ast_exten *e)
Definition: pbx.c:11088
const char * ast_get_context_registrar(struct ast_context *c)
Definition: pbx.c:11111
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static int show_dialplan_helper(int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[])
Definition: pbx.c:6919
int matchcid
Definition: pbx.c:886
const char * ast_get_switch_name(struct ast_sw *sw)
Definition: pbx.c:11151
const char * ast_get_include_name(struct ast_include *include)
Definition: pbx.c:11093
const char * ast_get_include_registrar(struct ast_include *i)
Definition: pbx.c:11121
ast_sw: Switch statement in extensions.conf
Definition: pbx.c:915
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority)
Definition: pbx.c:11179
#define AST_MAX_EXTENSION
Definition: channel.h:135
const char * ast_get_ignorepat_registrar(struct ast_ignorepat *ip)
Definition: pbx.c:11126
const char * ast_get_switch_data(struct ast_sw *sw)
Definition: pbx.c:11156
static void print_ext(struct ast_exten *e, char *buf, int buflen)
helper function to print an extension
Definition: pbx.c:6905
struct ast_ignorepat * ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip)
Definition: pbx.c:11212
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: pbx.c:11174
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
const char * ast_get_switch_registrar(struct ast_sw *sw)
Definition: pbx.c:11166
struct ast_exten * ast_walk_extension_priorities(struct ast_exten *exten, struct ast_exten *priority)
Definition: pbx.c:11197
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx.c:925
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
#define AST_PBX_MAX_STACK
Definition: extconf.h:223
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:11083
const char * ast_get_ignorepat_name(struct ast_ignorepat *ip)
Definition: pbx.c:11098
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
Definition: pbx.c:2943
const char * cidmatch
Definition: pbx.c:887
struct ast_sw * ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw)
Definition: pbx.c:11188
int total_prio
Definition: pbx.c:6899
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int total_context
Definition: pbx.c:6897
ast_context: An extension context
Definition: pbx.c:955
int extension_existence
Definition: pbx.c:6901
int ast_rdlock_context(struct ast_context *con)
Read locks a given context.
Definition: pbx.c:11060
static int statecbs_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 11383 of file pbx.c.

References ast_state_cb::change_cb, CMP_MATCH, and CMP_STOP.

Referenced by ast_pbx_init().

11384 {
11385  const struct ast_state_cb *state_cb = obj;
11387 
11388  return (state_cb->change_cb == change_cb) ? CMP_MATCH | CMP_STOP : 0;
11389 }
int(* ast_state_cb_type)(char *context, char *id, enum ast_extension_states state, void *data)
Typedef for devicestate and hint callbacks.
Definition: pbx.h:89
ast_state_cb: An extension state notify register item
Definition: pbx.c:989
ast_state_cb_type change_cb
Definition: pbx.c:995
static char* substring ( const char *  value,
int  offset,
int  length,
char *  workspace,
size_t  workspace_len 
)
static

takes a substring. It is ok to call with value == workspace.

Parameters
value
offset< 0 means start from the end of the string and set the beginning to be that many characters back.
lengthis the length of the substring, a value less than 0 means to leave that many off the end.
workspace
workspace_lenAlways return a copy in workspace.

Definition at line 3344 of file pbx.c.

References ast_copy_string().

Referenced by pbx_substitute_variables_helper_full().

3345 {
3346  char *ret = workspace;
3347  int lr; /* length of the input string after the copy */
3348 
3349  ast_copy_string(workspace, value, workspace_len); /* always make a copy */
3350 
3351  lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
3352 
3353  /* Quick check if no need to do anything */
3354  if (offset == 0 && length >= lr) /* take the whole string */
3355  return ret;
3356 
3357  if (offset < 0) { /* translate negative offset into positive ones */
3358  offset = lr + offset;
3359  if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
3360  offset = 0;
3361  }
3362 
3363  /* too large offset result in empty string so we know what to return */
3364  if (offset >= lr)
3365  return ret + lr; /* the final '\0' */
3366 
3367  ret += offset; /* move to the start position */
3368  if (length >= 0 && length < lr - offset) /* truncate if necessary */
3369  ret[length] = '\0';
3370  else if (length < 0) {
3371  if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */
3372  ret[lr + length - offset] = '\0';
3373  else
3374  ret[0] = '\0';
3375  }
3376 
3377  return ret;
3378 }
int value
Definition: syslog.c:39
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int thread_inhibits_escalations ( void  )
static

Indicates whether the current thread inhibits the execution of dangerous functions.

Returns
True (non-zero) if dangerous function execution is inhibited.
False (zero) if dangerous function execution is allowed.

Definition at line 4095 of file pbx.c.

References ast_log(), ast_threadstorage_get(), LOG_ERROR, and thread_inhibit_escalations_tl.

Referenced by is_read_allowed(), and is_write_allowed().

4096 {
4097  int *thread_inhibit_escalations;
4098 
4099  thread_inhibit_escalations = ast_threadstorage_get(
4100  &thread_inhibit_escalations_tl, sizeof(*thread_inhibit_escalations));
4101 
4102  if (thread_inhibit_escalations == NULL) {
4103  ast_log(LOG_ERROR, "Error checking thread's ability to run dangerous functions\n");
4104  /* On error, assume that we are inhibiting */
4105  return 1;
4106  }
4107 
4108  return *thread_inhibit_escalations;
4109 }
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
static struct ast_threadstorage thread_inhibit_escalations_tl
Definition: pbx.c:870
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_exten* trie_find_next_match ( struct match_char node)
static

Definition at line 1748 of file pbx.c.

References match_char::alt_char, match_char::exten, match_char::next_char, and match_char::x.

Referenced by pbx_find_extension().

1749 {
1750  struct match_char *m3;
1751  struct match_char *m4;
1752  struct ast_exten *e3;
1753 
1754  if (node && node->x[0] == '.' && !node->x[1]) { /* dot and ! will ALWAYS be next match in a matchmore */
1755  return node->exten;
1756  }
1757 
1758  if (node && node->x[0] == '!' && !node->x[1]) {
1759  return node->exten;
1760  }
1761 
1762  if (!node || !node->next_char) {
1763  return NULL;
1764  }
1765 
1766  m3 = node->next_char;
1767 
1768  if (m3->exten) {
1769  return m3->exten;
1770  }
1771  for (m4 = m3->alt_char; m4; m4 = m4->alt_char) {
1772  if (m4->exten) {
1773  return m4->exten;
1774  }
1775  }
1776  for (m4 = m3; m4; m4 = m4->alt_char) {
1777  e3 = trie_find_next_match(m3);
1778  if (e3) {
1779  return e3;
1780  }
1781  }
1782 
1783  return NULL;
1784 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
struct ast_exten * exten
Definition: pbx.c:939
struct match_char * alt_char
Definition: pbx.c:937
char x[1]
Definition: pbx.c:940
static struct ast_exten * trie_find_next_match(struct match_char *node)
Definition: pbx.c:1748
struct match_char * next_char
Definition: pbx.c:938
match_char: forms a syntax tree for quick matching of extension patterns
Definition: pbx.c:932
static void unload_pbx ( void  )
static

Definition at line 10973 of file pbx.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_data_unregister, ast_event_unsubscribe(), ast_manager_unregister(), ast_taskprocessor_unreference(), ast_unregister_application(), builtins, device_state_sub, exception_function, pbx_cli, and testtime_function.

Referenced by load_pbx().

10974 {
10975  int x;
10976 
10977  if (device_state_sub) {
10979  }
10980  if (device_state_tps) {
10982  device_state_tps = NULL;
10983  }
10984 
10985  /* Unregister builtin applications */
10986  for (x = 0; x < ARRAY_LEN(builtins); x++) {
10988  }
10989  ast_manager_unregister("ShowDialPlan");
10993  ast_data_unregister(NULL);
10994 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
static struct ast_cli_entry pbx_cli[]
Definition: pbx.c:7665
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
#define ast_data_unregister(path)
Definition: data.h:394
static struct ast_event_sub * device_state_sub
Subscription for device state change events.
Definition: pbx.c:1225
static struct ast_custom_function testtime_function
Definition: pbx.c:10114
static const char name[]
static struct ast_custom_function exception_function
Definition: pbx.c:3646
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
static struct ast_taskprocessor * device_state_tps
Definition: pbx.c:862
static struct pbx_builtin builtins[]
struct ast_event_sub * ast_event_unsubscribe(struct ast_event_sub *event_sub)
Un-subscribe from events.
Definition: event.c:987
int ast_manager_unregister(char *action)
Unregister a registered manager command.
Definition: manager.c:5355
static void unreference_cached_app ( struct ast_app app)
static

Definition at line 7686 of file pbx.c.

References ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_contexts(), and ast_walk_extension_priorities().

Referenced by ast_unregister_application().

7687 {
7688  struct ast_context *context = NULL;
7689  struct ast_exten *eroot = NULL, *e = NULL;
7690 
7692  while ((context = ast_walk_contexts(context))) {
7693  while ((eroot = ast_walk_context_extensions(context, eroot))) {
7694  while ((e = ast_walk_extension_priorities(eroot, e))) {
7695  if (e->cached_app == app)
7696  e->cached_app = NULL;
7697  }
7698  }
7699  }
7701 
7702  return;
7703 }
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:884
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:11042
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority)
Definition: pbx.c:11179
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: pbx.c:11174
struct ast_exten * ast_walk_extension_priorities(struct ast_exten *exten, struct ast_exten *priority)
Definition: pbx.c:11197
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:11047
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
ast_context: An extension context
Definition: pbx.c:955
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 
)
static

Definition at line 1652 of file pbx.c.

References ast_log(), exten, ast_exten::exten, scoreboard::exten, last, scoreboard::last_char, LOG_NOTICE, scoreboard::node, scoreboard::total_length, and scoreboard::total_specificity.

Referenced by new_find_extension().

1653 {
1654  /* if this extension is marked as deleted, then skip this -- if it never shows
1655  on the scoreboard, it will never be found, nor will halt the traversal. */
1656  if (deleted)
1657  return;
1658  board->total_specificity = spec;
1659  board->total_length = length;
1660  board->exten = exten;
1661  board->last_char = last;
1662  board->node = node;
1663 #ifdef NEED_DEBUG_HERE
1664  ast_log(LOG_NOTICE,"Scoreboarding (LONGER) %s, len=%d, score=%d\n", exten->exten, length, spec);
1665 #endif
1666 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
char last_char
Definition: pbx.c:947
struct sla_ringing_trunk * last
Definition: app_meetme.c:965
char * exten
Definition: pbx.c:885
int total_specificity
Definition: pbx.c:945
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
struct match_char * node
Definition: pbx.c:949
int total_length
Definition: pbx.c:946
struct ast_exten * exten
Definition: pbx.c:951
static void wait_for_hangup ( struct ast_channel chan,
const void *  data 
)
static

Definition at line 9882 of file pbx.c.

References ast_frfree, ast_read(), ast_safe_sleep(), ast_strlen_zero(), ast_waitfor(), and f.

Referenced by pbx_builtin_busy(), and pbx_builtin_congestion().

9883 {
9884  int res;
9885  struct ast_frame *f;
9886  double waitsec;
9887  int waittime;
9888 
9889  if (ast_strlen_zero(data) || (sscanf(data, "%30lg", &waitsec) != 1) || (waitsec < 0))
9890  waitsec = -1;
9891  if (waitsec > -1) {
9892  waittime = waitsec * 1000.0;
9893  ast_safe_sleep(chan, waittime);
9894  } else do {
9895  res = ast_waitfor(chan, -1);
9896  if (res < 0)
9897  return;
9898  f = ast_read(chan);
9899  if (f)
9900  ast_frfree(f);
9901  } while(f);
9902 }
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1916
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_format f[]
Definition: format_g726.c:181
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3539
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_frfree(fr)
Definition: frame.h:583
union ast_frame::@172 data
static int write_escalates ( const struct ast_custom_function acf)
static

Returns true if given custom function escalates privileges on write.

Parameters
acfCustom function to query.
Returns
True (non-zero) if writes escalate privileges.
False (zero) if writes just write.

Definition at line 3878 of file pbx.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.

Referenced by is_write_allowed().

3878  {
3879  int res = 0;
3880  struct ast_custom_escalating_function *cur_escalation;
3881 
3883  AST_RWLIST_TRAVERSE(&escalation_root, cur_escalation, list) {
3884  if (cur_escalation->acf == acf) {
3885  res = cur_escalation->write_escalates;
3886  break;
3887  }
3888  }
3890  return res;
3891 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Extra information for an ast_custom_function holding privilege escalation information. Kept in a separate structure for ABI compatibility.
Definition: pbx.c:1237

Variable Documentation

struct acf_root acf_root = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
struct apps apps = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
int autofallthrough = 1
static

Definition at line 1220 of file pbx.c.

Referenced by __ast_pbx_run(), and pbx_set_autofallthrough().

struct ast_app_option background_opts[128] = { [ 's' ] = { .flag = (1 << 0) }, [ 'n' ] = { .flag = (1 << 1) }, [ 'm' ] = { .flag = (1 << 2) }, [ 'p' ] = { .flag = (1 << 3) }, }
static

Definition at line 849 of file pbx.c.

Referenced by pbx_builtin_background().

struct pbx_builtin builtins[]
static

Referenced by load_pbx(), and unload_pbx().

ast_mutex_t conlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Lock for the ast_context list.

Note
This lock MUST be recursive, or a deadlock on reload may result. See https://issues.asterisk.org/view.php?id=17643

Definition at line 1294 of file pbx.c.

Referenced by ast_rdlock_contexts(), ast_unlock_contexts(), and ast_wrlock_contexts().

ast_mutex_t context_merge_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Lock to hold off restructuring of hints by ast_merge_contexts_and_delete.

Definition at line 1299 of file pbx.c.

Referenced by ast_merge_contexts_and_delete(), and handle_statechange().

int countcalls
static

Definition at line 1228 of file pbx.c.

Referenced by ast_active_calls(), decrease_call_count(), and increase_call_count().

const char* const days[]
static

Definition at line 8285 of file pbx.c.

Referenced by ast_build_timing().

struct ast_event_sub* device_state_sub
static

Subscription for device state change events.

Definition at line 1225 of file pbx.c.

Referenced by load_pbx(), and unload_pbx().

struct ast_taskprocessor* device_state_tps
static

Definition at line 862 of file pbx.c.

struct escalation_root escalation_root = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
struct ast_custom_function exception_function
static
Initial value:
= {
.name = "EXCEPTION",
}
static int acf_exception_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
Definition: pbx.c:3626

Definition at line 3646 of file pbx.c.

Referenced by load_pbx(), and unload_pbx().

struct ast_datastore_info exception_store_info
static
Initial value:
= {
.type = "EXCEPTION",
}
static void exception_store_free(void *data)
Definition: pbx.c:3571

Definition at line 3578 of file pbx.c.

Referenced by acf_exception_read(), and raise_exception().

int extenpatternmatchnew = 0
static

Definition at line 1221 of file pbx.c.

Referenced by pbx_find_extension(), and pbx_set_extenpatternmatchnew().

struct cfextension_states extension_states[]
static

Referenced by ast_extension_state2str().

struct ast_threadstorage extensionstate_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_extensionstate_buf , .custom_init = NULL , }
static

Definition at line 865 of file pbx.c.

Referenced by ast_extension_state2().

ast_rwlock_t globalslock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 }
static
struct ao2_container* hints
static
Note
When holding this container's lock, do not do anything that will cause conlock to be taken, unless you already hold it. The ast_merge_contexts_and_delete function will take the locks in conlock/hints order, so any other paths that require both locks must also take them in that order.

Definition at line 1314 of file pbx.c.

Referenced by ast_add_hint(), ast_change_hint(), ast_extension_state_add_destroy(), ast_extension_state_del(), ast_merge_contexts_and_delete(), ast_pbx_init(), ast_remove_hint(), complete_core_show_hint(), handle_show_hint(), handle_show_hints(), handle_statechange(), hints_data_provider_get(), pbx_shutdown(), and pvalExtenSetHints().

struct ast_data_handler hints_data_provider
static
Initial value:
= {
}
#define AST_DATA_HANDLER_VERSION
The Data API structures version.
Definition: data.h:204
static int hints_data_provider_get(const struct ast_data_search *search, struct ast_data *data_root)
Definition: pbx.c:10928

Definition at line 10962 of file pbx.c.

int live_dangerously
static

Set to true (non-zero) to globally allow all dangerous dialplan functions to run.

Definition at line 870 of file pbx.c.

Referenced by ast_readconfig().

ast_mutex_t maxcalllock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 1227 of file pbx.c.

Referenced by decrease_call_count(), and increase_call_count().

const char* const months[]
static

Definition at line 8297 of file pbx.c.

Referenced by ast_build_timing().

char* overrideswitch = NULL
static

Definition at line 1222 of file pbx.c.

Referenced by handle_cli_dialplan_save(), pbx_find_extension(), and pbx_set_overrideswitch().

struct ast_cli_entry pbx_cli[]
static

Definition at line 7665 of file pbx.c.

Referenced by load_pbx(), and unload_pbx().

struct ast_data_entry pbx_data_providers[]
static
Initial value:
= {
AST_DATA_ENTRY("asterisk/core/hints", &hints_data_provider),
}
#define AST_DATA_ENTRY(__path, __handler)
Definition: data.h:260
static struct ast_data_handler hints_data_provider
Definition: pbx.c:10962

Definition at line 10967 of file pbx.c.

Referenced by load_pbx().

struct ast_app_option resetcdr_opts[128] = { [ 'w' ] = { .flag = AST_CDR_FLAG_POSTED }, [ 'a' ] = { .flag = AST_CDR_FLAG_LOCKED }, [ 'v' ] = { .flag = AST_CDR_FLAG_KEEP_VARS }, [ 'e' ] = { .flag = AST_CDR_FLAG_POST_ENABLE }, }
static

Definition at line 10023 of file pbx.c.

Referenced by pbx_builtin_resetcdr().

int stateid = 1
static

Definition at line 1305 of file pbx.c.

Referenced by ast_extension_state_add_destroy().

struct ast_threadstorage switch_data = { .once = PTHREAD_ONCE_INIT , .key_init = __init_switch_data , .custom_init = NULL , }
static

Definition at line 864 of file pbx.c.

Referenced by pbx_find_extension().

struct switches switches = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
struct ast_custom_function testtime_function
static
Initial value:
= {
.name = "TESTTIME",
.write = testtime_write,
}
static int testtime_write(struct ast_channel *chan, const char *cmd, char *var, const char *value)
Definition: pbx.c:10090

Definition at line 10114 of file pbx.c.

Referenced by load_pbx(), and unload_pbx().

struct ast_threadstorage thread_inhibit_escalations_tl = { .once = PTHREAD_ONCE_INIT , .key_init = __init_thread_inhibit_escalations_tl , .custom_init = NULL , }
static

Definition at line 870 of file pbx.c.

Referenced by ast_thread_inhibit_escalations(), and thread_inhibits_escalations().

int totalcalls
static

Definition at line 1229 of file pbx.c.

Referenced by ast_processed_calls(), increase_call_count(), and timing_read().

struct ast_app_option waitexten_opts[128] = { [ 'm' ] = { .flag = (1 << 0) , .arg_index = 0 + 1 }, [ 'd' ] = { .flag = (1 << 1) , .arg_index = 0 + 1 }, }
static

Definition at line 857 of file pbx.c.

Referenced by pbx_builtin_waitexten().