Tue Apr 6 15:46:00 2010

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.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_switch
struct  ast_timing

Defines

#define AST_MAX_APP   32
#define AST_PBX_KEEP   0
#define AST_PBX_KEEPALIVE   10
 Special return values from applications to the PBX {.
#define AST_PBX_REPLACE   1
#define PRIORITY_HINT   -1

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 }

Functions

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_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).
ast_contextast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar)
 Register a new 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, const char *name, const char *registrar)
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)
 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 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_register (struct ast_custom_function *acf)
 Reigster a custom function.
int ast_custom_function_unregister (struct ast_custom_function *acf)
 Unregister a custom function.
enum ast_extension_states ast_devstate_to_extenstate (enum ast_device_state devstate)
 Map devstate to an extension state.
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_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, char *function, char *workspace, size_t len)
 executes a read operation on a function
int ast_func_write (struct ast_channel *chan, char *function, const char *value)
 executes a write operation on a function
const char * ast_get_context_name (struct ast_context *con)
const char * ast_get_context_registrar (struct ast_context *c)
const char * ast_get_extension_app (struct ast_exten *e)
void * ast_get_extension_app_data (struct ast_exten *e)
const char * ast_get_extension_cidmatch (struct ast_exten *e)
ast_contextast_get_extension_context (struct ast_exten *exten)
const char * ast_get_extension_label (struct ast_exten *e)
int ast_get_extension_matchcid (struct ast_exten *e)
const char * ast_get_extension_name (struct ast_exten *exten)
int ast_get_extension_priority (struct ast_exten *exten)
const char * ast_get_extension_registrar (struct ast_exten *e)
int ast_get_hint (char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten)
 If an extension exists, return non-zero.
const char * ast_get_ignorepat_name (struct ast_ignorepat *ip)
const char * ast_get_ignorepat_registrar (struct ast_ignorepat *ip)
const char * ast_get_include_name (struct ast_include *include)
const char * ast_get_include_registrar (struct ast_include *i)
const char * ast_get_switch_data (struct ast_sw *sw)
const char * ast_get_switch_name (struct ast_sw *sw)
const char * ast_get_switch_registrar (struct ast_sw *sw)
int ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
void ast_hint_state_changed (const char *device)
int ast_ignore_pattern (const char *context, const char *pattern)
 Checks to see if a number should be ignored.
int ast_lock_context (struct ast_context *con)
 Locks a given context.
int ast_lock_contexts (void)
 Locks the context list.
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, 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_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_contexts (void)
int ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
 Register an application.
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)
 Launch a new extension (i.e. new stack).
int ast_unlock_context (struct ast_context *con)
int ast_unlock_contexts (void)
 Unlocks contexts.
int ast_unregister_application (const char *app)
 Unregister an application.
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_contexts (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_serialize_variables (struct ast_channel *chan, char *buf, size_t size)
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_checkcondition (const char *condition)
 Evaluate a condition.
int pbx_exec (struct ast_channel *c, struct ast_app *app, void *data)
 Execute an application.
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)
 pbx_retrieve_variable: Support for Asterisk built-in variables ---
int pbx_set_autofallthrough (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_MAX_APP   32

Max length of an application

Definition at line 35 of file pbx.h.

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

#define AST_PBX_KEEP   0

Definition at line 37 of file pbx.h.

#define AST_PBX_KEEPALIVE   10

Special return values from applications to the PBX {.

Destroy the thread, but don't hang up the channel

Definition at line 41 of file pbx.h.

Referenced by __ast_pbx_run(), _macro_exec(), agi_handle_command(), and run_agi().

#define AST_PBX_REPLACE   1

Definition at line 38 of file pbx.h.

#define PRIORITY_HINT   -1

} Special Priority for a hint

Definition at line 44 of file pbx.h.

Referenced by add_extensions(), add_pri(), ast_add_extension2(), ast_hint_extension(), ast_merge_contexts_and_delete(), destroy_exten(), destroy_station(), handle_context_add_extension(), handle_context_add_extension_deprecated(), handle_context_remove_extension(), handle_context_remove_extension_deprecated(), handle_save_dialplan(), park_add_hints(), pbx_load_config(), and print_ext().


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


Enumeration Type Documentation

enum ast_extension_states

Extension states.

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

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

enum ast_pbx_result

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 214 of file pbx.h.

00214                     {
00215    AST_PBX_SUCCESS = 0,
00216    AST_PBX_FAILED = -1,
00217    AST_PBX_CALL_LIMIT = -2,
00218 };


Function Documentation

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 2693 of file pbx.c.

References countcalls.

Referenced by handle_chanlist(), and handle_chanlist_deprecated().

02694 {
02695    return countcalls;
02696 }

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

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

Referenced by handle_context_add_extension(), handle_context_add_extension_deprecated(), park_add_hints(), and register_peer_exten().

04617 {
04618    int ret = -1;
04619    struct ast_context *c = find_context_locked(context);
04620 
04621    if (c) {
04622       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04623          application, data, datad, registrar);
04624       ast_unlock_contexts();
04625    }
04626    return ret;
04627 }

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

References add_pri(), ast_exten::app, ast_add_hint(), ast_calloc, AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, errno, ext_cmp(), ext_strncpy(), ast_exten::exten, globals, globalslock, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_context::name, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.

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

04833 {
04834    /*
04835     * Sort extensions (or patterns) according to the rules indicated above.
04836     * These are implemented by the function ext_cmp()).
04837     * All priorities for the same ext/pattern/cid are kept in a list,
04838     * using the 'peer' field  as a link field..
04839     */
04840    struct ast_exten *tmp, *e, *el = NULL;
04841    int res;
04842    int length;
04843    char *p;
04844    char expand_buf[VAR_BUF_SIZE] = { 0, };
04845 
04846    /* if we are adding a hint, and there are global variables, and the hint
04847       contains variable references, then expand them
04848    */
04849    ast_mutex_lock(&globalslock);
04850    if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) {
04851       pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf));
04852       application = expand_buf;
04853    }
04854    ast_mutex_unlock(&globalslock);
04855 
04856    length = sizeof(struct ast_exten);
04857    length += strlen(extension) + 1;
04858    length += strlen(application) + 1;
04859    if (label)
04860       length += strlen(label) + 1;
04861    if (callerid)
04862       length += strlen(callerid) + 1;
04863    else
04864       length ++;  /* just the '\0' */
04865 
04866    /* Be optimistic:  Build the extension structure first */
04867    if (!(tmp = ast_calloc(1, length)))
04868       return -1;
04869 
04870    /* use p as dst in assignments, as the fields are const char * */
04871    p = tmp->stuff;
04872    if (label) {
04873       tmp->label = p;
04874       strcpy(p, label);
04875       p += strlen(label) + 1;
04876    }
04877    tmp->exten = p;
04878    p += ext_strncpy(p, extension, strlen(extension) + 1) + 1;
04879    tmp->priority = priority;
04880    tmp->cidmatch = p;   /* but use p for assignments below */
04881    if (callerid) {
04882       p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1;
04883       tmp->matchcid = 1;
04884    } else {
04885       *p++ = '\0';
04886       tmp->matchcid = 0;
04887    }
04888    tmp->app = p;
04889    strcpy(p, application);
04890    tmp->parent = con;
04891    tmp->data = data;
04892    tmp->datad = datad;
04893    tmp->registrar = registrar;
04894 
04895    ast_mutex_lock(&con->lock);
04896    res = 0; /* some compilers will think it is uninitialized otherwise */
04897    for (e = con->root; e; el = e, e = e->next) {   /* scan the extension list */
04898       res = ext_cmp(e->exten, tmp->exten);
04899       if (res == 0) { /* extension match, now look at cidmatch */
04900          if (!e->matchcid && !tmp->matchcid)
04901             res = 0;
04902          else if (tmp->matchcid && !e->matchcid)
04903             res = 1;
04904          else if (e->matchcid && !tmp->matchcid)
04905             res = -1;
04906          else
04907             res = ext_cmp(e->cidmatch, tmp->cidmatch);
04908       }
04909       if (res >= 0)
04910          break;
04911    }
04912    if (e && res == 0) { /* exact match, insert in the pri chain */
04913       res = add_pri(con, tmp, el, e, replace);
04914       ast_mutex_unlock(&con->lock);
04915       if (res < 0) {
04916          errno = EEXIST;   /* XXX do we care ? */
04917          return 0; /* XXX should we return -1 maybe ? */
04918       }
04919    } else {
04920       /*
04921        * not an exact match, this is the first entry with this pattern,
04922        * so insert in the main list right before 'e' (if any)
04923        */
04924       tmp->next = e;
04925       if (el)
04926          el->next = tmp;
04927       else
04928          con->root = tmp;
04929       ast_mutex_unlock(&con->lock);
04930       if (tmp->priority == PRIORITY_HINT)
04931          ast_add_hint(tmp);
04932    }
04933    if (option_debug) {
04934       if (tmp->matchcid) {
04935          if (option_debug)
04936             ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n",
04937                tmp->exten, tmp->priority, tmp->cidmatch, con->name);
04938       } else {
04939          if (option_debug)
04940             ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n",
04941                tmp->exten, tmp->priority, con->name);
04942       }
04943    }
04944    if (option_verbose > 2) {
04945       if (tmp->matchcid) {
04946          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n",
04947             tmp->exten, tmp->priority, tmp->cidmatch, con->name);
04948       } else {
04949          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n",
04950             tmp->exten, tmp->priority, con->name);
04951       }
04952    }
04953    return 0;
04954 }

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

Definition at line 4652 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, 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(), console_transfer_deprecated(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), and socket_process().

04653 {
04654    int res = 0;
04655 
04656    ast_channel_lock(chan);
04657 
04658    if (chan->pbx) { /* This channel is currently in the PBX */
04659       ast_explicit_goto(chan, context, exten, priority);
04660       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
04661    } else {
04662       /* In order to do it when the channel doesn't really exist within
04663          the PBX, we have to make a new channel, masquerade, and start the PBX
04664          at the new location */
04665       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
04666       if (!tmpchan) {
04667          res = -1;
04668       } else {
04669          if (chan->cdr) {
04670             ast_cdr_discard(tmpchan->cdr);
04671             tmpchan->cdr = ast_cdr_dup(chan->cdr);  /* share the love */
04672          }
04673          /* Make formats okay */
04674          tmpchan->readformat = chan->readformat;
04675          tmpchan->writeformat = chan->writeformat;
04676          /* Setup proper location */
04677          ast_explicit_goto(tmpchan,
04678             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
04679 
04680          /* Masquerade into temp channel */
04681          if (ast_channel_masquerade(tmpchan, chan)) {
04682             /* Failed to set up the masquerade.  It's probably chan_local
04683              * in the middle of optimizing itself out.  Sad. :( */
04684             ast_hangup(tmpchan);
04685             tmpchan = NULL;
04686             res = -1;
04687          } else {
04688             /* Grab the locks and get going */
04689             ast_channel_lock(tmpchan);
04690             ast_do_masquerade(tmpchan);
04691             ast_channel_unlock(tmpchan);
04692             /* Start the PBX going on our stolen channel */
04693             if (ast_pbx_start(tmpchan)) {
04694                ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
04695                ast_hangup(tmpchan);
04696                res = -1;
04697             }
04698          }
04699       }
04700    }
04701    ast_channel_unlock(chan);
04702    return res;
04703 }

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

Definition at line 4705 of file pbx.c.

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

04706 {
04707    struct ast_channel *chan;
04708    int res = -1;
04709 
04710    chan = ast_get_channel_by_name_locked(channame);
04711    if (chan) {
04712       res = ast_async_goto(chan, context, exten, priority);
04713       ast_channel_unlock(chan);
04714    }
04715    return res;
04716 }

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

References __ast_goto_if_exists().

Referenced by asyncgoto_exec().

06539 {
06540    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06541 }

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

Definition at line 4292 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, and months.

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

04293 {
04294    char info_save[256];
04295    char *info;
04296 
04297    /* Check for empty just in case */
04298    if (ast_strlen_zero(info_in))
04299       return 0;
04300    /* make a copy just in case we were passed a static string */
04301    ast_copy_string(info_save, info_in, sizeof(info_save));
04302    info = info_save;
04303    /* Assume everything except time */
04304    i->monthmask = 0xfff;   /* 12 bits */
04305    i->daymask = 0x7fffffffU; /* 31 bits */
04306    i->dowmask = 0x7f; /* 7 bits */
04307    /* on each call, use strsep() to move info to the next argument */
04308    get_timerange(i, strsep(&info, "|"));
04309    if (info)
04310       i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week");
04311    if (info)
04312       i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day");
04313    if (info)
04314       i->monthmask = get_range(strsep(&info, "|"), 12, months, "month");
04315    return 1;
04316 }

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 2314 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(), local_dtmf_helper(), loopback_canmatch(), mgcp_ss(), pbx_builtin_background(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().

02315 {
02316    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
02317 }

int ast_check_timing ( const struct ast_timing i  ) 

Definition at line 4318 of file pbx.c.

References ast_localtime(), ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, and t.

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

04319 {
04320    struct tm tm;
04321    time_t t = time(NULL);
04322 
04323    ast_localtime(&t, &tm, NULL);
04324 
04325    /* If it's not the right month, return */
04326    if (!(i->monthmask & (1 << tm.tm_mon)))
04327       return 0;
04328 
04329    /* If it's not that time of the month.... */
04330    /* Warning, tm_mday has range 1..31! */
04331    if (!(i->daymask & (1 << (tm.tm_mday-1))))
04332       return 0;
04333 
04334    /* If it's not the right day of the week */
04335    if (!(i->dowmask & (1 << tm.tm_wday)))
04336       return 0;
04337 
04338    /* Sanity check the hour just to be safe */
04339    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
04340       ast_log(LOG_WARNING, "Insane time...\n");
04341       return 0;
04342    }
04343 
04344    /* Now the tough part, we calculate if it fits
04345       in the right time based on min/hour */
04346    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
04347       return 0;
04348 
04349    /* If we got this far, then we're good */
04350    return 1;
04351 }

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

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

Referenced by handle_context_add_ignorepat(), and handle_context_add_ignorepat_deprecated().

04546 {
04547    int ret = -1;
04548    struct ast_context *c = find_context_locked(context);
04549 
04550    if (c) {
04551       ret = ast_context_add_ignorepat2(c, value, registrar);
04552       ast_unlock_contexts();
04553    }
04554    return ret;
04555 }

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

Definition at line 4557 of file pbx.c.

References ast_calloc, ast_mutex_lock(), ast_mutex_unlock(), errno, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.

Referenced by ast_context_add_ignorepat(), and pbx_load_config().

04558 {
04559    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04560    int length;
04561    char *pattern;
04562    length = sizeof(struct ast_ignorepat);
04563    length += strlen(value) + 1;
04564    if (!(ignorepat = ast_calloc(1, length)))
04565       return -1;
04566    /* The cast to char * is because we need to write the initial value.
04567     * The field is not supposed to be modified otherwise.  Also, gcc 4.2
04568     * sees the cast as dereferencing a type-punned pointer and warns about
04569     * it.  This is the workaround (we're telling gcc, yes, that's really
04570     * what we wanted to do).
04571     */
04572    pattern = (char *) ignorepat->pattern;
04573    strcpy(pattern, value);
04574    ignorepat->next = NULL;
04575    ignorepat->registrar = registrar;
04576    ast_mutex_lock(&con->lock);
04577    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
04578       ignorepatl = ignorepatc;
04579       if (!strcasecmp(ignorepatc->pattern, value)) {
04580          /* Already there */
04581          ast_mutex_unlock(&con->lock);
04582          errno = EEXIST;
04583          return -1;
04584       }
04585    }
04586    if (ignorepatl)
04587       ignorepatl->next = ignorepat;
04588    else
04589       con->ignorepats = ignorepat;
04590    ast_mutex_unlock(&con->lock);
04591    return 0;
04592 
04593 }

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

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

Referenced by handle_context_add_include(), and handle_context_add_include_deprecated().

04099 {
04100    int ret = -1;
04101    struct ast_context *c = find_context_locked(context);
04102 
04103    if (c) {
04104       ret = ast_context_add_include2(c, include, registrar);
04105       ast_unlock_contexts();
04106    }
04107    return ret;
04108 }

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

References ast_build_timing(), ast_calloc, ast_get_context_name(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), errno, free, ast_include::hastime, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, option_verbose, ast_include::registrar, ast_include::rname, ast_include::stuff, ast_include::timing, and VERBOSE_PREFIX_3.

Referenced by ast_context_add_include(), and pbx_load_config().

04362 {
04363    struct ast_include *new_include;
04364    char *c;
04365    struct ast_include *i, *il = NULL; /* include, include_last */
04366    int length;
04367    char *p;
04368 
04369    length = sizeof(struct ast_include);
04370    length += 2 * (strlen(value) + 1);
04371 
04372    /* allocate new include structure ... */
04373    if (!(new_include = ast_calloc(1, length)))
04374       return -1;
04375    /* Fill in this structure. Use 'p' for assignments, as the fields
04376     * in the structure are 'const char *'
04377     */
04378    p = new_include->stuff;
04379    new_include->name = p;
04380    strcpy(p, value);
04381    p += strlen(value) + 1;
04382    new_include->rname = p;
04383    strcpy(p, value);
04384    /* Strip off timing info, and process if it is there */
04385    if ( (c = strchr(p, '|')) ) {
04386       *c++ = '\0';
04387            new_include->hastime = ast_build_timing(&(new_include->timing), c);
04388    }
04389    new_include->next      = NULL;
04390    new_include->registrar = registrar;
04391 
04392    ast_mutex_lock(&con->lock);
04393 
04394    /* ... go to last include and check if context is already included too... */
04395    for (i = con->includes; i; i = i->next) {
04396       if (!strcasecmp(i->name, new_include->name)) {
04397          free(new_include);
04398          ast_mutex_unlock(&con->lock);
04399          errno = EEXIST;
04400          return -1;
04401       }
04402       il = i;
04403    }
04404 
04405    /* ... include new context into context list, unlock, return */
04406    if (il)
04407       il->next = new_include;
04408    else
04409       con->includes = new_include;
04410    if (option_verbose > 2)
04411       ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
04412    ast_mutex_unlock(&con->lock);
04413 
04414    return 0;
04415 }

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

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

04423 {
04424    int ret = -1;
04425    struct ast_context *c = find_context_locked(context);
04426 
04427    if (c) { /* found, add switch to this context */
04428       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04429       ast_unlock_contexts();
04430    }
04431    return ret;
04432 }

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

References ast_context::alts, ast_calloc, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, errno, ast_sw::eval, free, store_hint::list, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, ast_sw::stuff, and VERBOSE_PREFIX_3.

Referenced by ast_context_add_switch(), and pbx_load_config().

04443 {
04444    struct ast_sw *new_sw;
04445    struct ast_sw *i;
04446    int length;
04447    char *p;
04448 
04449    length = sizeof(struct ast_sw);
04450    length += strlen(value) + 1;
04451    if (data)
04452       length += strlen(data);
04453    length++;
04454 
04455    /* allocate new sw structure ... */
04456    if (!(new_sw = ast_calloc(1, length)))
04457       return -1;
04458    /* ... fill in this structure ... */
04459    p = new_sw->stuff;
04460    new_sw->name = p;
04461    strcpy(new_sw->name, value);
04462    p += strlen(value) + 1;
04463    new_sw->data = p;
04464    if (data) {
04465       strcpy(new_sw->data, data);
04466       p += strlen(data) + 1;
04467    } else {
04468       strcpy(new_sw->data, "");
04469       p++;
04470    }
04471    new_sw->eval     = eval;
04472    new_sw->registrar = registrar;
04473 
04474    /* ... try to lock this context ... */
04475    ast_mutex_lock(&con->lock);
04476 
04477    /* ... go to last sw and check if context is already swd too... */
04478    AST_LIST_TRAVERSE(&con->alts, i, list) {
04479       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
04480          free(new_sw);
04481          ast_mutex_unlock(&con->lock);
04482          errno = EEXIST;
04483          return -1;
04484       }
04485    }
04486 
04487    /* ... sw new context into context list, unlock, return */
04488    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
04489 
04490    if (option_verbose > 2)
04491       ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
04492 
04493    ast_mutex_unlock(&con->lock);
04494 
04495    return 0;
04496 }

struct ast_context* ast_context_create ( struct ast_context **  extcontexts,
const char *  name,
const char *  registrar 
)

Register a new context.

Parameters:
extcontexts pointer to the ast_context structure pointer
name name of the new context
registrar registrar of the context
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 3968 of file pbx.c.

References __ast_context_create().

Referenced by do_parking_thread(), park_call_full(), and set_config().

03969 {
03970    return __ast_context_create(extcontexts, name, registrar, 0);
03971 }

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

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

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

05411 {
05412    ast_wrlock_contexts();
05413    __ast_context_destroy(con,registrar);
05414    ast_unlock_contexts();
05415 }

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

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

Referenced by _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), do_parking_thread(), park_call_full(), park_exec(), register_peer_exten(), set_config(), and unload_module().

00935 {
00936    struct ast_context *tmp = NULL;
00937 
00938    ast_rdlock_contexts();
00939 
00940    while ( (tmp = ast_walk_contexts(tmp)) ) {
00941       if (!name || !strcasecmp(name, tmp->name))
00942          break;
00943    }
00944 
00945    ast_unlock_contexts();
00946 
00947    return tmp;
00948 }

struct ast_context* ast_context_find_or_create ( struct ast_context **  extcontexts,
const char *  name,
const char *  registrar 
)

Definition at line 3973 of file pbx.c.

References __ast_context_create().

Referenced by pbx_load_config(), and pbx_load_users().

03974 {
03975    return __ast_context_create(extcontexts, name, registrar, 1);
03976 }

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

References ast_get_context_name(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.

Referenced by _macro_exec().

02936 {
02937    struct ast_context *c = NULL;
02938    int ret = -1;
02939 
02940    ast_rdlock_contexts();
02941 
02942    while ((c = ast_walk_contexts(c))) {
02943       if (!strcmp(ast_get_context_name(c), context)) {
02944          ret = 0;
02945          break;
02946       }
02947    }
02948 
02949    ast_unlock_contexts();
02950 
02951    /* if we found context, lock macrolock */
02952    if (ret == 0) 
02953       ret = ast_mutex_lock(&c->macrolock);
02954 
02955    return ret;
02956 }

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

References ast_context_remove_extension_callerid().

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

02837 {
02838    return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
02839 }

int ast_context_remove_extension2 ( struct ast_context con,
const char *  extension,
int  priority,
const char *  registrar 
)

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

References ast_context_remove_extension_callerid2().

Referenced by do_parking_thread(), and park_exec().

02864 {
02865    return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar);
02866 }

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

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

Referenced by ast_context_remove_extension(), handle_context_remove_extension(), and handle_context_remove_extension_deprecated().

02842 {
02843    int ret = -1; /* default error return */
02844    struct ast_context *c = find_context_locked(context);
02845 
02846    if (c) { /* ... remove extension ... */
02847       ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar);
02848       ast_unlock_contexts();
02849    }
02850    return ret;
02851 }

int ast_context_remove_extension_callerid2 ( struct ast_context con,
const char *  extension,
int  priority,
const char *  callerid,
int  matchcid,
const char *  registrar 
)

Definition at line 2868 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_exten::cidmatch, destroy_exten(), ast_exten::exten, exten, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::priority, ast_exten::registrar, and ast_context::root.

Referenced by ast_context_remove_extension2(), and ast_context_remove_extension_callerid().

02869 {
02870    struct ast_exten *exten, *prev_exten = NULL;
02871    struct ast_exten *peer;
02872    struct ast_exten *previous_peer = NULL;
02873    struct ast_exten *next_peer = NULL;
02874    int found = 0;
02875 
02876    ast_mutex_lock(&con->lock);
02877 
02878    /* scan the extension list to find first matching extension-registrar */
02879    for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
02880       if (!strcmp(exten->exten, extension) &&
02881          (!registrar || !strcmp(exten->registrar, registrar)))
02882          break;
02883    }
02884    if (!exten) {
02885       /* we can't find right extension */
02886       ast_mutex_unlock(&con->lock);
02887       return -1;
02888    }
02889 
02890    /* scan the priority list to remove extension with exten->priority == priority */
02891    for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
02892          peer && !strcmp(peer->exten, extension);
02893          peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
02894       if ((priority == 0 || peer->priority == priority) &&
02895             (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) &&
02896             (!registrar || !strcmp(peer->registrar, registrar) )) {
02897          found = 1;
02898 
02899          /* we are first priority extension? */
02900          if (!previous_peer) {
02901             /*
02902              * We are first in the priority chain, so must update the extension chain.
02903              * The next node is either the next priority or the next extension
02904              */
02905             struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
02906 
02907             if (!prev_exten) {   /* change the root... */
02908                con->root = next_node;
02909             } else {
02910                prev_exten->next = next_node; /* unlink */
02911             }
02912             if (peer->peer)   { /* update the new head of the pri list */
02913                peer->peer->next = peer->next;
02914             }
02915          } else { /* easy, we are not first priority in extension */
02916             previous_peer->peer = peer->peer;
02917          }
02918 
02919          /* now, free whole priority extension */
02920          destroy_exten(peer);
02921       } else {
02922          previous_peer = peer;
02923       }
02924    }
02925    ast_mutex_unlock(&con->lock);
02926    return found ? 0 : -1;
02927 }

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

Definition at line 4502 of file pbx.c.

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

Referenced by handle_context_remove_ignorepat(), and handle_context_remove_ignorepat_deprecated().

04503 {
04504    int ret = -1;
04505    struct ast_context *c = find_context_locked(context);
04506 
04507    if (c) {
04508       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04509       ast_unlock_contexts();
04510    }
04511    return ret;
04512 }

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

Definition at line 4514 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), errno, free, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.

Referenced by ast_context_remove_ignorepat().

04515 {
04516    struct ast_ignorepat *ip, *ipl = NULL;
04517 
04518    ast_mutex_lock(&con->lock);
04519 
04520    for (ip = con->ignorepats; ip; ip = ip->next) {
04521       if (!strcmp(ip->pattern, ignorepat) &&
04522          (!registrar || (registrar == ip->registrar))) {
04523          if (ipl) {
04524             ipl->next = ip->next;
04525             free(ip);
04526          } else {
04527             con->ignorepats = ip->next;
04528             free(ip);
04529          }
04530          ast_mutex_unlock(&con->lock);
04531          return 0;
04532       }
04533       ipl = ip;
04534    }
04535 
04536    ast_mutex_unlock(&con->lock);
04537    errno = EINVAL;
04538    return -1;
04539 }

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

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

Referenced by handle_context_dont_include_deprecated(), and handle_context_remove_include().

02733 {
02734    int ret = -1;
02735    struct ast_context *c = find_context_locked(context);
02736 
02737    if (c) {
02738       /* found, remove include from this context ... */
02739       ret = ast_context_remove_include2(c, include, registrar);
02740       ast_unlock_contexts();
02741    }
02742    return ret;
02743 }

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

Removes an include by an ast_context structure.

Note:
See ast_context_add_include2 for information on arguments
Return values:
0 on success
-1 on success

Definition at line 2753 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), free, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, and ast_include::registrar.

Referenced by ast_context_remove_include().

02754 {
02755    struct ast_include *i, *pi = NULL;
02756    int ret = -1;
02757 
02758    ast_mutex_lock(&con->lock);
02759 
02760    /* find our include */
02761    for (i = con->includes; i; pi = i, i = i->next) {
02762       if (!strcmp(i->name, include) &&
02763             (!registrar || !strcmp(i->registrar, registrar))) {
02764          /* remove from list */
02765          if (pi)
02766             pi->next = i->next;
02767          else
02768             con->includes = i->next;
02769          /* free include and return */
02770          free(i);
02771          ret = 0;
02772          break;
02773       }
02774    }
02775 
02776    ast_mutex_unlock(&con->lock);
02777    return ret;
02778 }

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

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

02786 {
02787    int ret = -1; /* default error return */
02788    struct ast_context *c = find_context_locked(context);
02789 
02790    if (c) {
02791       /* remove switch from this context ... */
02792       ret = ast_context_remove_switch2(c, sw, data, registrar);
02793       ast_unlock_contexts();
02794    }
02795    return ret;
02796 }

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

References ast_context::alts, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_sw::list, ast_context::lock, ast_sw::name, and ast_sw::registrar.

Referenced by ast_context_remove_switch().

02807 {
02808    struct ast_sw *i;
02809    int ret = -1;
02810 
02811    ast_mutex_lock(&con->lock);
02812 
02813    /* walk switches */
02814    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
02815       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02816          (!registrar || !strcmp(i->registrar, registrar))) {
02817          /* found, remove from list */
02818          AST_LIST_REMOVE_CURRENT(&con->alts, list);
02819          free(i); /* free switch and return */
02820          ret = 0;
02821          break;
02822       }
02823    }
02824    AST_LIST_TRAVERSE_SAFE_END
02825 
02826    ast_mutex_unlock(&con->lock);
02827 
02828    return ret;
02829 }

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

References ast_get_context_name(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.

Referenced by _macro_exec().

02964 {
02965    struct ast_context *c = NULL;
02966    int ret = -1;
02967 
02968    ast_rdlock_contexts();
02969 
02970    while ((c = ast_walk_contexts(c))) {
02971       if (!strcmp(ast_get_context_name(c), context)) {
02972          ret = 0;
02973          break;
02974       }
02975    }
02976 
02977    ast_unlock_contexts();
02978 
02979    /* if we found context, unlock macrolock */
02980    if (ret == 0) 
02981       ret = ast_mutex_unlock(&c->macrolock);
02982 
02983    return ret;
02984 }

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

06496 {
06497    struct ast_include *inc = NULL;
06498    int res = 0;
06499 
06500    while ( (inc = ast_walk_context_includes(con, inc)) ) {
06501       if (ast_context_find(inc->rname))
06502          continue;
06503 
06504       res = -1;
06505       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
06506          ast_get_context_name(con), inc->rname);
06507       break;
06508    }
06509 
06510    return res;
06511 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

Definition at line 1496 of file pbx.c.

References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_custom_function::name.

Referenced by ast_custom_function_register(), ast_func_read(), ast_func_write(), handle_show_function(), and handle_show_function_deprecated().

01497 {
01498    struct ast_custom_function *acf = NULL;
01499 
01500    AST_LIST_LOCK(&acf_root);
01501    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01502       if (!strcmp(name, acf->name))
01503          break;
01504    }
01505    AST_LIST_UNLOCK(&acf_root);
01506 
01507    return acf;
01508 }

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

Definition at line 1532 of file pbx.c.

References ast_custom_function::acflist, ast_custom_function_find(), AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), LOG_ERROR, ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.

Referenced by load_module(), odbc_load_module(), and reload().

01533 {
01534    struct ast_custom_function *cur;
01535 
01536    if (!acf)
01537       return -1;
01538 
01539    AST_LIST_LOCK(&acf_root);
01540 
01541    if (ast_custom_function_find(acf->name)) {
01542       ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
01543       AST_LIST_UNLOCK(&acf_root);
01544       return -1;
01545    }
01546 
01547    /* Store in alphabetical order */
01548    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01549       if (strcasecmp(acf->name, cur->name) < 0) {
01550          AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
01551          break;
01552       }
01553    }
01554    AST_LIST_TRAVERSE_SAFE_END
01555    if (!cur)
01556       AST_LIST_INSERT_TAIL(&acf_root, acf, acflist);
01557 
01558    AST_LIST_UNLOCK(&acf_root);
01559 
01560    if (option_verbose > 1)
01561       ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
01562 
01563    return 0;
01564 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

Definition at line 1510 of file pbx.c.

References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.

Referenced by odbc_unload_module(), reload(), and unload_module().

01511 {
01512    struct ast_custom_function *cur;
01513 
01514    if (!acf)
01515       return -1;
01516 
01517    AST_LIST_LOCK(&acf_root);
01518    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01519       if (cur == acf) {
01520          AST_LIST_REMOVE_CURRENT(&acf_root, acflist);
01521          if (option_verbose > 1)
01522             ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
01523          break;
01524       }
01525    }
01526    AST_LIST_TRAVERSE_SAFE_END
01527    AST_LIST_UNLOCK(&acf_root);
01528 
01529    return acf ? 0 : -1;
01530 }

enum ast_extension_states ast_devstate_to_extenstate ( enum ast_device_state  devstate  ) 

Map devstate to an extension state.

Parameters:
[in] device state
Returns:
the extension state mapping.

Definition at line 1960 of file pbx.c.

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

Referenced by ast_extension_state2().

01961 {
01962    switch (devstate) {
01963    case AST_DEVICE_ONHOLD:
01964       return AST_EXTENSION_ONHOLD;
01965    case AST_DEVICE_BUSY:
01966       return AST_EXTENSION_BUSY;
01967    case AST_DEVICE_UNAVAILABLE:
01968    case AST_DEVICE_UNKNOWN:
01969    case AST_DEVICE_INVALID:
01970       return AST_EXTENSION_UNAVAILABLE;
01971    case AST_DEVICE_RINGINUSE:
01972       return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
01973    case AST_DEVICE_RINGING:
01974       return AST_EXTENSION_RINGING;
01975    case AST_DEVICE_INUSE:
01976       return AST_EXTENSION_INUSE;
01977    case AST_DEVICE_NOT_INUSE:
01978       return AST_EXTENSION_NOT_INUSE;
01979    case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
01980       break;
01981    }
01982 
01983    return AST_EXTENSION_NOT_INUSE;
01984 }

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

References E_MATCH, and pbx_extension_helper().

Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), _macro_exec(), agentmonitoroutgoing_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), builtin_blindtransfer(), cb_events(), conf_run(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), dahdi_r2_on_call_offered(), dahdi_r2_on_dnis_digit_received(), disa_exec(), do_atxfer(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), process_ast_dsp(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().

02300 {
02301    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
02302 }

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

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

Referenced by __ast_goto_if_exists(), ast_async_goto(), ast_parseable_goto(), disa_exec(), do_atxfer(), and handle_setpriority().

04630 {
04631    if (!chan)
04632       return -1;
04633 
04634    ast_channel_lock(chan);
04635 
04636    if (!ast_strlen_zero(context))
04637       ast_copy_string(chan->context, context, sizeof(chan->context));
04638    if (!ast_strlen_zero(exten))
04639       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04640    if (priority > -1) {
04641       chan->priority = priority;
04642       /* see flag description in channel.h for explanation */
04643       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04644          chan->priority--;
04645    }
04646 
04647    ast_channel_unlock(chan);
04648 
04649    return 0;
04650 }

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

Definition at line 927 of file pbx.c.

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

Referenced by realtime_switch_common().

00928 {
00929    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
00930       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
00931    return extension_match_core(pattern, data, needmore);
00932 }

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

References E_MATCH, and extension_match_core().

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

00923 {
00924    return extension_match_core(pattern, data, E_MATCH);
00925 }

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

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

02022 {
02023    struct ast_exten *e;
02024 
02025    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
02026    if (!e)
02027       return -1;           /* No hint, return -1 */
02028 
02029    return ast_extension_state2(e);        /* Check all devices in the hint */
02030 }

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

References extension_states.

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

02010 {
02011    int i;
02012 
02013    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
02014       if (extension_states[i].extension_state == extension_state)
02015          return extension_states[i].text;
02016    }
02017    return "Unknown";
02018 }

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

References ast_calloc, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_state_cb::callback, ast_state_cb::data, ast_state_cb::next, and statecbs.

Referenced by handle_request_subscribe(), and init_manager().

02080 {
02081    struct ast_hint *hint;
02082    struct ast_state_cb *cblist;
02083    struct ast_exten *e;
02084 
02085    /* If there's no context and extension:  add callback to statecbs list */
02086    if (!context && !exten) {
02087       AST_LIST_LOCK(&hints);
02088 
02089       for (cblist = statecbs; cblist; cblist = cblist->next) {
02090          if (cblist->callback == callback) {
02091             cblist->data = data;
02092             AST_LIST_UNLOCK(&hints);
02093             return 0;
02094          }
02095       }
02096 
02097       /* Now insert the callback */
02098       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02099          AST_LIST_UNLOCK(&hints);
02100          return -1;
02101       }
02102       cblist->id = 0;
02103       cblist->callback = callback;
02104       cblist->data = data;
02105 
02106       cblist->next = statecbs;
02107       statecbs = cblist;
02108 
02109       AST_LIST_UNLOCK(&hints);
02110       return 0;
02111    }
02112 
02113    if (!context || !exten)
02114       return -1;
02115 
02116    /* This callback type is for only one hint, so get the hint */
02117    e = ast_hint_extension(NULL, context, exten);
02118    if (!e) {
02119       return -1;
02120    }
02121 
02122    /* Find the hint in the list of hints */
02123    AST_LIST_LOCK(&hints);
02124 
02125    AST_LIST_TRAVERSE(&hints, hint, list) {
02126       if (hint->exten == e)
02127          break;
02128    }
02129 
02130    if (!hint) {
02131       /* We have no hint, sorry */
02132       AST_LIST_UNLOCK(&hints);
02133       return -1;
02134    }
02135 
02136    /* Now insert the callback in the callback list  */
02137    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02138       AST_LIST_UNLOCK(&hints);
02139       return -1;
02140    }
02141    cblist->id = stateid++;    /* Unique ID for this callback */
02142    cblist->callback = callback;  /* Pointer to callback routine */
02143    cblist->data = data;    /* Data for the callback */
02144 
02145    cblist->next = hint->callbacks;
02146    hint->callbacks = cblist;
02147 
02148    AST_LIST_UNLOCK(&hints);
02149    return cblist->id;
02150 }

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

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, free, ast_sw::list, ast_state_cb::next, and statecbs.

Referenced by __sip_destroy(), and handle_request_subscribe().

02154 {
02155    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
02156    int ret = -1;
02157 
02158    if (!id && !callback)
02159       return -1;
02160 
02161    AST_LIST_LOCK(&hints);
02162 
02163    if (!id) {  /* id == 0 is a callback without extension */
02164       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
02165          if ((*p_cur)->callback == callback)
02166             break;
02167       }
02168    } else { /* callback with extension, find the callback based on ID */
02169       struct ast_hint *hint;
02170       AST_LIST_TRAVERSE(&hints, hint, list) {
02171          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
02172             if ((*p_cur)->id == id)
02173                break;
02174          }
02175          if (*p_cur) /* found in the inner loop */
02176             break;
02177       }
02178    }
02179    if (p_cur && *p_cur) {
02180       struct ast_state_cb *cur = *p_cur;
02181       *p_cur = cur->next;
02182       free(cur);
02183       ret = 0;
02184    }
02185    AST_LIST_UNLOCK(&hints);
02186    return ret;
02187 }

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
Returns:
the priority which matches the given label in the extension or -1 if not found.

Definition at line 2304 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by action_originate(), action_redirect(), ast_parseable_goto(), asyncgoto_exec(), and handle_setpriority().

02305 {
02306    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
02307 }

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

02310 {
02311    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
02312 }

int ast_func_read ( struct ast_channel chan,
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 1586 of file pbx.c.

References ast_custom_function_find(), ast_log(), func_args(), LOG_ERROR, and ast_custom_function::read.

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

01587 {
01588    char *args = func_args(function);
01589    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01590 
01591    if (acfptr == NULL)
01592       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01593    else if (!acfptr->read)
01594       ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
01595    else
01596       return acfptr->read(chan, function, args, workspace, len);
01597    return -1;
01598 }

int ast_func_write ( struct ast_channel chan,
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 1600 of file pbx.c.

References ast_custom_function_find(), ast_log(), func_args(), LOG_ERROR, and ast_custom_function::write.

Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

01601 {
01602    char *args = func_args(function);
01603    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01604 
01605    if (acfptr == NULL)
01606       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01607    else if (!acfptr->write)
01608       ast_log(LOG_ERROR, "Function %s cannot be written to\n", function);
01609    else
01610       return acfptr->write(chan, function, args, value);
01611 
01612    return -1;
01613 }

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 6352 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_unlockmacro(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().

06353 {
06354    return con ? con->name : NULL;
06355 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6390 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06391 {
06392    return c ? c->registrar : NULL;
06393 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

Definition at line 6420 of file pbx.c.

References ast_exten::app.

Referenced by _macro_exec(), ast_add_hint(), ast_extension_state2(), ast_get_hint(), ast_hint_state_changed(), find_matching_endwhile(), handle_save_dialplan(), handle_show_hints(), and print_ext().

06421 {
06422    return e ? e->app : NULL;
06423 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6425 of file pbx.c.

References ast_exten::data.

Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().

06426 {
06427    return e ? e->data : NULL;
06428 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6415 of file pbx.c.

References ast_exten::cidmatch.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), and handle_save_dialplan().

06416 {
06417    return e ? e->cidmatch : NULL;
06418 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 6357 of file pbx.c.

References exten.

Referenced by handle_show_hints().

06358 {
06359    return exten ? exten->parent : NULL;
06360 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6367 of file pbx.c.

References exten.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06368 {
06369    return exten ? exten->label : NULL;
06370 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6410 of file pbx.c.

References ast_exten::matchcid.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), and handle_save_dialplan().

06411 {
06412    return e ? e->matchcid : 0;
06413 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

Definition at line 6362 of file pbx.c.

References exten.

Referenced by ast_add_hint(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().

06363 {
06364    return exten ? exten->exten : NULL;
06365 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 6382 of file pbx.c.

References exten.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), and print_ext().

06383 {
06384    return exten ? exten->priority : -1;
06385 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6395 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06396 {
06397    return e ? e->registrar : NULL;
06398 }

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 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 2282 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(), pbx_retrieve_variable(), and transmit_state_notify().

02283 {
02284    struct ast_exten *e = ast_hint_extension(c, context, exten);
02285 
02286    if (e) {
02287       if (hint)
02288          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02289       if (name) {
02290          const char *tmp = ast_get_extension_app_data(e);
02291          if (tmp)
02292             ast_copy_string(name, tmp, namesize);
02293       }
02294       return -1;
02295    }
02296    return 0;
02297 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

Definition at line 6377 of file pbx.c.

References ast_ignorepat::pattern.

Referenced by complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), handle_save_dialplan(), lookup_c_ip(), and show_dialplan_helper().

06378 {
06379    return ip ? ip->pattern : NULL;
06380 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6405 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06406 {
06407    return ip ? ip->registrar : NULL;
06408 }

const char* ast_get_include_name ( struct ast_include include  ) 

Definition at line 6372 of file pbx.c.

References ast_include::name.

Referenced by complete_context_dont_include_deprecated(), complete_context_remove_include(), find_matching_priority(), handle_save_dialplan(), lookup_ci(), and show_dialplan_helper().

06373 {
06374    return inc ? inc->name : NULL;
06375 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6400 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06401 {
06402    return i ? i->registrar : NULL;
06403 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6435 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06436 {
06437    return sw ? sw->data : NULL;
06438 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6430 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06431 {
06432    return sw ? sw->name : NULL;
06433 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6440 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06441 {
06442    return sw ? sw->registrar : NULL;
06443 }

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

References __ast_goto_if_exists().

Referenced by aqm_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), do_directory(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), onedigit_goto(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), system_exec_helper(), transfer_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer().

06534 {
06535    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06536 }

void ast_hint_state_changed ( const char *  device  ) 

Definition at line 2032 of file pbx.c.

References ast_copy_string(), ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_rdlock_contexts(), ast_unlock_contexts(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, ast_hint::laststate, ast_sw::list, ast_context::name, ast_state_cb::next, ast_exten::parent, parse(), and statecbs.

Referenced by do_state_change().

02033 {
02034    struct ast_hint *hint;
02035 
02036    ast_rdlock_contexts();
02037    AST_LIST_LOCK(&hints);
02038 
02039    AST_LIST_TRAVERSE(&hints, hint, list) {
02040       struct ast_state_cb *cblist;
02041       char buf[AST_MAX_EXTENSION];
02042       char *parse = buf;
02043       char *cur;
02044       int state;
02045 
02046       ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
02047       while ( (cur = strsep(&parse, "&")) ) {
02048          if (!strcasecmp(cur, device))
02049             break;
02050       }
02051       if (!cur)
02052          continue;
02053 
02054       /* Get device state for this hint */
02055       state = ast_extension_state2(hint->exten);
02056 
02057       if ((state == -1) || (state == hint->laststate))
02058          continue;
02059 
02060       /* Device state changed since last check - notify the watchers */
02061 
02062       /* For general callbacks */
02063       for (cblist = statecbs; cblist; cblist = cblist->next)
02064          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02065 
02066       /* For extension callbacks */
02067       for (cblist = hint->callbacks; cblist; cblist = cblist->next)
02068          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02069 
02070       hint->laststate = state;   /* record we saw the change */
02071    }
02072 
02073    AST_LIST_UNLOCK(&hints);
02074    ast_unlock_contexts();
02075 }

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

04596 {
04597    struct ast_context *con = ast_context_find(context);
04598    if (con) {
04599       struct ast_ignorepat *pat;
04600       for (pat = con->ignorepats; pat; pat = pat->next) {
04601          if (ast_extension_match(pat->pattern, pattern))
04602             return 1;
04603       }
04604    }
04605 
04606    return 0;
04607 }

int ast_lock_context ( struct ast_context con  ) 

Locks a given context.

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

Definition at line 6339 of file pbx.c.

References ast_mutex_lock(), and ast_context::lock.

Referenced by _macro_exec(), complete_context_dont_include_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), and show_dialplan_helper().

06340 {
06341    return ast_mutex_lock(&con->lock);
06342 }

int ast_lock_contexts ( void   ) 

Locks the context list.

Return values:
0 on success
-1 on error

Definition at line 6316 of file pbx.c.

References ast_rwlock_wrlock(), and conlock.

Referenced by find_matching_endwhile().

06317 {
06318    return ast_rwlock_wrlock(&conlock);
06319 }

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

References E_MATCHMORE, and pbx_extension_helper().

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

02320 {
02321    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
02322 }

void ast_merge_contexts_and_delete ( struct ast_context **  extcontexts,
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 pointer
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 3991 of file pbx.c.

References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_unlock_contexts(), ast_wrlock_contexts(), ast_state_cb::callback, store_hint::callbacks, ast_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, E_MATCH, store_hint::exten, ast_exten::exten, ast_hint::exten, free, ast_hint::laststate, store_hint::laststate, store_hint::list, LOG_WARNING, ast_context::name, ast_state_cb::next, ast_context::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.

Referenced by pbx_load_module().

03992 {
03993    struct ast_context *tmp, *lasttmp = NULL;
03994    struct store_hints store = AST_LIST_HEAD_INIT_VALUE;
03995    struct store_hint *this;
03996    struct ast_hint *hint;
03997    struct ast_exten *exten;
03998    int length;
03999    struct ast_state_cb *thiscb, *prevcb;
04000 
04001    /* it is very important that this function hold the hint list lock _and_ the conlock
04002       during its operation; not only do we need to ensure that the list of contexts
04003       and extensions does not change, but also that no hint callbacks (watchers) are
04004       added or removed during the merge/delete process
04005 
04006       in addition, the locks _must_ be taken in this order, because there are already
04007       other code paths that use this order
04008    */
04009    ast_wrlock_contexts();
04010    AST_LIST_LOCK(&hints);
04011 
04012    /* preserve all watchers for hints associated with this registrar */
04013    AST_LIST_TRAVERSE(&hints, hint, list) {
04014       if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) {
04015          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
04016          if (!(this = ast_calloc(1, length)))
04017             continue;
04018          this->callbacks = hint->callbacks;
04019          hint->callbacks = NULL;
04020          this->laststate = hint->laststate;
04021          this->context = this->data;
04022          strcpy(this->data, hint->exten->parent->name);
04023          this->exten = this->data + strlen(this->context) + 1;
04024          strcpy(this->exten, hint->exten->exten);
04025          AST_LIST_INSERT_HEAD(&store, this, list);
04026       }
04027    }
04028 
04029    tmp = *extcontexts;
04030    if (registrar) {
04031       /* XXX remove previous contexts from same registrar */
04032       if (option_debug)
04033          ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar);
04034       __ast_context_destroy(NULL,registrar);
04035       while (tmp) {
04036          lasttmp = tmp;
04037          tmp = tmp->next;
04038       }
04039    } else {
04040       /* XXX remove contexts with the same name */
04041       while (tmp) {
04042          ast_log(LOG_WARNING, "must remove %s  reg %s\n", tmp->name, tmp->registrar);
04043          __ast_context_destroy(tmp,tmp->registrar);
04044          lasttmp = tmp;
04045          tmp = tmp->next;
04046       }
04047    }
04048    if (lasttmp) {
04049       lasttmp->next = contexts;
04050       contexts = *extcontexts;
04051       *extcontexts = NULL;
04052    } else
04053       ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
04054 
04055    /* restore the watchers for hints that can be found; notify those that
04056       cannot be restored
04057    */
04058    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
04059       struct pbx_find_info q = { .stacklen = 0 };
04060       exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH);
04061       /* Find the hint in the list of hints */
04062       AST_LIST_TRAVERSE(&hints, hint, list) {
04063          if (hint->exten == exten)
04064             break;
04065       }
04066       if (!exten || !hint) {
04067          /* this hint has been removed, notify the watchers */
04068          prevcb = NULL;
04069          thiscb = this->callbacks;
04070          while (thiscb) {
04071             prevcb = thiscb;
04072             thiscb = thiscb->next;
04073             prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data);
04074             free(prevcb);
04075             }
04076       } else {
04077          thiscb = this->callbacks;
04078          while (thiscb->next)
04079             thiscb = thiscb->next;
04080          thiscb->next = hint->callbacks;
04081          hint->callbacks = this->callbacks;
04082          hint->laststate = this->laststate;
04083       }
04084       free(this);
04085    }
04086 
04087    AST_LIST_UNLOCK(&hints);
04088    ast_unlock_contexts();
04089 
04090    return;
04091 }

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

References ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, LOG_WARNING, and ast_channel::priority.

Referenced by _while_exec(), check_goto_on_transfer(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), return_exec(), and while_continue_exec().

06544 {
06545    char *exten, *pri, *context;
06546    char *stringp;
06547    int ipri;
06548    int mode = 0;
06549 
06550    if (ast_strlen_zero(goto_string)) {
06551       ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
06552       return -1;
06553    }
06554    stringp = ast_strdupa(goto_string);
06555    context = strsep(&stringp, "|"); /* guaranteed non-null */
06556    exten = strsep(&stringp, "|");
06557    pri = strsep(&stringp, "|");
06558    if (!exten) {  /* Only a priority in this one */
06559       pri = context;
06560       exten = NULL;
06561       context = NULL;
06562    } else if (!pri) {   /* Only an extension and priority in this one */
06563       pri = exten;
06564       exten = context;
06565       context = NULL;
06566    }
06567    if (*pri == '+') {
06568       mode = 1;
06569       pri++;
06570    } else if (*pri == '-') {
06571       mode = -1;
06572       pri++;
06573    }
06574    if (sscanf(pri, "%30d", &ipri) != 1) {
06575       if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
06576          pri, chan->cid.cid_num)) < 1) {
06577          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
06578          return -1;
06579       } else
06580          mode = 0;
06581    }
06582    /* At this point we have a priority and maybe an extension and a context */
06583 
06584    if (mode)
06585       ipri = chan->priority + (ipri * mode);
06586 
06587    ast_explicit_goto(chan, context, exten, ipri);
06588    return 0;
06589 
06590 }

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 5222 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_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), async_stat::chan, errno, free, LOG_WARNING, option_verbose, outgoing_helper::vars, and VERBOSE_PREFIX_4.

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

05223 {
05224    struct ast_channel *chan;
05225    struct app_tmp *tmp;
05226    int res = -1, cdr_res = -1;
05227    struct outgoing_helper oh;
05228    pthread_attr_t attr;
05229 
05230    memset(&oh, 0, sizeof(oh));
05231    oh.vars = vars;
05232    oh.account = account;
05233 
05234    if (locked_channel)
05235       *locked_channel = NULL;
05236    if (ast_strlen_zero(app)) {
05237       res = -1;
05238       goto outgoing_app_cleanup;
05239    }
05240    if (sync) {
05241       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05242       if (chan) {
05243          ast_set_variables(chan, vars);
05244          if (account)
05245             ast_cdr_setaccount(chan, account);
05246          if (chan->_state == AST_STATE_UP) {
05247             res = 0;
05248             if (option_verbose > 3)
05249                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05250             tmp = ast_calloc(1, sizeof(*tmp));
05251             if (!tmp)
05252                res = -1;
05253             else {
05254                ast_copy_string(tmp->app, app, sizeof(tmp->app));
05255                if (appdata)
05256                   ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
05257                tmp->chan = chan;
05258                if (sync > 1) {
05259                   if (locked_channel)
05260                      ast_channel_unlock(chan);
05261                   ast_pbx_run_app(tmp);
05262                } else {
05263                   pthread_attr_init(&attr);
05264                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05265                   if (locked_channel)
05266                      ast_channel_lock(chan);
05267                   if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
05268                      ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
05269                      free(tmp);
05270                      if (locked_channel)
05271                         ast_channel_unlock(chan);
05272                      ast_hangup(chan);
05273                      res = -1;
05274                   } else {
05275                      if (locked_channel)
05276                         *locked_channel = chan;
05277                   }
05278                   pthread_attr_destroy(&attr);
05279                }
05280             }
05281          } else {
05282             if (option_verbose > 3)
05283                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05284             if (chan->cdr) { /* update the cdr */
05285                /* here we update the status of the call, which sould be busy.
05286                 * if that fails then we set the status to failed */
05287                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05288                   ast_cdr_failed(chan->cdr);
05289             }
05290             ast_hangup(chan);
05291          }
05292       }
05293 
05294       if (res < 0) { /* the call failed for some reason */
05295          if (*reason == 0) { /* if the call failed (not busy or no answer)
05296                         * update the cdr with the failed message */
05297             cdr_res = ast_pbx_outgoing_cdr_failed();
05298             if (cdr_res != 0) {
05299                res = cdr_res;
05300                goto outgoing_app_cleanup;
05301             }
05302          }
05303       }
05304 
05305    } else {
05306       struct async_stat *as;
05307       if (!(as = ast_calloc(1, sizeof(*as)))) {
05308          res = -1;
05309          goto outgoing_app_cleanup;
05310       }
05311       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05312       if (!chan) {
05313          free(as);
05314          res = -1;
05315          goto outgoing_app_cleanup;
05316       }
05317       as->chan = chan;
05318       ast_copy_string(as->app, app, sizeof(as->app));
05319       if (appdata)
05320          ast_copy_string(as->appdata,  appdata, sizeof(as->appdata));
05321       as->timeout = timeout;
05322       ast_set_variables(chan, vars);
05323       if (account)
05324          ast_cdr_setaccount(chan, account);
05325       /* Start a new thread, and get something handling this channel. */
05326       pthread_attr_init(&attr);
05327       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05328       if (locked_channel)
05329          ast_channel_lock(chan);
05330       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05331          ast_log(LOG_WARNING, "Failed to start async wait\n");
05332          free(as);
05333          if (locked_channel)
05334             ast_channel_unlock(chan);
05335          ast_hangup(chan);
05336          res = -1;
05337          pthread_attr_destroy(&attr);
05338          goto outgoing_app_cleanup;
05339       } else {
05340          if (locked_channel)
05341             *locked_channel = chan;
05342       }
05343       pthread_attr_destroy(&attr);
05344       res = 0;
05345    }
05346 outgoing_app_cleanup:
05347    ast_variables_destroy(vars);
05348    return res;
05349 }

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

References __ast_request_and_dial(), ast_channel::_state, 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_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, ast_channel::name, option_verbose, pbx_builtin_setvar_helper(), set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.

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

05057 {
05058    struct ast_channel *chan;
05059    struct async_stat *as;
05060    int res = -1, cdr_res = -1;
05061    struct outgoing_helper oh;
05062    pthread_attr_t attr;
05063 
05064    if (sync) {
05065       LOAD_OH(oh);
05066       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05067       if (channel) {
05068          *channel = chan;
05069          if (chan)
05070             ast_channel_lock(chan);
05071       }
05072       if (chan) {
05073          if (chan->_state == AST_STATE_UP) {
05074                res = 0;
05075             if (option_verbose > 3)
05076                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05077 
05078             if (sync > 1) {
05079                if (channel)
05080                   ast_channel_unlock(chan);
05081                if (ast_pbx_run(chan)) {
05082                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
05083                   if (channel)
05084                      *channel = NULL;
05085                   ast_hangup(chan);
05086                   chan = NULL;
05087                   res = -1;
05088                }
05089             } else {
05090                if (ast_pbx_start(chan)) {
05091                   ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
05092                   if (channel) {
05093                      *channel = NULL;
05094                      ast_channel_unlock(chan);
05095                   }
05096                   ast_hangup(chan);
05097                   res = -1;
05098                }
05099                chan = NULL;
05100             }
05101          } else {
05102             if (option_verbose > 3)
05103                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05104 
05105             if (chan->cdr) { /* update the cdr */
05106                /* here we update the status of the call, which sould be busy.
05107                 * if that fails then we set the status to failed */
05108                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05109                   ast_cdr_failed(chan->cdr);
05110             }
05111 
05112             if (channel) {
05113                *channel = NULL;
05114                ast_channel_unlock(chan);
05115             }
05116             ast_hangup(chan);
05117             chan = NULL;
05118          }
05119       }
05120 
05121       if (res < 0) { /* the call failed for some reason */
05122          if (*reason == 0) { /* if the call failed (not busy or no answer)
05123                         * update the cdr with the failed message */
05124             cdr_res = ast_pbx_outgoing_cdr_failed();
05125             if (cdr_res != 0) {
05126                res = cdr_res;
05127                goto outgoing_exten_cleanup;
05128             }
05129          }
05130 
05131          /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
05132          /* check if "failed" exists */
05133          if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
05134             chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed");
05135             if (chan) {
05136                char failed_reason[4] = "";
05137                if (!ast_strlen_zero(context))
05138                   ast_copy_string(chan->context, context, sizeof(chan->context));
05139                set_ext_pri(chan, "failed", 1);
05140                ast_set_variables(chan, vars);
05141                snprintf(failed_reason, sizeof(failed_reason), "%d", *reason);
05142                pbx_builtin_setvar_helper(chan, "REASON", failed_reason);
05143                if (account)
05144                   ast_cdr_setaccount(chan, account);
05145                if (ast_pbx_run(chan)) {
05146                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
05147                   ast_hangup(chan);
05148                }
05149                chan = NULL;
05150             }
05151          }
05152       }
05153    } else {
05154       if (!(as = ast_calloc(1, sizeof(*as)))) {
05155          res = -1;
05156          goto outgoing_exten_cleanup;
05157       }
05158       chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
05159       if (channel) {
05160          *channel = chan;
05161          if (chan)
05162             ast_channel_lock(chan);
05163       }
05164       if (!chan) {
05165          free(as);
05166          res = -1;
05167          goto outgoing_exten_cleanup;
05168       }
05169       as->chan = chan;
05170       ast_copy_string(as->context, context, sizeof(as->context));
05171       set_ext_pri(as->chan,  exten, priority);
05172       as->timeout = timeout;
05173       ast_set_variables(chan, vars);
05174       if (account)
05175          ast_cdr_setaccount(chan, account);
05176       pthread_attr_init(&attr);
05177       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05178       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05179          ast_log(LOG_WARNING, "Failed to start async wait\n");
05180          free(as);
05181          if (channel) {
05182             *channel = NULL;
05183             ast_channel_unlock(chan);
05184          }
05185          ast_hangup(chan);
05186          res = -1;
05187          pthread_attr_destroy(&attr);
05188          goto outgoing_exten_cleanup;
05189       }
05190       pthread_attr_destroy(&attr);
05191       res = 0;
05192    }
05193 outgoing_exten_cleanup:
05194    ast_variables_destroy(vars);
05195    return res;
05196 }

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.

Returns:
Zero on success, non-zero on failure

Definition at line 2680 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_outgoing_exten(), async_wait(), do_idle_thread(), mgcp_ss(), skinny_newcall(), and ss_thread().

02681 {
02682    enum ast_pbx_result res = AST_PBX_SUCCESS;
02683 
02684    if (increase_call_count(c))
02685       return AST_PBX_CALL_LIMIT;
02686 
02687    res = __ast_pbx_run(c);
02688    decrease_call_count();
02689 
02690    return res;
02691 }

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 ast_pbx_run for a synchronous function to run the PBX in the current thread, as opposed to starting a new one.

Returns:
Zero on success, non-zero on failure

Definition at line 2653 of file pbx.c.

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

Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), dahdi_new(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), and skinny_new().

02654 {
02655    pthread_t t;
02656    pthread_attr_t attr;
02657 
02658    if (!c) {
02659       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02660       return AST_PBX_FAILED;
02661    }
02662 
02663    if (increase_call_count(c))
02664       return AST_PBX_CALL_LIMIT;
02665 
02666    /* Start a new thread, and get something handling this channel. */
02667    pthread_attr_init(&attr);
02668    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02669    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02670       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02671       pthread_attr_destroy(&attr);
02672       decrease_call_count();
02673       return AST_PBX_FAILED;
02674    }
02675    pthread_attr_destroy(&attr);
02676 
02677    return AST_PBX_SUCCESS;
02678 }

int ast_processed_calls ( void   ) 

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

Definition at line 2698 of file pbx.c.

References totalcalls.

02699 {
02700    return totalcalls;
02701 }

int ast_rdlock_contexts ( void   ) 

Definition at line 6321 of file pbx.c.

References ast_rwlock_rdlock(), and conlock.

Referenced by __ast_context_create(), _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().

06322 {
06323    return ast_rwlock_rdlock(&conlock);
06324 }

int ast_register_application ( const char *  app,
int(*)(struct ast_channel *, void *)  execute,
const char *  synopsis,
const char *  description 
)

Register an application.

Parameters:
app Short name of the application
execute a function callback to execute the application. It should return non-zero if the channel needs to be hung up.
synopsis a short description (one line synopsis) of the application
description long description with all of the details about the use of the application
This registers an application with Asterisk's internal application list.
Note:
The individual applications themselves are responsible for registering and unregistering and unregistering their own CLI commands.
Return values:
0 success
-1 failure.

Definition at line 2987 of file pbx.c.

References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, ast_app::list, LOG_WARNING, ast_app::name, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.

Referenced by load_module(), and load_pbx().

02988 {
02989    struct ast_app *tmp, *cur = NULL;
02990    char tmps[80];
02991    int length;
02992 
02993    AST_LIST_LOCK(&apps);
02994    AST_LIST_TRAVERSE(&apps, tmp, list) {
02995       if (!strcasecmp(app, tmp->name)) {
02996          ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
02997          AST_LIST_UNLOCK(&apps);
02998          return -1;
02999       }
03000    }
03001 
03002    length = sizeof(*tmp) + strlen(app) + 1;
03003 
03004    if (!(tmp = ast_calloc(1, length))) {
03005       AST_LIST_UNLOCK(&apps);
03006       return -1;
03007    }
03008 
03009    strcpy(tmp->name, app);
03010    tmp->execute = execute;
03011    tmp->synopsis = synopsis;
03012    tmp->description = description;
03013 
03014    /* Store in alphabetical order */
03015    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
03016       if (strcasecmp(tmp->name, cur->name) < 0) {
03017          AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list);
03018          break;
03019       }
03020    }
03021    AST_LIST_TRAVERSE_SAFE_END
03022    if (!cur)
03023       AST_LIST_INSERT_TAIL(&apps, tmp, list);
03024 
03025    if (option_verbose > 1)
03026       ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
03027 
03028    AST_LIST_UNLOCK(&apps);
03029 
03030    return 0;
03031 }

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

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_switch::list, LOG_WARNING, and ast_switch::name.

Referenced by load_module().

03038 {
03039    struct ast_switch *tmp;
03040 
03041    AST_LIST_LOCK(&switches);
03042    AST_LIST_TRAVERSE(&switches, tmp, list) {
03043       if (!strcasecmp(tmp->name, sw->name)) {
03044          AST_LIST_UNLOCK(&switches);
03045          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
03046          return -1;
03047       }
03048    }
03049    AST_LIST_INSERT_TAIL(&switches, sw, list);
03050    AST_LIST_UNLOCK(&switches);
03051 
03052    return 0;
03053 }

int ast_spawn_extension ( struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid 
)

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

References E_SPAWN, and pbx_extension_helper().

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

02325 {
02326    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
02327 }

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

References ast_mutex_unlock(), and ast_context::lock.

Referenced by _macro_exec(), complete_context_dont_include_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), and show_dialplan_helper().

06345 {
06346    return ast_mutex_unlock(&con->lock);
06347 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 6331 of file pbx.c.

References ast_rwlock_unlock(), and conlock.

Referenced by __ast_context_create(), _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_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_hint_state_changed(), ast_merge_contexts_and_delete(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().

06332 {
06333    return ast_rwlock_unlock(&conlock);
06334 }

int ast_unregister_application ( const char *  app  ) 

Unregister an application.

Parameters:
app name of the application (does not have to be the same string as the one that was registered)
This unregisters an application from Asterisk's internal application list.

Return values:
0 success
-1 failure

Definition at line 3902 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, ast_app::list, ast_app::name, option_verbose, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

03903 {
03904    struct ast_app *tmp;
03905 
03906    AST_LIST_LOCK(&apps);
03907    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
03908       if (!strcasecmp(app, tmp->name)) {
03909          AST_LIST_REMOVE_CURRENT(&apps, list);
03910          if (option_verbose > 1)
03911             ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
03912          free(tmp);
03913          break;
03914       }
03915    }
03916    AST_LIST_TRAVERSE_SAFE_END
03917    AST_LIST_UNLOCK(&apps);
03918 
03919    return tmp ? 0 : -1;
03920 }

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

References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and ast_switch::list.

Referenced by __unload_module(), and unload_module().

03056 {
03057    AST_LIST_LOCK(&switches);
03058    AST_LIST_REMOVE(&switches, sw, list);
03059    AST_LIST_UNLOCK(&switches);
03060 }

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

Definition at line 6453 of file pbx.c.

References exten, and ast_context::root.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().

06455 {
06456    if (!exten)
06457       return con ? con->root : NULL;
06458    else
06459       return exten->next;
06460 }

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

Definition at line 6486 of file pbx.c.

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

Referenced by complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), handle_save_dialplan(), lookup_c_ip(), and show_dialplan_helper().

06488 {
06489    if (!ip)
06490       return con ? con->ignorepats : NULL;
06491    else
06492       return ip->next;
06493 }

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

Definition at line 6477 of file pbx.c.

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

Referenced by ast_context_verify_includes(), complete_context_dont_include_deprecated(), complete_context_remove_include(), find_matching_priority(), handle_save_dialplan(), lookup_ci(), and show_dialplan_helper().

06479 {
06480    if (!inc)
06481       return con ? con->includes : NULL;
06482    else
06483       return inc->next;
06484 }

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

Definition at line 6462 of file pbx.c.

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

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06464 {
06465    if (!sw)
06466       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06467    else
06468       return AST_LIST_NEXT(sw, list);
06469 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

Definition at line 6448 of file pbx.c.

References contexts, and ast_context::next.

Referenced by _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), pbx_load_module(), and show_dialplan_helper().

06449 {
06450    return con ? con->next : contexts;
06451 }

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

Definition at line 6471 of file pbx.c.

References exten, and ast_exten::priority.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().

06473 {
06474    return priority ? priority->peer : exten;
06475 }

int ast_wrlock_contexts ( void   ) 

Definition at line 6326 of file pbx.c.

References ast_rwlock_wrlock(), and conlock.

Referenced by ast_context_destroy(), ast_merge_contexts_and_delete(), and complete_context_dont_include_deprecated().

06327 {
06328    return ast_rwlock_wrlock(&conlock);
06329 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 6092 of file pbx.c.

References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), ast_var_delete(), ast_var_t::entries, globals, and globalslock.

Referenced by handle_reload_extensions(), and reload().

06093 {
06094    struct ast_var_t *vardata;
06095 
06096    ast_mutex_lock(&globalslock);
06097    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
06098       ast_var_delete(vardata);
06099    ast_mutex_unlock(&globalslock);
06100 }

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

Note:
Will lock the channel.

Definition at line 5869 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), globals, and globalslock.

Referenced by __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_call_forward(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dahdi_r2_answer(), dahdi_r2_get_channel_category(), dundi_exec(), dundi_helper(), feature_interpret(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), macro_fixup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), park_space_reserve(), pbx_builtin_background(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), ring_entry(), run_agi(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_suggested_sip_codec(), update_bridgepeer(), and wait_for_answer().

05870 {
05871    struct ast_var_t *variables;
05872    const char *ret = NULL;
05873    int i;
05874    struct varshead *places[2] = { NULL, &globals };
05875 
05876    if (!name)
05877       return NULL;
05878 
05879    if (chan) {
05880       ast_channel_lock(chan);
05881       places[0] = &chan->varshead;
05882    }
05883 
05884    for (i = 0; i < 2; i++) {
05885       if (!places[i])
05886          continue;
05887       if (places[i] == &globals)
05888          ast_mutex_lock(&globalslock);
05889       AST_LIST_TRAVERSE(places[i], variables, entries) {
05890          if (!strcmp(name, ast_var_name(variables))) {
05891             ret = ast_var_value(variables);
05892             break;
05893          }
05894       }
05895       if (places[i] == &globals)
05896          ast_mutex_unlock(&globalslock);
05897       if (ret)
05898          break;
05899    }
05900 
05901    if (chan)
05902       ast_channel_unlock(chan);
05903 
05904    return ret;
05905 }

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

Note:
Will lock the channel.

Definition at line 5907 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_verbose(), globals, globalslock, LOG_WARNING, option_verbose, and VERBOSE_PREFIX_2.

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

05908 {
05909    struct ast_var_t *newvariable;
05910    struct varshead *headp;
05911 
05912    if (name[strlen(name)-1] == ')') {
05913       char *function = ast_strdupa(name);
05914 
05915       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05916       ast_func_write(chan, function, value);
05917       return;
05918    }
05919 
05920    if (chan) {
05921       ast_channel_lock(chan);
05922       headp = &chan->varshead;
05923    } else {
05924       ast_mutex_lock(&globalslock);
05925       headp = &globals;
05926    }
05927 
05928    if (value) {
05929       if ((option_verbose > 1) && (headp == &globals))
05930          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05931       newvariable = ast_var_assign(name, value);
05932       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05933    }
05934 
05935    if (chan)
05936       ast_channel_unlock(chan);
05937    else
05938       ast_mutex_unlock(&globalslock);
05939 }

int pbx_builtin_serialize_variables ( struct ast_channel chan,
char *  buf,
size_t  size 
)

Note:
Will lock the channel.

Definition at line 5838 of file pbx.c.

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

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

05839 {
05840    struct ast_var_t *variables;
05841    const char *var, *val;
05842    int total = 0;
05843 
05844    if (!chan)
05845       return 0;
05846 
05847    memset(buf, 0, size);
05848 
05849    ast_channel_lock(chan);
05850 
05851    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05852       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05853          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05854          ) {
05855          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05856             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05857             break;
05858          } else
05859             total++;
05860       } else
05861          break;
05862    }
05863 
05864    ast_channel_unlock(chan);
05865 
05866    return total;
05867 }

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 5941 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_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), globals, globalslock, option_verbose, and VERBOSE_PREFIX_2.

Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), aqm_exec(), array(), ast_bridge_call(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), dahdi_handle_dtmfup(), dahdi_new(), disa_exec(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), function_db_delete(), function_db_exists(), function_db_read(), global_write(), handle_request_bye(), handle_request_refer(), handle_set_global(), handle_set_global_deprecated(), handle_setvariable(), hasvoicemail_exec(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lookupblacklist_exec(), macro_fixup(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_call_full(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_load_config(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_exec(), realtime_update_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_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(), tryexec_exec(), update_bridgepeer(), upqm_exec(), vm_box_exists(), vm_exec(), and vmauthenticate().

05942 {
05943    struct ast_var_t *newvariable;
05944    struct varshead *headp;
05945    const char *nametail = name;
05946 
05947    if (name[strlen(name)-1] == ')') {
05948       char *function = ast_strdupa(name);
05949 
05950       ast_func_write(chan, function, value);
05951       return;
05952    }
05953 
05954    if (chan) {
05955       ast_channel_lock(chan);
05956       headp = &chan->varshead;
05957    } else {
05958       ast_mutex_lock(&globalslock);
05959       headp = &globals;
05960    }
05961 
05962    /* For comparison purposes, we have to strip leading underscores */
05963    if (*nametail == '_') {
05964       nametail++;
05965       if (*nametail == '_')
05966          nametail++;
05967    }
05968 
05969    AST_LIST_TRAVERSE (headp, newvariable, entries) {
05970       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
05971          /* there is already such a variable, delete it */
05972          AST_LIST_REMOVE(headp, newvariable, entries);
05973          ast_var_delete(newvariable);
05974          break;
05975       }
05976    }
05977 
05978    if (value) {
05979       if ((option_verbose > 1) && (headp == &globals))
05980          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05981       newvariable = ast_var_assign(name, value);
05982       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05983    }
05984 
05985    if (chan)
05986       ast_channel_unlock(chan);
05987    else
05988       ast_mutex_unlock(&globalslock);
05989 }

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

06103 {
06104    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
06105       return 0;
06106    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
06107       return atoi(condition);
06108    else  /* Strings are true */
06109       return 1;
06110 }

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

References app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, ast_channel::data, and S_OR.

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

00540 {
00541    int res;
00542 
00543    const char *saved_c_appl;
00544    const char *saved_c_data;
00545 
00546    if (c->cdr && !ast_check_hangup(c))
00547       ast_cdr_setapp(c->cdr, app->name, data);
00548 
00549    /* save channel values */
00550    saved_c_appl= c->appl;
00551    saved_c_data= c->data;
00552 
00553    c->appl = app->name;
00554    c->data = data;
00555    /* XXX remember what to to when we have linked apps to modules */
00556    if (app->module) {
00557       /* XXX LOCAL_USER_ADD(app->module) */
00558    }
00559    res = app->execute(c, S_OR(data, ""));
00560    if (app->module) {
00561       /* XXX LOCAL_USER_REMOVE(app->module) */
00562    }
00563    /* restore channel values */
00564    c->appl = saved_c_appl;
00565    c->data = saved_c_data;
00566    return res;
00567 }

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

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sw::list, and ast_app::name.

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

00576 {
00577    struct ast_app *tmp;
00578 
00579    AST_LIST_LOCK(&apps);
00580    AST_LIST_TRAVERSE(&apps, tmp, list) {
00581       if (!strcasecmp(tmp->name, app))
00582          break;
00583    }
00584    AST_LIST_UNLOCK(&apps);
00585 
00586    return tmp;
00587 }

void pbx_retrieve_variable ( struct ast_channel c,
const char *  var,
char **  ret,
char *  workspace,
int  workspacelen,
struct varshead headp 
)

pbx_retrieve_variable: Support for Asterisk built-in variables ---

Note:
Will lock the channel.

Definition at line 1190 of file pbx.c.

References ast_cause2str(), ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_get_hint(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_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, offset, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::uniqueid.

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

01191 {
01192    const char not_found = '\0';
01193    char *tmpvar;
01194    const char *s; /* the result */
01195    int offset, length;
01196    int i, need_substring;
01197    struct varshead *places[2] = { headp, &globals };  /* list of places where we may look */
01198 
01199    if (c) {
01200       ast_channel_lock(c);
01201       places[0] = &c->varshead;
01202    }
01203    /*
01204     * Make a copy of var because parse_variable_name() modifies the string.
01205     * Then if called directly, we might need to run substring() on the result;
01206     * remember this for later in 'need_substring', 'offset' and 'length'
01207     */
01208    tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */
01209    need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
01210 
01211    /*
01212     * Look first into predefined variables, then into variable lists.
01213     * Variable 's' points to the result, according to the following rules:
01214     * s == &not_found (set at the beginning) means that we did not find a
01215     * matching variable and need to look into more places.
01216     * If s != &not_found, s is a valid result string as follows:
01217     * s = NULL if the variable does not have a value;
01218     * you typically do this when looking for an unset predefined variable.
01219     * s = workspace if the result has been assembled there;
01220     * typically done when the result is built e.g. with an snprintf(),
01221     * so we don't need to do an additional copy.
01222     * s != workspace in case we have a string, that needs to be copied
01223     * (the ast_copy_string is done once for all at the end).
01224     * Typically done when the result is already available in some string.
01225     */
01226    s = &not_found;   /* default value */
01227    if (c) { /* This group requires a valid channel */
01228       /* Names with common parts are looked up a piece at a time using strncmp. */
01229       if (!strncmp(var, "CALL", 4)) {
01230          if (!strncmp(var + 4, "ING", 3)) {
01231             if (!strcmp(var + 7, "PRES")) {        /* CALLINGPRES */
01232                snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
01233                s = workspace;
01234             } else if (!strcmp(var + 7, "ANI2")) {    /* CALLINGANI2 */
01235                snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
01236                s = workspace;
01237             } else if (!strcmp(var + 7, "TON")) {     /* CALLINGTON */
01238                snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
01239                s = workspace;
01240             } else if (!strcmp(var + 7, "TNS")) {     /* CALLINGTNS */
01241                snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
01242                s = workspace;
01243             }
01244          }
01245       } else if (!strcmp(var, "HINT")) {
01246          s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL;
01247       } else if (!strcmp(var, "HINTNAME")) {
01248          s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL;
01249       } else if (!strcmp(var, "EXTEN")) {
01250          s = c->exten;
01251       } else if (!strcmp(var, "CONTEXT")) {
01252          s = c->context;
01253       } else if (!strcmp(var, "PRIORITY")) {
01254          snprintf(workspace, workspacelen, "%d", c->priority);
01255          s = workspace;
01256       } else if (!strcmp(var, "CHANNEL")) {
01257          s = c->name;
01258       } else if (!strcmp(var, "UNIQUEID")) {
01259          s = c->uniqueid;
01260       } else if (!strcmp(var, "HANGUPCAUSE")) {
01261          snprintf(workspace, workspacelen, "%d", c->hangupcause);
01262          s = workspace;
01263       } else if (c && !strcmp(var, "HANGUPCAUSESTR")) {
01264          ast_copy_string(workspace, ast_cause2str(c->hangupcause), workspacelen);
01265          *ret = workspace;
01266       }
01267    }
01268    if (s == &not_found) { /* look for more */
01269       if (!strcmp(var, "EPOCH")) {
01270          snprintf(workspace, workspacelen, "%u",(int)time(NULL));
01271          s = workspace;
01272       } else if (!strcmp(var, "SYSTEMNAME")) {
01273          s = ast_config_AST_SYSTEM_NAME;
01274       }
01275    }
01276    /* if not found, look into chanvars or global vars */
01277    for (i = 0; s == &not_found && i < (sizeof(places) / sizeof(places[0])); i++) {
01278       struct ast_var_t *variables;
01279       if (!places[i])
01280          continue;
01281       if (places[i] == &globals)
01282          ast_mutex_lock(&globalslock);
01283       AST_LIST_TRAVERSE(places[i], variables, entries) {
01284          if (strcasecmp(ast_var_name(variables), var)==0) {
01285             s = ast_var_value(variables);
01286             break;
01287          }
01288       }
01289       if (places[i] == &globals)
01290          ast_mutex_unlock(&globalslock);
01291    }
01292    if (s == &not_found || s == NULL)
01293       *ret = NULL;
01294    else {
01295       if (s != workspace)
01296          ast_copy_string(workspace, s, workspacelen);
01297       *ret = workspace;
01298       if (need_substring)
01299          *ret = substring(*ret, offset, length, workspace, workspacelen);
01300    }
01301 
01302    if (c)
01303       ast_channel_unlock(c);
01304 }

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

References autofallthrough.

Referenced by pbx_load_module().

02704 {
02705    int oldval = autofallthrough;
02706    autofallthrough = newval;
02707    return oldval;
02708 }

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

Definition at line 1810 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

Referenced by _macro_exec(), acf_odbc_read(), acf_odbc_write(), add_extensions(), custom_log(), cut_internal(), exec_exec(), function_eval(), function_fieldqty(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), pbx_builtin_importvar(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), sendpage(), and tryexec_exec().

01811 {
01812    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
01813 }

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

Definition at line 1815 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

01816 {
01817    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01818 }


Generated on Tue Apr 6 15:46:00 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7