Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Typedefs | Enumerations | Functions
pbx.h File Reference

Core PBX routines and definitions. More...

#include "asterisk/channel.h"
#include "asterisk/sched.h"
#include "asterisk/devicestate.h"
#include "asterisk/presencestate.h"
#include "asterisk/chanvars.h"
#include "asterisk/hashtab.h"
#include "asterisk/stringfields.h"
#include "asterisk/xmldoc.h"
#include "asterisk/format.h"
Include dependency graph for pbx.h:

Go to the source code of this file.

Data Structures

struct  ast_custom_function
 Data structure associated with a custom dialplan function. More...
 
struct  ast_device_state_info
 
struct  ast_pbx
 
struct  ast_pbx_args
 Options for ast_pbx_run() More...
 
struct  ast_state_cb_info
 
struct  ast_switch
 
struct  ast_timing
 
struct  pbx_find_info
 

Macros

#define ast_custom_function_register(acf)   __ast_custom_function_register(acf, AST_MODULE_SELF)
 Register a custom function. More...
 
#define ast_custom_function_register_escalating(acf, escalation)   __ast_custom_function_register_escalating(acf, escalation, AST_MODULE_SELF)
 Register a custom function which requires escalated privileges. More...
 
#define AST_MAX_APP   32
 
#define AST_PBX_GOTO_FAILED   -3
 
#define AST_PBX_KEEP   0
 
#define AST_PBX_MAX_STACK   512
 
#define AST_PBX_REPLACE   1
 
#define PRIORITY_HINT   -1
 
#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 AST_PBX_ERROR   1
 
#define AST_PBX_HANGUP   -1
 Special return values from applications to the PBX. More...
 
#define AST_PBX_INCOMPLETE   12
 
#define AST_PBX_OK   0
 

Typedefs

typedef void(* ast_state_cb_destroy_type) (int id, void *data)
 Typedef for devicestate and hint callback removal indication callback. More...
 
typedef int(* ast_state_cb_type) (const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
 Typedef for devicestate and hint callbacks. More...
 
typedef 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. More...
 

Enumerations

enum  ast_custom_function_escalation { AST_CFE_NONE , AST_CFE_READ , AST_CFE_WRITE , AST_CFE_BOTH }
 Description of the ways in which a function may escalate privileges. More...
 
enum  ast_ext_matchcid_types { AST_EXT_MATCHCID_OFF = 0 , AST_EXT_MATCHCID_ON = 1 , AST_EXT_MATCHCID_ANY = 2 }
 extension matchcid types More...
 
enum  ast_extension_states {
  AST_EXTENSION_REMOVED = -2 , AST_EXTENSION_DEACTIVATED = -1 , AST_EXTENSION_NOT_INUSE = 0 , AST_EXTENSION_INUSE = 1 << 0 ,
  AST_EXTENSION_BUSY = 1 << 1 , AST_EXTENSION_UNAVAILABLE = 1 << 2 , AST_EXTENSION_RINGING = 1 << 3 , AST_EXTENSION_ONHOLD = 1 << 4 ,
  AST_EXTENSION_REMOVED = -2 , AST_EXTENSION_DEACTIVATED = -1 , AST_EXTENSION_NOT_INUSE = 0 , AST_EXTENSION_INUSE = 1 << 0 ,
  AST_EXTENSION_BUSY = 1 << 1 , AST_EXTENSION_UNAVAILABLE = 1 << 2 , AST_EXTENSION_RINGING = 1 << 3 , AST_EXTENSION_ONHOLD = 1 << 4
}
 Extension states. More...
 
enum  ast_pbx_outgoing_sync { AST_OUTGOING_NO_WAIT = 0 , AST_OUTGOING_WAIT = 1 , AST_OUTGOING_WAIT_COMPLETE = 2 }
 
enum  ast_pbx_result { AST_PBX_SUCCESS = 0 , AST_PBX_FAILED = -1 , AST_PBX_CALL_LIMIT = -2 }
 The result codes when starting the PBX on a channel with ast_pbx_start. More...
 
enum  ast_state_cb_update_reason { AST_HINT_UPDATE_DEVICE = 1 , AST_HINT_UPDATE_PRESENCE = 2 }
 
enum  ext_match_t {
  E_MATCHMORE = 0x00 , E_CANMATCH = 0x01 , E_MATCH = 0x02 , E_MATCH_MASK = 0x03 ,
  E_SPAWN = 0x12 , E_FINDLABEL = 0x22 , E_MATCHMORE = 0x00 , E_CANMATCH = 0x01 ,
  E_MATCH = 0x02 , E_MATCH_MASK = 0x03 , E_SPAWN = 0x12 , E_FINDLABEL = 0x22
}
 

Functions

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...
 
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, const char *registrar_file, int registrar_line)
 Add an extension to an extension context, this time with an ast_context *. More...
 
int ast_add_extension2_nolock (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, const char *registrar_file, int registrar_line)
 Same as ast_add_extension2, but assumes you have already locked context. 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 *chan, 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...
 
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 *ignorepat, const char *registrar)
 Add an ignorepat. More...
 
int ast_context_add_ignorepat2 (struct ast_context *con, const char *ignorepat, 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 *sw, 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...
 
int ast_context_destroy_by_name (const char *context, const char *registrar)
 Destroy a context by name. 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_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar)
 Remove an ignorepat. More...
 
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 a context include. More...
 
int ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar)
 Removes an include by an ast_context structure. 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...
 
void ast_context_set_autohints (struct ast_context *con, int enabled)
 Enable or disable autohints support on a 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 *extension)
 Determine if a given extension matches a given pattern (in NXX format) More...
 
int ast_extension_patmatch (const char *pattern, const char *data)
 
int ast_extension_state (struct ast_channel *c, const char *context, const char *exten)
 Uses hint and devicestate callback to get the state of an extension. More...
 
const char * ast_extension_state2str (int extension_state)
 Return string representation of the state of an extension. More...
 
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_add_destroy_extended (const char *context, const char *exten, ast_state_cb_type change_cb, ast_state_cb_destroy_type destroy_cb, void *data)
 Add watcher for extended extension states with destructor. More...
 
int ast_extension_state_add_extended (const char *context, const char *exten, ast_state_cb_type change_cb, void *data)
 Add watcher for extended extension states. More...
 
int ast_extension_state_del (int id, ast_state_cb_type change_cb)
 Deletes a state change watcher by ID. More...
 
int ast_extension_state_extended (struct ast_channel *c, const char *context, const char *exten, struct ao2_container **device_state_info)
 Uses hint and devicestate callback to get the extended state of an extension. 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_extension_registrar_file (struct ast_exten *e)
 Get name of configuration file used by registrar to register this extension. More...
 
int ast_get_extension_registrar_line (struct ast_exten *e)
 Get line number of configuration file used by registrar to register this extension. More...
 
int ast_get_hint (char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
 If an extension hint exists, return non-zero. More...
 
int ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
 
int ast_hint_presence_state (struct ast_channel *c, const char *context, const char *exten, char **subtype, char **message)
 Uses hint and presence state callback to get the presence state of an extension. 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_exec_application (struct ast_channel *chan, const char *app_name, const char *app_args)
 Execute an application. More...
 
void ast_pbx_h_exten_run (struct ast_channel *chan, const char *context)
 Run the h exten from the given context. More...
 
void ast_pbx_hangup_handler_destroy (struct ast_channel *chan)
 Destroy the hangup handler container on a channel. More...
 
void ast_pbx_hangup_handler_init (struct ast_channel *chan)
 Init the hangup handler container on a channel. More...
 
int ast_pbx_hangup_handler_pop (struct ast_channel *chan)
 Pop the top of the channel hangup handler stack. More...
 
void ast_pbx_hangup_handler_push (struct ast_channel *chan, const char *handler)
 Push the given hangup handler onto the channel hangup handler stack. More...
 
int ast_pbx_hangup_handler_run (struct ast_channel *chan)
 Run all hangup handlers on the channel. More...
 
int ast_pbx_outgoing_app (const char *type, struct ast_format_cap *cap, const char *addr, 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, const struct ast_assigned_ids *assignedids)
 Synchronously or asynchronously make an outbound call and execute an application on the channel. More...
 
int ast_pbx_outgoing_app_predial (const char *type, struct ast_format_cap *cap, const char *addr, 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, const struct ast_assigned_ids *assignedids, const char *predial_callee)
 
int ast_pbx_outgoing_exten (const char *type, struct ast_format_cap *cap, const char *addr, 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 **locked_channel, int early_media, const struct ast_assigned_ids *assignedids)
 Synchronously or asynchronously make an outbound call and send it to a particular extension. More...
 
int ast_pbx_outgoing_exten_predial (const char *type, struct ast_format_cap *cap, const char *addr, 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 **locked_channel, int early_media, const struct ast_assigned_ids *assignedids, const char *predial_callee)
 
enum ast_pbx_result ast_pbx_run (struct ast_channel *c)
 Execute the PBX in the current thread. 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_switch (struct ast_switch *sw)
 Register an alternative dialplan switch. 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)
 If an extension hint exists, return non-zero. More...
 
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_thread_inhibit_escalations_swap (int inhibit)
 Swap the current thread escalation inhibit setting. More...
 
int ast_unlock_context (struct ast_context *con)
 
int ast_unlock_contexts (void)
 Unlocks contexts. More...
 
void ast_unregister_switch (struct ast_switch *sw)
 Unregister an alternative switch. More...
 
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...
 
void pbx_builtin_clear_globals (void)
 
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...
 
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 *data)
 
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...
 
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 *data)
 Parse and set multiple channel variables, where the pairs are separated by the ',' character, and name and value are separated with an '=' character. More...
 
int pbx_checkcondition (const char *condition)
 Evaluate a condition. More...
 
int pbx_exec (struct ast_channel *c, struct ast_app *app, const char *data)
 Execute an application. 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)
 Look up an application. More...
 
void pbx_live_dangerously (int new_live_dangerously)
 Enable/disable the execution of 'dangerous' functions from external protocols (AMI, etc.). More...
 
int pbx_parse_location (struct ast_channel *chan, char **context, char **exten, char **pri, int *ipri, int *mode, char *rest)
 Parses a dialplan location into context, extension, priority. More...
 
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. More...
 
int pbx_set_autofallthrough (int newval)
 
int pbx_set_extenpatternmatchnew (int newval)
 
void pbx_set_overrideswitch (const char *newval)
 
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 matchcid, const char *registrar)
 
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)
 

Functions for returning values from structures

const char * ast_get_context_name (struct ast_context *con)
 
struct ast_contextast_get_extension_context (struct ast_exten *exten)
 
const char * ast_get_extension_name (struct ast_exten *exten)
 
const char * ast_get_ignorepat_name (const struct ast_ignorepat *ip)
 
const char * ast_get_include_name (const struct ast_include *include)
 
const char * ast_get_switch_data (const struct ast_sw *sw)
 
int ast_get_switch_eval (const struct ast_sw *sw)
 
const char * ast_get_switch_name (const struct ast_sw *sw)
 
Other Extension stuff
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)
 
int ast_get_extension_data (char *buf, int bufsize, struct ast_channel *c, const char *context, const char *exten, int priority)
 Fill a string buffer with the data at a dialplan extension. More...
 
const char * ast_get_extension_label (struct ast_exten *e)
 
int ast_get_extension_matchcid (struct ast_exten *e)
 
int ast_get_extension_priority (struct ast_exten *exten)
 
Registrar info functions ...
const char * ast_get_context_registrar (struct ast_context *c)
 
const char * ast_get_extension_registrar (struct ast_exten *e)
 
const char * ast_get_ignorepat_registrar (const struct ast_ignorepat *ip)
 
const char * ast_get_include_registrar (const struct ast_include *i)
 
const char * ast_get_switch_registrar (const struct ast_sw *sw)
 
Walking functions ...
struct ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
 
const struct ast_ignorepatast_walk_context_ignorepats (const struct ast_context *con, const struct ast_ignorepat *ip)
 
const struct ast_includeast_walk_context_includes (const struct ast_context *con, const struct ast_include *inc)
 
const struct ast_swast_walk_context_switches (const struct ast_context *con, const 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)
 
Iterator functions ...
int ast_context_ignorepats_count (const struct ast_context *con)
 
const struct ast_ignorepatast_context_ignorepats_get (const struct ast_context *con, int idx)
 
int ast_context_includes_count (const struct ast_context *con)
 
const struct ast_includeast_context_includes_get (const struct ast_context *con, int idx)
 
int ast_context_switches_count (const struct ast_context *con)
 
const struct ast_swast_context_switches_get (const struct ast_context *con, int idx)
 
Substitution routines, using static string buffers
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 cp2_size, size_t *used)
 
void pbx_substitute_variables_helper_full_location (struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used, const char *context, const char *exten, int pri)
 Substitutes variables, similar to pbx_substitute_variables_helper_full, but allows passing the context, extension, and priority in. More...
 
void pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count)
 
Substitution routines, using dynamic string buffers
const char * ast_str_retrieve_variable (struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, 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_full2 (struct ast_str **buf, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *templ, size_t *used, int use_both)
 Perform variable/function/expression substitution on an ast_str. More...
 
void ast_str_substitute_variables_varshead (struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
 
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)
 

Detailed Description

Core PBX routines and definitions.

Definition in file pbx.h.

Macro Definition Documentation

◆ ast_custom_function_register

#define ast_custom_function_register (   acf)    __ast_custom_function_register(acf, AST_MODULE_SELF)

Register a custom function.

Definition at line 1558 of file pbx.h.

◆ ast_custom_function_register_escalating

#define ast_custom_function_register_escalating (   acf,
  escalation 
)    __ast_custom_function_register_escalating(acf, escalation, AST_MODULE_SELF)

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 1567 of file pbx.h.

◆ AST_MAX_APP

#define AST_MAX_APP   32

Max length of an application

Definition at line 40 of file pbx.h.

◆ AST_PBX_ERROR

#define AST_PBX_ERROR   1

Jump to the 'e' exten

Definition at line 50 of file pbx.h.

◆ AST_PBX_GOTO_FAILED

#define AST_PBX_GOTO_FAILED   -3

Definition at line 42 of file pbx.h.

◆ AST_PBX_HANGUP

#define AST_PBX_HANGUP   -1

Special return values from applications to the PBX.

Jump to the 'h' exten

Definition at line 48 of file pbx.h.

◆ AST_PBX_INCOMPLETE

#define AST_PBX_INCOMPLETE   12

Return to PBX matching, allowing more digits for the extension

Definition at line 51 of file pbx.h.

◆ AST_PBX_KEEP

#define AST_PBX_KEEP   0

Definition at line 43 of file pbx.h.

◆ AST_PBX_MAX_STACK

#define AST_PBX_MAX_STACK   512

Definition at line 1663 of file pbx.h.

◆ AST_PBX_OK

#define AST_PBX_OK   0

No errors

Definition at line 49 of file pbx.h.

◆ AST_PBX_REPLACE

#define AST_PBX_REPLACE   1

Definition at line 44 of file pbx.h.

◆ PRIORITY_HINT

#define PRIORITY_HINT   -1

Special Priority for a hint

Definition at line 54 of file pbx.h.

◆ STATUS_NO_CONTEXT

#define STATUS_NO_CONTEXT   1

Definition at line 1654 of file pbx.h.

◆ STATUS_NO_EXTENSION

#define STATUS_NO_EXTENSION   2

Definition at line 1655 of file pbx.h.

◆ STATUS_NO_LABEL

#define STATUS_NO_LABEL   4

Definition at line 1657 of file pbx.h.

◆ STATUS_NO_PRIORITY

#define STATUS_NO_PRIORITY   3

Definition at line 1656 of file pbx.h.

◆ STATUS_SUCCESS

#define STATUS_SUCCESS   5

Definition at line 1658 of file pbx.h.

Typedef Documentation

◆ ast_state_cb_destroy_type

typedef void(* ast_state_cb_destroy_type) (int id, void *data)

Typedef for devicestate and hint callback removal indication callback.

Definition at line 115 of file pbx.h.

◆ ast_state_cb_type

typedef int(* ast_state_cb_type) (const char *context, const char *exten, struct ast_state_cb_info *info, void *data)

Typedef for devicestate and hint callbacks.

Definition at line 112 of file pbx.h.

◆ ast_switch_f

typedef 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.

Data structure associated with an Asterisk switch

Definition at line 156 of file pbx.h.

Enumeration Type Documentation

◆ ast_custom_function_escalation

Description of the ways in which a function may escalate privileges.

Enumerator
AST_CFE_NONE 
AST_CFE_READ 
AST_CFE_WRITE 
AST_CFE_BOTH 

Definition at line 1548 of file pbx.h.

1548 {
1553};
@ AST_CFE_NONE
Definition: pbx.h:1549
@ AST_CFE_READ
Definition: pbx.h:1550
@ AST_CFE_WRITE
Definition: pbx.h:1551
@ AST_CFE_BOTH
Definition: pbx.h:1552

◆ ast_ext_matchcid_types

extension matchcid types

Note
matchcid in ast_exten retains 0/1, this adds 3rd state for functions to specify all
See also
ast_context_remove_extension_callerid
Enumerator
AST_EXT_MATCHCID_OFF 

Match only extensions with matchcid=0

AST_EXT_MATCHCID_ON 

Match only extensions with matchcid=1 AND cidmatch matches

AST_EXT_MATCHCID_ANY 

Match both - used only in functions manipulating ast_exten's

Definition at line 77 of file pbx.h.

77 {
78 AST_EXT_MATCHCID_OFF = 0, /*!< Match only extensions with matchcid=0 */
79 AST_EXT_MATCHCID_ON = 1, /*!< Match only extensions with matchcid=1 AND cidmatch matches */
80 AST_EXT_MATCHCID_ANY = 2, /*!< Match both - used only in functions manipulating ast_exten's */
81};
@ AST_EXT_MATCHCID_ON
Definition: pbx.h:79
@ AST_EXT_MATCHCID_OFF
Definition: pbx.h:78
@ AST_EXT_MATCHCID_ANY
Definition: pbx.h:80

◆ ast_extension_states

Extension states.

Note
States can be combined Extension and device states in Asterisk
Enumerator
AST_EXTENSION_REMOVED 

Extension removed

AST_EXTENSION_DEACTIVATED 

Extension hint removed

AST_EXTENSION_NOT_INUSE 

No device INUSE or BUSY

AST_EXTENSION_INUSE 

One or more devices INUSE

AST_EXTENSION_BUSY 

All devices BUSY

AST_EXTENSION_UNAVAILABLE 

All devices UNAVAILABLE/UNREGISTERED

AST_EXTENSION_RINGING 

All devices RINGING

AST_EXTENSION_ONHOLD 

All devices ONHOLD

AST_EXTENSION_REMOVED 

Extension removed

AST_EXTENSION_DEACTIVATED 

Extension hint removed

AST_EXTENSION_NOT_INUSE 

No device INUSE or BUSY

AST_EXTENSION_INUSE 

One or more devices INUSE

AST_EXTENSION_BUSY 

All devices BUSY

AST_EXTENSION_UNAVAILABLE 

All devices UNAVAILABLE/UNREGISTERED

AST_EXTENSION_RINGING 

All devices RINGING

AST_EXTENSION_ONHOLD 

All devices ONHOLD

Definition at line 61 of file pbx.h.

61 {
62 AST_EXTENSION_REMOVED = -2, /*!< Extension removed */
63 AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */
64 AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */
65 AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
66 AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */
67 AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
68 AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */
69 AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */
70};
@ AST_EXTENSION_REMOVED
Definition: pbx.h:62
@ AST_EXTENSION_RINGING
Definition: pbx.h:68
@ AST_EXTENSION_NOT_INUSE
Definition: pbx.h:64
@ AST_EXTENSION_INUSE
Definition: pbx.h:65
@ AST_EXTENSION_UNAVAILABLE
Definition: pbx.h:67
@ AST_EXTENSION_ONHOLD
Definition: pbx.h:69
@ AST_EXTENSION_BUSY
Definition: pbx.h:66
@ AST_EXTENSION_DEACTIVATED
Definition: pbx.h:63

◆ ast_pbx_outgoing_sync

Enumerator
AST_OUTGOING_NO_WAIT 

Don't wait for originated call to answer

AST_OUTGOING_WAIT 

Wait for originated call to answer

AST_OUTGOING_WAIT_COMPLETE 

Wait for originated call to answer and hangup

Definition at line 1139 of file pbx.h.

1139 {
1140 AST_OUTGOING_NO_WAIT = 0, /*!< Don't wait for originated call to answer */
1141 AST_OUTGOING_WAIT = 1, /*!< Wait for originated call to answer */
1142 AST_OUTGOING_WAIT_COMPLETE = 2, /*!< Wait for originated call to answer and hangup */
1143};
@ AST_OUTGOING_NO_WAIT
Definition: pbx.h:1140
@ AST_OUTGOING_WAIT
Definition: pbx.h:1141
@ AST_OUTGOING_WAIT_COMPLETE
Definition: pbx.h:1142

◆ ast_pbx_result

The result codes when starting the PBX on a channel with ast_pbx_start.

Note
AST_PBX_CALL_LIMIT refers to the maxcalls call limit in asterisk.conf
See also
ast_pbx_start
Enumerator
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 370 of file pbx.h.

370 {
371 AST_PBX_SUCCESS = 0,
372 AST_PBX_FAILED = -1,
374};
@ AST_PBX_FAILED
Definition: pbx.h:372
@ AST_PBX_CALL_LIMIT
Definition: pbx.h:373
@ AST_PBX_SUCCESS
Definition: pbx.h:371

◆ ast_state_cb_update_reason

Enumerator
AST_HINT_UPDATE_DEVICE 

The extension state update is a result of a device state changing on the extension.

AST_HINT_UPDATE_PRESENCE 

The extension state update is a result of presence state changing on the extension.

Definition at line 89 of file pbx.h.

89 {
90 /*! The extension state update is a result of a device state changing on the extension. */
92 /*! The extension state update is a result of presence state changing on the extension. */
94};
@ AST_HINT_UPDATE_DEVICE
Definition: pbx.h:91
@ AST_HINT_UPDATE_PRESENCE
Definition: pbx.h:93

◆ ext_match_t

When looking up extensions, we can have different requests identified by the 'action' argument, as follows.

Note
that the coding is such that the low 4 bits are the third argument to extension_match_core.
Enumerator
E_MATCHMORE 
E_CANMATCH 
E_MATCH 
E_MATCH_MASK 
E_SPAWN 
E_FINDLABEL 
E_MATCHMORE 
E_CANMATCH 
E_MATCH 
E_MATCH_MASK 
E_SPAWN 
E_FINDLABEL 

Definition at line 1645 of file pbx.h.

1645 {
1646 E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */
1647 E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */
1648 E_MATCH = 0x02, /* extension is an exact match */
1649 E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
1650 E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */
1651 E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */
1652};
@ E_MATCH_MASK
Definition: pbx.h:1649
@ E_MATCH
Definition: pbx.h:1648
@ E_CANMATCH
Definition: pbx.h:1647
@ E_FINDLABEL
Definition: pbx.h:1651
@ E_MATCHMORE
Definition: pbx.h:1646
@ E_SPAWN
Definition: pbx.h:1650

Function Documentation

◆ __ast_custom_function_register()

int __ast_custom_function_register ( struct ast_custom_function acf,
struct ast_module mod 
)

Register a custom function.

Definition at line 373 of file pbx_functions.c.

374{
375 struct ast_custom_function *cur;
376
377 if (!acf) {
378 return -1;
379 }
380
381 acf->mod = mod;
382#ifdef AST_XML_DOCS
383 acf->docsrc = AST_STATIC_DOC;
384#endif
385
386 if (acf_retrieve_docs(acf)) {
387 return -1;
388 }
389
391
393 if (cur) {
394 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
396 return -1;
397 }
398
399 /* Store in alphabetical order */
401 if (strcmp(acf->name, cur->name) < 0) {
403 break;
404 }
405 }
407 if (!cur) {
408 AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist);
409 }
410
412
413 ast_verb(5, "Registered custom function '" COLORIZE_FMT "'\n", COLORIZE(COLOR_BRCYAN, 0, acf->name));
414
415 return 0;
416}
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
#define ast_verb(level,...)
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:610
static struct ast_custom_function * ast_custom_function_find_nolock(const char *name)
static int acf_retrieve_docs(struct ast_custom_function *acf)
Registered functions container.
Definition: pbx_functions.c:59
Data structure associated with a custom dialplan function.
Definition: pbx.h:118
struct ast_module * mod
Definition: pbx.h:142
enum ast_doc_src docsrc
Definition: pbx.h:127
const char * name
Definition: pbx.h:119
#define COLOR_BRCYAN
Definition: term.h:63
#define COLORIZE(fg, bg, str)
Definition: term.h:72
#define COLORIZE_FMT
Shortcut macros for coloring a set of text.
Definition: term.h:71
@ AST_STATIC_DOC
Definition: xmldoc.h:32

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

Referenced by __ast_custom_function_register_escalating(), __init_manager(), ast_msg_init(), load_features_config(), and load_pbx().

◆ __ast_custom_function_register_escalating()

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 418 of file pbx_functions.c.

419{
420 int res;
421
422 res = __ast_custom_function_register(acf, mod);
423 if (res != 0) {
424 return -1;
425 }
426
427 switch (escalation) {
428 case AST_CFE_NONE:
429 break;
430 case AST_CFE_READ:
431 acf->read_escalates = 1;
432 break;
433 case AST_CFE_WRITE:
434 acf->write_escalates = 1;
435 break;
436 case AST_CFE_BOTH:
437 acf->read_escalates = 1;
438 acf->write_escalates = 1;
439 break;
440 }
441
442 return 0;
443}
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
Register a custom function.
unsigned int read_escalates
Definition: pbx.h:143
unsigned int write_escalates
Definition: pbx.h:147

References __ast_custom_function_register(), AST_CFE_BOTH, AST_CFE_NONE, AST_CFE_READ, AST_CFE_WRITE, ast_custom_function::mod, ast_custom_function::read_escalates, and ast_custom_function::write_escalates.

◆ ast_active_calls()

int ast_active_calls ( void  )

Retrieve the number of active calls.

Definition at line 4760 of file pbx.c.

4761{
4762 return countcalls;
4763}
static int countcalls
Definition: pbx.c:778

References countcalls.

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

◆ ast_add_extension()

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
datada pointer to a function that will deallocate data when needed or NULL if data does not need to be freed.
registrarwho registered the extension
Note
On any failure, the function pointed to by datap will be called and passed the data pointer.
Return values
0success
-1failure

Definition at line 6928 of file pbx.c.

6931{
6932 int ret = -1;
6933 struct ast_context *c;
6934
6936 if (c) {
6937 ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
6938 application, data, datad, registrar, NULL, 0);
6940 }
6941
6942 return ret;
6943}
static int priority
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:888
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, const char *registrar_file, int registrar_line)
Main interface to add extensions to the list for out context.
Definition: pbx.c:7257
static struct ast_context * find_context_locked(const char *context)
lookup for a context with a given name,
Definition: pbx.c:4814
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8473
static char * registrar
Definition: pbx_ael.c:78
#define NULL
Definition: resample.c:96
ast_context: An extension context
Definition: pbx.c:284
char data[]
Definition: pbx.c:304
structure to hold extensions
static struct test_val c

References ast_add_extension2(), ast_unlock_contexts(), c, voicemailpwcheck::context, ast_context::data, find_context_locked(), NULL, priority, registrar, and replace().

Referenced by add_to_regcontext(), app_create(), ast_hint_presence_state(), ast_sip_persistent_endpoint_update_state(), AST_TEST_DEFINE(), create_test_dialplan(), device_state_cb(), extension_state_add_destroy(), handle_cli_dialplan_add_extension(), internal_extension_state_extended(), join_conference_bridge(), load_module(), register_extension(), register_peer_exten(), sla_build_station(), and sla_build_trunk().

◆ ast_add_extension2()

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,
const char *  registrar_file,
int  registrar_line 
)

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

Parameters
concontext 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
datada pointer to a function that will deallocate data when needed or NULL if data does not need to be freed.
registrarwho registered the extension
registrar_fileoptional configuration file that defines this extension
registrar_lineoptional line number of configuration file that defines extension
Note
On any failure, the function pointed to by datap will be called and passed the data pointer.
Return values
0success
-1failure

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 7257 of file pbx.c.

7261{
7262 return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid,
7263 application, data, datad, registrar, registrar_file, registrar_line, 1);
7264}
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, const char *registrar_file, int registrar_line, int lock_context)
Same as ast_add_extension2() but controls the context locking.
Definition: pbx.c:7283

References ast_add_extension2_lockopt(), priority, registrar, and replace().

Referenced by add_extensions(), ast_add_extension(), context_merge(), lua_register_hints(), manager_dialplan_extension_add(), pbx_load_config(), and pbx_load_users().

◆ ast_add_extension2_nolock()

int ast_add_extension2_nolock ( 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,
const char *  registrar_file,
int  registrar_line 
)

Same as ast_add_extension2, but assumes you have already locked context.

Since
12.0.0
Note
con must be write locked prior to calling. For details about the arguments, check ast_add_extension()

Definition at line 7266 of file pbx.c.

7270{
7271 return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid,
7272 application, data, datad, registrar, registrar_file, registrar_line, 0);
7273}

References ast_add_extension2_lockopt(), priority, registrar, and replace().

Referenced by add_extension(), parking_add_extension(), and parking_duration_callback().

◆ ast_async_goto()

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 6969 of file pbx.c.

6970{
6971 struct ast_channel *newchan;
6972
6973 ast_channel_lock(chan);
6974 /* Channels in a bridge or running a PBX can be sent directly to the specified destination */
6975 if (ast_channel_is_bridged(chan) || ast_channel_pbx(chan)) {
6977 priority += 1;
6978 }
6981 ast_channel_unlock(chan);
6982 return 0;
6983 }
6984 ast_channel_unlock(chan);
6985
6986 /* Otherwise, we need to gain control of the channel first */
6987 newchan = ast_channel_yank(chan);
6988 if (!newchan) {
6989 ast_log(LOG_WARNING, "Unable to gain control of channel %s\n", ast_channel_name(chan));
6990 return -1;
6991 }
6993 if (ast_pbx_start(newchan)) {
6994 ast_hangup(newchan);
6995 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(newchan));
6996 return -1;
6997 }
6998
6999 return 0;
7000}
const char * ast_channel_name(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
#define ast_channel_lock(chan)
Definition: channel.h:2922
struct ast_channel * ast_channel_yank(struct ast_channel *yankee)
Gain control of a channel in the system.
Definition: channel.c:10593
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10545
@ AST_SOFTHANGUP_ASYNCGOTO
Definition: channel.h:1126
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2458
@ AST_FLAG_IN_AUTOLOOP
Definition: channel.h:997
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
#define LOG_WARNING
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4708
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:6945
Main Channel structure associated with a channel.
char exten[AST_MAX_EXTENSION]
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ast_channel_flags(), ast_channel_is_bridged(), ast_channel_lock, ast_channel_name(), ast_channel_pbx(), ast_channel_unlock, ast_channel_yank(), ast_explicit_goto(), AST_FLAG_IN_AUTOLOOP, ast_hangup(), ast_log, ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_test_flag, voicemailpwcheck::context, ast_channel::exten, LOG_WARNING, and priority.

Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), bridge_channel_blind_transfer(), chan_pjsip_cng_tone_detected(), comeback_goto(), dahdi_handle_dtmf(), fax_detect_framehook(), my_handle_dtmf(), onModeChanged(), ooh323_rtp_read(), and pbx_parseable_goto().

◆ ast_async_goto_by_name()

int ast_async_goto_by_name ( const char *  chan,
const char *  context,
const char *  exten,
int  priority 
)

Set the channel to next execute the specified dialplan location.

Definition at line 7002 of file pbx.c.

7003{
7004 struct ast_channel *chan;
7005 int res = -1;
7006
7007 if ((chan = ast_channel_get_by_name(channame))) {
7008 res = ast_async_goto(chan, context, exten, priority);
7009 chan = ast_channel_unref(chan);
7010 }
7011
7012 return res;
7013}
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
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:6969

References ast_async_goto(), ast_channel_get_by_name(), ast_channel_unref, voicemailpwcheck::context, ast_channel::exten, and priority.

◆ ast_async_goto_if_exists()

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 8786 of file pbx.c.

8787{
8788 return __ast_goto_if_exists(chan, context, exten, priority, 1);
8789}
static int __ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, int async)
Definition: pbx.c:8760

References __ast_goto_if_exists(), voicemailpwcheck::context, ast_channel::exten, and priority.

◆ ast_async_parseable_goto()

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 8871 of file pbx.c.

8872{
8873 return pbx_parseable_goto(chan, goto_string, 1);
8874}
static int pbx_parseable_goto(struct ast_channel *chan, const char *goto_string, int async)
Definition: pbx.c:8832

References pbx_parseable_goto().

Referenced by asyncgoto_exec(), detect_callback(), handle_redirect(), and parking_duration_callback().

◆ ast_build_timing()

int ast_build_timing ( struct ast_timing i,
const char *  info_in 
)

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

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

Definition at line 3806 of file extconf.c.

3807{
3808 char *info;
3809 int j, num_fields, last_sep = -1;
3810
3811 i->timezone = NULL;
3812
3813 /* Check for empty just in case */
3814 if (ast_strlen_zero(info_in)) {
3815 return 0;
3816 }
3817
3818 /* make a copy just in case we were passed a static string */
3819 info = ast_strdupa(info_in);
3820
3821 /* count the number of fields in the timespec */
3822 for (j = 0, num_fields = 1; info[j] != '\0'; j++) {
3823 if (info[j] == '|' || info[j] == ',') {
3824 last_sep = j;
3825 num_fields++;
3826 }
3827 }
3828
3829 /* save the timezone, if it is specified */
3830 if (num_fields == 5) {
3831 i->timezone = ast_strdup(info + last_sep + 1);
3832 }
3833
3834 /* Assume everything except time */
3835 i->monthmask = 0xfff; /* 12 bits */
3836 i->daymask = 0x7fffffffU; /* 31 bits */
3837 i->dowmask = 0x7f; /* 7 bits */
3838 /* on each call, use strsep() to move info to the next argument */
3839 get_timerange(i, strsep(&info, "|,"));
3840 if (info)
3841 i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
3842 if (info)
3843 i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
3844 if (info)
3845 i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
3846 return 1;
3847}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
char * days[]
Definition: extconf.c:3775
static void get_timerange(struct ast_timing *i, char *times)
store a bitmask of valid times, one bit each 2 minute
Definition: extconf.c:2682
static unsigned get_range(char *src, int max, char *const names[], const char *msg)
helper function to return a range up to max (7, 12, 31 respectively). names, if supplied,...
Definition: extconf.c:2638
char * months[]
Definition: extconf.c:3787
static force_inline int ast_strlen_zero(const char *s)
Definition: extconf.c:952
char * strsep(char **str, const char *delims)
def info(msg)
unsigned int monthmask
Definition: pbx.h:173
unsigned int daymask
Definition: pbx.h:174
char * timezone
Definition: pbx.h:177
unsigned int dowmask
Definition: pbx.h:175

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

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

◆ ast_canmatch_extension()

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 search 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 4190 of file pbx.c.

4191{
4192 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
4193}
@ E_CANMATCH
Definition: extconf.h:216
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:2875

References c, voicemailpwcheck::context, E_CANMATCH, ast_exten::exten, NULL, pbx_extension_helper(), and priority.

Referenced by __analog_ss_thread(), analog_ss_thread(), background_detect_exec(), dp_lookup(), dundi_lookup_local(), get_destination(), leave_voicemail(), loopback_canmatch(), pbx_builtin_background(), test_exten(), and valid_exit().

◆ ast_check_timing()

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
1if the time matches.
0if the current time falls outside of the specified range.

Definition at line 4000 of file extconf.c.

4001{
4002 /* sorry, but this feature will NOT be available
4003 in the standalone version */
4004 return 0;
4005}

References ast_check_timing2(), and ast_tvnow().

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

◆ ast_check_timing2()

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
1if the time matches.
0if the time falls outside of the specified range.

Definition at line 245 of file pbx_timing.c.

246{
247 struct ast_tm tm;
248
249 ast_localtime(&tv, &tm, i->timezone);
250
251 /* If it's not the right month, return */
252 if (!(i->monthmask & (1 << tm.tm_mon)))
253 return 0;
254
255 /* If it's not that time of the month.... */
256 /* Warning, tm_mday has range 1..31! */
257 if (!(i->daymask & (1 << (tm.tm_mday-1))))
258 return 0;
259
260 /* If it's not the right day of the week */
261 if (!(i->dowmask & (1 << tm.tm_wday)))
262 return 0;
263
264 /* Sanity check the hour just to be safe */
265 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
266 ast_log(LOG_WARNING, "Insane time...\n");
267 return 0;
268 }
269
270 /* Now the tough part, we calculate if it fits
271 in the right time based on min/hour */
272 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))))
273 return 0;
274
275 /* If we got this far, then we're good */
276 return 1;
277}
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:1739
unsigned int minmask[48]
Definition: pbx.h:176

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().

◆ ast_complete_applications()

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 429 of file pbx_app.c.

430{
431 struct ast_app *app;
432 int which = 0;
433 int cmp;
434 char *ret = NULL;
435 size_t wordlen = strlen(word);
436
438 AST_RWLIST_TRAVERSE(&apps, app, list) {
439 cmp = strncasecmp(word, app->name, wordlen);
440 if (cmp < 0) {
441 /* No more matches. */
442 break;
443 } else if (!cmp) {
444 /* Found match. */
445 if (state != -1) {
446 if (++which <= state) {
447 /* Not enough matches. */
448 continue;
449 }
450 ret = ast_strdup(app->name);
451 break;
452 }
454 break;
455 }
456 }
457 }
459
460 return ret;
461}
static const char app[]
Definition: app_adsiprog.c:56
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2756
short word
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
Registered applications container.
Definition: pbx_app.c:67
ast_app: A registered application
Definition: pbx_app.c:45

References app, ast_cli_completion_add(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, and NULL.

Referenced by handle_orig(), and handle_show_application().

◆ ast_context_add_ignorepat()

int ast_context_add_ignorepat ( const char *  context,
const char *  ignorepat,
const char *  registrar 
)

Add an ignorepat.

Parameters
contextwhich context to add the ignorepattern 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 6835 of file pbx.c.

6836{
6837 int ret = -1;
6838 struct ast_context *c;
6839
6841 if (c) {
6844 }
6845 return ret;
6846}
int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
Definition: pbx.c:6848
int value
Definition: syslog.c:37

References ast_context_add_ignorepat2(), ast_unlock_contexts(), c, voicemailpwcheck::context, find_context_locked(), registrar, and value.

Referenced by handle_cli_dialplan_add_ignorepat().

◆ ast_context_add_ignorepat2()

static int ast_context_add_ignorepat2 ( struct ast_context con,
const char *  ignorepat,
const char *  registrar 
)

Definition at line 348 of file ael_main.c.

349{
350 if(!no_comp)
351 printf("Executed ast_context_add_ignorepat2(con, value=%s, registrar=%s);\n", value, registrar);
352 if( dump_extensions ) {
353 struct namelist *x;
354 x = create_name(value);
355 ADD_LAST(con->ignorepats,x);
356 }
357}
struct namelist * create_name(const char *name)
Definition: ael_main.c:79
#define ADD_LAST(headptr, memptr)
Definition: ael_main.c:64
static int no_comp
Definition: ael_main.c:124
static int dump_extensions
Definition: ael_main.c:126
struct ast_ignorepats ignorepats
Definition: pbx.c:294

References ADD_LAST, ast_context_ignorepats_count(), ast_context_ignorepats_get(), ast_get_ignorepat_name(), ast_unlock_context(), AST_VECTOR_APPEND, ast_wrlock_context(), create_name(), dump_extensions, errno, ignorepat_alloc(), ignorepat_free(), ast_context::ignorepats, no_comp, registrar, and value.

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

◆ ast_context_add_include()

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 6664 of file pbx.c.

6665{
6666 int ret = -1;
6667 struct ast_context *c;
6668
6670 if (c) {
6671 ret = ast_context_add_include2(c, include, registrar);
6673 }
6674 return ret;
6675}
int ast_context_add_include2(struct ast_context *con, const char *value, const char *registrar)
Add a context include.
Definition: pbx.c:6684

References ast_context_add_include2(), ast_unlock_contexts(), c, voicemailpwcheck::context, find_context_locked(), and registrar.

Referenced by AST_TEST_DEFINE(), and handle_cli_dialplan_add_include().

◆ ast_context_add_include2()

static int ast_context_add_include2 ( struct ast_context con,
const char *  value,
const char *  registrar 
)

Add a context include.

Adds an include taking a struct ast_context as the first parameter

Note
See ast_context_add_include for information on arguments

Definition at line 359 of file ael_main.c.

360{
361 if(!no_comp)
362 printf("Executed ast_context_add_include2(con, value=%s, registrar=%s);\n", value, registrar);
363 if( dump_extensions ) {
364 struct namelist *x;
365 x = create_name((char*)value);
366 ADD_LAST(con->includes,x);
367 }
368}
struct ast_includes includes
Definition: pbx.c:293

References ADD_LAST, ast_context_includes_count(), ast_context_includes_get(), ast_debug, ast_get_context_name(), ast_get_include_name(), ast_unlock_context(), AST_VECTOR_APPEND, ast_wrlock_context(), create_name(), dump_extensions, errno, include_alloc(), include_free(), ast_context::includes, no_comp, registrar, and value.

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

◆ ast_context_add_switch()

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 6729 of file pbx.c.

6730{
6731 int ret = -1;
6732 struct ast_context *c;
6733
6735 if (c) { /* found, add switch to this context */
6736 ret = ast_context_add_switch2(c, sw, data, eval, registrar);
6738 }
6739 return ret;
6740}
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)
Definition: pbx.c:6749

References ast_context_add_switch2(), ast_unlock_contexts(), c, voicemailpwcheck::context, ast_context::data, find_context_locked(), and registrar.

◆ ast_context_add_switch2()

static 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 370 of file ael_main.c.

371{
372 if(!no_comp)
373 printf("Executed ast_context_add_switch2(con, value=%s, data=%s, eval=%d, registrar=%s);\n", value, data, eval, registrar);
374 if( dump_extensions ) {
375 struct namelist *x;
376 x = create_name((char*)value);
377 strncpy(x->name2, data, 99);
378 if( eval ) {
379
380 ADD_LAST(con->switches,x);
381
382 } else {
383
384 ADD_LAST(con->eswitches,x);
385 }
386 }
387}
struct namelist * switches
Definition: ael_main.c:53
struct namelist * eswitches
Definition: ael_main.c:54
char name2[100]
Definition: ael_main.c:42

References ADD_LAST, ast_context::alts, ast_context_switches_count(), ast_context_switches_get(), ast_get_context_name(), ast_get_switch_data(), ast_get_switch_name(), ast_unlock_context(), AST_VECTOR_APPEND, ast_verb, ast_wrlock_context(), create_name(), ast_sw::data, dump_extensions, errno, ast_context::eswitches, ast_sw::eval, namelist::name2, no_comp, registrar, sw_alloc(), sw_free(), ast_context::switches, and value.

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

◆ ast_context_destroy()

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.

Definition at line 8221 of file pbx.c.

8222{
8226}
void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *contexttab, struct ast_context *con, const char *registrar)
Definition: pbx.c:8056
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:8463
static struct ast_hashtab * contexts_table
Definition: pbx.c:782
static struct ast_context * contexts
Definition: pbx.c:781

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

Referenced by ast_context_destroy_by_name(), AST_TEST_DEFINE(), parking_lot_cfg_remove_extensions(), remove_all_configured_parking_lot_extensions(), remove_pending_parking_lot_extensions(), sla_destroy(), and unload_module().

◆ ast_context_destroy_by_name()

int ast_context_destroy_by_name ( const char *  context,
const char *  registrar 
)

Destroy a context by name.

Parameters
contextName of the context to destroy
registrarwho registered it

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

Return values
-1context not found
0Success

Definition at line 8205 of file pbx.c.

8206{
8207 struct ast_context *con;
8208 int ret = -1;
8209
8212 if (con) {
8214 ret = 0;
8215 }
8217
8218 return ret;
8219}
struct ast_context * ast_context_find(const char *name)
Find a context.
Definition: pbx.c:2439
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
Definition: pbx.c:8221

References ast_context_destroy(), ast_context_find(), ast_unlock_contexts(), ast_wrlock_contexts(), voicemailpwcheck::context, and registrar.

Referenced by __unload_module(), app_dtor(), ast_sip_destroy_sorcery_global(), check_regcontext(), and handle_cli_dialplan_remove_context().

◆ ast_context_find()

static 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 4172 of file extconf.c.

4173{
4174 struct ast_context *tmp = NULL;
4175 while ( (tmp = ast_walk_contexts(tmp)) ) {
4176 if (!name || !strcasecmp(name, tmp->name))
4177 break;
4178 }
4179 return tmp;
4180}
static int tmp()
Definition: bt_open.c:389
static struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: extconf.c:4024
static const char name[]
Definition: format_mp3.c:68

References ast_hashtab_lookup(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, item, name, aco_type::name, NULL, and tmp().

Referenced by app_create(), ast_context_destroy_by_name(), ast_context_verify_includes(), ast_ignore_pattern(), context_included(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_add_include(), and isexten_function_read().

◆ ast_context_find_or_create()

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 6149 of file pbx.c.

6150{
6151 struct ast_context *tmp, **local_contexts;
6152 struct ast_context search = {
6153 .name = name,
6154 };
6155 size_t name_bytes = strlen(name);
6156 size_t registrar_bytes = strlen(registrar);
6157 int length = sizeof(struct ast_context) + name_bytes + registrar_bytes + 2;
6158
6159 if (!contexts_table) {
6160 /* Protect creation of contexts_table from reentrancy. */
6162 if (!contexts_table) {
6168 0);
6169 }
6171 }
6172
6173 if (!extcontexts) {
6177 if (tmp) {
6178 tmp->refcount++;
6180 return tmp;
6181 }
6182 } else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */
6183 local_contexts = extcontexts;
6184 tmp = ast_hashtab_lookup(exttable, &search);
6185 if (tmp) {
6186 tmp->refcount++;
6187 return tmp;
6188 }
6189 }
6190
6191 if ((tmp = ast_calloc(1, length))) {
6192 ast_rwlock_init(&tmp->lock);
6193 tmp->name = memcpy(&tmp->data[0], name, name_bytes);
6194 tmp->registrar = memcpy(&tmp->data[name_bytes + 1], registrar, registrar_bytes);
6195 tmp->root = NULL;
6196 tmp->root_table = NULL;
6197 AST_VECTOR_INIT(&tmp->includes, 0);
6198 AST_VECTOR_INIT(&tmp->ignorepats, 0);
6199 AST_VECTOR_INIT(&tmp->alts, 0);
6200 tmp->refcount = 1;
6201
6202 /* The context 'name' must be stored at the beginning of 'data.' The
6203 * order of subsequent strings (currently only 'registrar') is not
6204 * relevant. */
6205 ast_assert(tmp->name == &tmp->data[0]);
6206 } else {
6207 ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
6208 if (!extcontexts) {
6210 }
6211 return NULL;
6212 }
6213
6214 if (!extcontexts) {
6215 tmp->next = *local_contexts;
6217 ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */
6219 } else {
6220 tmp->next = *local_contexts;
6221 if (exttable)
6222 ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */
6223
6225 }
6226 ast_debug(1, "Registered extension context '%s'; registrar: %s\n", tmp->name, registrar);
6227 return tmp;
6228}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_hashtab_insert_safe(tab, obj)
Definition: hashtab.h:316
int ast_hashtab_newsize_java(struct ast_hashtab *tab)
Create a prime number roughly 2x the current table size.
Definition: hashtab.c:127
#define ast_hashtab_insert_immediate(tab, obj)
Insert without checking.
Definition: hashtab.h:290
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
Lookup this object in the hash table.
Definition: hashtab.c:486
#define ast_hashtab_create(initial_buckets, compare, resize, newsize, hash, do_locking)
Create the hashtable list.
Definition: hashtab.h:254
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:84
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
Definition: lock.h:224
int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
hashtable functions for contexts
Definition: pbx.c:688
unsigned int ast_hashtab_hash_contexts(const void *obj)
Definition: pbx.c:740
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:8468
static struct ast_context * local_contexts
Definition: pbx_config.c:113
const char * name
Definition: pbx.c:285
#define ast_assert(a)
Definition: utils.h:739
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113

References ast_assert, ast_calloc, 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_rdlock_contexts(), ast_rwlock_init, ast_unlock_contexts(), AST_VECTOR_INIT, ast_wrlock_contexts(), contexts, contexts_table, local_contexts, LOG_ERROR, name, ast_context::name, NULL, registrar, and tmp().

Referenced by add_hints(), app_create(), ast_compile_ael2(), ast_sip_persistent_endpoint_add_to_regcontext(), AST_TEST_DEFINE(), context_merge(), create_test_dialplan(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_add_include(), load_module(), lua_register_hints(), lua_register_switches(), manager_dialplan_extension_add(), parking_duration_callback(), parking_lot_cfg_create_extensions(), pbx_load_config(), pbx_load_users(), set_config(), sla_build_station(), and sla_build_trunk().

◆ ast_context_ignorepats_count()

int ast_context_ignorepats_count ( const struct ast_context con)

◆ ast_context_ignorepats_get()

const struct ast_ignorepat * ast_context_ignorepats_get ( const struct ast_context con,
int  idx 
)

◆ ast_context_includes_count()

int ast_context_includes_count ( const struct ast_context con)

◆ ast_context_includes_get()

const struct ast_include * ast_context_includes_get ( const struct ast_context con,
int  idx 
)

◆ ast_context_remove_extension()

int ast_context_remove_extension ( const char *  context,
const char *  extension,
int  priority,
const char *  registrar 
)

Simply remove extension from context.

Parameters
contextcontext to remove extension from
extensionwhich extension to remove
prioritypriority of extension to remove (0 to remove all)
registrarregistrar of the extension

This function removes an extension from a given context.

Return values
0on success
-1on failure
Note
This function will lock conlock.

Definition at line 4948 of file pbx.c.

4949{
4951}
int ast_context_remove_extension_callerid(const char *context, const char *extension, int priority, const char *callerid, int matchcallerid, const char *registrar)
Definition: pbx.c:4953

References ast_context_remove_extension_callerid(), AST_EXT_MATCHCID_ANY, voicemailpwcheck::context, NULL, priority, and registrar.

Referenced by ast_sip_persistent_endpoint_update_state(), AST_TEST_DEFINE(), conf_ended(), delete_extens(), register_peer_exten(), sla_station_destructor(), sla_trunk_destructor(), and unregister_extension().

◆ ast_context_remove_extension2()

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 4978 of file pbx.c.

4979{
4981}
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: pbx.c:4983

References ast_context_remove_extension_callerid2(), AST_EXT_MATCHCID_ANY, NULL, priority, and registrar.

Referenced by add_extension(), and add_hints().

◆ ast_context_remove_extension_callerid()

int ast_context_remove_extension_callerid ( const char *  context,
const char *  extension,
int  priority,
const char *  callerid,
int  matchcid,
const char *  registrar 
)

Definition at line 4953 of file pbx.c.

4954{
4955 int ret = -1; /* default error return */
4956 struct ast_context *c;
4957
4959 if (c) { /* ... remove extension ... */
4961 matchcallerid, registrar, 0);
4963 }
4964
4965 return ret;
4966}

References ast_context_remove_extension_callerid2(), ast_unlock_contexts(), c, voicemailpwcheck::context, find_context_locked(), priority, and registrar.

Referenced by ast_context_remove_extension(), handle_cli_dialplan_remove_extension(), and manager_dialplan_extension_remove().

◆ ast_context_remove_extension_callerid2()

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 at line 4983 of file pbx.c.

4984{
4985 struct ast_exten *exten, *prev_exten = NULL;
4986 struct ast_exten *peer;
4987 struct ast_exten ex, *exten2, *exten3;
4988 char dummy_name[1024];
4989 char dummy_cid[1024];
4990 struct ast_exten *previous_peer = NULL;
4991 struct ast_exten *next_peer = NULL;
4992 int found = 0;
4993
4994 if (!already_locked)
4995 ast_wrlock_context(con);
4996
4997#ifdef NEED_DEBUG
4998 ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcallerid ? "/" : "", matchcallerid ? callerid : "", registrar);
4999#endif
5000#ifdef CONTEXT_DEBUG
5001 check_contexts(__FILE__, __LINE__);
5002#endif
5003 /* find this particular extension */
5004 ex.exten = dummy_name;
5005 ext_strncpy(dummy_name, extension, sizeof(dummy_name), 1);
5006 ex.matchcid = matchcallerid;
5007 if (callerid) {
5008 ex.cidmatch = dummy_cid;
5009 ext_strncpy(dummy_cid, callerid, sizeof(dummy_cid), 1);
5010 } else {
5011 ex.cidmatch = NULL;
5012 }
5013 exten = ast_hashtab_lookup(con->root_table, &ex);
5014 if (exten) {
5015 if (priority == 0) {
5017 if (!exten2)
5018 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);
5019 if (con->pattern_tree) {
5020 struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
5021
5022 if (x->exten) { /* this test for safety purposes */
5023 x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
5024 x->exten = 0; /* get rid of what will become a bad pointer */
5025 } else {
5026 ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n");
5027 }
5028 }
5029 } else {
5030 ex.priority = priority;
5031 exten2 = ast_hashtab_lookup(exten->peer_table, &ex);
5032 if (exten2) {
5033 if (exten2->label) { /* if this exten has a label, remove that, too */
5035 if (!exten3) {
5036 ast_log(LOG_ERROR, "Did not remove this priority label (%d/%s) "
5037 "from the peer_label_table of context %s, extension %s!\n",
5038 priority, exten2->label, con->name, exten2->name);
5039 }
5040 }
5041
5043 if (!exten3) {
5044 ast_log(LOG_ERROR, "Did not remove this priority (%d) from the "
5045 "peer_table of context %s, extension %s!\n",
5046 priority, con->name, exten2->name);
5047 }
5048 if (exten2 == exten && exten2->peer) {
5051 }
5052 if (ast_hashtab_size(exten->peer_table) == 0) {
5053 /* well, if the last priority of an exten is to be removed,
5054 then, the extension is removed, too! */
5056 if (!exten3) {
5057 ast_log(LOG_ERROR, "Did not remove this exten (%s) from the "
5058 "context root_table (%s) (priority %d)\n",
5059 exten->name, con->name, priority);
5060 }
5061 if (con->pattern_tree) {
5062 struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
5063 if (x->exten) { /* this test for safety purposes */
5064 x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
5065 x->exten = 0; /* get rid of what will become a bad pointer */
5066 }
5067 }
5068 }
5069 } else {
5070 ast_debug(3,"Could not find priority %d of exten %s in context %s!\n",
5071 priority, exten->name, con->name);
5072 }
5073 }
5074 } else {
5075 /* hmmm? this exten is not in this pattern tree? */
5076 ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n",
5077 extension, con->name);
5078 }
5079#ifdef NEED_DEBUG
5080 if (con->pattern_tree) {
5081 ast_log(LOG_NOTICE,"match char tree after exten removal:\n");
5082 log_match_char_tree(con->pattern_tree, " ");
5083 }
5084#endif
5085
5086 /* scan the extension list to find first matching extension-registrar */
5087 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
5088 if (!strcmp(exten->exten, ex.exten) &&
5089 (!matchcallerid ||
5090 (!ast_strlen_zero(ex.cidmatch) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, ex.cidmatch)) ||
5091 (ast_strlen_zero(ex.cidmatch) && ast_strlen_zero(exten->cidmatch)))) {
5092 break;
5093 }
5094 }
5095 if (!exten) {
5096 /* we can't find right extension */
5097 if (!already_locked)
5098 ast_unlock_context(con);
5099 return -1;
5100 }
5101
5102 /* scan the priority list to remove extension with exten->priority == priority */
5103 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
5104 peer && !strcmp(peer->exten, ex.exten) &&
5105 (!callerid || (!matchcallerid && !peer->matchcid) || (matchcallerid && peer->matchcid && !strcmp(peer->cidmatch, ex.cidmatch))) ;
5106 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
5107
5108 if ((priority == 0 || peer->priority == priority) &&
5109 (!registrar || !strcmp(peer->registrar, registrar) )) {
5110 found = 1;
5111
5112 /* we are first priority extension? */
5113 if (!previous_peer) {
5114 /*
5115 * We are first in the priority chain, so must update the extension chain.
5116 * The next node is either the next priority or the next extension
5117 */
5118 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
5119 if (peer->peer) {
5120 /* move the peer_table and peer_label_table down to the next peer, if
5121 it is there */
5124 peer->peer_table = NULL;
5126 }
5127 if (!prev_exten) { /* change the root... */
5128 con->root = next_node;
5129 } else {
5130 prev_exten->next = next_node; /* unlink */
5131 }
5132 if (peer->peer) { /* update the new head of the pri list */
5133 peer->peer->next = peer->next;
5134 }
5135 } else { /* easy, we are not first priority in extension */
5136 previous_peer->peer = peer->peer;
5137 }
5138
5139
5140 /* now, free whole priority extension */
5142 } else {
5143 previous_peer = peer;
5144 }
5145 }
5146 if (!already_locked)
5147 ast_unlock_context(con);
5148 return found ? 0 : -1;
5149}
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:789
int ast_hashtab_size(struct ast_hashtab *tab)
Returns the number of elements stored in the hashtab.
Definition: hashtab.c:577
#define LOG_NOTICE
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:8481
static unsigned int ext_strncpy(char *dst, const char *src, size_t dst_size, int nofluff)
Definition: pbx.c:7026
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8491
static struct match_char * add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly)
Definition: pbx.c:1663
static void destroy_exten(struct ast_exten *e)
Definition: pbx.c:4674
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
struct ast_exten * root
Definition: pbx.c:289
struct match_char * pattern_tree
Definition: pbx.c:291
struct ast_hashtab * root_table
Definition: pbx.c:290
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
Definition: pbx.c:237
char * exten
Definition: pbx.c:238
struct ast_hashtab * peer_label_table
Definition: pbx.c:252
struct ast_hashtab * peer_table
Definition: pbx.c:251
char * name
Definition: pbx.c:239
const char * registrar
Definition: pbx.c:253
const char * cidmatch
Definition: pbx.c:241
struct ast_exten * peer
Definition: pbx.c:250
struct ast_exten * next
Definition: pbx.c:256
int priority
Definition: pbx.c:243
const char * label
Definition: pbx.c:244
int matchcid
Definition: pbx.c:240
match_char: forms a syntax tree for quick matching of extension patterns
Definition: pbx.c:262
char x[1]
Definition: pbx.c:269
struct ast_exten * exten
Definition: pbx.c:268

References add_exten_to_pattern_tree(), ast_debug, 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, destroy_exten(), ext_strncpy(), ast_exten::exten, match_char::exten, ast_exten::label, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_exten::matchcid, ast_exten::name, ast_context::name, ast_exten::next, NULL, ast_context::pattern_tree, ast_exten::peer, ast_exten::peer_label_table, ast_exten::peer_table, priority, ast_exten::priority, ast_exten::registrar, 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().

◆ ast_context_remove_ignorepat()

int ast_context_remove_ignorepat ( const char *  context,
const char *  ignorepat,
const char *  registrar 
)

Remove an ignorepat.

Parameters
contextcontext from which to remove the pattern
ignorepatthe pattern to remove
registrarthe registrar of the ignore pattern

This removes the given ignorepattern

Return values
0on success
-1on failure

Definition at line 6795 of file pbx.c.

6796{
6797 int ret = -1;
6798 struct ast_context *c;
6799
6801 if (c) {
6802 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
6804 }
6805 return ret;
6806}
int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
Definition: pbx.c:6808

References ast_context_remove_ignorepat2(), ast_unlock_contexts(), c, voicemailpwcheck::context, find_context_locked(), and registrar.

Referenced by handle_cli_dialplan_remove_ignorepat().

◆ ast_context_remove_ignorepat2()

int ast_context_remove_ignorepat2 ( struct ast_context con,
const char *  ignorepat,
const char *  registrar 
)

Definition at line 6808 of file pbx.c.

6809{
6810 int idx;
6811
6812 ast_wrlock_context(con);
6813
6814 for (idx = 0; idx < ast_context_ignorepats_count(con); idx++) {
6815 struct ast_ignorepat *ip = AST_VECTOR_GET(&con->ignorepats, idx);
6816
6817 if (!strcmp(ast_get_ignorepat_name(ip), ignorepat) &&
6820 ignorepat_free(ip);
6821 ast_unlock_context(con);
6822 return 0;
6823 }
6824 }
6825
6826 ast_unlock_context(con);
6827 errno = EINVAL;
6828 return -1;
6829}
int errno
int ast_context_ignorepats_count(const struct ast_context *con)
Definition: pbx.c:8722
const char * ast_get_ignorepat_registrar(const struct ast_ignorepat *ip)
Definition: pbx_ignorepat.c:47
const char * ast_get_ignorepat_name(const struct ast_ignorepat *ip)
Definition: pbx_ignorepat.c:42
void ignorepat_free(struct ast_ignorepat *ip)
Definition: pbx_ignorepat.c:77
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx_ignorepat.c:37
#define AST_VECTOR_REMOVE_ORDERED(vec, idx)
Remove an element from a vector by index while maintaining order.
Definition: vector.h:448

References ast_context_ignorepats_count(), ast_get_ignorepat_name(), ast_get_ignorepat_registrar(), ast_unlock_context(), AST_VECTOR_GET, AST_VECTOR_REMOVE_ORDERED, ast_wrlock_context(), errno, ignorepat_free(), ast_context::ignorepats, and registrar.

Referenced by ast_context_remove_ignorepat().

◆ ast_context_remove_include()

int ast_context_remove_include ( const char *  context,
const char *  include,
const char *  registrar 
)

Remove a context include.

Note
See ast_context_add_include for information on arguments

Remove a context include.

Definition at line 4836 of file pbx.c.

4837{
4838 int ret = -1;
4839 struct ast_context *c;
4840
4842 if (c) {
4843 /* found, remove include from this context ... */
4844 ret = ast_context_remove_include2(c, include, registrar);
4846 }
4847 return ret;
4848}
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,...
Definition: pbx.c:4859

References ast_context_remove_include2(), ast_unlock_contexts(), c, voicemailpwcheck::context, find_context_locked(), and registrar.

Referenced by handle_cli_dialplan_remove_include().

◆ ast_context_remove_include2()

int ast_context_remove_include2 ( struct ast_context con,
const char *  include,
const char *  registrar 
)

Removes an include by an ast_context structure.

Note
See ast_context_add_include for information on arguments

Removes an include by an ast_context structure.

Return values
0on success.
-1on failure.

Definition at line 4859 of file pbx.c.

4860{
4861 int ret = -1;
4862 int idx;
4863
4864 ast_wrlock_context(con);
4865
4866 /* find our include */
4867 for (idx = 0; idx < ast_context_includes_count(con); idx++) {
4868 struct ast_include *i = AST_VECTOR_GET(&con->includes, idx);
4869
4870 if (!strcmp(ast_get_include_name(i), include) &&
4871 (!registrar || !strcmp(ast_get_include_registrar(i), registrar))) {
4872
4873 /* remove from list */
4874 ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar);
4876
4877 /* free include and return */
4878 include_free(i);
4879 ret = 0;
4880 break;
4881 }
4882 }
4883
4884 ast_unlock_context(con);
4885
4886 return ret;
4887}
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:8499
int ast_context_includes_count(const struct ast_context *con)
Definition: pbx.c:8679
const char * ast_get_include_name(const struct ast_include *include)
Definition: pbx_include.c:50
const char * ast_get_include_registrar(const struct ast_include *i)
Definition: pbx_include.c:60
void include_free(struct ast_include *inc)
Definition: pbx_include.c:106
ast_include: include= support in extensions.conf
Definition: pbx_include.c:37

References ast_context_includes_count(), ast_get_context_name(), ast_get_include_name(), ast_get_include_registrar(), ast_unlock_context(), AST_VECTOR_GET, AST_VECTOR_REMOVE_ORDERED, ast_verb, ast_wrlock_context(), include_free(), ast_context::includes, and registrar.

Referenced by ast_context_remove_include().

◆ ast_context_remove_switch()

int ast_context_remove_switch ( const char *  context,
const char *  sw,
const char *  data,
const char *  registrar 
)

Remove a switch.

Removes a switch with the given parameters

Return values
0on success
-1on failure
Note
This function locks contexts list by &conlist, search for the right context structure, leave context list locked and call ast_context_remove_switch2 which removes switch, unlock contexts list and return ...

Definition at line 4894 of file pbx.c.

4895{
4896 int ret = -1; /* default error return */
4897 struct ast_context *c;
4898
4900 if (c) {
4901 /* remove switch from this context ... */
4904 }
4905 return ret;
4906}
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:4916

References ast_context_remove_switch2(), ast_unlock_contexts(), c, voicemailpwcheck::context, ast_context::data, find_context_locked(), and registrar.

◆ ast_context_remove_switch2()

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 4916 of file pbx.c.

4917{
4918 int idx;
4919 int ret = -1;
4920
4921 ast_wrlock_context(con);
4922
4923 /* walk switches */
4924 for (idx = 0; idx < ast_context_switches_count(con); idx++) {
4925 struct ast_sw *i = AST_VECTOR_GET(&con->alts, idx);
4926
4927 if (!strcmp(ast_get_switch_name(i), sw) &&
4928 !strcmp(ast_get_switch_data(i), data) &&
4929 (!registrar || !strcmp(ast_get_switch_registrar(i), registrar))) {
4930
4931 /* found, remove from list */
4932 ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar);
4933 AST_VECTOR_REMOVE_ORDERED(&con->alts, idx);
4934
4935 /* free switch and return */
4936 sw_free(i);
4937 ret = 0;
4938 break;
4939 }
4940 }
4941
4942 ast_unlock_context(con);
4943
4944 return ret;
4945}
int ast_context_switches_count(const struct ast_context *con)
Definition: pbx.c:8634
const char * ast_get_switch_name(const struct ast_sw *sw)
Definition: pbx_sw.c:48
const char * ast_get_switch_data(const struct ast_sw *sw)
Definition: pbx_sw.c:53
const char * ast_get_switch_registrar(const struct ast_sw *sw)
Definition: pbx_sw.c:63
void sw_free(struct ast_sw *sw)
Definition: pbx_sw.c:101
struct ast_sws alts
Definition: pbx.c:295
ast_sw: Switch statement in extensions.conf
Definition: pbx_sw.c:37
const char * data
Definition: pbx_sw.c:42

References ast_context::alts, ast_context_switches_count(), ast_get_context_name(), ast_get_switch_data(), ast_get_switch_name(), ast_get_switch_registrar(), ast_unlock_context(), AST_VECTOR_GET, AST_VECTOR_REMOVE_ORDERED, ast_verb, ast_wrlock_context(), ast_sw::data, registrar, and sw_free().

Referenced by ast_context_remove_switch().

◆ ast_context_set_autohints()

void ast_context_set_autohints ( struct ast_context con,
int  enabled 
)

Enable or disable autohints support on a context.

Parameters
conpointer to the context
enabledwhether autohints are enabled

Definition at line 6230 of file pbx.c.

6231{
6232 con->autohints = enabled;
6233}
static int enabled
Definition: dnsmgr.c:91
int autohints
Definition: pbx.c:297

References ast_context::autohints, and enabled.

Referenced by pbx_load_config().

◆ ast_context_switches_count()

int ast_context_switches_count ( const struct ast_context con)

◆ ast_context_switches_get()

const struct ast_sw * ast_context_switches_get ( const struct ast_context con,
int  idx 
)

◆ ast_context_verify_includes()

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 8732 of file pbx.c.

8733{
8734 int idx;
8735 int res = 0;
8736 int includecount = ast_context_includes_count(con);
8737
8738 if (includecount >= AST_PBX_MAX_STACK) {
8739 ast_log(LOG_WARNING, "Context %s contains too many includes (%d). Maximum is %d.\n",
8740 ast_get_context_name(con), includecount, AST_PBX_MAX_STACK);
8741 }
8742
8743 for (idx = 0; idx < includecount; idx++) {
8744 const struct ast_include *inc = ast_context_includes_get(con, idx);
8745
8746 if (ast_context_find(include_rname(inc))) {
8747 continue;
8748 }
8749
8750 res = -1;
8751 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
8753 break;
8754 }
8755
8756 return res;
8757}
#define AST_PBX_MAX_STACK
Definition: extconf.h:225
const struct ast_include * ast_context_includes_get(const struct ast_context *con, int idx)
Definition: pbx.c:8684
const char * include_rname(const struct ast_include *inc)
Definition: pbx_include.c:55

References ast_context_find(), ast_context_includes_count(), ast_context_includes_get(), ast_get_context_name(), ast_log, AST_PBX_MAX_STACK, include_rname(), and LOG_WARNING.

Referenced by pbx_load_module().

◆ ast_custom_function_find()

struct ast_custom_function * ast_custom_function_find ( const char *  name)

◆ ast_custom_function_unregister()

int ast_custom_function_unregister ( struct ast_custom_function acf)

Unregister a custom function.

Definition at line 273 of file pbx_functions.c.

274{
275 struct ast_custom_function *cur;
276
277 if (!acf) {
278 return -1;
279 }
280
282 cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist);
283 if (cur) {
284#ifdef AST_XML_DOCS
285 if (cur->docsrc == AST_XML_DOC) {
287 }
288#endif
289 ast_verb(5, "Unregistered custom function %s\n", cur->name);
290 }
292
293 return cur ? 0 : -1;
294}
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:885
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
@ AST_XML_DOC
Definition: xmldoc.h:31

References AST_RWLIST_REMOVE, 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 __unload_module(), close_logger(), geoloc_dialplan_unload(), load_module(), manager_shutdown(), message_shutdown(), reload(), unload_features_config(), unload_module(), unload_parking_bridge_features(), and unload_pbx().

◆ ast_destroy_timing()

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 279 of file pbx_timing.c.

280{
281 if (i->timezone) {
282 ast_free(i->timezone);
283 i->timezone = NULL;
284 }
285 return 0;
286}
#define ast_free(a)
Definition: astmm.h:180

References ast_free, NULL, and ast_timing::timezone.

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

◆ ast_devstate_to_extenstate()

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 3006 of file pbx.c.

3007{
3008 switch (devstate) {
3009 case AST_DEVICE_ONHOLD:
3010 return AST_EXTENSION_ONHOLD;
3011 case AST_DEVICE_BUSY:
3012 return AST_EXTENSION_BUSY;
3013 case AST_DEVICE_UNKNOWN:
3016 case AST_DEVICE_INVALID:
3020 case AST_DEVICE_RINGING:
3021 return AST_EXTENSION_RINGING;
3022 case AST_DEVICE_INUSE:
3023 return AST_EXTENSION_INUSE;
3026 case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
3027 break;
3028 }
3029
3031}
@ AST_DEVICE_RINGINUSE
Definition: devicestate.h:60
@ AST_DEVICE_INUSE
Definition: devicestate.h:55
@ AST_DEVICE_UNKNOWN
Definition: devicestate.h:53
@ AST_DEVICE_ONHOLD
Definition: devicestate.h:61
@ AST_DEVICE_RINGING
Definition: devicestate.h:59
@ AST_DEVICE_INVALID
Definition: devicestate.h:57
@ AST_DEVICE_BUSY
Definition: devicestate.h:56
@ AST_DEVICE_NOT_INUSE
Definition: devicestate.h:54
@ AST_DEVICE_TOTAL
Definition: devicestate.h:62
@ AST_DEVICE_UNAVAILABLE
Definition: devicestate.h:58

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(), and AST_TEST_DEFINE().

◆ ast_exists_extension()

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 4175 of file pbx.c.

4176{
4177 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
4178}
@ E_MATCH
Definition: extconf.h:217

References c, voicemailpwcheck::context, E_MATCH, ast_exten::exten, NULL, pbx_extension_helper(), and priority.

Referenced by __analog_ss_thread(), __ast_goto_if_exists(), __ast_pbx_run(), acf_isexten_exec(), action_originate(), add_to_regcontext(), analog_ss_thread(), ast_app_dtget(), ast_bridge_setup_after_goto(), ast_pbx_outgoing_exten_predial(), ast_sip_persistent_endpoint_update_state(), chan_pjsip_cng_tone_detected(), cli_console_dial(), comeback_goto(), conf_run(), dahdi_handle_dtmf(), dial_exec_full(), dialplan_has_destination_cb(), disa_exec(), dp_lookup(), dundi_lookup_local(), fax_detect_framehook(), findmeexec(), get_destination(), gosub_exec(), grab_transfer(), handle_gosub(), isexten_function_read(), jingle_new(), join_conference_bridge(), key_dial_page(), leave_voicemail(), local_call(), local_devicestate(), loopback_exists(), minivm_greet_exec(), my_handle_dtmf(), new_subscribe(), onModeChanged(), ooh323_rtp_read(), options_on_rx_request(), pbx_builtin_waitexten(), privacy_exec(), readexten_exec(), refer_incoming_attended_request(), refer_incoming_blind_request(), register_peer_exten(), show_debug_helper(), socket_process_helper(), try_calling(), vm_authenticate(), and waitstream_core().

◆ ast_explicit_goto()

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 6945 of file pbx.c.

6946{
6947 if (!chan)
6948 return -1;
6949
6950 ast_channel_lock(chan);
6951
6954 if (!ast_strlen_zero(exten))
6955 ast_channel_exten_set(chan, exten);
6956 if (priority > -1) {
6957 /* see flag description in channel.h for explanation */
6959 --priority;
6960 }
6962 }
6963
6964 ast_channel_unlock(chan);
6965
6966 return 0;
6967}
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_channel_priority_set(struct ast_channel *chan, int value)

References ast_channel_context_set(), ast_channel_exten_set(), ast_channel_flags(), ast_channel_lock, ast_channel_priority_set(), ast_channel_unlock, AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, voicemailpwcheck::context, and priority.

Referenced by __ast_goto_if_exists(), app_control_continue(), ast_async_goto(), ast_bridge_setup_after_goto(), disa_exec(), handle_setpriority(), msg_route(), and pbx_parseable_goto().

◆ ast_extension_close()

int ast_extension_close ( const char *  pattern,
const char *  data,
int  needmore 
)

Definition at line 2432 of file pbx.c.

2433{
2434 if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
2435 ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
2436 return extension_match_core(pattern, data, needmore);
2437}
@ E_MATCHMORE
Definition: extconf.h:215
static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
Definition: pbx.c:2414

References ast_log, ast_exten::data, E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.

Referenced by lua_find_extension(), and realtime_switch_common().

◆ ast_extension_cmp()

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 2197 of file pbx.c.

2198{
2199 int cmp;
2200
2201 cmp = ext_cmp(a, b);
2202 if (cmp < 0) {
2203 return -1;
2204 }
2205 if (cmp > 0) {
2206 return 1;
2207 }
2208 return 0;
2209}
static int ext_cmp(const char *left, const char *right)
Definition: pbx.c:2140
static struct test_val b
static struct test_val a

References a, b, and ext_cmp().

Referenced by lua_extension_cmp().

◆ ast_extension_match()

static 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 4295 of file extconf.c.

4296{
4297 return extension_match_core(pattern, data, E_MATCH);
4298}
static int extension_match_core(const char *pattern, const char *data, enum ext_match_t mode)
Definition: extconf.c:4286

References ast_context::data, 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(), realtime_switch_common(), reload(), and show_dialplan_helper().

◆ ast_extension_patmatch()

int ast_extension_patmatch ( const char *  pattern,
const char *  data 
)

◆ ast_extension_state()

int ast_extension_state ( struct ast_channel c,
const char *  context,
const char *  exten 
)

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

Parameters
cthis is not important
contextwhich context to look in
extenwhich extension to get state
Returns
extension state as defined in the ast_extension_states enum

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

Definition at line 3170 of file pbx.c.

3171{
3173}
static int internal_extension_state_extended(struct ast_channel *c, const char *context, const char *exten, struct ao2_container *device_state_info)
Definition: pbx.c:3141

References c, voicemailpwcheck::context, ast_exten::exten, internal_extension_state_extended(), and NULL.

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

◆ ast_extension_state2str()

const char * ast_extension_state2str ( int  extension_state)

Return string representation of the state of an extension.

Parameters
extension_stateis the numerical state delivered by ast_extension_state
Returns
the state of an extension as string

Return string representation of the state of an extension.

Definition at line 3126 of file pbx.c.

3127{
3128 int i;
3129
3130 for (i = 0; (i < ARRAY_LEN(extension_states)); i++) {
3131 if (extension_states[i].extension_state == extension_state)
3132 return extension_states[i].text;
3133 }
3134 return "Unknown";
3135}
static const struct cfextension_states extension_states[]
const char *const text
Definition: pbx.c:613
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, extension_states, and cfextension_states::text.

Referenced by action_extensionstate(), action_extensionstatelist(), AST_TEST_DEFINE(), exten_state_publisher_state_cb(), handle_show_hint(), handle_show_hints(), manager_state_cb(), and to_ami().

◆ ast_extension_state_add()

int ast_extension_state_add ( const char *  context,
const char *  exten,
ast_state_cb_type  change_cb,
void *  data 
)

Add watcher for extension states.

Parameters
contextwhich context to look in
extenwhich extension to get state
change_cbcallback to call if state changed
datato pass to callback
Note
If context and exten are NULL then the added watcher is global. The change_cb is called for every extension's state change.
The change_cb is called if the state of an extension is changed.
Return values
-1on failure
0Global watcher added successfully
IDon success

Definition at line 3823 of file pbx.c.

3825{
3826 return extension_state_add_destroy(context, exten, change_cb, NULL, data, 0);
3827}
static int 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, int extended)
Definition: pbx.c:3727

References voicemailpwcheck::context, ast_exten::data, ast_exten::exten, extension_state_add_destroy(), and NULL.

Referenced by __init_manager(), create_queue_member(), and publisher_start().

◆ ast_extension_state_add_destroy()

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.

Since
1.8.9
10.1.0
Parameters
contextwhich context to look in
extenwhich extension to get state
change_cbcallback to call if state changed
destroy_cbcallback to call when the watcher is destroyed.
datato pass to callbacks
Note
If context and exten are NULL then the added watcher is global. The change_cb is called for every extension's state change.
The change_cb is called if the state of an extension is changed.
The destroy_cb is called when the watcher is deleted so the watcher can release any associated resources.
Return values
-1on failure
0Global watcher added successfully
IDon success

Definition at line 3817 of file pbx.c.

3819{
3820 return extension_state_add_destroy(context, exten, change_cb, destroy_cb, data, 0);
3821}

References voicemailpwcheck::context, ast_exten::data, ast_exten::exten, and extension_state_add_destroy().

◆ ast_extension_state_add_destroy_extended()

int ast_extension_state_add_destroy_extended ( const char *  context,
const char *  exten,
ast_state_cb_type  change_cb,
ast_state_cb_destroy_type  destroy_cb,
void *  data 
)

Add watcher for extended extension states with destructor.

Since
11
Parameters
contextwhich context to look in
extenwhich extension to get state
change_cbcallback to call if state changed
destroy_cbcallback to call when the watcher is destroyed.
datato pass to callbacks
Note
If context and exten are NULL then the added watcher is global. The change_cb is called for every extension's state change.
The change_cb is called if the state of an extension is changed. The extended state is passed to the callback in the device_state_info member of ast_state_cb_info.
The destroy_cb is called when the watcher is deleted so the watcher can release any associated resources.
Return values
-1on failure
0Global watcher added successfully
IDon success

Definition at line 3829 of file pbx.c.

3831{
3832 return extension_state_add_destroy(context, exten, change_cb, destroy_cb, data, 1);
3833}

References voicemailpwcheck::context, ast_exten::data, ast_exten::exten, and extension_state_add_destroy().

Referenced by subscription_established().

◆ ast_extension_state_add_extended()

int ast_extension_state_add_extended ( const char *  context,
const char *  exten,
ast_state_cb_type  change_cb,
void *  data 
)

Add watcher for extended extension states.

Since
11
Parameters
contextwhich context to look in
extenwhich extension to get state
change_cbcallback to call if state changed
datato pass to callback
Note
If context and exten are NULL then the added watcher is global. The change_cb is called for every extension's state change.
The change_cb is called if the state of an extension is changed. The extended state is passed to the callback in the device_state_info member of ast_state_cb_info.
Return values
-1on failure
0Global watcher added successfully
IDon success

Definition at line 3835 of file pbx.c.

3837{
3838 return extension_state_add_destroy(context, exten, change_cb, NULL, data, 1);
3839}

References voicemailpwcheck::context, ast_exten::data, ast_exten::exten, extension_state_add_destroy(), and NULL.

◆ ast_extension_state_del()

int ast_extension_state_del ( int  id,
ast_state_cb_type  change_cb 
)

Deletes a state change watcher by ID.

Parameters
idof the state watcher to delete (0 for global watcher)
change_cbcallback to call if state changed (Used if id == 0 (global))
Return values
0success
-1failure

Definition at line 3856 of file pbx.c.

3857{
3858 struct ast_state_cb *p_cur;
3859 int ret = -1;
3860
3861 if (!id) { /* id == 0 is a callback without extension */
3862 if (!change_cb) {
3863 return ret;
3864 }
3866 if (p_cur) {
3867 ret = 0;
3868 ao2_ref(p_cur, -1);
3869 }
3870 } else { /* callback with extension, find the callback based on ID */
3871 struct ast_hint *hint;
3872
3873 ao2_lock(hints);/* Locked to hold off ast_merge_contexts_and_delete */
3874 hint = ao2_callback(hints, 0, find_hint_by_cb_id, &id);
3875 if (hint) {
3876 p_cur = ao2_find(hint->callbacks, &id, OBJ_UNLINK);
3877 if (p_cur) {
3878 ret = 0;
3879 ao2_ref(p_cur, -1);
3880 }
3881 ao2_ref(hint, -1);
3882 }
3884 }
3885
3886 return ret;
3887}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ OBJ_UNLINK
Definition: astobj2.h:1039
static struct ao2_container * statecbs
Definition: pbx.c:808
static int find_hint_by_cb_id(void *obj, void *arg, int flags)
Find Hint by callback id.
Definition: pbx.c:3842
Structure for dial plan hints.
Definition: pbx.c:331
struct ao2_container * callbacks
Definition: pbx.c:339
ast_state_cb: An extension state notify register item
Definition: pbx.c:308
ast_state_cb_type change_cb
Definition: pbx.c:316

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

Referenced by destroy_queue_member_cb(), subscription_shutdown(), and unload_module().

◆ ast_extension_state_extended()

int ast_extension_state_extended ( struct ast_channel c,
const char *  context,
const char *  exten,
struct ao2_container **  device_state_info 
)

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

Since
11
Parameters
cthis is not important
contextwhich context to look in
extenwhich extension to get state
[out]device_state_infoptr to an ao2_container with extended state info, must be unref'd after use.
Returns
extension state as defined in the ast_extension_states enum

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

Definition at line 3176 of file pbx.c.

3178{
3179 struct ao2_container *container = NULL;
3180 int ret;
3181
3182 if (device_state_info) {
3184 }
3185
3187 if (ret < 0 && container) {
3188 ao2_ref(container, -1);
3189 container = NULL;
3190 }
3191
3192 if (device_state_info) {
3194 *device_state_info = container;
3195 }
3196
3197 return ret;
3198}
static struct ao2_container * alloc_device_state_info(void)
Definition: pbx.c:3076
static void get_device_state_causing_channels(struct ao2_container *c)
Definition: pbx.c:3296
struct ao2_container * container
Definition: res_fax.c:501
Generic container type.

References alloc_device_state_info(), ao2_ref, c, container, voicemailpwcheck::context, get_device_state_causing_channels(), internal_extension_state_extended(), and NULL.

Referenced by exten_state_data_alloc().

◆ ast_findlabel_extension()

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 4180 of file pbx.c.

4181{
4182 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
4183}
@ E_FINDLABEL
Definition: extconf.h:220

References c, voicemailpwcheck::context, E_FINDLABEL, ast_exten::exten, ast_exten::label, NULL, and pbx_extension_helper().

Referenced by action_originate(), action_redirect(), ari_channels_handle_originate_with_id(), ast_ari_channels_continue_in_dialplan(), handle_gosub(), handle_setpriority(), isexten_function_read(), and pbx_parse_location().

◆ ast_findlabel_extension2()

static 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 4975 of file extconf.c.

4976{
4977 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
4978}
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)
The return value depends on the action:
Definition: extconf.c:4914

References c, E_FINDLABEL, ast_exten::exten, ast_exten::label, NULL, and pbx_extension_helper().

Referenced by pbx_load_config().

◆ ast_func_read()

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 599 of file pbx_functions.c.

600{
601 char *copy = ast_strdupa(function);
602 char *args = func_args(copy);
604 int res;
605 struct ast_module_user *u = NULL;
606
607 if (acfptr == NULL) {
608 ast_log(LOG_ERROR, "Function %s not registered\n", copy);
609 } else if (!acfptr->read && !acfptr->read2) {
610 ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
611 } else if (!is_read_allowed(acfptr)) {
612 ast_log(LOG_ERROR, "Dangerous function %s read blocked\n", copy);
613 } else if (acfptr->read) {
614 if (acfptr->mod) {
615 u = __ast_module_user_add(acfptr->mod, chan);
616 }
617 res = acfptr->read(chan, copy, args, workspace, len);
618 if (acfptr->mod && u) {
619 __ast_module_user_remove(acfptr->mod, u);
620 }
621
622 return res;
623 } else {
624 struct ast_str *str = ast_str_create(16);
625
626 if (acfptr->mod) {
627 u = __ast_module_user_add(acfptr->mod, chan);
628 }
629 res = acfptr->read2(chan, copy, args, &str, 0);
630 if (acfptr->mod && u) {
631 __ast_module_user_remove(acfptr->mod, u);
632 }
634 ast_free(str);
635
636 return res;
637 }
638
639 return -1;
640}
const char * str
Definition: app_jack.c:147
static int copy(char *infile, char *outfile)
Utility function to copy a file.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ast_module_user * __ast_module_user_add(struct ast_module *, struct ast_channel *)
Definition: loader.c:800
void __ast_module_user_remove(struct ast_module *, struct ast_module_user *)
Definition: loader.c:826
static int is_read_allowed(struct ast_custom_function *acfptr)
Determines whether execution of a custom function's read function is allowed.
struct ast_custom_function * ast_custom_function_find(const char *name)
static char * func_args(char *function)
return a pointer to the arguments of the function, and terminates the function name with '\0'
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:742
ast_acf_read_fn_t read
Definition: pbx.h:129
ast_acf_read2_fn_t read2
Definition: pbx.h:137
struct ast_channel * chan
Definition: loader.c:128
Support for dynamic strings.
Definition: strings.h:623
const char * args

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, ast_module_user::chan, copy(), func_args(), is_read_allowed(), len(), LOG_ERROR, ast_custom_function::mod, NULL, ast_custom_function::read, ast_custom_function::read2, and str.

Referenced by action_getvar(), assign_uuid(), fetch_access_token(), fetch_google_access_token(), generate_status(), handle_eval_function(), handle_getvariable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full_location().

◆ ast_func_read2()

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 642 of file pbx_functions.c.

643{
644 char *copy = ast_strdupa(function);
645 char *args = func_args(copy);
647 int res;
648 struct ast_module_user *u = NULL;
649
650 if (acfptr == NULL) {
651 ast_log(LOG_ERROR, "Function %s not registered\n", copy);
652 } else if (!acfptr->read && !acfptr->read2) {
653 ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
654 } else if (!is_read_allowed(acfptr)) {
655 ast_log(LOG_ERROR, "Dangerous function %s read blocked\n", copy);
656 } else {
657 if (acfptr->mod) {
658 u = __ast_module_user_add(acfptr->mod, chan);
659 }
661 if (acfptr->read2) {
662 /* ast_str enabled */
663 res = acfptr->read2(chan, copy, args, str, maxlen);
664 } else {
665 /* Legacy function pointer, allocate buffer for result */
666 int maxsize = ast_str_size(*str);
667
668 if (maxlen > -1) {
669 if (maxlen == 0) {
670 if (acfptr->read_max) {
671 maxsize = acfptr->read_max;
672 } else {
674 }
675 } else {
676 maxsize = maxlen;
677 }
679 }
680 res = acfptr->read(chan, copy, args, ast_str_buffer(*str), maxsize);
681 ast_str_update(*str); /* Manually set the string length */
682 }
683 if (acfptr->mod && u) {
684 __ast_module_user_remove(acfptr->mod, u);
685 }
686
687 return res;
688 }
689
690 return -1;
691}
static int maxsize
#define VAR_BUF_SIZE
Definition: pbx_private.h:68
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:693
#define ast_str_make_space(buf, new_len)
Definition: strings.h:828
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:703
size_t read_max
Definition: pbx.h:139

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_str_update(), ast_strdupa, ast_module_user::chan, copy(), func_args(), is_read_allowed(), LOG_ERROR, maxsize, ast_custom_function::mod, NULL, ast_custom_function::read, ast_custom_function::read2, ast_custom_function::read_max, str, and VAR_BUF_SIZE.

Referenced by ast_ari_channels_get_channel_var(), ast_str_substitute_variables_full2(), AST_TEST_DEFINE(), and channel_get_external_vars().

◆ ast_func_write()

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 693 of file pbx_functions.c.

694{
695 char *copy = ast_strdupa(function);
696 char *args = func_args(copy);
698
699 if (acfptr == NULL) {
700 ast_log(LOG_ERROR, "Function %s not registered\n", copy);
701 } else if (!acfptr->write) {
702 ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy);
703 } else if (!is_write_allowed(acfptr)) {
704 ast_log(LOG_ERROR, "Dangerous function %s write blocked\n", copy);
705 } else {
706 int res;
707 struct ast_module_user *u = NULL;
708
709 if (acfptr->mod) {
710 u = __ast_module_user_add(acfptr->mod, chan);
711 }
712 res = acfptr->write(chan, copy, args, value);
713 if (acfptr->mod && u) {
714 __ast_module_user_remove(acfptr->mod, u);
715 }
716
717 return res;
718 }
719
720 return -1;
721}
static int is_write_allowed(struct ast_custom_function *acfptr)
Determines whether execution of a custom function's write function is allowed.
ast_acf_write_fn_t write
Definition: pbx.h:141

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

Referenced by ast_channel_hangupcause_hash_set(), AST_TEST_DEFINE(), chanavail_exec(), conf_run(), confbridge_exec(), fetch_google_access_token(), pbx_builtin_pushvar_helper(), pbx_builtin_setvar_helper(), setup_profile_bridge(), setup_profile_caller(), and setup_profile_paged().

◆ ast_get_context_name()

static const char * ast_get_context_name ( struct ast_context con)

◆ ast_get_context_registrar()

const char * ast_get_context_registrar ( struct ast_context c)

Definition at line 8527 of file pbx.c.

8528{
8529 return c ? c->registrar : NULL;
8530}

References c, and NULL.

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

◆ ast_get_extension_app()

const char * ast_get_extension_app ( struct ast_exten e)

◆ ast_get_extension_app_data()

void * ast_get_extension_app_data ( struct ast_exten e)

◆ ast_get_extension_cidmatch()

const char * ast_get_extension_cidmatch ( struct ast_exten e)

Definition at line 8552 of file pbx.c.

8553{
8554 return e ? e->cidmatch_display : NULL;
8555}
const char * cidmatch_display
Definition: pbx.c:242

References ast_exten::cidmatch_display, and NULL.

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

◆ ast_get_extension_context()

struct ast_context * ast_get_extension_context ( struct ast_exten exten)

◆ ast_get_extension_data()

int ast_get_extension_data ( char *  buf,
int  bufsize,
struct ast_channel c,
const char *  context,
const char *  exten,
int  priority 
)

Fill a string buffer with the data at a dialplan extension.

Parameters
bufString buffer
bufsizeSize of buf
cChannel
contextDialplan context
extenDialplan extension
priorityDialplan priority
Return values
-1Failed to obtain extension data
0Successfully obtained extension data

Definition at line 8567 of file pbx.c.

8569{
8570 struct ast_exten *e;
8571 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
8573 e = pbx_find_extension(c, NULL, &q, context, exten, priority, NULL, "", E_MATCH);
8574 if (e) {
8575 if (buf) {
8576 const char *tmp = ast_get_extension_app_data(e);
8577 if (tmp) {
8578 ast_copy_string(buf, tmp, bufsize);
8579 }
8580 }
8582 return 0;
8583 }
8585 return -1;
8586}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void * ast_get_extension_app_data(struct ast_exten *e)
Definition: pbx.c:8562
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:2482
int stacklen
Definition: extconf.h:237

References ast_copy_string(), ast_get_extension_app_data(), ast_rdlock_contexts(), ast_unlock_contexts(), buf, c, voicemailpwcheck::context, E_MATCH, NULL, pbx_find_extension(), priority, pbx_find_info::stacklen, and tmp().

Referenced by eval_exten_read().

◆ ast_get_extension_label()

const char * ast_get_extension_label ( struct ast_exten e)

Definition at line 8514 of file pbx.c.

8515{
8516 return exten ? exten->label : NULL;
8517}

References ast_exten::label, and NULL.

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

◆ ast_get_extension_matchcid()

int ast_get_extension_matchcid ( struct ast_exten e)

Definition at line 8547 of file pbx.c.

8548{
8549 return e ? e->matchcid : 0;
8550}

References ast_exten::matchcid.

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

◆ ast_get_extension_name()

const char * ast_get_extension_name ( struct ast_exten exten)

◆ ast_get_extension_priority()

int ast_get_extension_priority ( struct ast_exten exten)

Definition at line 8519 of file pbx.c.

8520{
8521 return exten ? exten->priority : -1;
8522}

References ast_exten::priority.

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

◆ ast_get_extension_registrar()

const char * ast_get_extension_registrar ( struct ast_exten e)

◆ ast_get_extension_registrar_file()

const char * ast_get_extension_registrar_file ( struct ast_exten e)

Get name of configuration file used by registrar to register this extension.

Return values
NULLif registrar did not indicate config file when registering the extension
nameof the file used to register the extension

Definition at line 8537 of file pbx.c.

8538{
8539 return e ? e->registrar_file : NULL;
8540}
const char * registrar_file
Definition: pbx.c:254

References NULL, and ast_exten::registrar_file.

Referenced by show_dialplan_helper_extension_output().

◆ ast_get_extension_registrar_line()

int ast_get_extension_registrar_line ( struct ast_exten e)

Get line number of configuration file used by registrar to register this extension.

Return values
0if the line wasn't indicated when the extension was registered
positiveinteger indicating what line in the config file was responsible for registering the extension.

Definition at line 8542 of file pbx.c.

8543{
8544 return e ? e->registrar_line : 0;
8545}
int registrar_line
Definition: pbx.c:255

References ast_exten::registrar_line.

Referenced by show_dialplan_helper_extension_output().

◆ ast_get_hint()

int ast_get_hint ( char *  hint,
int  hintsize,
char *  name,
int  namesize,
struct ast_channel c,
const char *  context,
const char *  exten 
)

If an extension hint exists, return non-zero.

Parameters
hintbuffer for hint
hintsizesize of hint buffer, in bytes
namebuffer for name portion of hint
namesizesize of name buffer
cChannel from which to return the hint. This is only important when the hint or name contains an expression to be expanded.
contextwhich context to look in
extenwhich extension to search for
Returns
If an extension within the given context with the priority PRIORITY_HINT is found, a non zero value will be returned. Otherwise, 0 is returned.

If an extension hint exists, return non-zero.

Definition at line 4137 of file pbx.c.

4138{
4140
4141 if (e) {
4142 if (hint)
4143 ast_copy_string(hint, ast_get_extension_app(e), hintsize);
4144 if (name) {
4145 const char *tmp = ast_get_extension_app_data(e);
4146 if (tmp)
4147 ast_copy_string(name, tmp, namesize);
4148 }
4149 return -1;
4150 }
4151 return 0;
4152}
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:8557
static struct ast_exten * ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
Definition: pbx.c:2997

References ast_copy_string(), ast_get_extension_app(), ast_get_extension_app_data(), ast_hint_extension(), c, voicemailpwcheck::context, ast_exten::exten, name, and tmp().

Referenced by action_extensionstate(), device_state_cb(), get_cid_name(), get_resource_display_name(), hint_read(), and manager_state_cb().

◆ ast_get_ignorepat_name()

const char * ast_get_ignorepat_name ( const struct ast_ignorepat ip)

◆ ast_get_ignorepat_registrar()

const char * ast_get_ignorepat_registrar ( const struct ast_ignorepat ip)

◆ ast_get_include_name()

const char * ast_get_include_name ( const struct ast_include include)

◆ ast_get_include_registrar()

const char * ast_get_include_registrar ( const struct ast_include i)

◆ ast_get_switch_data()

const char * ast_get_switch_data ( const struct ast_sw sw)

◆ ast_get_switch_eval()

int ast_get_switch_eval ( const struct ast_sw sw)

Definition at line 58 of file pbx_sw.c.

59{
60 return sw->eval;
61}
int eval
Definition: pbx_sw.c:43

References ast_sw::eval.

Referenced by context_merge_incls_swits_igps_other_registrars(), and pbx_find_extension().

◆ ast_get_switch_name()

const char * ast_get_switch_name ( const struct ast_sw sw)

◆ ast_get_switch_registrar()

const char * ast_get_switch_registrar ( const struct ast_sw sw)

◆ ast_goto_if_exists()

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 8781 of file pbx.c.

8782{
8783 return __ast_goto_if_exists(chan, context, exten, priority, 0);
8784}

References __ast_goto_if_exists(), voicemailpwcheck::context, ast_channel::exten, and priority.

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

◆ ast_hashtab_compare_contexts()

int ast_hashtab_compare_contexts ( const void *  ah_a,
const void *  ah_b 
)

hashtable functions for contexts

Definition at line 589 of file ael_main.c.

590{
591 return 0;
592}

References bc, and ast_context::name.

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

◆ ast_hashtab_hash_contexts()

unsigned int ast_hashtab_hash_contexts ( const void *  obj)

Definition at line 596 of file ael_main.c.

597{
598 return 0;
599}

References ast_hashtab_hash_string(), and ast_context::name.

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

◆ ast_hint_presence_state()

int ast_hint_presence_state ( struct ast_channel c,
const char *  context,
const char *  exten,
char **  subtype,
char **  message 
)

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

Parameters
cthis is not important
contextwhich context to look in
extenwhich extension to get state
[out]subtypeFurther information regarding the presence returned
[out]messageCustom message further describing current presence
Note
The subtype and message are dynamically allocated and must be freed by the caller of this function.
Returns
returns the presence state value.

Definition at line 3226 of file pbx.c.

3227{
3228 struct ast_exten *e;
3229
3230 if (!(e = ast_hint_extension(c, context, exten))) { /* Do we have a hint for this extension ? */
3231 return -1; /* No hint, return -1 */
3232 }
3233
3234 if (e->exten[0] == '_') {
3235 /* Create this hint on-the-fly */
3236 ao2_lock(hints);
3238 e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr,
3239 e->registrar);
3241 if (!(e = ast_hint_extension(c, context, exten))) {
3242 /* Improbable, but not impossible */
3243 return -1;
3244 }
3245 }
3246
3247 return extension_presence_state_helper(e, subtype, message);
3248}
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
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:6928
static int extension_presence_state_helper(struct ast_exten *e, char **subtype, char **message)
Definition: pbx.c:3200

References ao2_lock, ao2_unlock, ast_exten::app, ast_add_extension(), ast_free_ptr(), ast_hint_extension(), ast_strdup, c, ast_exten::cidmatch, voicemailpwcheck::context, ast_exten::data, ast_exten::exten, extension_presence_state_helper(), ast_exten::label, ast_exten::matchcid, ast_context::name, NULL, ast_exten::parent, ast_exten::priority, and ast_exten::registrar.

Referenced by exten_state_data_alloc().

◆ ast_ignore_pattern()

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 6879 of file pbx.c.

6880{
6881 int ret = 0;
6882 struct ast_context *con;
6883
6886 if (con) {
6887 int idx;
6888
6889 for (idx = 0; idx < ast_context_ignorepats_count(con); idx++) {
6890 const struct ast_ignorepat *pat = ast_context_ignorepats_get(con, idx);
6891
6893 ret = 1;
6894 break;
6895 }
6896 }
6897 }
6899
6900 return ret;
6901}
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:2427
const struct ast_ignorepat * ast_context_ignorepats_get(const struct ast_context *con, int idx)
Definition: pbx.c:8727

References ast_context_find(), ast_context_ignorepats_count(), ast_context_ignorepats_get(), ast_extension_match(), ast_get_ignorepat_name(), ast_rdlock_contexts(), ast_unlock_contexts(), voicemailpwcheck::context, and ast_ignorepat::pattern.

Referenced by __analog_ss_thread(), analog_ss_thread(), ast_app_dtget(), disa_exec(), dp_lookup(), and dundi_lookup_local().

◆ ast_matchmore_extension()

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 search 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 4195 of file pbx.c.

4196{
4197 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
4198}

References c, voicemailpwcheck::context, E_MATCHMORE, ast_exten::exten, NULL, pbx_extension_helper(), and priority.

Referenced by __analog_ss_thread(), __ast_pbx_run(), analog_ss_thread(), ast_app_dtget(), collect_digits(), disa_exec(), dp_lookup(), dundi_lookup_local(), key_dial_page(), loopback_matchmore(), pbx_builtin_background(), and readexten_exec().

◆ ast_merge_contexts_and_delete()

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 6426 of file pbx.c.

6427{
6428 double ft;
6429 struct ast_context *tmp;
6430 struct ast_context *oldcontextslist;
6431 struct ast_hashtab *oldtable;
6432 struct store_hints hints_stored = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
6433 struct store_hints hints_removed = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
6434 struct store_hint *saved_hint;
6435 struct ast_hint *hint;
6436 struct ast_exten *exten;
6437 int length;
6438 struct ast_state_cb *thiscb;
6439 struct ast_hashtab_iter *iter;
6440 struct ao2_iterator i;
6441 int ctx_count = 0;
6442 struct timeval begintime;
6443 struct timeval writelocktime;
6444 struct timeval endlocktime;
6445 struct timeval enddeltime;
6446
6447 /*
6448 * It is very important that this function hold the hints
6449 * container lock _and_ the conlock during its operation; not
6450 * only do we need to ensure that the list of contexts and
6451 * extensions does not change, but also that no hint callbacks
6452 * (watchers) are added or removed during the merge/delete
6453 * process
6454 *
6455 * In addition, the locks _must_ be taken in this order, because
6456 * there are already other code paths that use this order
6457 */
6458
6459 begintime = ast_tvnow();
6460 ast_mutex_lock(&context_merge_lock);/* Serialize ast_merge_contexts_and_delete */
6462
6463 if (!contexts_table) {
6464 /* Create any autohint contexts */
6466
6467 /* Well, that's odd. There are no contexts. */
6468 contexts_table = exttable;
6469 contexts = *extcontexts;
6472 return;
6473 }
6474
6476 while ((tmp = ast_hashtab_next(iter))) {
6477 ++ctx_count;
6478 context_merge(extcontexts, exttable, tmp, registrar);
6479 }
6481
6482 ao2_lock(hints);
6483 writelocktime = ast_tvnow();
6484
6485 /* preserve all watchers for hints */
6487 for (; (hint = ao2_iterator_next(&i)); ao2_ref(hint, -1)) {
6488 if (ao2_container_count(hint->callbacks)) {
6489 size_t exten_len;
6490
6491 ao2_lock(hint);
6492 if (!hint->exten) {
6493 /* The extension has already been destroyed. (Should never happen here) */
6494 ao2_unlock(hint);
6495 continue;
6496 }
6497
6498 exten_len = strlen(hint->exten->exten) + 1;
6499 length = exten_len + strlen(hint->exten->parent->name) + 1
6500 + sizeof(*saved_hint);
6501 if (!(saved_hint = ast_calloc(1, length))) {
6502 ao2_unlock(hint);
6503 continue;
6504 }
6505
6506 /* This removes all the callbacks from the hint into saved_hint. */
6507 while ((thiscb = ao2_callback(hint->callbacks, OBJ_UNLINK, NULL, NULL))) {
6508 AST_LIST_INSERT_TAIL(&saved_hint->callbacks, thiscb, entry);
6509 /*
6510 * We intentionally do not unref thiscb to account for the
6511 * non-ao2 reference in saved_hint->callbacks
6512 */
6513 }
6514
6515 saved_hint->laststate = hint->laststate;
6516 saved_hint->context = saved_hint->data;
6517 strcpy(saved_hint->data, hint->exten->parent->name);
6518 saved_hint->exten = saved_hint->data + strlen(saved_hint->context) + 1;
6519 ast_copy_string(saved_hint->exten, hint->exten->exten, exten_len);
6520 if (hint->last_presence_subtype) {
6521 saved_hint->last_presence_subtype = ast_strdup(hint->last_presence_subtype);
6522 }
6523 if (hint->last_presence_message) {
6524 saved_hint->last_presence_message = ast_strdup(hint->last_presence_message);
6525 }
6526 saved_hint->last_presence_state = hint->last_presence_state;
6527 ao2_unlock(hint);
6528 AST_LIST_INSERT_HEAD(&hints_stored, saved_hint, list);
6529 }
6530 }
6532
6533 /* save the old table and list */
6534 oldtable = contexts_table;
6535 oldcontextslist = contexts;
6536
6537 /* move in the new table and list */
6538 contexts_table = exttable;
6539 contexts = *extcontexts;
6540
6541 /*
6542 * Restore the watchers for hints that can be found; notify
6543 * those that cannot be restored.
6544 */
6545 while ((saved_hint = AST_LIST_REMOVE_HEAD(&hints_stored, list))) {
6546 struct pbx_find_info q = { .stacklen = 0 };
6547
6548 exten = pbx_find_extension(NULL, NULL, &q, saved_hint->context, saved_hint->exten,
6549 PRIORITY_HINT, NULL, "", E_MATCH);
6550 /*
6551 * If this is a pattern, dynamically create a new extension for this
6552 * particular match. Note that this will only happen once for each
6553 * individual extension, because the pattern will no longer match first.
6554 */
6555 if (exten && exten->exten[0] == '_') {
6556 ast_add_extension_nolock(exten->parent->name, 0, saved_hint->exten,
6557 PRIORITY_HINT, NULL, 0, exten->app, ast_strdup(exten->data), ast_free_ptr,
6558 exten->registrar);
6559 /* rwlocks are not recursive locks */
6560 exten = ast_hint_extension_nolock(NULL, saved_hint->context,
6561 saved_hint->exten);
6562 }
6563
6564 /* Find the hint in the hints container */
6565 hint = exten ? ao2_find(hints, exten, 0) : NULL;
6566 if (!hint) {
6567 /*
6568 * Notify watchers of this removed hint later when we aren't
6569 * encumbered by so many locks.
6570 */
6571 AST_LIST_INSERT_HEAD(&hints_removed, saved_hint, list);
6572 } else {
6573 ao2_lock(hint);
6574 while ((thiscb = AST_LIST_REMOVE_HEAD(&saved_hint->callbacks, entry))) {
6575 ao2_link(hint->callbacks, thiscb);
6576 /* Ref that we added when putting into saved_hint->callbacks */
6577 ao2_ref(thiscb, -1);
6578 }
6579 hint->laststate = saved_hint->laststate;
6580 hint->last_presence_state = saved_hint->last_presence_state;
6581 hint->last_presence_subtype = saved_hint->last_presence_subtype;
6582 hint->last_presence_message = saved_hint->last_presence_message;
6583 ao2_unlock(hint);
6584 ao2_ref(hint, -1);
6585 /*
6586 * The free of saved_hint->last_presence_subtype and
6587 * saved_hint->last_presence_message is not necessary here.
6588 */
6589 ast_free(saved_hint);
6590 }
6591 }
6592
6593 /* Create all applicable autohint contexts */
6595
6598
6599 /*
6600 * Notify watchers of all removed hints with the same lock
6601 * environment as device_state_cb().
6602 */
6603 while ((saved_hint = AST_LIST_REMOVE_HEAD(&hints_removed, list))) {
6604 /* this hint has been removed, notify the watchers */
6605 while ((thiscb = AST_LIST_REMOVE_HEAD(&saved_hint->callbacks, entry))) {
6607 saved_hint->context,
6608 saved_hint->exten,
6609 thiscb->data,
6611 NULL,
6612 NULL);
6613 /* Ref that we added when putting into saved_hint->callbacks */
6614 ao2_ref(thiscb, -1);
6615 }
6616 ast_free(saved_hint->last_presence_subtype);
6617 ast_free(saved_hint->last_presence_message);
6618 ast_free(saved_hint);
6619 }
6620
6622 endlocktime = ast_tvnow();
6623
6624 /*
6625 * The old list and hashtab no longer are relevant, delete them
6626 * while the rest of asterisk is now freely using the new stuff
6627 * instead.
6628 */
6629
6630 ast_hashtab_destroy(oldtable, NULL);
6631
6632 for (tmp = oldcontextslist; tmp; ) {
6633 struct ast_context *next; /* next starting point */
6634
6635 next = tmp->next;
6637 tmp = next;
6638 }
6639 enddeltime = ast_tvnow();
6640
6641 ft = ast_tvdiff_us(writelocktime, begintime);
6642 ft /= 1000000.0;
6643 ast_verb(5,"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft);
6644
6645 ft = ast_tvdiff_us(endlocktime, writelocktime);
6646 ft /= 1000000.0;
6647 ast_verb(5,"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft);
6648
6649 ft = ast_tvdiff_us(enddeltime, endlocktime);
6650 ft /= 1000000.0;
6651 ast_verb(5,"Time to delete the old dialplan: %8.6f sec\n", ft);
6652
6653 ft = ast_tvdiff_us(enddeltime, begintime);
6654 ft /= 1000000.0;
6655 ast_verb(5,"Total time merge_contexts_delete: %8.6f sec\n", ft);
6656 ast_verb(5, "%s successfully loaded %d contexts (enable debug for details).\n", registrar, ctx_count);
6657}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
@ AO2_ITERATOR_DONTLOCK
Assume that the ao2_container is already locked.
Definition: astobj2.h:1852
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_hashtab_start_traversal(tab)
Definition: hashtab.h:356
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:363
void ast_hashtab_end_traversal(struct ast_hashtab_iter *it)
end the traversal, free the iterator, unlock if necc.
Definition: hashtab.c:674
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:683
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
Definition: linkedlists.h:252
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
static int execute_state_callback(ast_state_cb_type cb, const char *context, const char *exten, void *data, enum ast_state_cb_update_reason reason, struct ast_hint *hint, struct ao2_container *device_state_info)
Definition: pbx.c:3250
static void context_table_create_autohints(struct ast_hashtab *table)
Definition: pbx.c:6290
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:6908
static void context_merge(struct ast_context **extcontexts, struct ast_hashtab *exttable, struct ast_context *context, const char *registrar)
Definition: pbx.c:6327
static ast_mutex_t context_merge_lock
Lock to hold off restructuring of hints by ast_merge_contexts_and_delete.
Definition: pbx.c:795
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:2991
static void __ast_internal_context_destroy(struct ast_context *con)
Definition: pbx.c:8015
#define PRIORITY_HINT
Definition: pbx.h:54
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct ast_context * next
Definition: pbx.c:292
an iterator for traversing the buckets
Definition: hashtab.h:106
int laststate
Definition: pbx.c:342
struct ast_exten * exten
Hint extension.
Definition: pbx.c:338
int last_presence_state
Definition: pbx.c:345
char * last_presence_subtype
Definition: pbx.c:346
char * last_presence_message
Definition: pbx.c:347
void * data
Definition: pbx.c:312
Definition: search.h:40
int64_t ast_tvdiff_us(struct timeval end, struct timeval start)
Computes the difference (in microseconds) between two struct timeval instances.
Definition: time.h:87
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

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_copy_string(), ast_free, ast_free_ptr(), ast_hashtab_destroy(), ast_hashtab_end_traversal(), ast_hashtab_next(), ast_hashtab_start_traversal, ast_hint_extension_nolock(), AST_HINT_UPDATE_DEVICE, 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, context_table_create_autohints(), contexts, contexts_table, ast_exten::data, ast_state_cb::data, E_MATCH, execute_state_callback(), ast_exten::exten, ast_hint::exten, store_hint::exten, ast_hint::last_presence_message, store_hint::last_presence_message, ast_hint::last_presence_state, store_hint::last_presence_state, ast_hint::last_presence_subtype, store_hint::last_presence_subtype, ast_hint::laststate, store_hint::laststate, ast_context::name, ast_context::next, NULL, OBJ_UNLINK, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_exten::registrar, registrar, pbx_find_info::stacklen, and tmp().

Referenced by lua_reload_extensions(), and pbx_load_module().

◆ ast_parseable_goto()

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 8866 of file pbx.c.

8867{
8868 return pbx_parseable_goto(chan, goto_string, 0);
8869}

References pbx_parseable_goto().

Referenced by _while_exec(), ast_bridge_setup_after_goto(), dial_exec_full(), gosub_exec(), if_helper(), ivr_dispatch(), pbx_builtin_goto(), and while_continue_exec().

◆ ast_pbx_exec_application()

int ast_pbx_exec_application ( struct ast_channel chan,
const char *  app_name,
const char *  app_args 
)

Execute an application.

Parameters
chanchannel to execute on
app_namename of app to execute
app_argsthe data passed into the app

This application executes an application by name on a given channel. It is a wrapper around pbx_exec that will perform variable substitution and then execute the application if it exists. If the application is not found, a warning is logged.

Return values
0success
-1failure (including application not found)

Definition at line 501 of file pbx_app.c.

502{
503 int res = -1;
504 struct ast_app *app;
505
507 if (!app) {
508 ast_log(LOG_WARNING, "Could not find application (%s)\n", app_name);
509 } else {
510 struct ast_str *substituted_args = NULL;
511
512 if (!ast_strlen_zero(app_args) && (substituted_args = ast_str_create(16))) {
513 ast_str_substitute_variables(&substituted_args, 0, chan, app_args);
514 res = pbx_exec(chan, app, ast_str_buffer(substituted_args));
515 ast_free(substituted_args);
516 } else {
517 if (!ast_strlen_zero(app_args)) {
518 ast_log(LOG_WARNING, "Could not substitute application argument variables for %s\n", app_name);
519 }
520 res = pbx_exec(chan, app, app_args);
521 }
522 /* Manually make a snapshot now, since pbx_exec won't necessarily get called again immediately. */
524 }
525 return res;
526}
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: pbx_app.c:91

References app, app_name(), ast_channel_publish_snapshot(), ast_free, ast_log, ast_str_buffer(), ast_str_create, ast_str_substitute_variables(), ast_strlen_zero(), LOG_WARNING, NULL, pbx_exec(), and pbx_findapp().

Referenced by answer_exec_run(), conf_kick_all(), conf_run(), disa_exec(), dundi_exec(), pbx_builtin_execiftime(), run_app_helper(), and snoop_stasis_thread().

◆ ast_pbx_h_exten_run()

void ast_pbx_h_exten_run ( struct ast_channel chan,
const char *  context 
)

Run the h exten from the given context.

Since
11.0
Parameters
chanChannel to run the h exten on.
contextContext the h exten is in.

Definition at line 4205 of file pbx.c.

4206{
4207 int autoloopflag;
4208 int found;
4209 int spawn_error;
4210
4211 ast_channel_lock(chan);
4212
4213 /*
4214 * Make sure that the channel is marked as hungup since we are
4215 * going to run the h exten on it.
4216 */
4218
4219 /* Set h exten location */
4220 if (context != ast_channel_context(chan)) {
4222 }
4223 ast_channel_exten_set(chan, "h");
4224 ast_channel_priority_set(chan, 1);
4225
4226 /* Save autoloop flag */
4229 ast_channel_unlock(chan);
4230
4231 for (;;) {
4232 spawn_error = ast_spawn_extension(chan, ast_channel_context(chan),
4234 S_COR(ast_channel_caller(chan)->id.number.valid,
4235 ast_channel_caller(chan)->id.number.str, NULL), &found, 1);
4236
4237 ast_channel_lock(chan);
4238 if (spawn_error) {
4239 /* The code after the loop needs the channel locked. */
4240 break;
4241 }
4243 ast_channel_unlock(chan);
4244 }
4245 if (found && spawn_error) {
4246 /* Something bad happened, or a hangup has been requested. */
4247 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n",
4250 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n",
4253 }
4254
4255 /* An "h" exten has been run, so indicate that one has been run. */
4257
4258 /* Restore autoloop flag */
4260 ast_channel_unlock(chan);
4261}
int ast_channel_priority(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
@ AST_SOFTHANGUP_HANGUP_EXEC
Definition: channel.h:1154
@ AST_FLAG_BRIDGE_HANGUP_RUN
Definition: channel.h:1018
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
const char * ast_channel_exten(const struct ast_channel *chan)
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:4200
#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:87
Number structure.
Definition: app_followme.c:154
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ast_channel_caller(), ast_channel_context(), ast_channel_context_set(), ast_channel_exten(), ast_channel_exten_set(), ast_channel_flags(), ast_channel_lock, ast_channel_name(), ast_channel_priority(), ast_channel_priority_set(), ast_channel_unlock, ast_debug, AST_FLAG_BRIDGE_HANGUP_RUN, AST_FLAG_IN_AUTOLOOP, ast_set2_flag, ast_set_flag, AST_SOFTHANGUP_HANGUP_EXEC, ast_softhangup_nolock(), ast_spawn_extension(), ast_test_flag, ast_verb, voicemailpwcheck::context, NULL, and S_COR.

Referenced by __ast_pbx_run(), and ast_bridge_setup_after_goto().

◆ ast_pbx_hangup_handler_destroy()

void ast_pbx_hangup_handler_destroy ( struct ast_channel chan)

Destroy the hangup handler container on a channel.

Since
11.0
Parameters
chanChannel to destroy the hangup handler container on.

Definition at line 103 of file pbx_hangup_handler.c.

104{
106 struct ast_hangup_handler *h_handler;
107
108 ast_channel_lock(chan);
109
110 /* Get rid of each of the hangup handlers on the channel */
112 while ((h_handler = AST_LIST_REMOVE_HEAD(handlers, node))) {
113 ast_free(h_handler);
114 }
115
116 ast_channel_unlock(chan);
117}
struct ast_hangup_handler_list * ast_channel_hangup_handlers(struct ast_channel *chan)
Definition: test_heap.c:38
static const struct ast_aeap_message_handler handlers[]
Definition: test_aeap.c:135

References ast_channel_hangup_handlers(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_REMOVE_HEAD, and handlers.

Referenced by ast_channel_destructor(), and ast_dummy_channel_destructor().

◆ ast_pbx_hangup_handler_init()

void ast_pbx_hangup_handler_init ( struct ast_channel chan)

Init the hangup handler container on a channel.

Since
11.0
Parameters
chanChannel to init the hangup handler container on.

Definition at line 95 of file pbx_hangup_handler.c.

96{
98
101}
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681

References ast_channel_hangup_handlers(), AST_LIST_HEAD_INIT_NOLOCK, and handlers.

Referenced by __ast_channel_alloc_ap(), and __ast_dummy_channel_alloc().

◆ ast_pbx_hangup_handler_pop()

int ast_pbx_hangup_handler_pop ( struct ast_channel chan)

Pop the top of the channel hangup handler stack.

Since
11.0
Parameters
chanChannel to push the hangup handler onto.
Return values
TRUEif a handler was popped off of the stack.

Definition at line 119 of file pbx_hangup_handler.c.

120{
122 struct ast_hangup_handler *h_handler;
123
124 ast_channel_lock(chan);
126 h_handler = AST_LIST_REMOVE_HEAD(handlers, node);
127 if (h_handler) {
128 publish_hangup_handler_message("pop", chan, h_handler->args);
129 }
130 ast_channel_unlock(chan);
131 if (h_handler) {
132 ast_free(h_handler);
133 return 1;
134 }
135 return 0;
136}
static void publish_hangup_handler_message(const char *action, struct ast_channel *chan, const char *handler)

References ast_hangup_handler::args, ast_channel_hangup_handlers(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_REMOVE_HEAD, handlers, and publish_hangup_handler_message().

Referenced by func_channel_write_real().

◆ ast_pbx_hangup_handler_push()

void ast_pbx_hangup_handler_push ( struct ast_channel chan,
const char *  handler 
)

Push the given hangup handler onto the channel hangup handler stack.

Since
11.0
Parameters
chanChannel to push the hangup handler onto.
handlerGosub application parameter string.

Definition at line 138 of file pbx_hangup_handler.c.

139{
141 struct ast_hangup_handler *h_handler;
142 const char *expanded_handler;
143
145 return;
146 }
147
148 expanded_handler = ast_app_expand_sub_args(chan, handler);
149 if (!expanded_handler) {
150 return;
151 }
152 h_handler = ast_malloc(sizeof(*h_handler) + 1 + strlen(expanded_handler));
153 if (!h_handler) {
154 ast_free((char *) expanded_handler);
155 return;
156 }
157 strcpy(h_handler->args, expanded_handler);/* Safe */
158 ast_free((char *) expanded_handler);
159
160 ast_channel_lock(chan);
161
164 publish_hangup_handler_message("push", chan, h_handler->args);
165 ast_channel_unlock(chan);
166}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
const char * ast_app_expand_sub_args(struct ast_channel *chan, const char *args)
Add missing context/exten to subroutine argument string.
Definition: main/app.c:278
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59

References ast_hangup_handler::args, ast_app_expand_sub_args(), ast_channel_hangup_handlers(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_INSERT_HEAD, ast_malloc, ast_strlen_zero(), handler(), handlers, and publish_hangup_handler_message().

Referenced by func_channel_write_real().

◆ ast_pbx_hangup_handler_run()

int ast_pbx_hangup_handler_run ( struct ast_channel chan)

Run all hangup handlers on the channel.

Since
11.0
Parameters
chanChannel to run the hangup handlers on.
Note
Absolutely NO channel locks should be held before calling this function.
Return values
Zeroif no hangup handlers run.
non-zeroif hangup handlers were run.

Definition at line 58 of file pbx_hangup_handler.c.

59{
61 struct ast_hangup_handler *h_handler;
62
63 ast_channel_lock(chan);
67 return 0;
68 }
69
70 /*
71 * Make sure that the channel is marked as hungup since we are
72 * going to run the hangup handlers on it.
73 */
75
76 for (;;) {
79 if (!h_handler) {
80 break;
81 }
82
83 publish_hangup_handler_message("run", chan, h_handler->args);
85
86 ast_app_exec_sub(NULL, chan, h_handler->args, 1);
87 ast_free(h_handler);
88
89 ast_channel_lock(chan);
90 }
92 return 1;
93}
int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
Run a subroutine on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:297
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450

References ast_hangup_handler::args, ast_app_exec_sub(), ast_channel_hangup_handlers(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_EMPTY, AST_LIST_REMOVE_HEAD, AST_SOFTHANGUP_HANGUP_EXEC, ast_softhangup_nolock(), handlers, NULL, and publish_hangup_handler_message().

Referenced by __ast_pbx_run(), and ast_hangup().

◆ ast_pbx_outgoing_app()

int ast_pbx_outgoing_app ( const char *  type,
struct ast_format_cap cap,
const char *  addr,
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,
const struct ast_assigned_ids assignedids 
)

Synchronously or asynchronously make an outbound call and execute an application on the channel.

Note that when the application stops executing, the channel is hungup.

Parameters
typeThe channel technology to create
capThe format capabilities for the channel
addrAddress data to pass to the channel technology driver
timeoutHow long we should attempt to dial the outbound channel
appThe name of the application to execute
appdataData to pass to the application
reasonOptional. If provided, the dialed status of the outgoing channel. Codes are AST_CONTROL_xxx values. Valid only if synchronous is non-zero.
synchronousdefined by the ast_pbx_outgoing_sync enum. If AST_OUTGOING_NO_WAIT then don't wait for anything. If AST_OUTGOING_WAIT then block until the outbound channel answers or the call fails. If AST_OUTGOING_WAIT_COMPLETE then wait for the call to complete or fail.
cid_numThe caller ID number to set on the outbound channel
cid_nameThe caller ID name to set on the outbound channel
varsVariables to set on the outbound channel
accountThe accountcode for the outbound channel
locked_channelOptional. The outbound channel that was created if success is returned. Otherwise it is set to NULL. This is returned both locked and reference bumped.
assignedidsOptional. The uniqueid(s) to assign the channel(s) that are created.
Return values
0on success
-1on failure

Definition at line 7980 of file pbx.c.

7985{
7986 return ast_pbx_outgoing_app_predial(type, cap, addr, timeout, app, appdata, reason, synchronous,
7987 cid_num, cid_name, vars, account, locked_channel, assignedids, NULL);
7988}
static const char type[]
Definition: chan_ooh323.c:109
int ast_pbx_outgoing_app_predial(const char *type, struct ast_format_cap *cap, const char *addr, 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, const struct ast_assigned_ids *assignedids, const char *predial_callee)
Definition: pbx.c:7990

References app, ast_pbx_outgoing_app_predial(), NULL, and type.

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

◆ ast_pbx_outgoing_app_predial()

int ast_pbx_outgoing_app_predial ( const char *  type,
struct ast_format_cap cap,
const char *  addr,
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,
const struct ast_assigned_ids assignedids,
const char *  predial_callee 
)

Definition at line 7990 of file pbx.c.

7995{
7996 if (reason) {
7997 *reason = 0;
7998 }
7999 if (locked_channel) {
8000 *locked_channel = NULL;
8001 }
8002 if (ast_strlen_zero(app)) {
8003 return -1;
8004 }
8005
8006 return pbx_outgoing_attempt(type, cap, addr, timeout, NULL, NULL, 0, app, appdata,
8007 reason, synchronous, cid_num, cid_name, vars, account, locked_channel, 0,
8008 assignedids, predial_callee);
8009}
static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, 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, int early_media, const struct ast_assigned_ids *assignedids, const char *predial_callee)
Definition: pbx.c:7720

References app, ast_strlen_zero(), NULL, pbx_outgoing_attempt(), and type.

Referenced by ast_pbx_outgoing_app(), and originate_exec().

◆ ast_pbx_outgoing_exten()

int ast_pbx_outgoing_exten ( const char *  type,
struct ast_format_cap cap,
const char *  addr,
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 **  locked_channel,
int  early_media,
const struct ast_assigned_ids assignedids 
)

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

Parameters
typeThe channel technology to create
capThe format capabilities for the channel
addrAddress data to pass to the channel technology driver
timeoutHow long we should attempt to dial the outbound channel
contextThe destination context for the outbound channel
extenThe destination extension for the outbound channel
priorityThe destination priority for the outbound channel
reasonOptional. If provided, the dialed status of the outgoing channel. Codes are AST_CONTROL_xxx values. Valid only if synchronous is non-zero.
synchronousdefined by the ast_pbx_outgoing_sync enum. If AST_OUTGOING_NO_WAIT then don't wait for anything. If AST_OUTGOING_WAIT then block until the outbound channel answers or the call fails. If AST_OUTGOING_WAIT_COMPLETE then wait for the call to complete or fail. If AST_OUTGOING_WAIT or AST_OUTGOING_WAIT_COMPLETE is specified, the call doesn't answer, and failed@context exists then run a channel named OutgoingSpoolFailed at failed@context.
cid_numThe caller ID number to set on the outbound channel
cid_nameThe caller ID name to set on the outbound channel
varsVariables to set on the outbound channel
accountThe accountcode for the outbound channel
locked_channelOptional. The outbound channel that was created if success is returned. Otherwise it is set to NULL. This is returned both locked and reference bumped.
early_mediaIf non-zero the channel "answers" when progress is indicated.
assignedidsOptional. The uniqueid(s) to assign the channel(s) that are created.
Return values
0on success
-1on failure

Definition at line 7916 of file pbx.c.

7921{
7922 return ast_pbx_outgoing_exten_predial(type, cap, addr, timeout, context, exten, priority, reason,
7923 synchronous, cid_num, cid_name, vars, account, locked_channel, early_media, assignedids, NULL);
7924}
int ast_pbx_outgoing_exten_predial(const char *type, struct ast_format_cap *cap, const char *addr, 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 **locked_channel, int early_media, const struct ast_assigned_ids *assignedids, const char *predial_callee)
Definition: pbx.c:7926

References ast_pbx_outgoing_exten_predial(), voicemailpwcheck::context, NULL, priority, and type.

Referenced by attempt_thread(), fast_originate(), hook_launch_thread(), and orig_exten().

◆ ast_pbx_outgoing_exten_predial()

int ast_pbx_outgoing_exten_predial ( const char *  type,
struct ast_format_cap cap,
const char *  addr,
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 **  locked_channel,
int  early_media,
const struct ast_assigned_ids assignedids,
const char *  predial_callee 
)
Todo:
XXX Not good. The channel name is not unique if more than one originate fails at a time.

Definition at line 7926 of file pbx.c.

7931{
7932 int res;
7933 int my_reason;
7934
7935 if (!reason) {
7936 reason = &my_reason;
7937 }
7938 *reason = 0;
7939 if (locked_channel) {
7940 *locked_channel = NULL;
7941 }
7942
7943 res = pbx_outgoing_attempt(type, cap, addr, timeout, context, exten, priority,
7944 NULL, NULL, reason, synchronous, cid_num, cid_name, vars, account, locked_channel,
7945 early_media, assignedids, predial_callee);
7946
7947 if (res < 0 /* Call failed to get connected for some reason. */
7948 && 0 < synchronous
7949 && ast_exists_extension(NULL, context, "failed", 1, NULL)) {
7950 struct ast_channel *failed;
7951
7952 /* We do not have to worry about a locked_channel if dialing failed. */
7953 ast_assert(!locked_channel || !*locked_channel);
7954
7955 /*!
7956 * \todo XXX Not good. The channel name is not unique if more than
7957 * one originate fails at a time.
7958 */
7959 failed = ast_channel_alloc(0, AST_STATE_DOWN, cid_num, cid_name, account,
7960 "failed", context, NULL, NULL, 0, "OutgoingSpoolFailed");
7961 if (failed) {
7962 char failed_reason[12];
7963
7964 ast_set_variables(failed, vars);
7965 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
7966 pbx_builtin_setvar_helper(failed, "REASON", failed_reason);
7967 ast_channel_unlock(failed);
7968
7969 if (ast_pbx_run(failed)) {
7970 ast_log(LOG_ERROR, "Unable to run PBX on '%s'\n",
7971 ast_channel_name(failed));
7972 ast_hangup(failed);
7973 }
7974 }
7975 }
7976
7977 return res;
7978}
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
adds a list of channel variables to a channel
Definition: channel.c:8115
@ AST_STATE_DOWN
Definition: channelstate.h:36
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:4755
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:4175
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.

References ast_assert, ast_channel_alloc, ast_channel_name(), ast_channel_unlock, ast_exists_extension(), ast_hangup(), ast_log, ast_pbx_run(), ast_set_variables(), AST_STATE_DOWN, voicemailpwcheck::context, LOG_ERROR, NULL, pbx_builtin_setvar_helper(), pbx_outgoing_attempt(), priority, and type.

Referenced by action_originate(), ast_pbx_outgoing_exten(), and originate_exec().

◆ ast_pbx_run()

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 4755 of file pbx.c.

4756{
4757 return ast_pbx_run_args(c, NULL);
4758}
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:4735

References ast_pbx_run_args(), c, and NULL.

Referenced by __analog_ss_thread(), analog_ss_thread(), ari_originate_dial(), ast_bridge_run_after_goto(), ast_pbx_outgoing_exten_predial(), do_notify(), pbx_outgoing_exec(), and unistim_ss().

◆ ast_pbx_run_args()

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 4735 of file pbx.c.

4736{
4738
4740 ast_log(LOG_WARNING, "PBX requires Asterisk to be fully booted\n");
4741 return AST_PBX_FAILED;
4742 }
4743
4744 if (increase_call_count(c)) {
4745 return AST_PBX_CALL_LIMIT;
4746 }
4747
4748 res = __ast_pbx_run(c, args);
4749
4751
4752 return res;
4753}
struct ast_flags ast_options
Definition: options.c:61
@ AST_OPT_FLAG_FULLY_BOOTED
Definition: options.h:58
static void decrease_call_count(void)
Definition: pbx.c:4666
static int increase_call_count(const struct ast_channel *c)
Increase call count for channel.
Definition: pbx.c:4617
static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c, struct ast_pbx_args *args)
Definition: pbx.c:4306
ast_pbx_result
The result codes when starting the PBX on a channel with ast_pbx_start.
Definition: pbx.h:370

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

Referenced by action_dialplan_exec(), ast_pbx_run(), handle_gosub(), msg_route(), and stasis_app_exec().

◆ ast_pbx_start()

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 4708 of file pbx.c.

4709{
4710 pthread_t t;
4711
4712 if (!c) {
4713 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
4714 return AST_PBX_FAILED;
4715 }
4716
4718 ast_log(LOG_WARNING, "PBX requires Asterisk to be fully booted\n");
4719 return AST_PBX_FAILED;
4720 }
4721
4723 return AST_PBX_CALL_LIMIT;
4724
4725 /* Start a new thread, and get something handling this channel. */
4727 ast_log(LOG_WARNING, "Failed to create new channel thread\n");
4729 return AST_PBX_FAILED;
4730 }
4731
4732 return AST_PBX_SUCCESS;
4733}
static void * pbx_thread(void *data)
Definition: pbx.c:4688
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:588

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, c, decrease_call_count(), increase_call_count(), LOG_WARNING, NULL, and pbx_thread().

Referenced by ast_async_goto(), ast_iax2_new(), bridge_failed_peer_goto(), console_new(), dahdi_new(), dial_exec_full(), do_monitor_headset(), generic_recall(), handle_response_clip(), handle_response_cmgr(), jingle_action_session_initiate(), local_call(), ooh323_new(), pbx_start_incoming_request(), and unistim_new().

◆ ast_processed_calls()

int ast_processed_calls ( void  )

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

Definition at line 4765 of file pbx.c.

4766{
4767 return totalcalls;
4768}
static int totalcalls
Definition: pbx.c:779

References totalcalls.

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

◆ ast_rdlock_context()

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 8486 of file pbx.c.

8487{
8488 return ast_rwlock_rdlock(&con->lock);
8489}
#define ast_rwlock_rdlock(a)
Definition: lock.h:235
ast_rwlock_t lock
Definition: pbx.c:288

References ast_rwlock_rdlock, and ast_context::lock.

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

◆ ast_rdlock_contexts()

int ast_rdlock_contexts ( void  )

◆ ast_register_switch()

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 58 of file pbx_switch.c.

59{
60 struct ast_switch *tmp;
61
64 if (!strcasecmp(tmp->name, sw->name)) {
66 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
67 return -1;
68 }
69 }
72
73 return 0;
74}
struct ast_switch::@241 list
const char * name
Definition: pbx.h:162

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

Referenced by load_module().

◆ ast_spawn_extension()

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_spawn

This 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 4200 of file pbx.c.

4201{
4202 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
4203}
@ E_SPAWN
Definition: extconf.h:219

References c, voicemailpwcheck::context, E_SPAWN, ast_exten::exten, NULL, pbx_extension_helper(), and priority.

Referenced by __ast_pbx_run(), ast_pbx_h_exten_run(), gosub_run(), and loopback_exec().

◆ ast_str_get_hint()

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.

Parameters
hintbuffer for hint
hintsizeMaximum size of hint buffer (<0 to prevent growth, >0 to limit growth to that number of bytes, or 0 for unlimited growth)
namebuffer for name portion of hint
namesizeMaximum size of name buffer (<0 to prevent growth, >0 to limit growth to that number of bytes, or 0 for unlimited growth)
cChannel from which to return the hint. This is only important when the hint or name contains an expression to be expanded.
contextwhich context to look in
extenwhich extension to search for
Returns
If an extension within the given context with the priority PRIORITY_HINT is found, a non zero value will be returned. Otherwise, 0 is returned.

If an extension hint exists, return non-zero.

Definition at line 4155 of file pbx.c.

4156{
4158
4159 if (!e) {
4160 return 0;
4161 }
4162
4163 if (hint) {
4164 ast_str_set(hint, hintsize, "%s", ast_get_extension_app(e));
4165 }
4166 if (name) {
4167 const char *tmp = ast_get_extension_app_data(e);
4168 if (tmp) {
4169 ast_str_set(name, namesize, "%s", tmp);
4170 }
4171 }
4172 return -1;
4173}
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:1113

References ast_get_extension_app(), ast_get_extension_app_data(), ast_hint_extension(), ast_str_set(), c, voicemailpwcheck::context, ast_exten::exten, name, and tmp().

Referenced by ast_str_retrieve_variable().

◆ ast_str_retrieve_variable()

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 250 of file pbx_variables.c.

251{
252 const char not_found = '\0';
253 char *tmpvar;
254 const char *ret;
255 const char *s; /* the result */
256 int offset, length;
257 int i, need_substring;
258 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */
259 char workspace[20];
260
261 if (c) {
263 places[0] = ast_channel_varshead(c);
264 }
265 /*
266 * Make a copy of var because parse_variable_name() modifies the string.
267 * Then if called directly, we might need to run substring() on the result;
268 * remember this for later in 'need_substring', 'offset' and 'length'
269 */
270 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
271 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
272
273 /*
274 * Look first into predefined variables, then into variable lists.
275 * Variable 's' points to the result, according to the following rules:
276 * s == &not_found (set at the beginning) means that we did not find a
277 * matching variable and need to look into more places.
278 * If s != &not_found, s is a valid result string as follows:
279 * s = NULL if the variable does not have a value;
280 * you typically do this when looking for an unset predefined variable.
281 * s = workspace if the result has been assembled there;
282 * typically done when the result is built e.g. with an snprintf(),
283 * so we don't need to do an additional copy.
284 * s != workspace in case we have a string, that needs to be copied
285 * (the ast_copy_string is done once for all at the end).
286 * Typically done when the result is already available in some string.
287 */
288 s = &not_found; /* default value */
289 if (c) { /* This group requires a valid channel */
290 /* Names with common parts are looked up a piece at a time using strncmp. */
291 if (!strncmp(var, "CALL", 4)) {
292 if (!strncmp(var + 4, "ING", 3)) {
293 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */
294 ast_str_set(str, maxlen, "%d",
296 s = ast_str_buffer(*str);
297 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */
298 ast_str_set(str, maxlen, "%d", ast_channel_caller(c)->ani2);
299 s = ast_str_buffer(*str);
300 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */
301 ast_str_set(str, maxlen, "%d", ast_channel_caller(c)->id.number.plan);
302 s = ast_str_buffer(*str);
303 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */
304 ast_str_set(str, maxlen, "%d", ast_channel_dialed(c)->transit_network_select);
305 s = ast_str_buffer(*str);
306 }
307 }
308 } else if (!strcmp(var, "HINT")) {
310 } else if (!strcmp(var, "HINTNAME")) {
312 } else if (!strcmp(var, "EXTEN")) {
313 s = ast_channel_exten(c);
314 } else if (!strcmp(var, "CONTEXT")) {
316 } else if (!strcmp(var, "PRIORITY")) {
317 ast_str_set(str, maxlen, "%d", ast_channel_priority(c));
318 s = ast_str_buffer(*str);
319 } else if (!strcmp(var, "CHANNEL")) {
320 s = ast_channel_name(c);
321 } else if (!strcmp(var, "UNIQUEID")) {
323 } else if (!strcmp(var, "HANGUPCAUSE")) {
324 ast_str_set(str, maxlen, "%d", ast_channel_hangupcause(c));
325 s = ast_str_buffer(*str);
326 }
327 }
328 if (s == &not_found) { /* look for more */
329 if (!strcmp(var, "EPOCH")) {
330 ast_str_set(str, maxlen, "%d", (int) time(NULL));
331 s = ast_str_buffer(*str);
332 } else if (!strcmp(var, "SYSTEMNAME")) {
334 } else if (!strcmp(var, "ASTCACHEDIR")) {
336 } else if (!strcmp(var, "ASTETCDIR")) {
338 } else if (!strcmp(var, "ASTMODDIR")) {
340 } else if (!strcmp(var, "ASTVARLIBDIR")) {
342 } else if (!strcmp(var, "ASTDBDIR")) {
344 } else if (!strcmp(var, "ASTKEYDIR")) {
346 } else if (!strcmp(var, "ASTDATADIR")) {
348 } else if (!strcmp(var, "ASTAGIDIR")) {
350 } else if (!strcmp(var, "ASTSPOOLDIR")) {
352 } else if (!strcmp(var, "ASTRUNDIR")) {
354 } else if (!strcmp(var, "ASTLOGDIR")) {
356 } else if (!strcmp(var, "ASTSBINDIR")) {
358 } else if (!strcmp(var, "ENTITYID")) {
359 ast_eid_to_str(workspace, sizeof(workspace), &ast_eid_default);
360 s = workspace;
361 }
362 }
363 /* if not found, look into chanvars or global vars */
364 for (i = 0; s == &not_found && i < ARRAY_LEN(places); i++) {
365 struct ast_var_t *variables;
366 if (!places[i])
367 continue;
368 if (places[i] == &globals)
370 AST_LIST_TRAVERSE(places[i], variables, entries) {
371 if (!strcmp(ast_var_name(variables), var)) {
372 s = ast_var_value(variables);
373 break;
374 }
375 }
376 if (places[i] == &globals)
378 }
379 if (s == &not_found || s == NULL) {
380 ast_debug(5, "Result of '%s' is NULL\n", var);
381 ret = NULL;
382 } else {
383 ast_debug(5, "Result of '%s' is '%s'\n", var, s);
384 if (s != ast_str_buffer(*str)) {
385 ast_str_set(str, maxlen, "%s", s);
386 }
387 ret = ast_str_buffer(*str);
388 if (need_substring) {
389 ret = ast_str_substring(*str, offset, length);
390 ast_debug(2, "Final result of '%s' is '%s'\n", var, ret);
391 }
392 }
393
394 if (c) {
396 }
397 return ret;
398}
#define var
Definition: ast_expr2f.c:605
struct varshead * ast_channel_varshead(struct ast_channel *chan)
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1821
const char * ast_channel_uniqueid(const struct ast_channel *chan)
int ast_channel_hangupcause(const struct ast_channel *chan)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define ast_rwlock_unlock(a)
Definition: lock.h:234
const char * ast_config_AST_KEY_DIR
Definition: options.c:161
const char * ast_config_AST_CACHE_DIR
Definition: options.c:150
const char * ast_config_AST_MODULE_DIR
Definition: options.c:153
const char * ast_config_AST_RUN_DIR
Definition: options.c:162
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
const char * ast_config_AST_SPOOL_DIR
Definition: options.c:154
const char * ast_config_AST_AGI_DIR
Definition: options.c:160
const char * ast_config_AST_VAR_DIR
Definition: options.c:157
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
const char * ast_config_AST_SBIN_DIR
Definition: options.c:163
const char * ast_config_AST_LOG_DIR
Definition: options.c:159
const char * ast_config_AST_DB
Definition: options.c:165
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:4155
static ast_rwlock_t globalslock
static const char * ast_str_substring(struct ast_str *value, int offset, int length)
static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
extract offset:length from variable name.
static struct varshead globals
struct ast_var_t::@211 entries
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: utils.c:2839
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93

References ARRAY_LEN, ast_channel_caller(), ast_channel_context(), ast_channel_dialed(), ast_channel_exten(), ast_channel_hangupcause(), ast_channel_lock, ast_channel_name(), ast_channel_priority(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_varshead(), ast_config_AST_AGI_DIR, ast_config_AST_CACHE_DIR, ast_config_AST_CONFIG_DIR, ast_config_AST_DATA_DIR, ast_config_AST_DB, ast_config_AST_KEY_DIR, ast_config_AST_LOG_DIR, ast_config_AST_MODULE_DIR, ast_config_AST_RUN_DIR, ast_config_AST_SBIN_DIR, ast_config_AST_SPOOL_DIR, ast_config_AST_SYSTEM_NAME, ast_config_AST_VAR_DIR, 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(), c, ast_var_t::entries, globals, globalslock, NULL, parse_variable_name(), str, and var.

Referenced by ast_ari_asterisk_get_global_var(), ast_ari_channels_get_channel_var(), ast_str_substitute_variables_full2(), and pbx_retrieve_variable().

◆ ast_str_substitute_variables()

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 650 of file pbx_variables.c.

651{
652 ast_str_substitute_variables_full(buf, maxlen, chan, NULL, templ, NULL);
653}
void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, struct varshead *headp, const char *templ, size_t *used)

References ast_str_substitute_variables_full(), buf, and NULL.

Referenced by acf_odbc_read(), acf_odbc_write(), ast_pbx_exec_application(), AST_TEST_DEFINE(), cli_odbc_read(), cli_odbc_write(), config_curl(), custom_log(), cut_internal(), destroy_curl(), do_notify(), exec_exec(), func_mchan_read(), function_eval2(), function_fieldnum_helper(), function_fieldqty_helper(), handle_exec(), handle_getvariablefull(), import_helper(), json_decode_read(), listfilter(), make_email_file(), realtime_curl(), realtime_multi_curl(), replace(), require_curl(), sendmail(), sendpage(), shift_pop(), store_curl(), strbetween(), strreplace(), test_2way_function(), test_chan_function(), test_chan_integer(), test_chan_integer_accessor(), test_chan_string(), test_chan_variable(), test_expected_result(), tryexec_exec(), unshift_push(), update2_curl(), and update_curl().

◆ ast_str_substitute_variables_full()

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. (May be NULL)

Definition at line 644 of file pbx_variables.c.

646{
647 ast_str_substitute_variables_full2(buf, maxlen, chan, headp, templ, used, 0);
648}
void ast_str_substitute_variables_full2(struct ast_str **buf, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *templ, size_t *used, int use_both)
Perform variable/function/expression substitution on an ast_str.

References ast_str_substitute_variables_full2(), and buf.

Referenced by ast_str_substitute_variables(), and ast_str_substitute_variables_varshead().

◆ ast_str_substitute_variables_full2()

void ast_str_substitute_variables_full2 ( struct ast_str **  buf,
ssize_t  maxlen,
struct ast_channel c,
struct varshead headp,
const char *  templ,
size_t *  used,
int  use_both 
)

Perform variable/function/expression substitution on an ast_str.

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.
cA channel from which to extract values, and to pass to any dialplan functions.
headpA channel variables list to also search for variables.
templVariable template to expand.
usedNumber of bytes read from the template. (May be NULL)
use_bothNormally, if a channel is specified, headp is ignored. If this parameter is set to 1 and both a channel and headp are specified, the channel will be searched for variables first and any not found will be searched for in headp.

Definition at line 400 of file pbx_variables.c.

403{
404 /* Substitutes variables into buf, based on string templ */
405 const char *whereweare;
406 struct ast_str *substr1 = ast_str_create(16);
407 struct ast_str *substr2 = NULL;
408 struct ast_str *substr3 = ast_str_create(16);
409
411
412 if (!substr1 || !substr3) {
413 if (used) {
414 *used = ast_str_strlen(*buf);
415 }
416 ast_free(substr1);
417 ast_free(substr3);
418 return;
419 }
420
421 whereweare = templ;
422 while (!ast_strlen_zero(whereweare)) {
423 const char *nextvar = NULL;
424 const char *nextexp = NULL;
425 const char *nextthing;
426 const char *vars;
427 const char *vare;
428 char *finalvars;
429 int pos;
430 int brackets;
431 int needsub;
432 int len;
433
434 /* reset our buffer */
435 ast_str_reset(substr3);
436
437 /* Determine how much simply needs to be copied to the output buf. */
438 nextthing = strchr(whereweare, '$');
439 if (nextthing) {
440 pos = nextthing - whereweare;
441 switch (nextthing[1]) {
442 case '{':
443 /* Variable substitution */
444 nextvar = nextthing;
445 break;
446 case '[':
447 /* Expression substitution */
448 nextexp = nextthing;
449 break;
450 default:
451 /* '$' is not part of a substitution so include it too. */
452 ++pos;
453 break;
454 }
455 } else {
456 /* We're copying the whole remaining string */
457 pos = strlen(whereweare);
458 }
459
460 if (pos) {
461 /* Copy that many bytes */
462 ast_str_append_substr(buf, maxlen, whereweare, pos);
463
464 whereweare += pos;
465 }
466
467 if (nextvar) {
468 int offset;
469 int offset2;
470 int isfunction;
471 int res;
472
473 /* We have a variable. Find the start and end, and determine
474 if we are going to have to recursively call ourselves on the
475 contents */
476 vars = vare = nextvar + 2;
477 brackets = 1;
478 needsub = 0;
479
480 /* Find the end of it */
481 while (brackets && *vare) {
482 if ((vare[0] == '$') && (vare[1] == '{')) {
483 needsub++;
484 brackets++;
485 vare++;
486 } else if (vare[0] == '{') {
487 brackets++;
488 } else if (vare[0] == '}') {
489 brackets--;
490 } else if ((vare[0] == '$') && (vare[1] == '[')) {
491 needsub++;
492 vare++;
493 }
494 vare++;
495 }
496 len = vare - vars;
497 if (brackets) {
498 ast_log(LOG_WARNING, "Error in extension logic (missing '}')\n");
499 } else {
500 /* Don't count the closing '}' in the length. */
501 --len;
502 }
503
504 /* Skip totally over variable string */
505 whereweare = vare;
506
507 /* Store variable name expression to lookup. */
508 ast_str_set_substr(&substr1, 0, vars, len);
509 ast_debug(5, "Evaluating '%s' (from '%s' len %d)\n",
510 ast_str_buffer(substr1), vars, len);
511
512 /* Substitute if necessary */
513 if (needsub) {
514 if (!substr2) {
515 substr2 = ast_str_create(16);
516 if (!substr2) {
517 continue;
518 }
519 }
520 ast_str_substitute_variables_full2(&substr2, 0, c, headp,
521 ast_str_buffer(substr1), NULL, use_both);
522 finalvars = ast_str_buffer(substr2);
523 } else {
524 finalvars = ast_str_buffer(substr1);
525 }
526
527 parse_variable_name(finalvars, &offset, &offset2, &isfunction);
528 if (isfunction) {
529 /* Evaluate function */
530 res = -1;
531 if (c) {
532 res = ast_func_read2(c, finalvars, &substr3, 0);
533 ast_debug(2, "Function %s result is '%s' from channel\n",
534 finalvars, res ? "" : ast_str_buffer(substr3));
535 }
536 if (!c || (c && res < 0 && use_both)) {
537 struct varshead old;
538 struct ast_channel *bogus;
539
540 bogus = ast_dummy_channel_alloc();
541 if (bogus) {
542 old = *ast_channel_varshead(bogus);
543 if (headp) {
544 *ast_channel_varshead(bogus) = *headp;
545 }
546 res = ast_func_read2(bogus, finalvars, &substr3, 0);
547 /* Don't deallocate the varshead that was passed in */
548 if (headp) {
549 *ast_channel_varshead(bogus) = old;
550 }
551 ast_channel_unref(bogus);
552 } else {
553 ast_log(LOG_ERROR, "Unable to allocate bogus channel for function value substitution.\n");
554 res = -1;
555 }
556 ast_debug(2, "Function %s result is '%s' from headp\n",
557 finalvars, res ? "" : ast_str_buffer(substr3));
558 }
559 } else {
560 const char *result;
561 if (c) {
562 result = ast_str_retrieve_variable(&substr3, 0, c, NULL, finalvars);
563 ast_debug(2, "Variable %s result is '%s' from channel\n",
564 finalvars, S_OR(result, ""));
565 }
566 if (!c || (c && !result && use_both)) {
567 result = ast_str_retrieve_variable(&substr3, 0, NULL, headp, finalvars);
568 ast_debug(2, "Variable %s result is '%s' from headp\n",
569 finalvars, S_OR(result, ""));
570 }
571 res = (result ? 0 : -1);
572 }
573 if (!res) {
574 ast_str_substring(substr3, offset, offset2);
575 ast_str_append(buf, maxlen, "%s", ast_str_buffer(substr3));
576 }
577 } else if (nextexp) {
578 /* We have an expression. Find the start and end, and determine
579 if we are going to have to recursively call ourselves on the
580 contents */
581 vars = vare = nextexp + 2;
582 brackets = 1;
583 needsub = 0;
584
585 /* Find the end of it */
586 while (brackets && *vare) {
587 if ((vare[0] == '$') && (vare[1] == '[')) {
588 needsub++;
589 brackets++;
590 vare++;
591 } else if (vare[0] == '[') {
592 brackets++;
593 } else if (vare[0] == ']') {
594 brackets--;
595 } else if ((vare[0] == '$') && (vare[1] == '{')) {
596 needsub++;
597 vare++;
598 }
599 vare++;
600 }
601 len = vare - vars;
602 if (brackets) {
603 ast_log(LOG_WARNING, "Error in extension logic (missing ']')\n");
604 } else {
605 /* Don't count the closing ']' in the length. */
606 --len;
607 }
608
609 /* Skip totally over expression */
610 whereweare = vare;
611
612 /* Store expression to evaluate. */
613 ast_str_set_substr(&substr1, 0, vars, len);
614
615 /* Substitute if necessary */
616 if (needsub) {
617 if (!substr2) {
618 substr2 = ast_str_create(16);
619 if (!substr2) {
620 continue;
621 }
622 }
623 ast_str_substitute_variables_full2(&substr2, 0, c, headp,
624 ast_str_buffer(substr1), NULL, use_both);
625 finalvars = ast_str_buffer(substr2);
626 } else {
627 finalvars = ast_str_buffer(substr1);
628 }
629
630 if (ast_str_expr(&substr3, 0, c, finalvars)) {
631 ast_debug(2, "Expression result is '%s'\n", ast_str_buffer(substr3));
632 }
633 ast_str_append(buf, maxlen, "%s", ast_str_buffer(substr3));
634 }
635 }
636 if (used) {
637 *used = ast_str_strlen(*buf);
638 }
639 ast_free(substr1);
640 ast_free(substr2);
641 ast_free(substr3);
642}
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:2433
static PGresult * result
Definition: cel_pgsql.c:84
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1282
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
const char * ast_str_retrieve_variable(struct ast_str **str, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *var)
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:1139
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
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:1062
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
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:1055

References ast_channel_unref, ast_channel_varshead(), 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_full2(), ast_str_substring(), ast_strlen_zero(), buf, c, len(), LOG_ERROR, LOG_WARNING, NULL, parse_variable_name(), result, and S_OR.

Referenced by ast_str_substitute_variables_full(), ast_str_substitute_variables_full2(), and geoloc_eprofile_resolve_varlist().

◆ ast_str_substitute_variables_varshead()

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 655 of file pbx_variables.c.

656{
657 ast_str_substitute_variables_full(buf, maxlen, NULL, headp, templ, NULL);
658}

References ast_str_substitute_variables_full(), buf, and NULL.

Referenced by add_user_extension(), build_user_routes(), handle_aor(), handle_registrations(), phoneprov_callback(), pp_each_extension_helper(), and pp_each_user_helper().

◆ ast_thread_inhibit_escalations()

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 479 of file pbx_functions.c.

480{
481 int *thread_inhibit_escalations;
482
483 thread_inhibit_escalations = ast_threadstorage_get(
484 &thread_inhibit_escalations_tl, sizeof(*thread_inhibit_escalations));
485 if (thread_inhibit_escalations == NULL) {
486 ast_log(LOG_ERROR, "Error inhibiting privilege escalations for current thread\n");
487 return -1;
488 }
489
490 *thread_inhibit_escalations = 1;
491 return 0;
492}
static struct ast_threadstorage thread_inhibit_escalations_tl
Definition: pbx_functions.c:46
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.

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

Referenced by ast_add_extension2_lockopt(), and handle_tcptls_connection().

◆ ast_thread_inhibit_escalations_swap()

int ast_thread_inhibit_escalations_swap ( int  inhibit)

Swap the current thread escalation inhibit setting.

Since
11.24.0
Parameters
inhibitNew setting. Non-zero to inhibit.
Return values
1if dangerous function execution was inhibited.
0if dangerous function execution was allowed.
-1on error.

Definition at line 494 of file pbx_functions.c.

495{
496 int *thread_inhibit_escalations;
497 int orig;
498
499 thread_inhibit_escalations = ast_threadstorage_get(
500 &thread_inhibit_escalations_tl, sizeof(*thread_inhibit_escalations));
501 if (thread_inhibit_escalations == NULL) {
502 ast_log(LOG_ERROR, "Error swapping privilege escalations inhibit for current thread\n");
503 return -1;
504 }
505
506 orig = *thread_inhibit_escalations;
507 *thread_inhibit_escalations = !!inhibit;
508 return orig;
509}

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

Referenced by ast_add_extension2_lockopt().

◆ ast_unlock_context()

int ast_unlock_context ( struct ast_context con)

◆ ast_unlock_contexts()

int ast_unlock_contexts ( void  )

◆ ast_unregister_switch()

void ast_unregister_switch ( struct ast_switch sw)

Unregister an alternative switch.

Parameters
swswitch to unregister

Unregisters a switch from asterisk.

Definition at line 76 of file pbx_switch.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_switch::list.

Referenced by __unload_module(), and unload_module().

◆ ast_walk_context_extensions()

static struct ast_exten * ast_walk_context_extensions ( struct ast_context con,
struct ast_exten priority 
)

◆ ast_walk_context_ignorepats()

const struct ast_ignorepat * ast_walk_context_ignorepats ( const struct ast_context con,
const struct ast_ignorepat ip 
)

Definition at line 8689 of file pbx.c.

8691{
8692 if (!con) {
8693 return NULL;
8694 }
8695
8696 if (ip) {
8697 int idx;
8698 int next = 0;
8699
8700 for (idx = 0; idx < ast_context_ignorepats_count(con); idx++) {
8701 const struct ast_ignorepat *i = ast_context_ignorepats_get(con, idx);
8702
8703 if (next) {
8704 return i;
8705 }
8706
8707 if (ip == i) {
8708 next = 1;
8709 }
8710 }
8711
8712 return NULL;
8713 }
8714
8715 if (!ast_context_ignorepats_count(con)) {
8716 return NULL;
8717 }
8718
8719 return ast_context_ignorepats_get(con, 0);
8720}
struct ast_ignorepat * next
Definition: extconf.c:2388

References ast_context_ignorepats_count(), ast_context_ignorepats_get(), ast_ignorepat::next, and NULL.

◆ ast_walk_context_includes()

const struct ast_include * ast_walk_context_includes ( const struct ast_context con,
const struct ast_include inc 
)

Definition at line 8650 of file pbx.c.

8652{
8653 if (inc) {
8654 int idx;
8655 int next = 0;
8656
8657 for (idx = 0; idx < ast_context_includes_count(con); idx++) {
8658 const struct ast_include *include = AST_VECTOR_GET(&con->includes, idx);
8659
8660 if (next) {
8661 return include;
8662 }
8663
8664 if (inc == include) {
8665 next = 1;
8666 }
8667 }
8668
8669 return NULL;
8670 }
8671
8672 if (!ast_context_includes_count(con)) {
8673 return NULL;
8674 }
8675
8676 return ast_context_includes_get(con, 0);
8677}
struct ast_include * next
Definition: extconf.c:2370

References ast_context_includes_count(), ast_context_includes_get(), AST_VECTOR_GET, ast_context::includes, ast_include::next, and NULL.

Referenced by context_included().

◆ ast_walk_context_switches()

const struct ast_sw * ast_walk_context_switches ( const struct ast_context con,
const struct ast_sw sw 
)

Definition at line 8605 of file pbx.c.

8607{
8608 if (sw) {
8609 int idx;
8610 int next = 0;
8611
8612 for (idx = 0; idx < ast_context_switches_count(con); idx++) {
8613 const struct ast_sw *s = ast_context_switches_get(con, idx);
8614
8615 if (next) {
8616 return s;
8617 }
8618
8619 if (sw == s) {
8620 next = 1;
8621 }
8622 }
8623
8624 return NULL;
8625 }
8626
8627 if (!ast_context_switches_count(con)) {
8628 return NULL;
8629 }
8630
8631 return ast_context_switches_get(con, 0);
8632}
const struct ast_sw * ast_context_switches_get(const struct ast_context *con, int idx)
Definition: pbx.c:8639
struct ast_sw * next
Definition: pbx_sw.c:44

References ast_context_switches_count(), ast_context_switches_get(), ast_sw::next, and NULL.

◆ ast_walk_contexts()

static struct ast_context * ast_walk_contexts ( struct ast_context con)

◆ ast_walk_extension_priorities()

static struct ast_exten * ast_walk_extension_priorities ( struct ast_exten exten,
struct ast_exten priority 
)

◆ ast_wrlock_context()

int ast_wrlock_context ( struct ast_context con)

◆ ast_wrlock_contexts()

int ast_wrlock_contexts ( void  )

◆ pbx_builtin_clear_globals()

void pbx_builtin_clear_globals ( void  )

Definition at line 1308 of file pbx_variables.c.

1309{
1310 struct ast_var_t *vardata;
1311
1313 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
1314 ast_var_delete(vardata);
1316}
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2471

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(), reload(), and unload_pbx_variables().

◆ pbx_builtin_getvar_helper()

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"))) {
}
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 at line 1117 of file pbx_variables.c.

1118{
1119 struct ast_var_t *variables;
1120 const char *ret = NULL;
1121 int i;
1122 struct varshead *places[2] = { NULL, &globals };
1123
1124 if (!name)
1125 return NULL;
1126
1127 if (chan) {
1128 ast_channel_lock(chan);
1129 places[0] = ast_channel_varshead(chan);
1130 }
1131
1132 for (i = 0; i < 2; i++) {
1133 if (!places[i])
1134 continue;
1135 if (places[i] == &globals)
1137 AST_LIST_TRAVERSE(places[i], variables, entries) {
1138 if (!strcmp(name, ast_var_name(variables))) {
1139 ret = ast_var_value(variables);
1140 break;
1141 }
1142 }
1143 if (places[i] == &globals)
1145 if (ret)
1146 break;
1147 }
1148
1149 if (chan)
1150 ast_channel_unlock(chan);
1151
1152 return ret;
1153}

References ast_channel_lock, ast_channel_unlock, ast_channel_varshead(), AST_LIST_TRAVERSE, ast_rwlock_rdlock, ast_rwlock_unlock, ast_var_name(), ast_var_value(), globals, globalslock, name, and NULL.

Referenced by __ast_pbx_run(), _while_exec(), action_agents(), add_header_from_channel_var(), agent_handle_show_specific(), agent_login_channel_config(), agent_request_exec(), agent_show_requested(), analog_call(), array(), ast_bridge_call_with_flags(), ast_bridge_timelimit(), ast_bridge_transfer_attended(), ast_call_forward(), ast_channel_connected_line_sub(), ast_channel_redirecting_sub(), ast_eivr_getvariable(), ast_get_chan_applicationmap(), ast_unreal_hangup(), attended_transfer_exec(), bridge_parking_push(), channel_get_external_vars(), check_bridge_play_sound(), common_exec(), conf_run(), create_dynamic_lot_full(), crement_function_read(), dahdi_hangup(), dial_exec_full(), do_forward(), dundi_exec(), eagi_exec(), feature_automixmonitor(), feature_blind_transfer(), find_by_mark(), find_channel_parking_lot_name(), find_conf_realtime(), func_channel_read(), generate_parked_user(), generic_fax_exec(), get_index(), get_transfer_context(), get_transfer_exten(), global_exists_read(), global_read(), gosub_run(), handle_call_forward(), handle_exec(), handle_gosub(), handle_hangup(), hash_read(), iax2_call(), iax2_exec(), if_helper(), leave_voicemail(), local_read(), manager_mixmonitor(), meetme_menu_admin_extended(), minivm_delete_exec(), minivm_notify_exec(), morsecode_exec(), notify_new_message(), ooh323_call(), ooh323_hangup(), park_app_exec(), pbx_builtin_gotoiftime(), permit_dtmf_interrupt(), pre_bridge_setup(), queue_exec(), receive_ademco_event(), refer_blind_callback(), report_receive_fax_status(), report_send_fax_status(), retrydial_exec(), run_agi(), sayunixtime_exec(), sendtext_exec(), set_from_header(), set_touch_variable(), set_transfer_variables_all(), setup_mixmonitor(), setup_park_common_datastore(), sla_trunk_exec(), speech_background(), transfer_refer(), try_calling(), variable_exists_read(), and wait_for_answer().

◆ pbx_builtin_pushvar_helper()

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 1155 of file pbx_variables.c.

1156{
1157 struct ast_var_t *newvariable;
1158 struct varshead *headp;
1159
1160 if (name[strlen(name)-1] == ')') {
1161 char *function = ast_strdupa(name);
1162
1163 ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
1164 ast_func_write(chan, function, value);
1165 return;
1166 }
1167
1168 if (chan) {
1169 ast_channel_lock(chan);
1170 headp = ast_channel_varshead(chan);
1171 } else {
1173 headp = &globals;
1174 }
1175
1176 if (value && (newvariable = ast_var_assign(name, value))) {
1177 if (headp == &globals)
1178 ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
1179 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
1180 }
1181
1182 if (chan)
1183 ast_channel_unlock(chan);
1184 else
1186}
#define ast_var_assign(name, value)
Definition: chanvars.h:40
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function

References ast_channel_lock, ast_channel_unlock, ast_channel_varshead(), 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, name, and value.

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

◆ pbx_builtin_raise_exception()

int pbx_builtin_raise_exception ( struct ast_channel chan,
const char *  data 
)

Definition at line 721 of file pbx_builtins.c.

722{
723 /* Priority will become 1, next time through the AUTOLOOP */
724 return raise_exception(chan, reason, 0);
725}
int raise_exception(struct ast_channel *chan, const char *reason, int priority)
Definition: pbx.c:2806

References raise_exception().

◆ pbx_builtin_serialize_variables()

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 1086 of file pbx_variables.c.

1087{
1088 struct ast_var_t *variables;
1089 const char *var, *val;
1090 int total = 0;
1091
1092 if (!chan)
1093 return 0;
1094
1096
1097 ast_channel_lock(chan);
1098
1100 if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))
1101 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
1102 ) {
1103 if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) {
1104 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
1105 break;
1106 } else
1107 total++;
1108 } else
1109 break;
1110 }
1111
1112 ast_channel_unlock(chan);
1113
1114 return total;
1115}
static int total
Definition: res_adsi.c:970
Definition: ast_expr2.c:325

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

Referenced by ast_var_channels_table(), and dumpchan_exec().

◆ pbx_builtin_setvar()

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 1246 of file pbx_variables.c.

1247{
1248 char *name, *value, *mydata;
1249
1250 if (ast_strlen_zero(data)) {
1251 ast_log(LOG_WARNING, "Set requires one variable name/value pair.\n");
1252 return 0;
1253 }
1254
1255 mydata = ast_strdupa(data);
1256 name = strsep(&mydata, "=");
1257 value = mydata;
1258 if (!value) {
1259 ast_log(LOG_WARNING, "Set requires an '=' to be a valid assignment.\n");
1260 return 0;
1261 }
1262
1263 if (strchr(name, ' ')) {
1264 ast_log(LOG_WARNING, "Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", name, mydata);
1265 }
1266
1268
1269 return 0;
1270}
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.

References ast_log, ast_strdupa, ast_strlen_zero(), LOG_WARNING, name, pbx_builtin_setvar_helper(), strsep(), and value.

Referenced by ast_compile_ael2(), and load_pbx_variables().

◆ pbx_builtin_setvar_helper()

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

True if the old value was not an empty string.

Definition at line 1188 of file pbx_variables.c.

1189{
1190 struct ast_var_t *newvariable;
1191 struct varshead *headp;
1192 const char *nametail = name;
1193 /*! True if the old value was not an empty string. */
1194 int old_value_existed = 0;
1195
1196 if (name[strlen(name) - 1] == ')') {
1197 char *function = ast_strdupa(name);
1198
1199 return ast_func_write(chan, function, value);
1200 }
1201
1202 if (chan) {
1203 ast_channel_lock(chan);
1204 headp = ast_channel_varshead(chan);
1205 } else {
1207 headp = &globals;
1208 }
1209
1210 /* For comparison purposes, we have to strip leading underscores */
1211 if (*nametail == '_') {
1212 nametail++;
1213 if (*nametail == '_')
1214 nametail++;
1215 }
1216
1217 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
1218 if (strcmp(ast_var_name(newvariable), nametail) == 0) {
1219 /* there is already such a variable, delete it */
1220 AST_LIST_REMOVE_CURRENT(entries);
1221 old_value_existed = !ast_strlen_zero(ast_var_value(newvariable));
1222 ast_var_delete(newvariable);
1223 break;
1224 }
1225 }
1227
1228 if (value && (newvariable = ast_var_assign(name, value))) {
1229 if (headp == &globals) {
1230 ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
1231 }
1232 AST_LIST_INSERT_HEAD(headp, newvariable, entries);
1234 } else if (old_value_existed) {
1235 /* We just deleted a non-empty dialplan variable. */
1237 }
1238
1239 if (chan)
1240 ast_channel_unlock(chan);
1241 else
1243 return 0;
1244}
void ast_channel_publish_varset(struct ast_channel *chan, const char *variable, const char *value)
Publish a ast_channel_publish_varset for a channel.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557

References ast_channel_lock, ast_channel_publish_varset(), ast_channel_unlock, ast_channel_varshead(), 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_strlen_zero(), ast_var_assign, ast_var_delete(), ast_var_name(), ast_var_value(), ast_verb, globals, globalslock, name, and value.

Referenced by __analog_ss_thread(), __ast_pbx_run(), _while_exec(), acf_curl_helper(), acf_fetch(), acf_odbc_read(), acf_odbc_write(), acf_transaction_write(), action_atxfer(), action_kick_last(), action_setvar(), admin_exec(), agent_login_exec(), agent_request_exec(), agi_exec_full(), analog_ss_thread(), app_control_set_channel_var(), app_exec(), aqm_exec(), array(), ast_ari_asterisk_set_global_var(), ast_bridge_set_transfer_variables(), ast_bridge_vars_set(), ast_call_forward(), ast_cc_agent_set_interfaces_chanvar(), ast_eivr_setvariable(), ast_iax2_new(), ast_pbx_outgoing_exten_predial(), ast_pickup_call(), ast_rtp_instance_set_stats_vars(), ast_set_cc_interfaces_chanvar(), ast_set_variables(), AST_TEST_DEFINE(), ast_unreal_hangup(), asyncgoto_exec(), attended_transfer_bridge(), attended_transfer_exec(), audiosocket_request(), background_detect_exec(), begin_dial_channel(), blind_transfer_bridge(), blind_transfer_exec(), bridge_channel_internal_push_full(), bridge_exec(), bridgeadd_exec(), calendar_write_exec(), caller_joined_bridge(), caller_safety_timeout(), cccancel_exec(), ccreq_exec(), chan_pjsip_cng_tone_detected(), chan_pjsip_new(), chanavail_exec(), channel_spy(), check_bridge_play_sound(), clear_agent_status(), commit_exec(), conf_run(), confbridge_exec(), confkick_exec(), controlplayback_exec(), count_exec(), crement_function_read(), dahdi_handle_dtmf(), dahdi_new(), delete_write(), dial_exec_full(), dial_transfer(), directory_exec(), disa_exec(), do_directory(), do_forward(), do_notify(), do_waiting(), dtmf_store_framehook(), dynamic_dtmf_hook_callback(), end_bridge_callback(), execute_menu_entry(), fax_detect_framehook(), frame_set_var(), func_export_write(), func_mchan_write(), function_db_delete(), function_db_exists(), function_db_read(), function_realtime_store(), generic_recall(), geoloc_profile_read(), geoloc_profile_write(), global_delete_write(), global_write(), gosub_release_frame(), gosub_run(), handle_controlstreamfile(), handle_gosub(), handle_incoming_request(), handle_outgoing_response(), handle_response_cmgr(), handle_set_chanvar(), handle_set_global(), handle_setvariable(), handle_streamfile(), hash_read(), hash_write(), if_helper(), isAnsweringMachine(), kick_conference_participant(), launch_monitor_thread(), leave_marked(), leave_queue(), leave_voicemail(), lua_set_variable(), lua_set_variable_value(), manager_park(), mbl_status_exec(), minivm_accmess_exec(), minivm_delete_exec(), minivm_greet_exec(), minivm_notify_exec(), minivm_record_exec(), mixmonitor_exec(), msg_send_exec(), my_get_callerid(), my_handle_dtmf(), onModeChanged(), ooh323_new(), ooh323_rtp_read(), originate_exec(), parking_duration_callback(), parking_timeout_set_caller_features(), pbx_builtin_background(), pbx_builtin_gotoiftime(), pbx_builtin_setvar(), pbx_builtin_setvar_multiple(), pbx_builtin_waitdigit(), pbx_load_config(), play_message_datetime(), playback_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), queue_exec(), read_exec(), read_mf_digits(), read_mf_exec(), read_sf_digits(), read_sf_exec(), readexten_exec(), realtimefield_read(), receivefax_exec(), record_abandoned(), record_exec(), recvtext_exec(), refer_blind_callback(), reload_exec(), reload_module(), return_exec(), ring_entry(), rollback_exec(), rotate_file(), rqm_exec(), scan_exec(), select_entry(), select_item_menu(), select_item_seq(), sendfax_exec(), sendtext_exec(), set(), set_channel_variables(), set_duration_var(), set_queue_result(), set_sipdomain_variable(), shift_pop(), signal_exec(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), speech_create(), start_automixmonitor(), system_exec_helper(), test_chan_variable(), testtime_write(), transfer_exec(), tryexec_exec(), unicast_rtp_request(), unshift_push(), update_qe_rule(), upqm_exec(), user_timeout(), vm_exec(), vm_playmsgexec(), vmauthenticate(), wait_exec(), wait_for_answer(), wait_for_signal_or_hangup(), waitforcond_exec(), waitsignal_exec(), waituntil_exec(), and zapateller_exec().

◆ pbx_builtin_setvar_multiple()

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 1272 of file pbx_variables.c.

1273{
1274 char *data;
1275 int x;
1277 AST_APP_ARG(pair)[99]; /* parse up to 99 variables */
1278 );
1282 );
1283
1284 if (ast_strlen_zero(vdata)) {
1285 ast_log(LOG_WARNING, "MSet requires at least one variable name/value pair.\n");
1286 return 0;
1287 }
1288
1289 data = ast_strdupa(vdata);
1291
1292 for (x = 0; x < args.argc; x++) {
1293 AST_NONSTANDARD_APP_ARGS(pair, args.pair[x], '=');
1294 if (pair.argc == 2) {
1296 if (strchr(pair.name, ' '))
1297 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);
1298 } else if (!chan) {
1299 ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '='\n", pair.name);
1300 } else {
1301 ast_log(LOG_WARNING, "MSet: ignoring entry '%s' with no '=' (in %s@%s:%d\n", pair.name, ast_channel_exten(chan), ast_channel_context(chan), ast_channel_priority(chan));
1302 }
1303 }
1304
1305 return 0;
1306}
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
const char * name
Definition: test_config.c:85

References args, AST_APP_ARG, ast_channel_context(), ast_channel_exten(), ast_channel_priority(), AST_DECLARE_APP_ARGS, ast_log, AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), LOG_WARNING, name, pair::name, pbx_builtin_setvar_helper(), and value.

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

◆ pbx_checkcondition()

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 8282 of file pbx.c.

8283{
8284 int res;
8285 if (ast_strlen_zero(condition)) { /* NULL or empty strings are false */
8286 return 0;
8287 } else if (sscanf(condition, "%30d", &res) == 1) { /* Numbers are evaluated for truth */
8288 return res;
8289 } else { /* Strings are true */
8290 return 1;
8291 }
8292}

References ast_strlen_zero().

Referenced by _while_exec(), acf_if(), execif_exec(), gosubif_exec(), if_helper(), pbx_builtin_gotoif(), testtime_write(), and waitforcond_exec().

◆ pbx_exec()

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
Note
This function is special. It saves the stack so that no matter how many times it is called, it returns to the same place
Parameters
cChannel
appApplication
dataData for execution

Definition at line 471 of file pbx_app.c.

474{
475 int res;
476 struct ast_module_user *u = NULL;
477 const char *saved_c_appl;
478 const char *saved_c_data;
479
480 /* save channel values */
481 saved_c_appl= ast_channel_appl(c);
482 saved_c_data= ast_channel_data(c);
483
485 ast_channel_appl_set(c, app->name);
486 ast_channel_data_set(c, data);
489
490 if (app->module)
491 u = __ast_module_user_add(app->module, c);
492 res = app->execute(c, S_OR(data, ""));
493 if (app->module && u)
494 __ast_module_user_remove(app->module, u);
495 /* restore channel values */
496 ast_channel_appl_set(c, saved_c_appl);
497 ast_channel_data_set(c, saved_c_data);
498 return res;
499}
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
const char * ast_channel_data(const struct ast_channel *chan)
void ast_channel_data_set(struct ast_channel *chan, const char *value)
const char * ast_channel_appl(const struct ast_channel *chan)

References __ast_module_user_add(), __ast_module_user_remove(), app, ast_channel_appl(), ast_channel_appl_set(), ast_channel_data(), ast_channel_data_set(), ast_channel_lock, ast_channel_publish_snapshot(), ast_channel_unlock, c, NULL, and S_OR.

Referenced by aelsub_exec(), ari_channel_thread(), ari_originate_dial(), ast_pbx_exec_application(), AST_TEST_DEFINE(), bridge_stasis_run_cb(), conf_run(), conf_start_record(), exec_exec(), execif_exec(), forward_message(), handle_exec(), iax2_exec(), lua_pbx_exec(), page_exec(), pbx_extension_helper(), pbx_outgoing_exec(), realtime_exec(), try_calling(), and tryexec_exec().

◆ pbx_find_extension()

static 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 152 of file ael_main.c.

161{
162 return localized_find_extension(bypass, q, context, exten, priority, label, callerid, action);
163}
struct ast_exten * localized_find_extension(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: extconf.c:4468

References ast_autoservice_start(), ast_autoservice_stop(), ast_context_includes_count(), ast_context_includes_get(), ast_context_switches_count(), ast_context_switches_get(), ast_debug, ast_get_switch_data(), ast_get_switch_eval(), ast_get_switch_name(), ast_hashtab_lookup(), 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, voicemailpwcheck::context, create_match_char_tree(), pbx_find_info::data, E_CANMATCH, E_FINDLABEL, E_MATCHMORE, ast_switch::exists, ast_exten::exten, scoreboard::exten, extenpatternmatchnew, extension_match_core(), find_context(), pbx_find_info::foundcontext, include_rname(), include_valid(), pbx_find_info::incstack, ast_exten::label, scoreboard::last_char, localized_find_extension(), LOG_NOTICE, LOG_WARNING, match(), matchcid(), ast_switch::matchmore, name, new_find_extension(), scoreboard::node, NULL, overrideswitch, pbx_find_extension(), pbx_findswitch(), pbx_substitute_variables_helper(), priority, ast_exten::priority, 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, tmp(), scoreboard::total_length, scoreboard::total_specificity, and trie_find_next_match().

Referenced by add_extension(), ast_get_extension_data(), ast_hint_extension_nolock(), ast_merge_contexts_and_delete(), ast_sip_persistent_endpoint_update_state(), check_goto(), check_pval_item(), conf_ended(), delete_extens(), parking_blind_transfer_park(), parking_duration_callback(), parking_is_exten_park(), parking_lot_cfg_create_extensions(), pbx_extension_helper(), pbx_find_extension(), and test_exten().

◆ pbx_findapp()

struct ast_app * pbx_findapp ( const char *  app)

Look up an application.

Parameters
appname of the app

This function searches for the ast_app structure within the apps that are registered for the one with the name you passed in.

Returns
the ast_app structure that matches on success, or NULL on failure

Definition at line 165 of file ael_main.c.

166{
167 return (struct ast_app*)1; /* so as not to trigger an error */
168}

References app, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and pbx_findapp_nolock().

Referenced by aelsub_exec(), ari_channel_thread(), ari_originate_dial(), ast_pbx_exec_application(), AST_TEST_DEFINE(), bridge_stasis_run_cb(), conf_run(), conf_start_record(), exec_exec(), execif_exec(), forward_message(), handle_exec(), iax2_exec(), lua_pbx_exec(), page_exec(), pbx_extension_helper(), pbx_outgoing_exec(), realtime_exec(), try_calling(), and tryexec_exec().

◆ pbx_live_dangerously()

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 466 of file pbx_functions.c.

467{
468 if (new_live_dangerously && !live_dangerously) {
469 ast_log(LOG_WARNING, "Privilege escalation protection disabled!\n"
470 "See https://docs.asterisk.org/Configuration/Dialplan/Privilege-Escalations-with-Dialplan-Functions/ for more details.\n");
471 }
472
473 if (!new_live_dangerously && live_dangerously) {
474 ast_log(LOG_NOTICE, "Privilege escalation protection enabled.\n");
475 }
476 live_dangerously = new_live_dangerously;
477}
static int live_dangerously
Set to true (non-zero) to globally allow all dangerous dialplan functions to run.
Definition: pbx_functions.c:52

References ast_log, live_dangerously, LOG_NOTICE, and LOG_WARNING.

Referenced by load_asterisk_conf().

◆ pbx_parse_location()

int pbx_parse_location ( struct ast_channel chan,
char **  context,
char **  exten,
char **  pri,
int *  ipri,
int *  mode,
char *  rest 
)

Parses a dialplan location into context, extension, priority.

Parameters
chanChannel to execute on
contextPointer to initial value for context.
extenPointer to initial value for exten.
priPointer to initial value for pri
ipriPointer to integer value of priority
modePointer to mode (or NULL if mode is not used)
restPointer to buffer to capture rest of parsing (or NULL if not used)

strsep should be used to initially populate context, exten, and pri prior to calling this function. All arguments are modified in place.

Return values
0success
non-zerofailure

Definition at line 8791 of file pbx.c.

8792{
8793 char *context, *exten, *pri;
8794 /* do the strsep before here, so we don't have to alloc and free */
8795 if (!*extenp) {
8796 /* Only a priority in this one */
8797 *prip = *contextp;
8798 *extenp = NULL;
8799 *contextp = NULL;
8800 } else if (!*prip) {
8801 /* Only an extension and priority in this one */
8802 *prip = *extenp;
8803 *extenp = *contextp;
8804 *contextp = NULL;
8805 }
8806 context = *contextp;
8807 exten = *extenp;
8808 pri = *prip;
8809 if (mode) {
8810 if (*pri == '+') {
8811 *mode = 1;
8812 pri++;
8813 } else if (*pri == '-') {
8814 *mode = -1;
8815 pri++;
8816 }
8817 }
8818 if ((rest && sscanf(pri, "%30d%1s", ipri, rest) != 1) || sscanf(pri, "%30d", ipri) != 1) {
8820 exten ? exten : ast_channel_exten(chan), pri,
8821 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL));
8822 if (*ipri < 1) {
8823 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
8824 return -1;
8825 } else if (mode) {
8826 *mode = 0;
8827 }
8828 }
8829 return 0;
8830}
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:4180

References ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_findlabel_extension(), ast_log, voicemailpwcheck::context, ast_channel::exten, LOG_WARNING, NULL, and S_COR.

Referenced by eval_exten_read(), and pbx_parseable_goto().

◆ pbx_retrieve_variable()

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.

Note
Will lock the channel.

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

Note
See also

Definition at line 239 of file pbx_variables.c.

240{
241 struct ast_str *str = ast_str_create(16);
242 const char *cret;
243
244 cret = ast_str_retrieve_variable(&str, 0, c, headp, var);
245 ast_copy_string(workspace, ast_str_buffer(str), workspacelen);
246 *ret = cret ? workspace : NULL;
247 ast_free(str);
248}

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

Referenced by action_getvar(), generate_status(), handle_getvariable(), lua_get_variable(), lua_get_variable_value(), and pbx_substitute_variables_helper_full_location().

◆ pbx_set_autofallthrough()

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 4770 of file pbx.c.

4771{
4772 int oldval = autofallthrough;
4773 autofallthrough = newval;
4774 return oldval;
4775}
static int autofallthrough
Definition: pbx.c:768

References autofallthrough.

Referenced by pbx_load_module().

◆ pbx_set_extenpatternmatchnew()

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 4777 of file pbx.c.

4778{
4779 int oldval = extenpatternmatchnew;
4780 extenpatternmatchnew = newval;
4781 return oldval;
4782}
static int extenpatternmatchnew
Definition: pbx.c:769

References extenpatternmatchnew.

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

◆ pbx_set_overrideswitch()

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 4784 of file pbx.c.

4785{
4786 if (overrideswitch) {
4788 }
4789 if (!ast_strlen_zero(newval)) {
4790 overrideswitch = ast_strdup(newval);
4791 } else {
4793 }
4794}
static char * overrideswitch
Definition: pbx.c:770

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

Referenced by pbx_load_module().

◆ pbx_substitute_variables_helper()

static void pbx_substitute_variables_helper ( struct ast_channel c,
const char *  cp1,
char *  cp2,
int  count 
)

◆ pbx_substitute_variables_helper_full()

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 at line 660 of file pbx_variables.c.

661{
662 pbx_substitute_variables_helper_full_location(c, headp, cp1, cp2, count, used, NULL, NULL, 0);
663}
void pbx_substitute_variables_helper_full_location(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count, size_t *used, const char *context, const char *exten, int pri)
Substitutes variables, similar to pbx_substitute_variables_helper_full, but allows passing the contex...

References c, NULL, and pbx_substitute_variables_helper_full_location().

Referenced by pbx_substitute_variables_helper(), and pbx_substitute_variables_varshead().

◆ pbx_substitute_variables_helper_full_location()

void pbx_substitute_variables_helper_full_location ( struct ast_channel c,
struct varshead headp,
const char *  cp1,
char *  cp2,
int  cp2_size,
size_t *  used,
const char *  context,
const char *  exten,
int  pri 
)

Substitutes variables, similar to pbx_substitute_variables_helper_full, but allows passing the context, extension, and priority in.

Definition at line 670 of file pbx_variables.c.

671{
672 /* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!! */
673 const char *whereweare;
674 const char *orig_cp2 = cp2;
675 char ltmp[VAR_BUF_SIZE];
676 char var[VAR_BUF_SIZE];
677 int *recurse_depth;
678
679 *cp2 = 0; /* just in case nothing ends up there */
680
681 /* It is possible to craft dialplan that will recurse indefinitely and cause a stack overflow.
682 * This is symptomatic of a dialplan bug, so abort substitution rather than crash. */
683 recurse_depth = ast_threadstorage_get(&varsub_recurse_level, sizeof(*recurse_depth));
684 if (!recurse_depth) {
685 return;
686 }
687 if ((*recurse_depth)++ >= MAX_VARIABLE_SUB_RECURSE_DEPTH) {
688 ast_log(LOG_ERROR, "Exceeded maximum variable substitution recursion depth (%d) - possible infinite recursion in dialplan?\n", MAX_VARIABLE_SUB_RECURSE_DEPTH);
689 (*recurse_depth)--;
690 return;
691 }
692
693 whereweare = cp1;
694 while (!ast_strlen_zero(whereweare) && count) {
695 char *nextvar = NULL;
696 char *nextexp = NULL;
697 char *nextthing;
698 char *vars;
699 char *vare;
700 int length;
701 int pos;
702 int brackets;
703 int needsub;
704 int len;
705
706 /* Determine how much simply needs to be copied to the output buf. */
707 nextthing = strchr(whereweare, '$');
708 if (nextthing) {
709 pos = nextthing - whereweare;
710 switch (nextthing[1]) {
711 case '{':
712 /* Variable substitution */
713 nextvar = nextthing;
714 break;
715 case '[':
716 /* Expression substitution */
717 nextexp = nextthing;
718 break;
719 default:
720 /* '$' is not part of a substitution so include it too. */
721 ++pos;
722 break;
723 }
724 } else {
725 /* We're copying the whole remaining string */
726 pos = strlen(whereweare);
727 }
728
729 if (pos) {
730 /* Can't copy more than 'count' bytes */
731 if (pos > count)
732 pos = count;
733
734 /* Copy that many bytes */
735 memcpy(cp2, whereweare, pos);
736
737 count -= pos;
738 cp2 += pos;
739 whereweare += pos;
740 *cp2 = 0;
741 }
742
743 if (nextvar) {
744 int offset;
745 int offset2;
746 int isfunction;
747 char *cp4 = NULL;
748 char workspace[VAR_BUF_SIZE] = "";
749
750 /* We have a variable. Find the start and end, and determine
751 if we are going to have to recursively call ourselves on the
752 contents */
753 vars = vare = nextvar + 2;
754 brackets = 1;
755 needsub = 0;
756
757 /* Find the end of it */
758 while (brackets && *vare) {
759 if ((vare[0] == '$') && (vare[1] == '{')) {
760 needsub++;
761 brackets++;
762 vare++;
763 } else if (vare[0] == '{') {
764 brackets++;
765 } else if (vare[0] == '}') {
766 brackets--;
767 } else if ((vare[0] == '$') && (vare[1] == '[')) {
768 needsub++;
769 vare++;
770 }
771 vare++;
772 }
773 len = vare - vars;
774 if (brackets) {
775 ast_log(LOG_WARNING, "Error in extension logic (missing '}')\n");
776 } else {
777 /* Don't count the closing '}' in the length. */
778 --len;
779 }
780
781 /* Skip totally over variable string */
782 whereweare = vare;
783
784 /* Store variable name expression to lookup (and truncate). */
785 ast_copy_string(var, vars, len + 1);
786
787 /* Substitute if necessary */
788 if (needsub) {
790 vars = ltmp;
791 } else {
792 vars = var;
793 }
794
795 parse_variable_name(vars, &offset, &offset2, &isfunction);
796 if (isfunction) {
797 /* Evaluate function */
798 if (c || !headp)
799 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
800 else {
801 struct varshead old;
802 struct ast_channel *bogus;
803
804 bogus = ast_dummy_channel_alloc();
805 if (bogus) {
806 old = *ast_channel_varshead(bogus);
807 *ast_channel_varshead(bogus) = *headp;
808 cp4 = ast_func_read(bogus, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
809 /* Don't deallocate the varshead that was passed in */
810 *ast_channel_varshead(bogus) = old;
811 ast_channel_unref(bogus);
812 } else {
813 ast_log(LOG_ERROR, "Unable to allocate bogus channel for function value substitution.\n");
814 cp4 = NULL;
815 }
816 }
817 ast_debug(2, "Function %s result is '%s'\n", vars, cp4 ? cp4 : "(null)");
818 } else {
819 /* Retrieve variable value */
820 /* For dialplan location, if we were told what to substitute explicitly, use that instead */
821 if (exten && !strcmp(vars, "EXTEN")) {
823 cp4 = workspace;
824 } else if (context && !strcmp(vars, "CONTEXT")) {
826 cp4 = workspace;
827 } else if (pri && !strcmp(vars, "PRIORITY")) {
828 snprintf(workspace, VAR_BUF_SIZE, "%d", pri);
829 cp4 = workspace;
830 } else {
831 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);
832 }
833 }
834 if (cp4) {
835 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);
836
837 length = strlen(cp4);
838 if (length > count)
839 length = count;
840 memcpy(cp2, cp4, length);
841 count -= length;
842 cp2 += length;
843 *cp2 = 0;
844 }
845 } else if (nextexp) {
846 /* We have an expression. Find the start and end, and determine
847 if we are going to have to recursively call ourselves on the
848 contents */
849 vars = vare = nextexp + 2;
850 brackets = 1;
851 needsub = 0;
852
853 /* Find the end of it */
854 while (brackets && *vare) {
855 if ((vare[0] == '$') && (vare[1] == '[')) {
856 needsub++;
857 brackets++;
858 vare++;
859 } else if (vare[0] == '[') {
860 brackets++;
861 } else if (vare[0] == ']') {
862 brackets--;
863 } else if ((vare[0] == '$') && (vare[1] == '{')) {
864 needsub++;
865 vare++;
866 }
867 vare++;
868 }
869 len = vare - vars;
870 if (brackets) {
871 ast_log(LOG_WARNING, "Error in extension logic (missing ']')\n");
872 } else {
873 /* Don't count the closing ']' in the length. */
874 --len;
875 }
876
877 /* Skip totally over expression */
878 whereweare = vare;
879
880 /* Store expression to evaluate (and truncate). */
881 ast_copy_string(var, vars, len + 1);
882
883 /* Substitute if necessary */
884 if (needsub) {
886 vars = ltmp;
887 } else {
888 vars = var;
889 }
890
891 length = ast_expr(vars, cp2, count, c);
892 if (length) {
893 ast_debug(1, "Expression result is '%s'\n", cp2);
894 count -= length;
895 cp2 += length;
896 *cp2 = 0;
897 }
898 }
899 }
900 if (used) {
901 *used = cp2 - orig_cp2;
902 }
903 (*recurse_depth)--;
904}
int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan)
Evaluate the given expression.
Definition: ast_expr2f.c:2391
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
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.
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.
static struct ast_threadstorage varsub_recurse_level
#define MAX_VARIABLE_SUB_RECURSE_DEPTH

References ast_channel_unref, ast_channel_varshead(), ast_copy_string(), ast_debug, ast_dummy_channel_alloc, ast_expr(), ast_func_read(), ast_log, ast_strlen_zero(), ast_threadstorage_get(), c, voicemailpwcheck::context, ast_channel::exten, len(), LOG_ERROR, LOG_WARNING, MAX_VARIABLE_SUB_RECURSE_DEPTH, NULL, parse_variable_name(), pbx_retrieve_variable(), pbx_substitute_variables_helper_full_location(), substring(), var, VAR_BUF_SIZE, and varsub_recurse_level.

Referenced by eval_exten_read(), pbx_substitute_variables_helper_full(), and pbx_substitute_variables_helper_full_location().

◆ pbx_substitute_variables_varshead()

void pbx_substitute_variables_varshead ( struct varshead headp,
const char *  cp1,
char *  cp2,
int  count 
)

Definition at line 911 of file pbx_variables.c.

912{
913 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count, NULL);
914}
void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count, size_t *used)

References NULL, and pbx_substitute_variables_helper_full().

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