Thu Jul 9 13:41:26 2009

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

#include "asterisk/sched.h"
#include "asterisk/chanvars.h"
#include "asterisk/hashtab.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_pbx
struct  ast_pbx_args
 Options for ast_pbx_run(). More...
struct  ast_switch
struct  ast_timing
struct  pbx_find_info
Functions for returning values from structures

const char * ast_get_context_name (struct ast_context *con)
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 (struct ast_ignorepat *ip)
const char * ast_get_include_name (struct ast_include *include)
const char * ast_get_switch_data (struct ast_sw *sw)
int ast_get_switch_eval (struct ast_sw *sw)
const char * ast_get_switch_name (struct ast_sw *sw)

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 (struct ast_ignorepat *ip)
const char * ast_get_include_registrar (struct ast_include *i)
const char * ast_get_switch_registrar (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)
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)

Defines

#define ast_custom_function_register(acf)   __ast_custom_function_register(acf, ast_module_info->self)
 Register a custom function.
#define AST_MAX_APP   32
#define AST_PBX_ERROR   1
#define AST_PBX_HANGUP   -1
 Special return values from applications to the PBX {.
#define AST_PBX_KEEP   0
#define AST_PBX_MAX_STACK   128
#define AST_PBX_OK   0
#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

Typedefs

typedef int(*) ast_state_cb_type (char *context, char *id, enum ast_extension_states state, void *data)
 Typedef for devicestate and hint callbacks.
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.

Enumerations

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
}
 Extension states. More...
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 channelwith. More...
enum  ext_match_t {
  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.
int ast_active_calls (void)
 Retrieve the number of active calls.
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.
int ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add an extension to an extension context, this time with an ast_context *.
int ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_async_goto_by_name (const char *chan, const char *context, const char *exten, int priority)
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)
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.
int ast_check_timing (const struct ast_timing *i)
int ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar)
 Add an ignorepat.
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.
int ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar)
 Add a switch.
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).
void ast_context_destroy (struct ast_context *con, const char *registrar)
 Destroy a context (matches the specified context (or ANY context if NULL).
ast_contextast_context_find (const char *name)
 Find a context.
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.
int ast_context_lockmacro (const char *macrocontext)
 locks the macrolock in the given given context
int ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar)
 Simply remove extension from context.
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.
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)
int ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar)
int ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_remove_include (const char *context, const char *include, const char *registrar)
 Remove a context include.
int ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar)
 Removes an include by an ast_context structure.
int ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar)
 Remove a switch.
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.
int ast_context_unlockmacro (const char *macrocontext)
 Unlocks the macrolock in the given context.
int ast_context_verify_includes (struct ast_context *con)
 Verifies includes in an ast_contect structure.
ast_custom_functionast_custom_function_find (const char *name)
int ast_custom_function_unregister (struct ast_custom_function *acf)
 Unregister a custom function.
int ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Determine whether an extension exists.
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.
int ast_extension_match (const char *pattern, const char *extension)
 Determine if a given extension matches a given pattern (in NXX format).
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.
const char * ast_extension_state2str (int extension_state)
 Return string representation of the state of an extension.
int ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data)
 Registers a state change callback.
int ast_extension_state_del (int id, ast_state_cb_type callback)
 Deletes a registered state change callback by ID.
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.
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.
int ast_func_read (struct ast_channel *chan, const char *function, char *workspace, size_t len)
 executes a read operation on a function
int ast_func_write (struct ast_channel *chan, const char *function, const char *value)
 executes a write operation on a function
int ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten)
 If an extension hint exists, return non-zero.
int ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_hashtab_compare_contexts (const void *ah_a, const void *ah_b)
unsigned int ast_hashtab_hash_contexts (const void *obj)
int ast_ignore_pattern (const char *context, const char *pattern)
 Checks to see if a number should be ignored.
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).
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.
int ast_parseable_goto (struct ast_channel *chan, const char *goto_string)
int ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
int ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
enum ast_pbx_result ast_pbx_run (struct ast_channel *c)
 Execute the PBX in the current thread.
enum ast_pbx_result ast_pbx_run_args (struct ast_channel *c, struct ast_pbx_args *args)
 Execute the PBX in the current thread.
enum ast_pbx_result ast_pbx_start (struct ast_channel *c)
 Create a new thread and start the PBX.
int ast_processed_calls (void)
 Retrieve the total number of calls processed through the PBX since last restart.
int ast_rdlock_context (struct ast_context *con)
 Read locks a given context.
int ast_rdlock_contexts (void)
 Read locks the context list.
int ast_register_switch (struct ast_switch *sw)
 Register an alternative dialplan switch.
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).
int ast_unlock_context (struct ast_context *con)
int ast_unlock_contexts (void)
 Unlocks contexts.
void ast_unregister_switch (struct ast_switch *sw)
 Unregister an alternative switch.
ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *priority)
ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
ast_contextast_walk_contexts (struct ast_context *con)
ast_extenast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority)
int ast_wrlock_context (struct ast_context *con)
 Write locks a given context.
int ast_wrlock_contexts (void)
 Write locks the context list.
int ast_wrlock_contexts_version (void)
void pbx_builtin_clear_globals (void)
const char * pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name)
void pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_builtin_raise_exception (struct ast_channel *chan, void *data)
int pbx_builtin_serialize_variables (struct ast_channel *chan, struct ast_str **buf)
int pbx_builtin_setvar (struct ast_channel *chan, void *data)
void pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value)
int pbx_builtin_setvar_multiple (struct ast_channel *chan, void *data)
int pbx_checkcondition (const char *condition)
 Evaluate a condition.
int pbx_exec (struct ast_channel *c, struct ast_app *app, void *data)
 Execute an application.
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)
ast_apppbx_findapp (const char *app)
 Look up an application.
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.
int pbx_set_autofallthrough (int newval)
int pbx_set_extenpatternmatchnew (int newval)
void pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count)
void pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count)


Detailed Description

Core PBX routines and definitions.

Definition in file pbx.h.


Define Documentation

#define ast_custom_function_register ( acf   )     __ast_custom_function_register(acf, ast_module_info->self)

Register a custom function.

Definition at line 960 of file pbx.h.

Referenced by load_module(), and reload().

#define AST_MAX_APP   32

Max length of an application

Definition at line 34 of file pbx.h.

Referenced by destroy_station(), handle_show_application(), and handle_show_function().

#define AST_PBX_ERROR   1

Jump to the 'e' exten

Definition at line 42 of file pbx.h.

#define AST_PBX_HANGUP   -1

Special return values from applications to the PBX {.

Jump to the 'h' exten

Definition at line 40 of file pbx.h.

#define AST_PBX_KEEP   0

Definition at line 36 of file pbx.h.

#define AST_PBX_MAX_STACK   128

Definition at line 1025 of file pbx.h.

#define AST_PBX_OK   0

No errors

Definition at line 41 of file pbx.h.

#define AST_PBX_REPLACE   1

Definition at line 37 of file pbx.h.

#define PRIORITY_HINT   -1

} Special Priority for a hint

Definition at line 45 of file pbx.h.

Referenced by ast_add_extension2_lockopt(), ast_hint_extension(), ast_merge_contexts_and_delete(), destroy_exten(), destroy_station(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), park_add_hints(), pbx_load_config(), and print_ext().

#define STATUS_NO_CONTEXT   1

Definition at line 1020 of file pbx.h.

#define STATUS_NO_EXTENSION   2

Definition at line 1021 of file pbx.h.

#define STATUS_NO_LABEL   4

Definition at line 1023 of file pbx.h.

#define STATUS_NO_PRIORITY   3

Definition at line 1022 of file pbx.h.

#define STATUS_SUCCESS   5

Definition at line 1024 of file pbx.h.


Typedef Documentation

typedef int(*) ast_state_cb_type(char *context, char *id, enum ast_extension_states state, void *data)

Typedef for devicestate and hint callbacks.

Definition at line 70 of file pbx.h.

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


Enumeration Type Documentation

enum ast_extension_states

Extension states.

Note:
States can be combined
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

Definition at line 51 of file pbx.h.

00051                           {
00052    AST_EXTENSION_REMOVED = -2,   /*!< Extension removed */
00053    AST_EXTENSION_DEACTIVATED = -1,  /*!< Extension hint removed */
00054    AST_EXTENSION_NOT_INUSE = 0,  /*!< No device INUSE or BUSY  */
00055    AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
00056    AST_EXTENSION_BUSY = 1 << 1,  /*!< All devices BUSY */
00057    AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
00058    AST_EXTENSION_RINGING = 1 << 3,  /*!< All devices RINGING */
00059    AST_EXTENSION_ONHOLD = 1 << 4,   /*!< All devices ONHOLD */
00060 };

enum ast_pbx_result

The result codes when starting the PBX on a channelwith.

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

Definition at line 227 of file pbx.h.

00227                     {
00228    AST_PBX_SUCCESS = 0,
00229    AST_PBX_FAILED = -1,
00230    AST_PBX_CALL_LIMIT = -2,
00231 };

enum 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 

Definition at line 1011 of file pbx.h.

01011                  {
01012    E_MATCHMORE =  0x00, /* extension can match but only with more 'digits' */
01013    E_CANMATCH =   0x01, /* extension can match with or without more 'digits' */
01014    E_MATCH =   0x02, /* extension is an exact match */
01015    E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
01016    E_SPAWN =   0x12, /* want to spawn an extension. Requires exact match */
01017    E_FINDLABEL =  0x22  /* returns the priority for a given label. Requires exact match */
01018 };


Function Documentation

int __ast_custom_function_register ( struct ast_custom_function acf,
struct ast_module mod 
)

Register a custom function.

Definition at line 2714 of file pbx.c.

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

Referenced by load_pbx().

02715 {
02716    struct ast_custom_function *cur;
02717    char tmps[80];
02718 
02719    if (!acf)
02720       return -1;
02721 
02722    acf->mod = mod;
02723 
02724    AST_RWLIST_WRLOCK(&acf_root);
02725 
02726    AST_RWLIST_TRAVERSE(&acf_root, cur, acflist) {
02727       if (!strcmp(acf->name, cur->name)) {
02728          ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
02729          AST_RWLIST_UNLOCK(&acf_root);
02730          return -1;
02731       }
02732    }
02733 
02734    /* Store in alphabetical order */
02735    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
02736       if (strcasecmp(acf->name, cur->name) < 0) {
02737          AST_RWLIST_INSERT_BEFORE_CURRENT(acf, acflist);
02738          break;
02739       }
02740    }
02741    AST_RWLIST_TRAVERSE_SAFE_END;
02742    if (!cur)
02743       AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist);
02744 
02745    AST_RWLIST_UNLOCK(&acf_root);
02746 
02747    ast_verb(2, "Registered custom function '%s'\n", term_color(tmps, acf->name, COLOR_BRCYAN, 0, sizeof(tmps)));
02748 
02749    return 0;
02750 }

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 4026 of file pbx.c.

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

04027 {
04028    return countcalls;
04029 }

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:
context context to add the extension to
replace 
extension extension to add
priority priority level of extension addition
label extension label
callerid pattern to match CallerID, or NULL to match any CallerID
application application to run on the extension with that priority level
data data to pass to the application
datad 
registrar who registered the extension
Return values:
0 success
-1 failure

Definition at line 6431 of file pbx.c.

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

Referenced by handle_cli_dialplan_add_extension(), park_add_hints(), register_exten(), register_peer_exten(), and RegisterExtension().

06434 {
06435    int ret = -1;
06436    struct ast_context *c = find_context_locked(context);
06437 
06438    if (c) {
06439       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
06440          application, data, datad, registrar);
06441       ast_unlock_contexts();
06442    }
06443    
06444    return ret;
06445 }

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 
)

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

References ast_add_extension2_lockopt().

Referenced by ast_add_extension(), context_merge(), do_parking_thread(), load_module(), park_call_full(), pbx_load_config(), and pbx_load_users().

06753 {
06754    return ast_add_extension2_lockopt(con, replace, extension, priority, label, callerid, application, data, datad, registrar, 1, 1);
06755 }

int ast_async_goto ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)

Definition at line 6470 of file pbx.c.

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

Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), pbx_parseable_goto(), process_ast_dsp(), and socket_process().

06471 {
06472    int res = 0;
06473 
06474    ast_channel_lock(chan);
06475 
06476    if (chan->pbx) { /* This channel is currently in the PBX */
06477       ast_explicit_goto(chan, context, exten, priority + 1);
06478       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
06479    } else {
06480       /* In order to do it when the channel doesn't really exist within
06481          the PBX, we have to make a new channel, masquerade, and start the PBX
06482          at the new location */
06483       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
06484       if (!tmpchan) {
06485          res = -1;
06486       } else {
06487          if (chan->cdr) {
06488             ast_cdr_discard(tmpchan->cdr);
06489             tmpchan->cdr = ast_cdr_dup(chan->cdr);  /* share the love */
06490          }
06491          /* Make formats okay */
06492          tmpchan->readformat = chan->readformat;
06493          tmpchan->writeformat = chan->writeformat;
06494          /* Setup proper location */
06495          ast_explicit_goto(tmpchan,
06496             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
06497 
06498          /* Masquerade into temp channel */
06499          if (ast_channel_masquerade(tmpchan, chan)) {
06500             /* Failed to set up the masquerade.  It's probably chan_local
06501              * in the middle of optimizing itself out.  Sad. :( */
06502             ast_hangup(tmpchan);
06503             tmpchan = NULL;
06504             res = -1;
06505          } else {
06506             /* Grab the locks and get going */
06507             ast_channel_lock(tmpchan);
06508             ast_do_masquerade(tmpchan);
06509             ast_channel_unlock(tmpchan);
06510             /* Start the PBX going on our stolen channel */
06511             if (ast_pbx_start(tmpchan)) {
06512                ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
06513                ast_hangup(tmpchan);
06514                res = -1;
06515             }
06516          }
06517       }
06518    }
06519    ast_channel_unlock(chan);
06520    return res;
06521 }

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

Definition at line 6523 of file pbx.c.

References ast_async_goto(), ast_channel_unlock, ast_get_channel_by_name_locked(), and chan.

06524 {
06525    struct ast_channel *chan;
06526    int res = -1;
06527 
06528    chan = ast_get_channel_by_name_locked(channame);
06529    if (chan) {
06530       res = ast_async_goto(chan, context, exten, priority);
06531       ast_channel_unlock(chan);
06532    }
06533    return res;
06534 }

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

References __ast_goto_if_exists(), and chan.

08631 {
08632    return __ast_goto_if_exists(chan, context, exten, priority, 1);
08633 }

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

References chan, and pbx_parseable_goto().

Referenced by asyncgoto_exec().

08694 {
08695    return pbx_parseable_goto(chan, goto_string, 1);
08696 }

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

Definition at line 6110 of file pbx.c.

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

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

06111 {
06112    char info_save[256];
06113    char *info;
06114 
06115    /* Check for empty just in case */
06116    if (ast_strlen_zero(info_in))
06117       return 0;
06118    /* make a copy just in case we were passed a static string */
06119    ast_copy_string(info_save, info_in, sizeof(info_save));
06120    info = info_save;
06121    /* Assume everything except time */
06122    i->monthmask = 0xfff;   /* 12 bits */
06123    i->daymask = 0x7fffffffU; /* 31 bits */
06124    i->dowmask = 0x7f; /* 7 bits */
06125    /* on each call, use strsep() to move info to the next argument */
06126    get_timerange(i, strsep(&info, "|,"));
06127    if (info)
06128       i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
06129    if (info)
06130       i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
06131    if (info)
06132       i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
06133    return 1;
06134 }

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:
c not really important
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid 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 3604 of file pbx.c.

References E_CANMATCH, and pbx_extension_helper().

Referenced by background_detect_exec(), cb_events(), do_immediate_setup(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), handle_link_data(), handle_link_phone_dtmf(), leave_voicemail(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().

03605 {
03606    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0, 0);
03607 }

int ast_check_timing ( const struct ast_timing i  ) 

Definition at line 6136 of file pbx.c.

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

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

06137 {
06138    struct ast_tm tm;
06139    struct timeval tv = ast_tvnow();
06140 
06141    ast_localtime(&tv, &tm, NULL);
06142 
06143    /* If it's not the right month, return */
06144    if (!(i->monthmask & (1 << tm.tm_mon)))
06145       return 0;
06146 
06147    /* If it's not that time of the month.... */
06148    /* Warning, tm_mday has range 1..31! */
06149    if (!(i->daymask & (1 << (tm.tm_mday-1))))
06150       return 0;
06151 
06152    /* If it's not the right day of the week */
06153    if (!(i->dowmask & (1 << tm.tm_wday)))
06154       return 0;
06155 
06156    /* Sanity check the hour just to be safe */
06157    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
06158       ast_log(LOG_WARNING, "Insane time...\n");
06159       return 0;
06160    }
06161 
06162    /* Now the tough part, we calculate if it fits
06163       in the right time based on min/hour */
06164    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
06165       return 0;
06166 
06167    /* If we got this far, then we're good */
06168    return 1;
06169 }

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

Add an ignorepat.

Parameters:
context which context to add the ignorpattern to
ignorepat ignorepattern to set up for the extension
registrar registrar of the ignore pattern
Adds an ignore pattern to a particular context.

Return values:
0 on success
-1 on failure

Definition at line 6362 of file pbx.c.

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

Referenced by handle_cli_dialplan_add_ignorepat().

06363 {
06364    int ret = -1;
06365    struct ast_context *c = find_context_locked(context);
06366 
06367    if (c) {
06368       ret = ast_context_add_ignorepat2(c, value, registrar);
06369       ast_unlock_contexts();
06370    }
06371    return ret;
06372 }

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

Definition at line 6374 of file pbx.c.

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

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

06375 {
06376    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
06377    int length;
06378    char *pattern;
06379    length = sizeof(struct ast_ignorepat);
06380    length += strlen(value) + 1;
06381    if (!(ignorepat = ast_calloc(1, length)))
06382       return -1;
06383    /* The cast to char * is because we need to write the initial value.
06384     * The field is not supposed to be modified otherwise.  Also, gcc 4.2
06385     * sees the cast as dereferencing a type-punned pointer and warns about
06386     * it.  This is the workaround (we're telling gcc, yes, that's really
06387     * what we wanted to do).
06388     */
06389    pattern = (char *) ignorepat->pattern;
06390    strcpy(pattern, value);
06391    ignorepat->next = NULL;
06392    ignorepat->registrar = registrar;
06393    ast_wrlock_context(con);
06394    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
06395       ignorepatl = ignorepatc;
06396       if (!strcasecmp(ignorepatc->pattern, value)) {
06397          /* Already there */
06398          ast_unlock_context(con);
06399          errno = EEXIST;
06400          return -1;
06401       }
06402    }
06403    if (ignorepatl)
06404       ignorepatl->next = ignorepat;
06405    else
06406       con->ignorepats = ignorepat;
06407    ast_unlock_context(con);
06408    return 0;
06409 
06410 }

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

Add a context include.

Parameters:
context context to add include to
include new include to add
registrar who's registering it
Adds an include taking a char * string as the context parameter

Return values:
0 on success
-1 on error

Definition at line 5916 of file pbx.c.

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

Referenced by handle_cli_dialplan_add_include().

05917 {
05918    int ret = -1;
05919    struct ast_context *c = find_context_locked(context);
05920 
05921    if (c) {
05922       ret = ast_context_add_include2(c, include, registrar);
05923       ast_unlock_contexts();
05924    }
05925    return ret;
05926 }

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

Add a context include.

Parameters:
con context to add the include to
include include to add
registrar who registered the context
Adds an include taking a struct ast_context as the first parameter

Return values:
0 on success
-1 on failure

Definition at line 6178 of file pbx.c.

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

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

06180 {
06181    struct ast_include *new_include;
06182    char *c;
06183    struct ast_include *i, *il = NULL; /* include, include_last */
06184    int length;
06185    char *p;
06186 
06187    length = sizeof(struct ast_include);
06188    length += 2 * (strlen(value) + 1);
06189 
06190    /* allocate new include structure ... */
06191    if (!(new_include = ast_calloc(1, length)))
06192       return -1;
06193    /* Fill in this structure. Use 'p' for assignments, as the fields
06194     * in the structure are 'const char *'
06195     */
06196    p = new_include->stuff;
06197    new_include->name = p;
06198    strcpy(p, value);
06199    p += strlen(value) + 1;
06200    new_include->rname = p;
06201    strcpy(p, value);
06202    /* Strip off timing info, and process if it is there */
06203    if ( (c = strchr(p, ',')) ) {
06204       *c++ = '\0';
06205       new_include->hastime = ast_build_timing(&(new_include->timing), c);
06206    }
06207    new_include->next      = NULL;
06208    new_include->registrar = registrar;
06209 
06210    ast_wrlock_context(con);
06211 
06212    /* ... go to last include and check if context is already included too... */
06213    for (i = con->includes; i; i = i->next) {
06214       if (!strcasecmp(i->name, new_include->name)) {
06215          ast_free(new_include);
06216          ast_unlock_context(con);
06217          errno = EEXIST;
06218          return -1;
06219       }
06220       il = i;
06221    }
06222 
06223    /* ... include new context into context list, unlock, return */
06224    if (il)
06225       il->next = new_include;
06226    else
06227       con->includes = new_include;
06228    ast_verb(3, "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
06229 
06230    ast_unlock_context(con);
06231 
06232    return 0;
06233 }

int ast_context_add_switch ( const char *  context,
const char *  sw,
const char *  data,
int  eval,
const char *  registrar 
)

Add a switch.

Parameters:
context context to which to add the switch
sw switch to add
data data to pass to switch
eval whether to evaluate variables when running switch
registrar whoever registered the switch
This function registers a switch with the asterisk switch architecture

Return values:
0 on success
-1 on failure

Definition at line 6240 of file pbx.c.

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

06241 {
06242    int ret = -1;
06243    struct ast_context *c = find_context_locked(context);
06244 
06245    if (c) { /* found, add switch to this context */
06246       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
06247       ast_unlock_contexts();
06248    }
06249    return ret;
06250 }

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

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

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

06261 {
06262    struct ast_sw *new_sw;
06263    struct ast_sw *i;
06264    int length;
06265    char *p;
06266 
06267    length = sizeof(struct ast_sw);
06268    length += strlen(value) + 1;
06269    if (data)
06270       length += strlen(data);
06271    length++;
06272 
06273    /* allocate new sw structure ... */
06274    if (!(new_sw = ast_calloc(1, length)))
06275       return -1;
06276    /* ... fill in this structure ... */
06277    p = new_sw->stuff;
06278    new_sw->name = p;
06279    strcpy(new_sw->name, value);
06280    p += strlen(value) + 1;
06281    new_sw->data = p;
06282    if (data) {
06283       strcpy(new_sw->data, data);
06284       p += strlen(data) + 1;
06285    } else {
06286       strcpy(new_sw->data, "");
06287       p++;
06288    }
06289    new_sw->eval     = eval;
06290    new_sw->registrar = registrar;
06291 
06292    /* ... try to lock this context ... */
06293    ast_wrlock_context(con);
06294 
06295    /* ... go to last sw and check if context is already swd too... */
06296    AST_LIST_TRAVERSE(&con->alts, i, list) {
06297       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
06298          ast_free(new_sw);
06299          ast_unlock_context(con);
06300          errno = EEXIST;
06301          return -1;
06302       }
06303    }
06304 
06305    /* ... sw new context into context list, unlock, return */
06306    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
06307 
06308    ast_verb(3, "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
06309 
06310    ast_unlock_context(con);
06311 
06312    return 0;
06313 }

void ast_context_destroy ( struct ast_context con,
const char *  registrar 
)

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

Parameters:
con context to destroy
registrar who registered it
You can optionally leave out either parameter. It will find it based on either the ast_context or the registrar name.

Returns:
nothing

Definition at line 7537 of file pbx.c.

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

Referenced by __unload_module(), cleanup_stale_contexts(), sla_destroy(), and unload_module().

struct ast_context* ast_context_find ( const char *  name  ) 

Find a context.

Parameters:
name name 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 2001 of file pbx.c.

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

Referenced by __unload_module(), _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), do_parking_thread(), isexten_function_read(), park_exec(), register_exten(), register_peer_exten(), unload_module(), and unregister_exten().

02002 {
02003    struct ast_context *tmp = NULL;
02004    struct fake_context item;
02005    strncpy(item.name,name,256);
02006    ast_rdlock_contexts();
02007    if( contexts_table ) {
02008       tmp = ast_hashtab_lookup(contexts_table,&item);
02009    } else {
02010       while ( (tmp = ast_walk_contexts(tmp)) ) {
02011          if (!name || !strcasecmp(name, tmp->name))
02012             break;
02013       }
02014    }
02015    ast_unlock_contexts();
02016    return tmp;
02017 }

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:
extcontexts pointer to the ast_context structure pointer
exttable pointer to the hashtable that contains all the elements in extcontexts
name name of the new context
registrar registrar 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 5575 of file pbx.c.

References 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_mutex_init(), ast_rdlock_contexts(), ast_rwlock_init(), ast_strdup, ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), contexts, contexts_table, ast_context::ignorepats, ast_context::includes, local_contexts, ast_context::lock, LOG_ERROR, ast_context::macrolock, ast_context::name, fake_context::name, name, ast_context::next, ast_context::refcount, ast_context::registrar, ast_context::root, and ast_context::root_table.

Referenced by context_merge(), do_parking_thread(), load_module(), lua_register_switches(), park_call_full(), pbx_load_config(), pbx_load_users(), reload_config(), and set_config().

05576 {
05577    struct ast_context *tmp, **local_contexts;
05578    struct fake_context search;
05579    int length = sizeof(struct ast_context) + strlen(name) + 1;
05580 
05581    if (!contexts_table) {
05582       contexts_table = ast_hashtab_create(17,
05583                                  ast_hashtab_compare_contexts, 
05584                                  ast_hashtab_resize_java,
05585                                  ast_hashtab_newsize_java,
05586                                  ast_hashtab_hash_contexts,
05587                                  0);
05588    }
05589    
05590    strncpy(search.name,name,sizeof(search.name));
05591    if (!extcontexts) {
05592       ast_rdlock_contexts();
05593       local_contexts = &contexts;
05594       tmp = ast_hashtab_lookup(contexts_table, &search);
05595       ast_unlock_contexts();
05596       if (tmp) {
05597          tmp->refcount++;
05598          return tmp;
05599       }
05600    } else { /* local contexts just in a linked list; search there for the new context; slow, linear search, but not frequent */
05601       local_contexts = extcontexts;
05602       tmp = ast_hashtab_lookup(exttable, &search);
05603       if (tmp) {
05604          tmp->refcount++;
05605          return tmp;
05606       }
05607    }
05608    
05609    if ((tmp = ast_calloc(1, length))) {
05610       ast_rwlock_init(&tmp->lock);
05611       ast_mutex_init(&tmp->macrolock);
05612       strcpy(tmp->name, name);
05613       tmp->root = NULL;
05614       tmp->root_table = NULL;
05615       tmp->registrar = ast_strdup(registrar);
05616       tmp->includes = NULL;
05617       tmp->ignorepats = NULL;
05618       tmp->refcount = 1;
05619    } else {
05620       ast_log(LOG_ERROR, "Danger! We failed to allocate a context for %s!\n", name);
05621       return NULL;
05622    }
05623    
05624    if (!extcontexts) {
05625       ast_wrlock_contexts();
05626       tmp->next = *local_contexts;
05627       *local_contexts = tmp;
05628       ast_hashtab_insert_safe(contexts_table, tmp); /*put this context into the tree */
05629       ast_unlock_contexts();
05630       ast_debug(1, "Registered context '%s'(%p) in table %p registrar: %s\n", tmp->name, tmp, contexts_table, registrar);
05631       ast_verb(3, "Registered extension context '%s' (%p) in table %p; registrar: %s\n", tmp->name, tmp, contexts_table, registrar);
05632    } else {
05633       tmp->next = *local_contexts;
05634       if (exttable)
05635          ast_hashtab_insert_immediate(exttable, tmp); /*put this context into the tree */
05636       
05637       *local_contexts = tmp;
05638       ast_debug(1, "Registered context '%s'(%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar);
05639       ast_verb(3, "Registered extension context '%s' (%p) in local table %p; registrar: %s\n", tmp->name, tmp, exttable, registrar);
05640    }
05641    return tmp;
05642 }

int ast_context_lockmacro ( const char *  context  ) 

locks the macrolock in the given given context

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

Definition at line 4385 of file pbx.c.

References ast_get_context_name(), ast_hashtab_lookup(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::macrolock, and fake_context::name.

Referenced by _macro_exec().

04386 {
04387    struct ast_context *c = NULL;
04388    int ret = -1;
04389    struct fake_context item;
04390 
04391    ast_rdlock_contexts();
04392 
04393    strncpy(item.name,context,256);
04394    c = ast_hashtab_lookup(contexts_table,&item);
04395    if (c)
04396       ret = 0;
04397 
04398 
04399 #ifdef NOTNOW
04400 
04401    while ((c = ast_walk_contexts(c))) {
04402       if (!strcmp(ast_get_context_name(c), context)) {
04403          ret = 0;
04404          break;
04405       }
04406    }
04407 
04408 #endif
04409    ast_unlock_contexts();
04410 
04411    /* if we found context, lock macrolock */
04412    if (ret == 0) 
04413       ret = ast_mutex_lock(&c->macrolock);
04414 
04415    return ret;
04416 }

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

Simply remove extension from context.

Parameters:
context context to remove extension from
extension which extension to remove
priority priority of extension to remove (0 to remove all)
callerid NULL to remove all; non-NULL to match a single record per priority
matchcid non-zero to match callerid element (if non-NULL); 0 to match default case
registrar registrar of the extension
This function removes an extension from a given context.

Return values:
0 on success
-1 on failure

Definition at line 4192 of file pbx.c.

References ast_context_remove_extension_callerid().

Referenced by destroy_station(), destroy_trunk(), register_peer_exten(), unregister_exten(), and UnregisterExtension().

04193 {
04194    return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
04195 }

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

References ast_context_remove_extension_callerid2().

Referenced by do_parking_thread(), park_exec(), and unload_module().

04220 {
04221    return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar, already_locked);
04222 }

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

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

Referenced by ast_context_remove_extension(), and handle_cli_dialplan_remove_extension().

04198 {
04199    int ret = -1; /* default error return */
04200    struct ast_context *c = find_context_locked(context);
04201 
04202    if (c) { /* ... remove extension ... */
04203       ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar, 1);
04204       ast_unlock_contexts();
04205    }
04206    return ret;
04207 }

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

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

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

04225 {
04226    struct ast_exten *exten, *prev_exten = NULL;
04227    struct ast_exten *peer;
04228    struct ast_exten ex, *exten2, *exten3;
04229    char dummy_name[1024];
04230    struct ast_exten *previous_peer = NULL;
04231    struct ast_exten *next_peer = NULL;
04232    int found = 0;
04233 
04234    if (!already_locked)
04235       ast_wrlock_context(con);
04236 
04237    /* Handle this is in the new world */
04238 
04239    /* FIXME For backwards compatibility, if callerid==NULL, then remove ALL
04240     * peers, not just those matching the callerid. */
04241 #ifdef NEED_DEBUG
04242    ast_verb(3,"Removing %s/%s/%d%s%s from trees, registrar=%s\n", con->name, extension, priority, matchcid ? "/" : "", matchcid ? callerid : "", registrar);
04243 #endif
04244 #ifdef CONTEXT_DEBUG
04245    check_contexts(__FILE__, __LINE__);
04246 #endif
04247    /* find this particular extension */
04248    ex.exten = dummy_name;
04249    ex.matchcid = matchcid && !ast_strlen_zero(callerid); /* don't say match if there's no callerid */
04250    ex.cidmatch = callerid;
04251    ast_copy_string(dummy_name, extension, sizeof(dummy_name));
04252    exten = ast_hashtab_lookup(con->root_table, &ex);
04253    if (exten) {
04254       if (priority == 0) {
04255          exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
04256          if (!exten2)
04257             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);
04258          if (con->pattern_tree) {
04259             
04260             struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
04261             
04262             if (x->exten) { /* this test for safety purposes */
04263                x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
04264                x->exten = 0; /* get rid of what will become a bad pointer */
04265             } else {
04266                ast_log(LOG_WARNING,"Trying to delete an exten from a context, but the pattern tree node returned isn't a full extension\n");
04267             }
04268          }
04269       } else {
04270          ex.priority = priority;
04271          exten2 = ast_hashtab_lookup(exten->peer_table, &ex);
04272          if (exten2) {
04273             
04274             if (exten2->label) { /* if this exten has a label, remove that, too */
04275                exten3 = ast_hashtab_remove_this_object(exten->peer_label_table,exten2);
04276                if (!exten3)
04277                   ast_log(LOG_ERROR,"Did not remove this priority label (%d/%s) from the peer_label_table of context %s, extension %s!\n", priority, exten2->label, con->name, exten2->exten);
04278             }
04279          
04280             exten3 = ast_hashtab_remove_this_object(exten->peer_table, exten2);
04281             if (!exten3)
04282                ast_log(LOG_ERROR,"Did not remove this priority (%d) from the peer_table of context %s, extension %s!\n", priority, con->name, exten2->exten);
04283             if (exten2 == exten && exten2->peer) {
04284                exten2 = ast_hashtab_remove_this_object(con->root_table, exten);
04285                ast_hashtab_insert_immediate(con->root_table, exten2->peer);
04286             }
04287             if (ast_hashtab_size(exten->peer_table) == 0) {
04288                /* well, if the last priority of an exten is to be removed,
04289                   then, the extension is removed, too! */
04290                exten3 = ast_hashtab_remove_this_object(con->root_table, exten);
04291                if (!exten3)
04292                   ast_log(LOG_ERROR,"Did not remove this exten (%s) from the context root_table (%s) (priority %d)\n", exten->exten, con->name, priority);
04293                if (con->pattern_tree) {
04294                   struct match_char *x = add_exten_to_pattern_tree(con, exten, 1);
04295                   if (x->exten) { /* this test for safety purposes */
04296                      x->deleted = 1; /* with this marked as deleted, it will never show up in the scoreboard, and therefore never be found */
04297                      x->exten = 0; /* get rid of what will become a bad pointer */
04298                   }
04299                }
04300             }
04301          } else {
04302             ast_log(LOG_ERROR,"Could not find priority %d of exten %s in context %s!\n",
04303                   priority, exten->exten, con->name);
04304          }
04305       }
04306    } else {
04307       /* hmmm? this exten is not in this pattern tree? */
04308       ast_log(LOG_WARNING,"Cannot find extension %s in root_table in context %s\n",
04309             extension, con->name);
04310    }
04311 #ifdef NEED_DEBUG
04312    if (con->pattern_tree) {
04313       ast_log(LOG_NOTICE,"match char tree after exten removal:\n");
04314       log_match_char_tree(con->pattern_tree, " ");
04315    }
04316 #endif
04317 
04318    /* scan the extension list to find first matching extension-registrar */
04319    for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
04320       if (!strcmp(exten->exten, extension) &&
04321          (!registrar || !strcmp(exten->registrar, registrar)) &&
04322          (!matchcid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(exten->cidmatch) && !strcmp(exten->cidmatch, callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(exten->cidmatch))))
04323          break;
04324    }
04325    if (!exten) {
04326       /* we can't find right extension */
04327       if (!already_locked)
04328          ast_unlock_context(con);
04329       return -1;
04330    }
04331 
04332    /* scan the priority list to remove extension with exten->priority == priority */
04333    for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
04334        peer && !strcmp(peer->exten, extension) && (!matchcid || (!ast_strlen_zero(callerid) && !ast_strlen_zero(peer->cidmatch) && !strcmp(peer->cidmatch,callerid)) || (ast_strlen_zero(callerid) && ast_strlen_zero(peer->cidmatch)));
04335          peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
04336       if ((priority == 0 || peer->priority == priority) &&
04337             (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) &&
04338             (!registrar || !strcmp(peer->registrar, registrar) )) {
04339          found = 1;
04340 
04341          /* we are first priority extension? */
04342          if (!previous_peer) {
04343             /*
04344              * We are first in the priority chain, so must update the extension chain.
04345              * The next node is either the next priority or the next extension
04346              */
04347             struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
04348             if (peer->peer) {
04349                /* move the peer_table and peer_label_table down to the next peer, if
04350                   it is there */
04351                peer->peer->peer_table = peer->peer_table;
04352                peer->peer->peer_label_table = peer->peer_label_table;
04353                peer->peer_table = NULL;
04354                peer->peer_label_table = NULL;
04355             }
04356             if (!prev_exten) {   /* change the root... */
04357                con->root = next_node;
04358             } else {
04359                prev_exten->next = next_node; /* unlink */
04360             }
04361             if (peer->peer)   { /* update the new head of the pri list */
04362                peer->peer->next = peer->next;
04363             }
04364          } else { /* easy, we are not first priority in extension */
04365             previous_peer->peer = peer->peer;
04366          }
04367 
04368          /* now, free whole priority extension */
04369          destroy_exten(peer);
04370       } else {
04371          previous_peer = peer;
04372       }
04373    }
04374    if (!already_locked)
04375       ast_unlock_context(con);
04376    return found ? 0 : -1;
04377 }

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

Definition at line 6319 of file pbx.c.

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

Referenced by handle_cli_dialplan_remove_ignorepat().

06320 {
06321    int ret = -1;
06322    struct ast_context *c = find_context_locked(context);
06323 
06324    if (c) {
06325       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
06326       ast_unlock_contexts();
06327    }
06328    return ret;
06329 }

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

Definition at line 6331 of file pbx.c.

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

Referenced by ast_context_remove_ignorepat().

06332 {
06333    struct ast_ignorepat *ip, *ipl = NULL;
06334 
06335    ast_wrlock_context(con);
06336 
06337    for (ip = con->ignorepats; ip; ip = ip->next) {
06338       if (!strcmp(ip->pattern, ignorepat) &&
06339          (!registrar || (registrar == ip->registrar))) {
06340          if (ipl) {
06341             ipl->next = ip->next;
06342             ast_free(ip);
06343          } else {
06344             con->ignorepats = ip->next;
06345             ast_free(ip);
06346          }
06347          ast_unlock_context(con);
06348          return 0;
06349       }
06350       ipl = ip;
06351    }
06352 
06353    ast_unlock_context(con);
06354    errno = EINVAL;
06355    return -1;
06356 }

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
Return values:
0 on success
-1 on failure

Definition at line 4084 of file pbx.c.

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

Referenced by handle_cli_dialplan_remove_include().

04085 {
04086    int ret = -1;
04087    struct ast_context *c = find_context_locked(context);
04088 
04089    if (c) {
04090       /* found, remove include from this context ... */
04091       ret = ast_context_remove_include2(c, include, registrar);
04092       ast_unlock_contexts();
04093    }
04094    return ret;
04095 }

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

Removes an include by an ast_context structure.

Return values:
0 on success.
-1 on failure.

Definition at line 4106 of file pbx.c.

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

Referenced by ast_context_remove_include().

04107 {
04108    struct ast_include *i, *pi = NULL;
04109    int ret = -1;
04110 
04111    ast_wrlock_context(con);
04112 
04113    /* find our include */
04114    for (i = con->includes; i; pi = i, i = i->next) {
04115       if (!strcmp(i->name, include) &&
04116             (!registrar || !strcmp(i->registrar, registrar))) {
04117          /* remove from list */
04118          ast_verb(3, "Removing inclusion of context '%s' in context '%s; registrar=%s'\n", include, ast_get_context_name(con), registrar);
04119          if (pi)
04120             pi->next = i->next;
04121          else
04122             con->includes = i->next;
04123          /* free include and return */
04124          ast_free(i);
04125          ret = 0;
04126          break;
04127       }
04128    }
04129 
04130    ast_unlock_context(con);
04131 
04132    return ret;
04133 }

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

Remove a switch.

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

Definition at line 4140 of file pbx.c.

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

04141 {
04142    int ret = -1; /* default error return */
04143    struct ast_context *c = find_context_locked(context);
04144 
04145    if (c) {
04146       /* remove switch from this context ... */
04147       ret = ast_context_remove_switch2(c, sw, data, registrar);
04148       ast_unlock_contexts();
04149    }
04150    return ret;
04151 }

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

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

Referenced by ast_context_remove_switch().

04162 {
04163    struct ast_sw *i;
04164    int ret = -1;
04165 
04166    ast_wrlock_context(con);
04167 
04168    /* walk switches */
04169    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
04170       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
04171          (!registrar || !strcmp(i->registrar, registrar))) {
04172          /* found, remove from list */
04173          ast_verb(3, "Removing switch '%s' from context '%s; registrar=%s'\n", sw, ast_get_context_name(con), registrar);
04174          AST_LIST_REMOVE_CURRENT(list);
04175          ast_free(i); /* free switch and return */
04176          ret = 0;
04177          break;
04178       }
04179    }
04180    AST_LIST_TRAVERSE_SAFE_END;
04181 
04182    ast_unlock_context(con);
04183 
04184    return ret;
04185 }

int ast_context_unlockmacro ( const char *  context  ) 

Unlocks the macrolock in the given context.

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

Definition at line 4423 of file pbx.c.

References ast_get_context_name(), ast_hashtab_lookup(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), contexts_table, ast_context::macrolock, and fake_context::name.

Referenced by _macro_exec().

04424 {
04425    struct ast_context *c = NULL;
04426    int ret = -1;
04427    struct fake_context item;
04428 
04429    ast_rdlock_contexts();
04430 
04431    strncpy(item.name, context, 256);
04432    c = ast_hashtab_lookup(contexts_table,&item);
04433    if (c)
04434       ret = 0;
04435 #ifdef NOTNOW
04436 
04437    while ((c = ast_walk_contexts(c))) {
04438       if (!strcmp(ast_get_context_name(c), context)) {
04439          ret = 0;
04440          break;
04441       }
04442    }
04443 
04444 #endif
04445    ast_unlock_contexts();
04446 
04447    /* if we found context, unlock macrolock */
04448    if (ret == 0) 
04449       ret = ast_mutex_unlock(&c->macrolock);
04450 
04451    return ret;
04452 }

int ast_context_verify_includes ( struct ast_context con  ) 

Verifies includes in an ast_contect structure.

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

Definition at line 8587 of file pbx.c.

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

Referenced by pbx_load_module().

08588 {
08589    struct ast_include *inc = NULL;
08590    int res = 0;
08591 
08592    while ( (inc = ast_walk_context_includes(con, inc)) ) {
08593       if (ast_context_find(inc->rname))
08594          continue;
08595 
08596       res = -1;
08597       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
08598          ast_get_context_name(con), inc->rname);
08599       break;
08600    }
08601 
08602    return res;
08603 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

Definition at line 2685 of file pbx.c.

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

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

02686 {
02687    struct ast_custom_function *acf = NULL;
02688 
02689    AST_RWLIST_RDLOCK(&acf_root);
02690    AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) {
02691       if (!strcmp(name, acf->name))
02692          break;
02693    }
02694    AST_RWLIST_UNLOCK(&acf_root);
02695 
02696    return acf;
02697 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

Definition at line 2699 of file pbx.c.

References ast_custom_function::acflist, AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and ast_custom_function::name.

Referenced by reload(), and unload_module().

02700 {
02701    struct ast_custom_function *cur;
02702 
02703    if (!acf)
02704       return -1;
02705 
02706    AST_RWLIST_WRLOCK(&acf_root);
02707    if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist)))
02708       ast_verb(2, "Unregistered custom function %s\n", cur->name);
02709    AST_RWLIST_UNLOCK(&acf_root);
02710 
02711    return cur ? 0 : -1;
02712 }

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:
c this is not important
context which context to look in
exten which extension to search for
priority priority of the action within the extension
callerid callerid 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 3589 of file pbx.c.

References E_MATCH, and pbx_extension_helper().

Referenced by __ast_goto_if_exists(), __ast_pbx_run(), _macro_exec(), acf_isexten_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), cli_console_dial(), conf_run(), console_dial(), console_transfer(), dahdi_handle_dtmfup(), dial_exec_full(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), gosub_exec(), handle_gosub(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), isexten_function_read(), leave_voicemail(), local_alloc(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), minivm_greet_exec(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), process_ast_dsp(), readexten_exec(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().

03590 {
03591    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0, 0);
03592 }

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

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

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

06448 {
06449    if (!chan)
06450       return -1;
06451 
06452    ast_channel_lock(chan);
06453 
06454    if (!ast_strlen_zero(context))
06455       ast_copy_string(chan->context, context, sizeof(chan->context));
06456    if (!ast_strlen_zero(exten))
06457       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
06458    if (priority > -1) {
06459       chan->priority = priority;
06460       /* see flag description in channel.h for explanation */
06461       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
06462          chan->priority--;
06463    }
06464 
06465    ast_channel_unlock(chan);
06466 
06467    return 0;
06468 }

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

Definition at line 1978 of file pbx.c.

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

Referenced by lua_find_extension(), and realtime_switch_common().

01979 {
01980    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
01981       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
01982    return extension_match_core(pattern, data, needmore);
01983 }

int ast_extension_cmp ( const char *  a,
const char *  b 
)

Determine if one extension should match before another.

Parameters:
a extension to compare with b
b extension to compare with a
Checks whether or extension a should match before extension b

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

Definition at line 1780 of file pbx.c.

References ext_cmp().

Referenced by lua_extension_cmp().

01781 {
01782    return ext_cmp(a, b);
01783 }

int ast_extension_match ( const char *  pattern,
const char *  extension 
)

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

Parameters:
pattern pattern to match
extension extension to check against the pattern.
Checks whether or not the given extension matches the given pattern.

Return values:
1 on match
0 on failure

Definition at line 1973 of file pbx.c.

References E_MATCH, and extension_match_core().

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

01974 {
01975    return extension_match_core(pattern, data, E_MATCH);
01976 }

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.

Parameters:
c this is not important
context which context to look in
exten which extension to get state
Returns:
extension state as defined in the ast_extension_states enum

Definition at line 3266 of file pbx.c.

References ast_extension_state2(), and ast_hint_extension().

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

03267 {
03268    struct ast_exten *e;
03269 
03270    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
03271    if (!e)
03272       return -1;           /* No hint, return -1 */
03273 
03274    return ast_extension_state2(e);        /* Check all devices in the hint */
03275 }

const char* ast_extension_state2str ( int  extension_state  ) 

Return string representation of the state of an extension.

Parameters:
extension_state is the numerical state delivered by ast_extension_state
Returns:
the state of an extension as string

Definition at line 3254 of file pbx.c.

References ARRAY_LEN, extension_states, and cfextension_states::text.

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

03255 {
03256    int i;
03257 
03258    for (i = 0; (i < ARRAY_LEN(extension_states)); i++) {
03259       if (extension_states[i].extension_state == extension_state)
03260          return extension_states[i].text;
03261    }
03262    return "Unknown";
03263 }

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

Registers a state change callback.

Parameters:
context which context to look in
exten which extension to get state
callback callback to call if state changed
data to pass to callback
The callback is called if the state of an extension is changed.

Return values:
-1 on failure
ID on success

Definition at line 3364 of file pbx.c.

References ast_calloc, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_state_cb::callback, ast_state_cb::data, ast_state_cb::next, and statecbs.

Referenced by __init_manager(), and handle_request_subscribe().

03366 {
03367    struct ast_hint *hint;
03368    struct ast_state_cb *cblist;
03369    struct ast_exten *e;
03370 
03371    /* If there's no context and extension:  add callback to statecbs list */
03372    if (!context && !exten) {
03373       AST_RWLIST_WRLOCK(&hints);
03374 
03375       for (cblist = statecbs; cblist; cblist = cblist->next) {
03376          if (cblist->callback == callback) {
03377             cblist->data = data;
03378             AST_RWLIST_UNLOCK(&hints);
03379             return 0;
03380          }
03381       }
03382 
03383       /* Now insert the callback */
03384       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
03385          AST_RWLIST_UNLOCK(&hints);
03386          return -1;
03387       }
03388       cblist->id = 0;
03389       cblist->callback = callback;
03390       cblist->data = data;
03391 
03392       cblist->next = statecbs;
03393       statecbs = cblist;
03394 
03395       AST_RWLIST_UNLOCK(&hints);
03396       return 0;
03397    }
03398 
03399    if (!context || !exten)
03400       return -1;
03401 
03402    /* This callback type is for only one hint, so get the hint */
03403    e = ast_hint_extension(NULL, context, exten);
03404    if (!e) {
03405       return -1;
03406    }
03407 
03408    /* Find the hint in the list of hints */
03409    AST_RWLIST_WRLOCK(&hints);
03410 
03411    AST_RWLIST_TRAVERSE(&hints, hint, list) {
03412       if (hint->exten == e)
03413          break;
03414    }
03415 
03416    if (!hint) {
03417       /* We have no hint, sorry */
03418       AST_RWLIST_UNLOCK(&hints);
03419       return -1;
03420    }
03421 
03422    /* Now insert the callback in the callback list  */
03423    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
03424       AST_RWLIST_UNLOCK(&hints);
03425       return -1;
03426    }
03427    cblist->id = stateid++;    /* Unique ID for this callback */
03428    cblist->callback = callback;  /* Pointer to callback routine */
03429    cblist->data = data;    /* Data for the callback */
03430 
03431    cblist->next = hint->callbacks;
03432    hint->callbacks = cblist;
03433 
03434    AST_RWLIST_UNLOCK(&hints);
03435    return cblist->id;
03436 }

int ast_extension_state_del ( int  id,
ast_state_cb_type  callback 
)

Deletes a registered state change callback by ID.

Parameters:
id of the callback to delete
callback callback
Removes the callback from list of callbacks

Return values:
0 success
-1 failure

Definition at line 3439 of file pbx.c.

References ast_free, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_hint::callbacks, ast_hint::list, ast_state_cb::next, and statecbs.

Referenced by __sip_destroy(), handle_request_subscribe(), and skinny_unregister().

03440 {
03441    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
03442    int ret = -1;
03443 
03444    if (!id && !callback)
03445       return -1;
03446 
03447    AST_RWLIST_WRLOCK(&hints);
03448 
03449    if (!id) {  /* id == 0 is a callback without extension */
03450       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
03451          if ((*p_cur)->callback == callback)
03452             break;
03453       }
03454    } else { /* callback with extension, find the callback based on ID */
03455       struct ast_hint *hint;
03456       AST_RWLIST_TRAVERSE(&hints, hint, list) {
03457          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
03458             if ((*p_cur)->id == id)
03459                break;
03460          }
03461          if (*p_cur) /* found in the inner loop */
03462             break;
03463       }
03464    }
03465    if (p_cur && *p_cur) {
03466       struct ast_state_cb *cur = *p_cur;
03467       *p_cur = cur->next;
03468       ast_free(cur);
03469       ret = 0;
03470    }
03471    AST_RWLIST_UNLOCK(&hints);
03472    return ret;
03473 }

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:
c this is not important
context which context to look in
exten which extension to search for
label label of the action within the extension to match to priority
callerid callerid 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:
the priority which matches the given label in the extension
-1 if not found.

Definition at line 3594 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

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

03595 {
03596    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03597 }

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

03600 {
03601    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0, 0);
03602 }

int ast_func_read ( struct ast_channel chan,
const char *  function,
char *  workspace,
size_t  len 
)

executes a read operation on a function

Parameters:
chan Channel to execute on
function Data containing the function call string (will be modified)
workspace A pointer to safe memory to use for a return value
len the number of bytes in workspace
This application executes a function in read mode on a given channel.

Returns:
zero on success, non-zero on failure

Definition at line 2772 of file pbx.c.

References __ast_module_user_add(), __ast_module_user_remove(), ast_custom_function_find(), ast_log(), ast_strdupa, chan, copy(), func_args(), LOG_ERROR, ast_custom_function::mod, and ast_custom_function::read.

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

02773 {
02774    char *copy = ast_strdupa(function);
02775    char *args = func_args(copy);
02776    struct ast_custom_function *acfptr = ast_custom_function_find(copy);
02777 
02778    if (acfptr == NULL)
02779       ast_log(LOG_ERROR, "Function %s not registered\n", copy);
02780    else if (!acfptr->read)
02781       ast_log(LOG_ERROR, "Function %s cannot be read\n", copy);
02782    else {
02783       int res;
02784       struct ast_module_user *u = NULL;
02785       if (acfptr->mod)
02786          u = __ast_module_user_add(acfptr->mod, chan);
02787       res = acfptr->read(chan, copy, args, workspace, len);
02788       if (acfptr->mod && u)
02789          __ast_module_user_remove(acfptr->mod, u);
02790       return res;
02791    }
02792    return -1;
02793 }

int ast_func_write ( struct ast_channel chan,
const char *  function,
const char *  value 
)

executes a write operation on a function

Parameters:
chan Channel to execute on
function Data containing the function call string (will be modified)
value A value parameter to pass for writing
This application executes a function in write mode on a given channel.

Returns:
zero on success, non-zero on failure

Definition at line 2795 of file pbx.c.

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

Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

02796 {
02797    char *copy = ast_strdupa(function);
02798    char *args = func_args(copy);
02799    struct ast_custom_function *acfptr = ast_custom_function_find(copy);
02800 
02801    if (acfptr == NULL)
02802       ast_log(LOG_ERROR, "Function %s not registered\n", copy);
02803    else if (!acfptr->write)
02804       ast_log(LOG_ERROR, "Function %s cannot be written to\n", copy);
02805    else {
02806       int res;
02807       struct ast_module_user *u = NULL;
02808       if (acfptr->mod)
02809          u = __ast_module_user_add(acfptr->mod, chan);
02810       res = acfptr->write(chan, copy, args, value);
02811       if (acfptr->mod && u)
02812          __ast_module_user_remove(acfptr->mod, u);
02813       return res;
02814    }
02815 
02816    return -1;
02817 }

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 8439 of file pbx.c.

References ast_context::name.

Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_remove_include2(), ast_context_remove_switch2(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), context_merge_incls_swits_igps_other_registrars(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), manager_show_dialplan_helper(), and show_dialplan_helper().

08440 {
08441    return con ? con->name : NULL;
08442 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 8477 of file pbx.c.

References ast_context::registrar.

Referenced by handle_cli_dialplan_save(), and show_dialplan_helper().

08478 {
08479    return c ? c->registrar : NULL;
08480 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

Definition at line 8507 of file pbx.c.

References ast_exten::app.

Referenced by _macro_exec(), ast_add_hint_nolock(), ast_extension_state2(), ast_get_hint(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), handle_statechange(), manager_show_dialplan_helper(), and print_ext().

08508 {
08509    return e ? e->app : NULL;
08510 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 8512 of file pbx.c.

References ast_exten::data.

Referenced by _macro_exec(), ast_get_hint(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), and print_ext().

08513 {
08514    return e ? e->data : NULL;
08515 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 8502 of file pbx.c.

References ast_exten::cidmatch.

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

08503 {
08504    return e ? e->cidmatch : NULL;
08505 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 8444 of file pbx.c.

References exten.

Referenced by handle_show_hint(), and handle_show_hints().

08445 {
08446    return exten ? exten->parent : NULL;
08447 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 8454 of file pbx.c.

References exten.

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

08455 {
08456    return exten ? exten->label : NULL;
08457 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 8497 of file pbx.c.

References ast_exten::matchcid.

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

08498 {
08499    return e ? e->matchcid : 0;
08500 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

Definition at line 8449 of file pbx.c.

References exten.

Referenced by ast_add_hint_nolock(), complete_core_show_hint(), complete_dialplan_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_cli_dialplan_save(), handle_show_hint(), handle_show_hints(), manager_show_dialplan_helper(), and show_dialplan_helper().

08450 {
08451    return exten ? exten->exten : NULL;
08452 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 8469 of file pbx.c.

References exten.

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

08470 {
08471    return exten ? exten->priority : -1;
08472 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 8482 of file pbx.c.

References ast_exten::registrar.

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

08483 {
08484    return e ? e->registrar : NULL;
08485 }

int ast_get_hint ( char *  hint,
int  maxlen,
char *  name,
int  maxnamelen,
struct ast_channel c,
const char *  context,
const char *  exten 
)

If an extension hint exists, return non-zero.

Parameters:
hint buffer for hint
maxlen size of hint buffer
name buffer for name portion of hint
maxnamelen size of name buffer
c this is not important
context which context to look in
exten which 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.

Definition at line 3572 of file pbx.c.

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

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

03573 {
03574    struct ast_exten *e = ast_hint_extension(c, context, exten);
03575 
03576    if (e) {
03577       if (hint)
03578          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
03579       if (name) {
03580          const char *tmp = ast_get_extension_app_data(e);
03581          if (tmp)
03582             ast_copy_string(name, tmp, namesize);
03583       }
03584       return -1;
03585    }
03586    return 0;
03587 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

Definition at line 8464 of file pbx.c.

References ast_ignorepat::pattern.

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

08465 {
08466    return ip ? ip->pattern : NULL;
08467 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 8492 of file pbx.c.

References ast_ignorepat::registrar.

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

08493 {
08494    return ip ? ip->registrar : NULL;
08495 }

const char* ast_get_include_name ( struct ast_include include  ) 

Definition at line 8459 of file pbx.c.

References ast_include::name.

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

08460 {
08461    return inc ? inc->name : NULL;
08462 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 8487 of file pbx.c.

References ast_include::registrar.

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

08488 {
08489    return i ? i->registrar : NULL;
08490 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 8522 of file pbx.c.

References ast_sw::data.

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

08523 {
08524    return sw ? sw->data : NULL;
08525 }

int ast_get_switch_eval ( struct ast_sw sw  ) 

Definition at line 8527 of file pbx.c.

References ast_sw::eval.

Referenced by context_merge_incls_swits_igps_other_registrars().

08528 {
08529    return sw->eval;
08530 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 8517 of file pbx.c.

References ast_sw::name.

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

08518 {
08519    return sw ? sw->name : NULL;
08520 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 8532 of file pbx.c.

References ast_sw::registrar.

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

08533 {
08534    return sw ? sw->registrar : NULL;
08535 }

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

References __ast_goto_if_exists(), and chan.

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

08626 {
08627    return __ast_goto_if_exists(chan, context, exten, priority, 0);
08628 }

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

unsigned int ast_hashtab_hash_contexts ( const void *  obj  ) 

int ast_ignore_pattern ( const char *  context,
const char *  pattern 
)

Checks to see if a number should be ignored.

Parameters:
context context to search within
pattern to check whether it should be ignored or not
Check if a number should be ignored with respect to dialtone cancellation.

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

Definition at line 6412 of file pbx.c.

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

Referenced by ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_enbloc_call_message(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_ss(), skinny_ss(), and ss_thread().

06413 {
06414    struct ast_context *con = ast_context_find(context);
06415    if (con) {
06416       struct ast_ignorepat *pat;
06417       for (pat = con->ignorepats; pat; pat = pat->next) {
06418          if (ast_extension_match(pat->pattern, pattern))
06419             return 1;
06420       }
06421    }
06422 
06423    return 0;
06424 }

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:
c not really important XXX
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid 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 3609 of file pbx.c.

References E_MATCHMORE, and pbx_extension_helper().

Referenced by ast_app_dtget(), collect_digits(), disa_exec(), dp_lookup(), dundi_lookup_local(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), readexten_exec(), skinny_ss(), and ss_thread().

03610 {
03611    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0, 0);
03612 }

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:
extcontexts pointer to the ast_context structure
exttable pointer to the ast_hashtab structure that contains all the elements in extcontexts
registrar of 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 5774 of file pbx.c.

References __ast_internal_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, ast_free, ast_hashtab_destroy(), ast_hashtab_end_traversal(), ast_hashtab_next(), ast_hashtab_start_traversal(), AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_rdlock_contexts(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tvdiff_us(), ast_tvnow(), ast_unlock_contexts(), ast_verb, ast_wrlock_contexts(), ast_wrlock_contexts_version(), ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, store_hint::context, context_merge(), contexts, contexts_table, ast_state_cb::data, E_MATCH, ast_exten::exten, ast_hint::exten, store_hint::exten, ast_hint::laststate, store_hint::laststate, store_hint::list, LOG_WARNING, ast_context::name, ast_context::next, store_hint::next, ast_state_cb::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.

Referenced by lua_reload_extensions(), and pbx_load_module().

05775 {
05776    double ft;
05777    struct ast_context *tmp, *oldcontextslist;
05778    struct ast_hashtab *oldtable;
05779    struct store_hints store = AST_LIST_HEAD_INIT_VALUE;
05780    struct store_hint *this;
05781    struct ast_hint *hint;
05782    struct ast_exten *exten;
05783    int length;
05784    struct ast_state_cb *thiscb, *prevcb;
05785    struct ast_hashtab_iter *iter;
05786    
05787    /* it is very important that this function hold the hint list lock _and_ the conlock
05788       during its operation; not only do we need to ensure that the list of contexts
05789       and extensions does not change, but also that no hint callbacks (watchers) are
05790       added or removed during the merge/delete process
05791 
05792       in addition, the locks _must_ be taken in this order, because there are already
05793       other code paths that use this order
05794    */
05795    
05796    struct timeval begintime, writelocktime, endlocktime, enddeltime;
05797    int wrlock_ver;
05798    
05799    begintime = ast_tvnow();
05800    ast_rdlock_contexts();
05801    iter = ast_hashtab_start_traversal(contexts_table);
05802    while ((tmp=ast_hashtab_next(iter))) {
05803       context_merge(extcontexts, exttable, tmp, registrar);
05804    }
05805    ast_hashtab_end_traversal(iter);
05806    wrlock_ver = ast_wrlock_contexts_version();
05807    
05808    ast_unlock_contexts(); /* this feels real retarded, but you must do
05809                        what you must do If this isn't done, the following 
05810                         wrlock is a guraranteed deadlock */
05811    ast_wrlock_contexts();
05812    if (ast_wrlock_contexts_version() > wrlock_ver+1) {
05813       ast_log(LOG_WARNING,"==================!!!!!!!!!!!!!!!Something changed the contexts in the middle of merging contexts!\n");
05814    }
05815    
05816    AST_RWLIST_WRLOCK(&hints);
05817    writelocktime = ast_tvnow();
05818 
05819    /* preserve all watchers for hints associated with this registrar */
05820    AST_RWLIST_TRAVERSE(&hints, hint, list) {
05821       if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) {
05822          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
05823          if (!(this = ast_calloc(1, length)))
05824             continue;
05825          this->callbacks = hint->callbacks;
05826          hint->callbacks = NULL;
05827          this->laststate = hint->laststate;
05828          this->context = this->data;
05829          strcpy(this->data, hint->exten->parent->name);
05830          this->exten = this->data + strlen(this->context) + 1;
05831          strcpy(this->exten, hint->exten->exten);
05832          AST_LIST_INSERT_HEAD(&store, this, list);
05833       }
05834    }
05835 
05836    /* save the old table and list */
05837    oldtable = contexts_table;
05838    oldcontextslist = contexts;
05839 
05840    /* move in the new table and list */
05841    contexts_table = exttable;
05842    contexts = *extcontexts;
05843    
05844    /* restore the watchers for hints that can be found; notify those that
05845       cannot be restored
05846    */
05847    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
05848       struct pbx_find_info q = { .stacklen = 0 };
05849       exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH);
05850       /* Find the hint in the list of hints */
05851       AST_RWLIST_TRAVERSE(&hints, hint, list) {
05852          if (hint->exten == exten)
05853             break;
05854       }
05855       if (!exten || !hint) {
05856          /* this hint has been removed, notify the watchers */
05857          prevcb = NULL;
05858          thiscb = this->callbacks;
05859          while (thiscb) {
05860             prevcb = thiscb;
05861             thiscb = thiscb->next;
05862             prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data);
05863             ast_free(prevcb);
05864             }
05865       } else {
05866          thiscb = this->callbacks;
05867          while (thiscb->next)
05868             thiscb = thiscb->next;
05869          thiscb->next = hint->callbacks;
05870          hint->callbacks = this->callbacks;
05871          hint->laststate = this->laststate;
05872       }
05873       ast_free(this);
05874    }
05875 
05876    AST_RWLIST_UNLOCK(&hints);
05877    ast_unlock_contexts();
05878    endlocktime = ast_tvnow();
05879    
05880    /* the old list and hashtab no longer are relevant, delete them while the rest of asterisk
05881       is now freely using the new stuff instead */
05882    
05883    ast_hashtab_destroy(oldtable, NULL);
05884    
05885    for (tmp = oldcontextslist; tmp; ) {
05886       struct ast_context *next;  /* next starting point */
05887       next = tmp->next;
05888       __ast_internal_context_destroy(tmp);
05889       tmp = next;
05890    }
05891    enddeltime = ast_tvnow();
05892    
05893    ft = ast_tvdiff_us(writelocktime, begintime);
05894    ft /= 1000000.0;
05895    ast_verb(3,"Time to scan old dialplan and merge leftovers back into the new: %8.6f sec\n", ft);
05896    
05897    ft = ast_tvdiff_us(endlocktime, writelocktime);
05898    ft /= 1000000.0;
05899    ast_verb(3,"Time to restore hints and swap in new dialplan: %8.6f sec\n", ft);
05900 
05901    ft = ast_tvdiff_us(enddeltime, endlocktime);
05902    ft /= 1000000.0;
05903    ast_verb(3,"Time to delete the old dialplan: %8.6f sec\n", ft);
05904 
05905    ft = ast_tvdiff_us(enddeltime, begintime);
05906    ft /= 1000000.0;
05907    ast_verb(3,"Total time merge_contexts_delete: %8.6f sec\n", ft);
05908    return;
05909 }

int ast_parseable_goto ( struct ast_channel chan,
const char *  goto_string 
)

Note:
I can find neither parsable nor parseable at dictionary.com, but google gives me 169000 hits for parseable and only 49,800 for parsable

This function will handle locking the channel as needed.

Definition at line 8688 of file pbx.c.

References chan, and pbx_parseable_goto().

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

08689 {
08690    return pbx_parseable_goto(chan, goto_string, 0);
08691 }

int ast_pbx_outgoing_app ( const char *  type,
int  format,
void *  data,
int  timeout,
const char *  app,
const char *  appdata,
int *  reason,
int  sync,
const char *  cid_num,
const char *  cid_name,
struct ast_variable vars,
const char *  account,
struct ast_channel **  locked_channel 
)

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

Definition at line 7228 of file pbx.c.

References __ast_request_and_dial(), ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_free, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create_detached, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verb, async_wait(), chan, errno, LOG_WARNING, and outgoing_helper::vars.

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

07229 {
07230    struct ast_channel *chan;
07231    struct app_tmp *tmp;
07232    int res = -1, cdr_res = -1;
07233    struct outgoing_helper oh;
07234 
07235    memset(&oh, 0, sizeof(oh));
07236    oh.vars = vars;
07237    oh.account = account;
07238 
07239    if (locked_channel)
07240       *locked_channel = NULL;
07241    if (ast_strlen_zero(app)) {
07242       res = -1;
07243       goto outgoing_app_cleanup;
07244    }
07245    if (sync) {
07246       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07247       if (chan) {
07248          ast_set_variables(chan, vars);
07249          if (account)
07250             ast_cdr_setaccount(chan, account);
07251          if (chan->_state == AST_STATE_UP) {
07252             res = 0;
07253             ast_verb(4, "Channel %s was answered.\n", chan->name);
07254             tmp = ast_calloc(1, sizeof(*tmp));
07255             if (!tmp)
07256                res = -1;
07257             else {
07258                ast_copy_string(tmp->app, app, sizeof(tmp->app));
07259                if (appdata)
07260                   ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
07261                tmp->chan = chan;
07262                if (sync > 1) {
07263                   if (locked_channel)
07264                      ast_channel_unlock(chan);
07265                   ast_pbx_run_app(tmp);
07266                } else {
07267                   if (locked_channel)
07268                      ast_channel_lock(chan);
07269                   if (ast_pthread_create_detached(&tmp->t, NULL, ast_pbx_run_app, tmp)) {
07270                      ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
07271                      ast_free(tmp);
07272                      if (locked_channel)
07273                         ast_channel_unlock(chan);
07274                      ast_hangup(chan);
07275                      res = -1;
07276                   } else {
07277                      if (locked_channel)
07278                         *locked_channel = chan;
07279                   }
07280                }
07281             }
07282          } else {
07283             ast_verb(4, "Channel %s was never answered.\n", chan->name);
07284             if (chan->cdr) { /* update the cdr */
07285                /* here we update the status of the call, which sould be busy.
07286                 * if that fails then we set the status to failed */
07287                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
07288                   ast_cdr_failed(chan->cdr);
07289             }
07290             ast_hangup(chan);
07291          }
07292       }
07293 
07294       if (res < 0) { /* the call failed for some reason */
07295          if (*reason == 0) { /* if the call failed (not busy or no answer)
07296                         * update the cdr with the failed message */
07297             cdr_res = ast_pbx_outgoing_cdr_failed();
07298             if (cdr_res != 0) {
07299                res = cdr_res;
07300                goto outgoing_app_cleanup;
07301             }
07302          }
07303       }
07304 
07305    } else {
07306       struct async_stat *as;
07307       if (!(as = ast_calloc(1, sizeof(*as)))) {
07308          res = -1;
07309          goto outgoing_app_cleanup;
07310       }
07311       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07312       if (!chan) {
07313          ast_free(as);
07314          res = -1;
07315          goto outgoing_app_cleanup;
07316       }
07317       as->chan = chan;
07318       ast_copy_string(as->app, app, sizeof(as->app));
07319       if (appdata)
07320          ast_copy_string(as->appdata,  appdata, sizeof(as->appdata));
07321       as->timeout = timeout;
07322       ast_set_variables(chan, vars);
07323       if (account)
07324          ast_cdr_setaccount(chan, account);
07325       /* Start a new thread, and get something handling this channel. */
07326       if (locked_channel)
07327          ast_channel_lock(chan);
07328       if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
07329          ast_log(LOG_WARNING, "Failed to start async wait\n");
07330          ast_free(as);
07331          if (locked_channel)
07332             ast_channel_unlock(chan);
07333          ast_hangup(chan);
07334          res = -1;
07335          goto outgoing_app_cleanup;
07336       } else {
07337          if (locked_channel)
07338             *locked_channel = chan;
07339       }
07340       res = 0;
07341    }
07342 outgoing_app_cleanup:
07343    ast_variables_destroy(vars);
07344    return res;
07345 }

int ast_pbx_outgoing_exten ( const char *  type,
int  format,
void *  data,
int  timeout,
const char *  context,
const char *  exten,
int  priority,
int *  reason,
int  sync,
const char *  cid_num,
const char *  cid_name,
struct ast_variable vars,
const char *  account,
struct ast_channel **  locked_channel 
)

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

Definition at line 7062 of file pbx.c.

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

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

07063 {
07064    struct ast_channel *chan;
07065    struct async_stat *as;
07066    int res = -1, cdr_res = -1;
07067    struct outgoing_helper oh;
07068 
07069    if (sync) {
07070       oh.context = context;
07071       oh.exten = exten;
07072       oh.priority = priority;
07073       oh.cid_num = cid_num;
07074       oh.cid_name = cid_name;
07075       oh.account = account;
07076       oh.vars = vars;
07077       oh.parent_channel = NULL;
07078 
07079       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
07080       if (channel) {
07081          *channel = chan;
07082          if (chan)
07083             ast_channel_lock(chan);
07084       }
07085       if (chan) {
07086          if (chan->_state == AST_STATE_UP) {
07087                res = 0;
07088             ast_verb(4, "Channel %s was answered.\n", chan->name);
07089 
07090             if (sync > 1) {
07091                if (channel)
07092                   ast_channel_unlock(chan);
07093                if (ast_pbx_run(chan)) {
07094                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
07095                   if (channel)
07096                      *channel = NULL;
07097                   ast_hangup(chan);
07098                   chan = NULL;
07099                   res = -1;
07100                }
07101             } else {
07102                if (ast_pbx_start(chan)) {
07103                   ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
07104                   if (channel) {
07105                      *channel = NULL;
07106                      ast_channel_unlock(chan);
07107                   }
07108                   ast_hangup(chan);
07109                   res = -1;
07110                }
07111                chan = NULL;
07112             }
07113          } else {
07114             ast_verb(4, "Channel %s was never answered.\n", chan->name);
07115 
07116             if (chan->cdr) { /* update the cdr */
07117                /* here we update the status of the call, which sould be busy.
07118                 * if that fails then we set the status to failed */
07119                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
07120                   ast_cdr_failed(chan->cdr);
07121             }
07122 
07123             if (channel) {
07124                *channel = NULL;
07125                ast_channel_unlock(chan);
07126             }
07127             ast_hangup(chan);
07128             chan = NULL;
07129          }
07130       }
07131 
07132       if (res < 0) { /* the call failed for some reason */
07133          if (*reason == 0) { /* if the call failed (not busy or no answer)
07134                         * update the cdr with the failed message */
07135             cdr_res = ast_pbx_outgoing_cdr_failed();
07136             if (cdr_res != 0) {
07137                res = cdr_res;
07138                goto outgoing_exten_cleanup;
07139             }
07140          }
07141 
07142          /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
07143          /* check if "failed" exists */
07144          if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
07145             chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed");
07146             if (chan) {
07147                char failed_reason[4] = "";
07148                if (!ast_strlen_zero(context))
07149                   ast_copy_string(chan->context, context, sizeof(chan->context));
07150                set_ext_pri(chan, "failed", 1);
07151                ast_set_variables(chan, vars);
07152                snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
07153                pbx_builtin_setvar_helper(chan, "REASON", failed_reason);
07154                if (account)
07155                   ast_cdr_setaccount(chan, account);
07156                if (ast_pbx_run(chan)) {
07157                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
07158                   ast_hangup(chan);
07159                }
07160                chan = NULL;
07161             }
07162          }
07163       }
07164    } else {
07165       if (!(as = ast_calloc(1, sizeof(*as)))) {
07166          res = -1;
07167          goto outgoing_exten_cleanup;
07168       }
07169       chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
07170       if (channel) {
07171          *channel = chan;
07172          if (chan)
07173             ast_channel_lock(chan);
07174       }
07175       if (!chan) {
07176          ast_free(as);
07177          res = -1;
07178          goto outgoing_exten_cleanup;
07179       }
07180       as->chan = chan;
07181       ast_copy_string(as->context, context, sizeof(as->context));
07182       set_ext_pri(as->chan,  exten, priority);
07183       as->timeout = timeout;
07184       ast_set_variables(chan, vars);
07185       if (account)
07186          ast_cdr_setaccount(chan, account);
07187       if (ast_pthread_create_detached(&as->p, NULL, async_wait, as)) {
07188          ast_log(LOG_WARNING, "Failed to start async wait\n");
07189          ast_free(as);
07190          if (channel) {
07191             *channel = NULL;
07192             ast_channel_unlock(chan);
07193          }
07194          ast_hangup(chan);
07195          res = -1;
07196          goto outgoing_exten_cleanup;
07197       }
07198       res = 0;
07199    }
07200 outgoing_exten_cleanup:
07201    ast_variables_destroy(vars);
07202    return res;
07203 }

enum ast_pbx_result ast_pbx_run ( struct ast_channel c  ) 

Execute the PBX in the current thread.

Parameters:
c channel 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:
Zero on success
non-zero on failure

Definition at line 4021 of file pbx.c.

References ast_pbx_run_args().

Referenced by ast_pbx_outgoing_exten(), async_wait(), do_idle_thread(), mgcp_ss(), skinny_newcall(), ss_thread(), and unistim_ss().

04022 {
04023    return ast_pbx_run_args(c, NULL);
04024 }

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:
c channel to run the pbx on
args options 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:
Zero on success
non-zero on failure

Definition at line 4006 of file pbx.c.

References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().

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

04007 {
04008    enum ast_pbx_result res = AST_PBX_SUCCESS;
04009 
04010    if (increase_call_count(c)) {
04011       return AST_PBX_CALL_LIMIT;
04012    }
04013 
04014    res = __ast_pbx_run(c, args);
04015 
04016    decrease_call_count();
04017 
04018    return res;
04019 }

enum ast_pbx_result ast_pbx_start ( struct ast_channel c  ) 

Create a new thread and start the PBX.

Parameters:
c channel 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:
Zero on success
non-zero on failure

Definition at line 3984 of file pbx.c.

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

Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_iax2_new(), ast_pbx_outgoing_exten(), bridge_exec(), check_goto_on_transfer(), console_new(), dahdi_new(), dial_exec_full(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), jingle_new(), jingle_newcall(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), unistim_new(), and usbradio_new().

03985 {
03986    pthread_t t;
03987 
03988    if (!c) {
03989       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
03990       return AST_PBX_FAILED;
03991    }
03992 
03993    if (increase_call_count(c))
03994       return AST_PBX_CALL_LIMIT;
03995 
03996    /* Start a new thread, and get something handling this channel. */
03997    if (ast_pthread_create_detached(&t, NULL, pbx_thread, c)) {
03998       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
03999       decrease_call_count();
04000       return AST_PBX_FAILED;
04001    }
04002 
04003    return AST_PBX_SUCCESS;
04004 }

int ast_processed_calls ( void   ) 

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

Definition at line 4031 of file pbx.c.

Referenced by handle_chanlist(), and handle_showcalls().

04032 {
04033    return totalcalls;
04034 }

int ast_rdlock_context ( struct ast_context con  ) 

Read locks a given context.

Parameters:
con context to lock
Return values:
0 on success
-1 on failure

Definition at line 8426 of file pbx.c.

References ast_rwlock_rdlock(), and ast_context::lock.

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

08427 {
08428    return ast_rwlock_rdlock(&con->lock);
08429 }

int ast_rdlock_contexts ( void   ) 

Read locks the context list.

Return values:
0 on success
-1 on error

Definition at line 8408 of file pbx.c.

References ast_rwlock_rdlock(), and conlock.

Referenced by _macro_exec(), ast_context_find(), ast_context_find_or_create(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_statechange(), manager_show_dialplan_helper(), pbx_extension_helper(), show_dialplan_helper(), and unreference_cached_app().

08409 {
08410    return ast_rwlock_rdlock(&conlock);
08411 }

int ast_register_switch ( struct ast_switch sw  ) 

Register an alternative dialplan switch.

Parameters:
sw switch to register
This function registers a populated ast_switch structure with the asterisk switching architecture.

Returns:
0 on success, and other than 0 on failure

Definition at line 4506 of file pbx.c.

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

Referenced by load_module().

04507 {
04508    struct ast_switch *tmp;
04509 
04510    AST_RWLIST_WRLOCK(&switches);
04511    AST_RWLIST_TRAVERSE(&switches, tmp, list) {
04512       if (!strcasecmp(tmp->name, sw->name)) {
04513          AST_RWLIST_UNLOCK(&switches);
04514          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
04515          return -1;
04516       }
04517    }
04518    AST_RWLIST_INSERT_TAIL(&switches, sw, list);
04519    AST_RWLIST_UNLOCK(&switches);
04520 
04521    return 0;
04522 }

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:
c not important
context which context to generate the extension within
exten new extension to add
priority priority of new extension
callerid callerid 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:
0 on success
-1 on failure.

Definition at line 3614 of file pbx.c.

References E_SPAWN, and pbx_extension_helper().

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

03615 {
03616    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found, combined_find_spawn);
03617 }

int ast_unlock_context ( struct ast_context con  ) 

Return values:
Unlocks the given context
Parameters:
con context to unlock
Return values:
0 on success
-1 on failure

Definition at line 8431 of file pbx.c.

References ast_rwlock_unlock(), and ast_context::lock.

Referenced by __ast_context_destroy(), _macro_exec(), ast_add_extension2_lockopt(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_remove_extension_callerid2(), ast_context_remove_ignorepat2(), ast_context_remove_include2(), ast_context_remove_switch2(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_cli_dialplan_save(), lookup_c_ip(), lookup_ci(), manager_show_dialplan_helper(), and show_dialplan_helper().

08432 {
08433    return ast_rwlock_unlock(&con->lock);
08434 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 8413 of file pbx.c.

References ast_rwlock_unlock(), and conlock.

Referenced by _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_destroy(), ast_context_find(), ast_context_find_or_create(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_cli_dialplan_save(), handle_statechange(), manager_show_dialplan_helper(), pbx_extension_helper(), show_dialplan_helper(), and unreference_cached_app().

08414 {
08415    return ast_rwlock_unlock(&conlock);
08416 }

void ast_unregister_switch ( struct ast_switch sw  ) 

Unregister an alternative switch.

Parameters:
sw switch to unregister
Unregisters a switch from asterisk.

Returns:
nothing

Definition at line 4524 of file pbx.c.

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

Referenced by __unload_module(), and unload_module().

04525 {
04526    AST_RWLIST_WRLOCK(&switches);
04527    AST_RWLIST_REMOVE(&switches, sw, list);
04528    AST_RWLIST_UNLOCK(&switches);
04529 }

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

Definition at line 8545 of file pbx.c.

References exten, and ast_context::root.

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

08547 {
08548    if (!exten)
08549       return con ? con->root : NULL;
08550    else
08551       return exten->next;
08552 }

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

Definition at line 8578 of file pbx.c.

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

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

08580 {
08581    if (!ip)
08582       return con ? con->ignorepats : NULL;
08583    else
08584       return ip->next;
08585 }

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

Definition at line 8569 of file pbx.c.

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

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

08571 {
08572    if (!inc)
08573       return con ? con->includes : NULL;
08574    else
08575       return inc->next;
08576 }

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

Definition at line 8554 of file pbx.c.

References ast_context::alts, AST_LIST_FIRST, AST_LIST_NEXT, and ast_sw::list.

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

08556 {
08557    if (!sw)
08558       return con ? AST_LIST_FIRST(&con->alts) : NULL;
08559    else
08560       return AST_LIST_NEXT(sw, list);
08561 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

Definition at line 8540 of file pbx.c.

References contexts, and ast_context::next.

Referenced by _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), complete_dialplan_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_cli_dialplan_save(), manager_show_dialplan_helper(), pbx_find_extension(), pbx_load_module(), show_dialplan_helper(), and unreference_cached_app().

08541 {
08542    return con ? con->next : contexts;
08543 }

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

Definition at line 8563 of file pbx.c.

References exten, and ast_exten::priority.

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

08565 {
08566    return priority ? priority->peer : exten;
08567 }

int ast_wrlock_context ( struct ast_context con  ) 

Write locks a given context.

Parameters:
con context to lock
Return values:
0 on success
-1 on failure

Definition at line 8421 of file pbx.c.

References ast_rwlock_wrlock(), and ast_context::lock.

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

08422 {
08423    return ast_rwlock_wrlock(&con->lock);
08424 }

int ast_wrlock_contexts ( void   ) 

Write locks the context list.

Return values:
0 on success
-1 on error

Definition at line 8400 of file pbx.c.

References ast_atomic_fetchadd_int(), ast_rwlock_wrlock(), and conlock.

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

08401 {
08402    int res = ast_rwlock_wrlock(&conlock);
08403    if (!res)
08404       ast_atomic_fetchadd_int(&conlock_wrlock_version, 1);
08405    return res;
08406 }

int ast_wrlock_contexts_version ( void   ) 

Definition at line 8392 of file pbx.c.

Referenced by ast_merge_contexts_and_delete().

08393 {
08394    return conlock_wrlock_version;
08395 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 8244 of file pbx.c.

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

Referenced by handle_cli_dialplan_reload(), and reload().

08245 {
08246    struct ast_var_t *vardata;
08247 
08248    ast_rwlock_wrlock(&globalslock);
08249    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
08250       ast_var_delete(vardata);
08251    ast_rwlock_unlock(&globalslock);
08252 }

const char* pbx_builtin_getvar_helper ( struct ast_channel chan,
const char *  name 
)

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;

      ast_channel_lock(chan);
      if ((var = pbx_builtin_getvar_helper(chan, "MYVAR"))) {
         var = ast_strdupa(var);
      }
      ast_channel_unlock(chan);

Definition at line 8014 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_var_name(), ast_var_value(), chan, globals, and globalslock.

Referenced by _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), array(), ast_bridge_call(), ast_call_forward(), ast_eivr_getvariable(), ast_feature_interpret(), ast_monitor_stop(), builtin_automixmonitor(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dial_exec_full(), do_forward(), do_timelimit(), dundi_exec(), dundi_helper(), get_also_info(), get_index(), get_refer_info(), global_read(), hash_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), local_read(), login_exec(), macro_fixup(), minivm_delete_exec(), minivm_notify_exec(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), park_space_reserve(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), ring_entry(), run_agi(), set_config_flags(), set_local_info(), sip_addheader(), sla_trunk_exec(), speech_background(), try_suggested_sip_codec(), and update_bridge_vars().

08015 {
08016    struct ast_var_t *variables;
08017    const char *ret = NULL;
08018    int i;
08019    struct varshead *places[2] = { NULL, &globals };
08020 
08021    if (!name)
08022       return NULL;
08023 
08024    if (chan) {
08025       ast_channel_lock(chan);
08026       places[0] = &chan->varshead;
08027    }
08028 
08029    for (i = 0; i < 2; i++) {
08030       if (!places[i])
08031          continue;
08032       if (places[i] == &globals)
08033          ast_rwlock_rdlock(&globalslock);
08034       AST_LIST_TRAVERSE(places[i], variables, entries) {
08035          if (!strcmp(name, ast_var_name(variables))) {
08036             ret = ast_var_value(variables);
08037             break;
08038          }
08039       }
08040       if (places[i] == &globals)
08041          ast_rwlock_unlock(&globalslock);
08042       if (ret)
08043          break;
08044    }
08045 
08046    if (chan)
08047       ast_channel_unlock(chan);
08048 
08049    return ret;
08050 }

void pbx_builtin_pushvar_helper ( struct ast_channel chan,
const char *  name,
const char *  value 
)

Note:
Will lock the channel.

Definition at line 8052 of file pbx.c.

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

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

08053 {
08054    struct ast_var_t *newvariable;
08055    struct varshead *headp;
08056 
08057    if (name[strlen(name)-1] == ')') {
08058       char *function = ast_strdupa(name);
08059 
08060       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
08061       ast_func_write(chan, function, value);
08062       return;
08063    }
08064 
08065    if (chan) {
08066       ast_channel_lock(chan);
08067       headp = &chan->varshead;
08068    } else {
08069       ast_rwlock_wrlock(&globalslock);
08070       headp = &globals;
08071    }
08072 
08073    if (value) {
08074       if (headp == &globals)
08075          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08076       newvariable = ast_var_assign(name, value);
08077       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08078    }
08079 
08080    if (chan)
08081       ast_channel_unlock(chan);
08082    else
08083       ast_rwlock_unlock(&globalslock);
08084 }

int pbx_builtin_raise_exception ( struct ast_channel chan,
void *  data 
)

Definition at line 2498 of file pbx.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_alloc(), ast_channel_datastore_find(), ast_channel_datastore_free(), ast_free, ast_string_field_init, ast_string_field_set, chan, ast_channel::context, context, ast_datastore::data, exception_store_info, ast_channel::exten, exten, ast_channel::priority, pbx_exception::priority, and set_ext_pri().

Referenced by __ast_pbx_run().

02499 {
02500    const char *reason = vreason;
02501    struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL);
02502    struct pbx_exception *exception = NULL;
02503 
02504    if (!ds) {
02505       ds = ast_channel_datastore_alloc(&exception_store_info, NULL);
02506       if (!ds)
02507          return -1;
02508       exception = ast_calloc(1, sizeof(struct pbx_exception));
02509       if (!exception) {
02510          ast_channel_datastore_free(ds);
02511          return -1;
02512       }
02513       if (ast_string_field_init(exception, 128)) {
02514          ast_free(exception);
02515          ast_channel_datastore_free(ds);
02516          return -1;
02517       }
02518       ds->data = exception;
02519       ast_channel_datastore_add(chan, ds);
02520    } else
02521       exception = ds->data;
02522 
02523    ast_string_field_set(exception, reason, reason);
02524    ast_string_field_set(exception, context, chan->context);
02525    ast_string_field_set(exception, exten, chan->exten);
02526    exception->priority = chan->priority;
02527    set_ext_pri(chan, "e", 0);
02528    return 0;
02529 }

int pbx_builtin_serialize_variables ( struct ast_channel chan,
struct ast_str **  buf 
)

Note:
Will lock the channel.

Definition at line 7982 of file pbx.c.

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

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

07983 {
07984    struct ast_var_t *variables;
07985    const char *var, *val;
07986    int total = 0;
07987 
07988    if (!chan)
07989       return 0;
07990 
07991    (*buf)->used = 0;
07992    (*buf)->str[0] = '\0';
07993 
07994    ast_channel_lock(chan);
07995 
07996    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
07997       if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))
07998          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
07999          ) {
08000          if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) {
08001             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
08002             break;
08003          } else
08004             total++;
08005       } else
08006          break;
08007    }
08008 
08009    ast_channel_unlock(chan);
08010 
08011    return total;
08012 }

int pbx_builtin_setvar ( struct ast_channel chan,
void *  data 
)

Note:
Will lock the channel.

void pbx_builtin_setvar_helper ( struct ast_channel chan,
const char *  name,
const char *  value 
)

Note:
Will lock the channel.

Definition at line 8086 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verb, chan, EVENT_FLAG_DIALPLAN, globals, globalslock, manager_event, ast_channel::name, and ast_channel::uniqueid.

Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_fetch(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), aqm_exec(), array(), ast_bridge_call(), ast_eivr_setvariable(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_set_variables(), asyncgoto_exec(), background_detect_exec(), bridge_exec(), builtin_automixmonitor(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), channel_spy(), conf_run(), controlplayback_exec(), count_exec(), dahdi_handle_dtmfup(), dahdi_new(), dial_exec_full(), do_parking_thread(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), frame_set_var(), function_db_delete(), function_db_exists(), function_db_read(), function_realtime_store(), get_rdnis(), get_refer_info(), global_write(), gosub_release_frame(), handle_request_bye(), handle_request_refer(), handle_set_chanvar(), handle_set_global(), handle_setvariable(), hash_read(), hash_write(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lua_set_variable(), lua_set_variable_value(), macro_fixup(), minivm_accmess_exec(), minivm_delete_exec(), minivm_greet_exec(), minivm_notify_exec(), minivm_record_exec(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_background(), pbx_builtin_importvar(), pbx_builtin_setvar(), pbx_builtin_setvar_multiple(), pbx_load_config(), phase_e_handler(), play_message_datetime(), playback_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readexten_exec(), readfile_exec(), record_exec(), return_exec(), rotate_file(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), skinny_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), transmit(), tryexec_exec(), update_bridge_vars(), update_qe_rule(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), waituntil_exec(), and zapateller_exec().

08087 {
08088    struct ast_var_t *newvariable;
08089    struct varshead *headp;
08090    const char *nametail = name;
08091 
08092    if (name[strlen(name) - 1] == ')') {
08093       char *function = ast_strdupa(name);
08094 
08095       ast_func_write(chan, function, value);
08096       return;
08097    }
08098 
08099    if (chan) {
08100       ast_channel_lock(chan);
08101       headp = &chan->varshead;
08102    } else {
08103       ast_rwlock_wrlock(&globalslock);
08104       headp = &globals;
08105    }
08106 
08107    /* For comparison purposes, we have to strip leading underscores */
08108    if (*nametail == '_') {
08109       nametail++;
08110       if (*nametail == '_')
08111          nametail++;
08112    }
08113 
08114    AST_LIST_TRAVERSE (headp, newvariable, entries) {
08115       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
08116          /* there is already such a variable, delete it */
08117          AST_LIST_REMOVE(headp, newvariable, entries);
08118          ast_var_delete(newvariable);
08119          break;
08120       }
08121    }
08122 
08123    if (value) {
08124       if (headp == &globals)
08125          ast_verb(2, "Setting global variable '%s' to '%s'\n", name, value);
08126       newvariable = ast_var_assign(name, value);
08127       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
08128       manager_event(EVENT_FLAG_DIALPLAN, "VarSet", 
08129          "Channel: %s\r\n"
08130          "Variable: %s\r\n"
08131          "Value: %s\r\n"
08132          "Uniqueid: %s\r\n", 
08133          chan ? chan->name : "none", name, value, 
08134          chan ? chan->uniqueid : "none");
08135    }
08136 
08137    if (chan)
08138       ast_channel_unlock(chan);
08139    else
08140       ast_rwlock_unlock(&globalslock);
08141 }

int pbx_builtin_setvar_multiple ( struct ast_channel chan,
void *  data 
)

int pbx_checkcondition ( const char *  condition  ) 

Evaluate a condition.

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

Definition at line 8254 of file pbx.c.

References ast_strlen_zero().

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

08255 {
08256    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
08257       return 0;
08258    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
08259       return atoi(condition);
08260    else  /* Strings are true */
08261       return 1;
08262 }

int pbx_exec ( struct ast_channel c,
struct ast_app app,
void *  data 
)

Execute an application.

Parameters:
c channel to execute on
app which app to execute
data the 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.

Returns:
0 on success, and -1 on failure
Parameters:
c  Channel
app  Application
data  Data for execution

Definition at line 925 of file pbx.c.

References __ast_module_user_add(), __ast_module_user_remove(), app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_log(), ast_strlen_zero(), ast_channel::cdr, ast_channel::data, LOG_WARNING, ast_channel::name, and S_OR.

Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), handle_gosub(), iax2_exec(), lua_pbx_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and tryexec_exec().

00928 {
00929    int res;
00930    struct ast_module_user *u = NULL;
00931    const char *saved_c_appl;
00932    const char *saved_c_data;
00933 
00934    if (c->cdr && !ast_check_hangup(c))
00935       ast_cdr_setapp(c->cdr, app->name, data);
00936 
00937    /* save channel values */
00938    saved_c_appl= c->appl;
00939    saved_c_data= c->data;
00940 
00941    c->appl = app->name;
00942    c->data = data;
00943    if (app->module)
00944       u = __ast_module_user_add(app->module, c);
00945    if (strcasecmp(app->name, "system") && !ast_strlen_zero(data) &&
00946          strchr(data, '|') && !strchr(data, ',')) {
00947       ast_log(LOG_WARNING, "The application delimiter is now the comma, not "
00948          "the pipe.  Did you forget to convert your dialplan?  (%s(%s))\n",
00949          app->name, (char *) data);
00950    }
00951    res = app->execute(c, S_OR(data, ""));
00952    if (app->module && u)
00953       __ast_module_user_remove(app->module, u);
00954    /* restore channel values */
00955    c->appl = saved_c_appl;
00956    c->data = saved_c_data;
00957    return res;
00958 }

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

References ast_context::alts, ast_autoservice_start(), ast_autoservice_stop(), ast_hashtab_lookup(), AST_LIST_TRAVERSE, ast_log(), AST_PBX_MAX_STACK, ast_str_thread_get(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), ast_switch::canmatch, scoreboard::canmatch_exten, chan, contexts_table, create_match_char_tree(), ast_sw::data, pbx_find_info::data, E_CANMATCH, E_FINDLABEL, E_MATCHMORE, ast_sw::eval, ast_switch::exists, ast_exten::exten, scoreboard::exten, extension_match_core(), pbx_find_info::foundcontext, include_valid(), ast_context::includes, pbx_find_info::incstack, ast_exten::label, scoreboard::last_char, ast_str::len, LOG_DEBUG, log_match_char_tree(), LOG_NOTICE, LOG_WARNING, match(), matchcid(), ast_switch::matchmore, ast_sw::name, ast_context::name, fake_context::name, new_find_extension(), ast_include::next, scoreboard::node, ast_context::pattern_tree, pbx_find_extension(), pbx_findswitch(), pbx_substitute_variables_helper(), ast_exten::priority, ast_include::rname, ast_context::root_table, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, STATUS_SUCCESS, ast_str::str, switch_data, pbx_find_info::swo, scoreboard::total_length, scoreboard::total_specificity, and trie_find_next_match().

Referenced by ast_hint_extension(), ast_merge_contexts_and_delete(), pbx_extension_helper(), pbx_find_extension(), and register_peer_exten().

02040 {
02041    int x, res;
02042    struct ast_context *tmp = NULL;
02043    struct ast_exten *e = NULL, *eroot = NULL;
02044    struct ast_include *i = NULL;
02045    struct ast_sw *sw = NULL;
02046    struct ast_exten pattern = {NULL, };
02047    struct scoreboard score = {0, };
02048    struct ast_str *tmpdata = NULL;
02049 
02050    pattern.label = label;
02051    pattern.priority = priority;
02052 #ifdef NEED_DEBUG_HERE
02053    ast_log(LOG_NOTICE,"Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int)action);
02054 #endif
02055    /* Initialize status if appropriate */
02056    if (q->stacklen == 0) {
02057       q->status = STATUS_NO_CONTEXT;
02058       q->swo = NULL;
02059       q->data = NULL;
02060       q->foundcontext = NULL;
02061    } else if (q->stacklen >= AST_PBX_MAX_STACK) {
02062       ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
02063       return NULL;
02064    }
02065 
02066    /* Check first to see if we've already been checked */
02067    for (x = 0; x < q->stacklen; x++) {
02068       if (!strcasecmp(q->incstack[x], context))
02069          return NULL;
02070    }
02071 
02072    if (bypass) /* bypass means we only look there */
02073       tmp = bypass;
02074    else {   /* look in contexts */
02075       struct fake_context item;
02076       strncpy(item.name,context,256);
02077       tmp = ast_hashtab_lookup(contexts_table,&item);
02078 #ifdef NOTNOW
02079       tmp = NULL;
02080       while ((tmp = ast_walk_contexts(tmp)) ) {
02081          if (!strcmp(tmp->name, context))
02082             break;
02083       }
02084 #endif
02085       if (!tmp)
02086          return NULL;
02087       
02088    }
02089 
02090    if (q->status < STATUS_NO_EXTENSION)
02091       q->status = STATUS_NO_EXTENSION;
02092    
02093    /* Do a search for matching extension */
02094 
02095    eroot = NULL;
02096    score.total_specificity = 0;
02097    score.exten = 0;
02098    score.total_length = 0;
02099    if (!tmp->pattern_tree && tmp->root_table)
02100    {
02101       create_match_char_tree(tmp);
02102 #ifdef NEED_DEBUG
02103       ast_log(LOG_DEBUG,"Tree Created in context %s:\n", context);
02104       log_match_char_tree(tmp->pattern_tree," ");
02105 #endif
02106    }
02107 #ifdef NEED_DEBUG
02108    ast_log(LOG_NOTICE,"The Trie we are searching in:\n");
02109    log_match_char_tree(tmp->pattern_tree, "::  ");
02110 #endif
02111 
02112    if (extenpatternmatchnew) {
02113       new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid, label, action);
02114       eroot = score.exten;
02115       
02116       if (score.last_char == '!' && action == E_MATCHMORE) {
02117          /* We match an extension ending in '!'.
02118           * The decision in this case is final and is NULL (no match).
02119           */
02120 #ifdef NEED_DEBUG_HERE
02121          ast_log(LOG_NOTICE,"Returning MATCHMORE NULL with exclamation point.\n");
02122 #endif
02123          return NULL;
02124       }
02125       
02126       if (!eroot && (action == E_CANMATCH || action == E_MATCHMORE) && score.canmatch_exten) {
02127          q->status = STATUS_SUCCESS;
02128 #ifdef NEED_DEBUG_HERE
02129          ast_log(LOG_NOTICE,"Returning CANMATCH exten %s\n", score.canmatch_exten->exten);
02130 #endif
02131          return score.canmatch_exten;
02132       }
02133       
02134       if ((action == E_MATCHMORE || action == E_CANMATCH)  && eroot) {
02135          if (score.node) {
02136             struct ast_exten *z = trie_find_next_match(score.node);
02137             if (z) {
02138 #ifdef NEED_DEBUG_HERE
02139                ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten %s\n", z->exten);
02140 #endif
02141             } else {
02142                if (score.canmatch_exten) {
02143 #ifdef NEED_DEBUG_HERE
02144                   ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE canmatchmatch exten %s(%p)\n", score.canmatch_exten->exten, score.canmatch_exten);
02145 #endif
02146                   return score.canmatch_exten;
02147                } else {
02148 #ifdef NEED_DEBUG_HERE
02149                   ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE next_match exten NULL\n");
02150 #endif
02151                }
02152             }
02153             return z;
02154          }
02155 #ifdef NEED_DEBUG_HERE
02156          ast_log(LOG_NOTICE,"Returning CANMATCH/MATCHMORE NULL (no next_match)\n");
02157 #endif
02158          return NULL;  /* according to the code, complete matches are null matches in MATCHMORE mode */
02159       }
02160       
02161       if (eroot) {
02162          /* found entry, now look for the right priority */
02163          if (q->status < STATUS_NO_PRIORITY)
02164             q->status = STATUS_NO_PRIORITY;
02165          e = NULL;
02166          if (action == E_FINDLABEL && label ) {
02167             if (q->status < STATUS_NO_LABEL)
02168                q->status = STATUS_NO_LABEL;
02169             e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
02170          } else {
02171             e = ast_hashtab_lookup(eroot->peer_table, &pattern);
02172          }
02173          if (e) { /* found a valid match */
02174             q->status = STATUS_SUCCESS;
02175             q->foundcontext = context;
02176 #ifdef NEED_DEBUG_HERE
02177             ast_log(LOG_NOTICE,"Returning complete match of exten %s\n", e->exten);
02178 #endif
02179             return e;
02180          }
02181       }
02182    } else {   /* the old/current default exten pattern match algorithm */
02183       
02184       /* scan the list trying to match extension and CID */
02185       eroot = NULL;
02186       while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
02187          int match = extension_match_core(eroot->exten, exten, action);
02188          /* 0 on fail, 1 on match, 2 on earlymatch */
02189          
02190          if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
02191             continue;   /* keep trying */
02192          if (match == 2 && action == E_MATCHMORE) {
02193             /* We match an extension ending in '!'.
02194              * The decision in this case is final and is NULL (no match).
02195              */
02196             return NULL;
02197          }
02198          /* found entry, now look for the right priority */
02199          if (q->status < STATUS_NO_PRIORITY)
02200             q->status = STATUS_NO_PRIORITY;
02201          e = NULL;
02202          if (action == E_FINDLABEL && label ) {
02203             if (q->status < STATUS_NO_LABEL)
02204                q->status = STATUS_NO_LABEL;
02205             e = ast_hashtab_lookup(eroot->peer_label_table, &pattern);
02206          } else {
02207             e = ast_hashtab_lookup(eroot->peer_table, &pattern);
02208          }
02209 #ifdef NOTNOW
02210          while ( (e = ast_walk_extension_priorities(eroot, e)) ) {
02211             /* Match label or priority */
02212             if (action == E_FINDLABEL) {
02213                if (q->status < STATUS_NO_LABEL)
02214                   q->status = STATUS_NO_LABEL;
02215                if (label && e->label && !strcmp(label, e->label))
02216                   break;   /* found it */
02217             } else if (e->priority == priority) {
02218                break;   /* found it */
02219             } /* else keep searching */
02220          }
02221 #endif
02222          if (e) { /* found a valid match */
02223             q->status = STATUS_SUCCESS;
02224             q->foundcontext = context;
02225             return e;
02226          }
02227       }
02228    }
02229    
02230    
02231    /* Check alternative switches */
02232    AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
02233       struct ast_switch *asw = pbx_findswitch(sw->name);
02234       ast_switch_f *aswf = NULL;
02235       char *datap;
02236 
02237       if (!asw) {
02238          ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
02239          continue;
02240       }
02241       /* Substitute variables now */
02242       
02243       if (sw->eval) {
02244          if (!(tmpdata = ast_str_thread_get(&switch_data, 512))) {
02245             ast_log(LOG_WARNING, "Can't evaluate switch?!");
02246             continue;
02247          }
02248          pbx_substitute_variables_helper(chan, sw->data, tmpdata->str, tmpdata->len);
02249       }
02250 
02251       /* equivalent of extension_match_core() at the switch level */
02252       if (action == E_CANMATCH)
02253          aswf = asw->canmatch;
02254       else if (action == E_MATCHMORE)
02255          aswf = asw->matchmore;
02256       else /* action == E_MATCH */
02257          aswf = asw->exists;
02258       datap = sw->eval ? tmpdata->str : sw->data;
02259       if (!aswf)
02260          res = 0;
02261       else {
02262          if (chan)
02263             ast_autoservice_start(chan);
02264          res = aswf(chan, context, exten, priority, callerid, datap);
02265          if (chan)
02266             ast_autoservice_stop(chan);
02267       }
02268       if (res) {  /* Got a match */
02269          q->swo = asw;
02270          q->data = datap;
02271          q->foundcontext = context;
02272          /* XXX keep status = STATUS_NO_CONTEXT ? */
02273          return NULL;
02274       }
02275    }
02276    q->incstack[q->stacklen++] = tmp->name;   /* Setup the stack */
02277    /* Now try any includes we have in this context */
02278    for (i = tmp->includes; i; i = i->next) {
02279       if (include_valid(i)) {
02280          if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) {
02281 #ifdef NEED_DEBUG_HERE
02282             ast_log(LOG_NOTICE,"Returning recursive match of %s\n", e->exten);
02283 #endif
02284             return e;
02285          }
02286          if (q->swo)
02287             return NULL;
02288       }
02289    }
02290    return NULL;
02291 }

struct ast_app* pbx_findapp ( const char *  app  ) 

Look up an application.

Parameters:
app name 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 966 of file pbx.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_app::list, and ast_app::name.

Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automixmonitor(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), handle_gosub(), iax2_exec(), lua_pbx_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and tryexec_exec().

00967 {
00968    struct ast_app *tmp;
00969 
00970    AST_RWLIST_RDLOCK(&apps);
00971    AST_RWLIST_TRAVERSE(&apps, tmp, list) {
00972       if (!strcasecmp(tmp->name, app))
00973          break;
00974    }
00975    AST_RWLIST_UNLOCK(&apps);
00976 
00977    return tmp;
00978 }

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.

Note:
See also

Definition at line 2373 of file pbx.c.

References ARRAY_LEN, ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_get_hint(), AST_LIST_TRAVERSE, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, globals, globalslock, ast_channel::hangupcause, ast_channel::name, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::uniqueid.

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

02374 {
02375    const char not_found = '\0';
02376    char *tmpvar;
02377    const char *s; /* the result */
02378    int offset, length;
02379    int i, need_substring;
02380    struct varshead *places[2] = { headp, &globals };  /* list of places where we may look */
02381 
02382    if (c) {
02383       ast_channel_lock(c);
02384       places[0] = &c->varshead;
02385    }
02386    /*
02387     * Make a copy of var because parse_variable_name() modifies the string.
02388     * Then if called directly, we might need to run substring() on the result;
02389     * remember this for later in 'need_substring', 'offset' and 'length'
02390     */
02391    tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
02392    need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
02393 
02394    /*
02395     * Look first into predefined variables, then into variable lists.
02396     * Variable 's' points to the result, according to the following rules:
02397     * s == &not_found (set at the beginning) means that we did not find a
02398     * matching variable and need to look into more places.
02399     * If s != &not_found, s is a valid result string as follows:
02400     * s = NULL if the variable does not have a value;
02401     * you typically do this when looking for an unset predefined variable.
02402     * s = workspace if the result has been assembled there;
02403     * typically done when the result is built e.g. with an snprintf(),
02404     * so we don't need to do an additional copy.
02405     * s != workspace in case we have a string, that needs to be copied
02406     * (the ast_copy_string is done once for all at the end).
02407     * Typically done when the result is already available in some string.
02408     */
02409    s = &not_found;   /* default value */
02410    if (c) { /* This group requires a valid channel */
02411       /* Names with common parts are looked up a piece at a time using strncmp. */
02412       if (!strncmp(var, "CALL", 4)) {
02413          if (!strncmp(var + 4, "ING", 3)) {
02414             if (!strcmp(var + 7, "PRES")) {        /* CALLINGPRES */
02415                snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
02416                s = workspace;
02417             } else if (!strcmp(var + 7, "ANI2")) {    /* CALLINGANI2 */
02418                snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
02419                s = workspace;
02420             } else if (!strcmp(var + 7, "TON")) {     /* CALLINGTON */
02421                snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
02422                s = workspace;
02423             } else if (!strcmp(var + 7, "TNS")) {     /* CALLINGTNS */
02424                snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
02425                s = workspace;
02426             }
02427          }
02428       } else if (!strcmp(var, "HINT")) {
02429          s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
02430       } else if (!strcmp(var, "HINTNAME")) {
02431          s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
02432       } else if (!strcmp(var, "EXTEN")) {
02433          s = c->exten;
02434       } else if (!strcmp(var, "CONTEXT")) {
02435          s = c->context;
02436       } else if (!strcmp(var, "PRIORITY")) {
02437          snprintf(workspace, workspacelen, "%d", c->priority);
02438          s = workspace;
02439       } else if (!strcmp(var, "CHANNEL")) {
02440          s = c->name;
02441       } else if (!strcmp(var, "UNIQUEID")) {
02442          s = c->uniqueid;
02443       } else if (!strcmp(var, "HANGUPCAUSE")) {
02444          snprintf(workspace, workspacelen, "%d", c->hangupcause);
02445          s = workspace;
02446       }
02447    }
02448    if (s == &not_found) { /* look for more */
02449       if (!strcmp(var, "EPOCH")) {
02450          snprintf(workspace, workspacelen, "%u",(int)time(NULL));
02451          s = workspace;
02452       } else if (!strcmp(var, "SYSTEMNAME")) {
02453          s = ast_config_AST_SYSTEM_NAME;
02454       }
02455    }
02456    /* if not found, look into chanvars or global vars */
02457    for (i = 0; s == &not_found && i < ARRAY_LEN(places); i++) {
02458       struct ast_var_t *variables;
02459       if (!places[i])
02460          continue;
02461       if (places[i] == &globals)
02462          ast_rwlock_rdlock(&globalslock);
02463       AST_LIST_TRAVERSE(places[i], variables, entries) {
02464          if (!strcasecmp(ast_var_name(variables), var)) {
02465             s = ast_var_value(variables);
02466             break;
02467          }
02468       }
02469       if (places[i] == &globals)
02470          ast_rwlock_unlock(&globalslock);
02471    }
02472    if (s == &not_found || s == NULL)
02473       *ret = NULL;
02474    else {
02475       if (s != workspace)
02476          ast_copy_string(workspace, s, workspacelen);
02477       *ret = workspace;
02478       if (need_substring)
02479          *ret = substring(*ret, offset, length, workspace, workspacelen);
02480    }
02481 
02482    if (c)
02483       ast_channel_unlock(c);
02484 }

int pbx_set_autofallthrough ( int  newval  ) 

Set "autofallthrough" flag, if newval is <0, does not acutally 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 4036 of file pbx.c.

Referenced by pbx_load_module().

04037 {
04038    int oldval = autofallthrough;
04039    autofallthrough = newval;
04040    return oldval;
04041 }

int pbx_set_extenpatternmatchnew ( int  newval  ) 

Set "extenpatternmatchnew" flag, if newval is <0, does not acutally 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 4043 of file pbx.c.

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

04044 {
04045    int oldval = extenpatternmatchnew;
04046    extenpatternmatchnew = newval;
04047    return oldval;
04048 }

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

Definition at line 3011 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

Referenced by _macro_exec(), acf_import(), acf_odbc_read(), acf_odbc_write(), config_curl(), custom_log(), cut_internal(), destroy_curl(), exec_exec(), function_eval(), function_fieldqty(), get_mapping_weight(), handle_cli_rpt_lstats(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), manager_log(), pbx_builtin_importvar(), pbx_find_extension(), pbx_load_config(), pbx_substitute_variables(), realtime_curl(), realtime_multi_curl(), rotate_file(), sendmail(), sendpage(), sqlite3_log(), store_curl(), substituted(), tryexec_exec(), and update_curl().

03012 {
03013    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
03014 }

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

Definition at line 3016 of file pbx.c.

References pbx_substitute_variables_helper_full().

Referenced by ast_add_extension2_lockopt(), build_user_routes(), dundi_lookup_local(), loopback_subst(), phoneprov_callback(), and pp_each_user_exec().

03017 {
03018    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
03019 }


Generated on Thu Jul 9 13:41:27 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7