Fri Sep 11 13:45:36 2009

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

References countcalls.

Referenced by handle_chanlist(), and handle_chanlist_deprecated().

02676 {
02677    return countcalls;
02678 }

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

04599 {
04600    int ret = -1;
04601    struct ast_context *c = find_context_locked(context);
04602 
04603    if (c) {
04604       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04605          application, data, datad, registrar);
04606       ast_unlock_contexts();
04607    }
04608    return ret;
04609 }

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

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

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

Definition at line 4634 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().

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

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

Definition at line 4687 of file pbx.c.

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

04688 {
04689    struct ast_channel *chan;
04690    int res = -1;
04691 
04692    chan = ast_get_channel_by_name_locked(channame);
04693    if (chan) {
04694       res = ast_async_goto(chan, context, exten, priority);
04695       ast_channel_unlock(chan);
04696    }
04697    return res;
04698 }

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

References __ast_goto_if_exists().

Referenced by asyncgoto_exec().

06506 {
06507    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06508 }

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

Definition at line 4274 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().

04275 {
04276    char info_save[256];
04277    char *info;
04278 
04279    /* Check for empty just in case */
04280    if (ast_strlen_zero(info_in))
04281       return 0;
04282    /* make a copy just in case we were passed a static string */
04283    ast_copy_string(info_save, info_in, sizeof(info_save));
04284    info = info_save;
04285    /* Assume everything except time */
04286    i->monthmask = 0xfff;   /* 12 bits */
04287    i->daymask = 0x7fffffffU; /* 31 bits */
04288    i->dowmask = 0x7f; /* 7 bits */
04289    /* on each call, use strsep() to move info to the next argument */
04290    get_timerange(i, strsep(&info, "|"));
04291    if (info)
04292       i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week");
04293    if (info)
04294       i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day");
04295    if (info)
04296       i->monthmask = get_range(strsep(&info, "|"), 12, months, "month");
04297    return 1;
04298 }

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 2297 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(), phone_check_exception(), skinny_ss(), ss_thread(), and valid_exit().

02298 {
02299    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
02300 }

int ast_check_timing ( const struct ast_timing i  ) 

Definition at line 4300 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().

04301 {
04302    struct tm tm;
04303    time_t t = time(NULL);
04304 
04305    ast_localtime(&t, &tm, NULL);
04306 
04307    /* If it's not the right month, return */
04308    if (!(i->monthmask & (1 << tm.tm_mon)))
04309       return 0;
04310 
04311    /* If it's not that time of the month.... */
04312    /* Warning, tm_mday has range 1..31! */
04313    if (!(i->daymask & (1 << (tm.tm_mday-1))))
04314       return 0;
04315 
04316    /* If it's not the right day of the week */
04317    if (!(i->dowmask & (1 << tm.tm_wday)))
04318       return 0;
04319 
04320    /* Sanity check the hour just to be safe */
04321    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
04322       ast_log(LOG_WARNING, "Insane time...\n");
04323       return 0;
04324    }
04325 
04326    /* Now the tough part, we calculate if it fits
04327       in the right time based on min/hour */
04328    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
04329       return 0;
04330 
04331    /* If we got this far, then we're good */
04332    return 1;
04333 }

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

04528 {
04529    int ret = -1;
04530    struct ast_context *c = find_context_locked(context);
04531 
04532    if (c) {
04533       ret = ast_context_add_ignorepat2(c, value, registrar);
04534       ast_unlock_contexts();
04535    }
04536    return ret;
04537 }

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

Definition at line 4539 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().

04540 {
04541    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04542    int length;
04543    char *pattern;
04544    length = sizeof(struct ast_ignorepat);
04545    length += strlen(value) + 1;
04546    if (!(ignorepat = ast_calloc(1, length)))
04547       return -1;
04548    /* The cast to char * is because we need to write the initial value.
04549     * The field is not supposed to be modified otherwise.  Also, gcc 4.2
04550     * sees the cast as dereferencing a type-punned pointer and warns about
04551     * it.  This is the workaround (we're telling gcc, yes, that's really
04552     * what we wanted to do).
04553     */
04554    pattern = (char *) ignorepat->pattern;
04555    strcpy(pattern, value);
04556    ignorepat->next = NULL;
04557    ignorepat->registrar = registrar;
04558    ast_mutex_lock(&con->lock);
04559    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
04560       ignorepatl = ignorepatc;
04561       if (!strcasecmp(ignorepatc->pattern, value)) {
04562          /* Already there */
04563          ast_mutex_unlock(&con->lock);
04564          errno = EEXIST;
04565          return -1;
04566       }
04567    }
04568    if (ignorepatl)
04569       ignorepatl->next = ignorepat;
04570    else
04571       con->ignorepats = ignorepat;
04572    ast_mutex_unlock(&con->lock);
04573    return 0;
04574 
04575 }

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

04081 {
04082    int ret = -1;
04083    struct ast_context *c = find_context_locked(context);
04084 
04085    if (c) {
04086       ret = ast_context_add_include2(c, include, registrar);
04087       ast_unlock_contexts();
04088    }
04089    return ret;
04090 }

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

04344 {
04345    struct ast_include *new_include;
04346    char *c;
04347    struct ast_include *i, *il = NULL; /* include, include_last */
04348    int length;
04349    char *p;
04350 
04351    length = sizeof(struct ast_include);
04352    length += 2 * (strlen(value) + 1);
04353 
04354    /* allocate new include structure ... */
04355    if (!(new_include = ast_calloc(1, length)))
04356       return -1;
04357    /* Fill in this structure. Use 'p' for assignments, as the fields
04358     * in the structure are 'const char *'
04359     */
04360    p = new_include->stuff;
04361    new_include->name = p;
04362    strcpy(p, value);
04363    p += strlen(value) + 1;
04364    new_include->rname = p;
04365    strcpy(p, value);
04366    /* Strip off timing info, and process if it is there */
04367    if ( (c = strchr(p, '|')) ) {
04368       *c++ = '\0';
04369            new_include->hastime = ast_build_timing(&(new_include->timing), c);
04370    }
04371    new_include->next      = NULL;
04372    new_include->registrar = registrar;
04373 
04374    ast_mutex_lock(&con->lock);
04375 
04376    /* ... go to last include and check if context is already included too... */
04377    for (i = con->includes; i; i = i->next) {
04378       if (!strcasecmp(i->name, new_include->name)) {
04379          free(new_include);
04380          ast_mutex_unlock(&con->lock);
04381          errno = EEXIST;
04382          return -1;
04383       }
04384       il = i;
04385    }
04386 
04387    /* ... include new context into context list, unlock, return */
04388    if (il)
04389       il->next = new_include;
04390    else
04391       con->includes = new_include;
04392    if (option_verbose > 2)
04393       ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
04394    ast_mutex_unlock(&con->lock);
04395 
04396    return 0;
04397 }

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

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

04405 {
04406    int ret = -1;
04407    struct ast_context *c = find_context_locked(context);
04408 
04409    if (c) { /* found, add switch to this context */
04410       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04411       ast_unlock_contexts();
04412    }
04413    return ret;
04414 }

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

04425 {
04426    struct ast_sw *new_sw;
04427    struct ast_sw *i;
04428    int length;
04429    char *p;
04430 
04431    length = sizeof(struct ast_sw);
04432    length += strlen(value) + 1;
04433    if (data)
04434       length += strlen(data);
04435    length++;
04436 
04437    /* allocate new sw structure ... */
04438    if (!(new_sw = ast_calloc(1, length)))
04439       return -1;
04440    /* ... fill in this structure ... */
04441    p = new_sw->stuff;
04442    new_sw->name = p;
04443    strcpy(new_sw->name, value);
04444    p += strlen(value) + 1;
04445    new_sw->data = p;
04446    if (data) {
04447       strcpy(new_sw->data, data);
04448       p += strlen(data) + 1;
04449    } else {
04450       strcpy(new_sw->data, "");
04451       p++;
04452    }
04453    new_sw->eval     = eval;
04454    new_sw->registrar = registrar;
04455 
04456    /* ... try to lock this context ... */
04457    ast_mutex_lock(&con->lock);
04458 
04459    /* ... go to last sw and check if context is already swd too... */
04460    AST_LIST_TRAVERSE(&con->alts, i, list) {
04461       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
04462          free(new_sw);
04463          ast_mutex_unlock(&con->lock);
04464          errno = EEXIST;
04465          return -1;
04466       }
04467    }
04468 
04469    /* ... sw new context into context list, unlock, return */
04470    AST_LIST_INSERT_TAIL(&con->alts, new_sw, list);
04471 
04472    if (option_verbose > 2)
04473       ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
04474 
04475    ast_mutex_unlock(&con->lock);
04476 
04477    return 0;
04478 }

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

References __ast_context_create().

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

03951 {
03952    return __ast_context_create(extcontexts, name, registrar, 0);
03953 }

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

05393 {
05394    ast_wrlock_contexts();
05395    __ast_context_destroy(con,registrar);
05396    ast_unlock_contexts();
05397 }

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

00919 {
00920    struct ast_context *tmp = NULL;
00921 
00922    ast_rdlock_contexts();
00923 
00924    while ( (tmp = ast_walk_contexts(tmp)) ) {
00925       if (!name || !strcasecmp(name, tmp->name))
00926          break;
00927    }
00928 
00929    ast_unlock_contexts();
00930 
00931    return tmp;
00932 }

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

Definition at line 3955 of file pbx.c.

References __ast_context_create().

Referenced by pbx_load_config(), and pbx_load_users().

03956 {
03957    return __ast_context_create(extcontexts, name, registrar, 1);
03958 }

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

02918 {
02919    struct ast_context *c = NULL;
02920    int ret = -1;
02921 
02922    ast_rdlock_contexts();
02923 
02924    while ((c = ast_walk_contexts(c))) {
02925       if (!strcmp(ast_get_context_name(c), context)) {
02926          ret = 0;
02927          break;
02928       }
02929    }
02930 
02931    ast_unlock_contexts();
02932 
02933    /* if we found context, lock macrolock */
02934    if (ret == 0) 
02935       ret = ast_mutex_lock(&c->macrolock);
02936 
02937    return ret;
02938 }

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

References ast_context_remove_extension_callerid().

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

02819 {
02820    return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
02821 }

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

References ast_context_remove_extension_callerid2().

Referenced by do_parking_thread(), and park_exec().

02846 {
02847    return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar);
02848 }

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

02824 {
02825    int ret = -1; /* default error return */
02826    struct ast_context *c = find_context_locked(context);
02827 
02828    if (c) { /* ... remove extension ... */
02829       ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar);
02830       ast_unlock_contexts();
02831    }
02832    return ret;
02833 }

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

02851 {
02852    struct ast_exten *exten, *prev_exten = NULL;
02853    struct ast_exten *peer;
02854    struct ast_exten *previous_peer = NULL;
02855    struct ast_exten *next_peer = NULL;
02856    int found = 0;
02857 
02858    ast_mutex_lock(&con->lock);
02859 
02860    /* scan the extension list to find first matching extension-registrar */
02861    for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
02862       if (!strcmp(exten->exten, extension) &&
02863          (!registrar || !strcmp(exten->registrar, registrar)))
02864          break;
02865    }
02866    if (!exten) {
02867       /* we can't find right extension */
02868       ast_mutex_unlock(&con->lock);
02869       return -1;
02870    }
02871 
02872    /* scan the priority list to remove extension with exten->priority == priority */
02873    for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next;
02874          peer && !strcmp(peer->exten, extension);
02875          peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) {
02876       if ((priority == 0 || peer->priority == priority) &&
02877             (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) &&
02878             (!registrar || !strcmp(peer->registrar, registrar) )) {
02879          found = 1;
02880 
02881          /* we are first priority extension? */
02882          if (!previous_peer) {
02883             /*
02884              * We are first in the priority chain, so must update the extension chain.
02885              * The next node is either the next priority or the next extension
02886              */
02887             struct ast_exten *next_node = peer->peer ? peer->peer : peer->next;
02888 
02889             if (!prev_exten) {   /* change the root... */
02890                con->root = next_node;
02891             } else {
02892                prev_exten->next = next_node; /* unlink */
02893             }
02894             if (peer->peer)   { /* update the new head of the pri list */
02895                peer->peer->next = peer->next;
02896             }
02897          } else { /* easy, we are not first priority in extension */
02898             previous_peer->peer = peer->peer;
02899          }
02900 
02901          /* now, free whole priority extension */
02902          destroy_exten(peer);
02903       } else {
02904          previous_peer = peer;
02905       }
02906    }
02907    ast_mutex_unlock(&con->lock);
02908    return found ? 0 : -1;
02909 }

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

Definition at line 4484 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().

04485 {
04486    int ret = -1;
04487    struct ast_context *c = find_context_locked(context);
04488 
04489    if (c) {
04490       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04491       ast_unlock_contexts();
04492    }
04493    return ret;
04494 }

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

Definition at line 4496 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().

04497 {
04498    struct ast_ignorepat *ip, *ipl = NULL;
04499 
04500    ast_mutex_lock(&con->lock);
04501 
04502    for (ip = con->ignorepats; ip; ip = ip->next) {
04503       if (!strcmp(ip->pattern, ignorepat) &&
04504          (!registrar || (registrar == ip->registrar))) {
04505          if (ipl) {
04506             ipl->next = ip->next;
04507             free(ip);
04508          } else {
04509             con->ignorepats = ip->next;
04510             free(ip);
04511          }
04512          ast_mutex_unlock(&con->lock);
04513          return 0;
04514       }
04515       ipl = ip;
04516    }
04517 
04518    ast_mutex_unlock(&con->lock);
04519    errno = EINVAL;
04520    return -1;
04521 }

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

02715 {
02716    int ret = -1;
02717    struct ast_context *c = find_context_locked(context);
02718 
02719    if (c) {
02720       /* found, remove include from this context ... */
02721       ret = ast_context_remove_include2(c, include, registrar);
02722       ast_unlock_contexts();
02723    }
02724    return ret;
02725 }

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

02736 {
02737    struct ast_include *i, *pi = NULL;
02738    int ret = -1;
02739 
02740    ast_mutex_lock(&con->lock);
02741 
02742    /* find our include */
02743    for (i = con->includes; i; pi = i, i = i->next) {
02744       if (!strcmp(i->name, include) &&
02745             (!registrar || !strcmp(i->registrar, registrar))) {
02746          /* remove from list */
02747          if (pi)
02748             pi->next = i->next;
02749          else
02750             con->includes = i->next;
02751          /* free include and return */
02752          free(i);
02753          ret = 0;
02754          break;
02755       }
02756    }
02757 
02758    ast_mutex_unlock(&con->lock);
02759    return ret;
02760 }

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

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

02768 {
02769    int ret = -1; /* default error return */
02770    struct ast_context *c = find_context_locked(context);
02771 
02772    if (c) {
02773       /* remove switch from this context ... */
02774       ret = ast_context_remove_switch2(c, sw, data, registrar);
02775       ast_unlock_contexts();
02776    }
02777    return ret;
02778 }

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

02789 {
02790    struct ast_sw *i;
02791    int ret = -1;
02792 
02793    ast_mutex_lock(&con->lock);
02794 
02795    /* walk switches */
02796    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
02797       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02798          (!registrar || !strcmp(i->registrar, registrar))) {
02799          /* found, remove from list */
02800          AST_LIST_REMOVE_CURRENT(&con->alts, list);
02801          free(i); /* free switch and return */
02802          ret = 0;
02803          break;
02804       }
02805    }
02806    AST_LIST_TRAVERSE_SAFE_END
02807 
02808    ast_mutex_unlock(&con->lock);
02809 
02810    return ret;
02811 }

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

02946 {
02947    struct ast_context *c = NULL;
02948    int ret = -1;
02949 
02950    ast_rdlock_contexts();
02951 
02952    while ((c = ast_walk_contexts(c))) {
02953       if (!strcmp(ast_get_context_name(c), context)) {
02954          ret = 0;
02955          break;
02956       }
02957    }
02958 
02959    ast_unlock_contexts();
02960 
02961    /* if we found context, unlock macrolock */
02962    if (ret == 0) 
02963       ret = ast_mutex_unlock(&c->macrolock);
02964 
02965    return ret;
02966 }

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

06463 {
06464    struct ast_include *inc = NULL;
06465    int res = 0;
06466 
06467    while ( (inc = ast_walk_context_includes(con, inc)) ) {
06468       if (ast_context_find(inc->rname))
06469          continue;
06470 
06471       res = -1;
06472       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
06473          ast_get_context_name(con), inc->rname);
06474       break;
06475    }
06476 
06477    return res;
06478 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

Definition at line 1480 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().

01481 {
01482    struct ast_custom_function *acf = NULL;
01483 
01484    AST_LIST_LOCK(&acf_root);
01485    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01486       if (!strcmp(name, acf->name))
01487          break;
01488    }
01489    AST_LIST_UNLOCK(&acf_root);
01490 
01491    return acf;
01492 }

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

Definition at line 1516 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().

01517 {
01518    struct ast_custom_function *cur;
01519 
01520    if (!acf)
01521       return -1;
01522 
01523    AST_LIST_LOCK(&acf_root);
01524 
01525    if (ast_custom_function_find(acf->name)) {
01526       ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
01527       AST_LIST_UNLOCK(&acf_root);
01528       return -1;
01529    }
01530 
01531    /* Store in alphabetical order */
01532    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01533       if (strcasecmp(acf->name, cur->name) < 0) {
01534          AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist);
01535          break;
01536       }
01537    }
01538    AST_LIST_TRAVERSE_SAFE_END
01539    if (!cur)
01540       AST_LIST_INSERT_TAIL(&acf_root, acf, acflist);
01541 
01542    AST_LIST_UNLOCK(&acf_root);
01543 
01544    if (option_verbose > 1)
01545       ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
01546 
01547    return 0;
01548 }

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

Definition at line 1494 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().

01495 {
01496    struct ast_custom_function *cur;
01497 
01498    if (!acf)
01499       return -1;
01500 
01501    AST_LIST_LOCK(&acf_root);
01502    AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) {
01503       if (cur == acf) {
01504          AST_LIST_REMOVE_CURRENT(&acf_root, acflist);
01505          if (option_verbose > 1)
01506             ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
01507          break;
01508       }
01509    }
01510    AST_LIST_TRAVERSE_SAFE_END
01511    AST_LIST_UNLOCK(&acf_root);
01512 
01513    return acf ? 0 : -1;
01514 }

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

01944 {
01945    switch (devstate) {
01946    case AST_DEVICE_ONHOLD:
01947       return AST_EXTENSION_ONHOLD;
01948    case AST_DEVICE_BUSY:
01949       return AST_EXTENSION_BUSY;
01950    case AST_DEVICE_UNAVAILABLE:
01951    case AST_DEVICE_UNKNOWN:
01952    case AST_DEVICE_INVALID:
01953       return AST_EXTENSION_UNAVAILABLE;
01954    case AST_DEVICE_RINGINUSE:
01955       return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
01956    case AST_DEVICE_RINGING:
01957       return AST_EXTENSION_RINGING;
01958    case AST_DEVICE_INUSE:
01959       return AST_EXTENSION_INUSE;
01960    case AST_DEVICE_NOT_INUSE:
01961       return AST_EXTENSION_NOT_INUSE;
01962    case AST_DEVICE_TOTAL: /* not a device state, included for completeness */
01963       break;
01964    }
01965 
01966    return AST_EXTENSION_NOT_INUSE;
01967 }

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

02283 {
02284    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
02285 }

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

04612 {
04613    if (!chan)
04614       return -1;
04615 
04616    ast_channel_lock(chan);
04617 
04618    if (!ast_strlen_zero(context))
04619       ast_copy_string(chan->context, context, sizeof(chan->context));
04620    if (!ast_strlen_zero(exten))
04621       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04622    if (priority > -1) {
04623       chan->priority = priority;
04624       /* see flag description in channel.h for explanation */
04625       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04626          chan->priority--;
04627    }
04628 
04629    ast_channel_unlock(chan);
04630 
04631    return 0;
04632 }

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

Definition at line 911 of file pbx.c.

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

Referenced by realtime_switch_common().

00912 {
00913    if (needmore != E_MATCHMORE && needmore != E_CANMATCH)
00914       ast_log(LOG_WARNING, "invalid argument %d\n", needmore);
00915    return extension_match_core(pattern, data, needmore);
00916 }

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

00907 {
00908    return extension_match_core(pattern, data, E_MATCH);
00909 }

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

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

02005 {
02006    struct ast_exten *e;
02007 
02008    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
02009    if (!e)
02010       return -1;           /* No hint, return -1 */
02011 
02012    return ast_extension_state2(e);        /* Check all devices in the hint */
02013 }

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

References extension_states.

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

01993 {
01994    int i;
01995 
01996    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
01997       if (extension_states[i].extension_state == extension_state)
01998          return extension_states[i].text;
01999    }
02000    return "Unknown";
02001 }

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

02063 {
02064    struct ast_hint *hint;
02065    struct ast_state_cb *cblist;
02066    struct ast_exten *e;
02067 
02068    /* If there's no context and extension:  add callback to statecbs list */
02069    if (!context && !exten) {
02070       AST_LIST_LOCK(&hints);
02071 
02072       for (cblist = statecbs; cblist; cblist = cblist->next) {
02073          if (cblist->callback == callback) {
02074             cblist->data = data;
02075             AST_LIST_UNLOCK(&hints);
02076             return 0;
02077          }
02078       }
02079 
02080       /* Now insert the callback */
02081       if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02082          AST_LIST_UNLOCK(&hints);
02083          return -1;
02084       }
02085       cblist->id = 0;
02086       cblist->callback = callback;
02087       cblist->data = data;
02088 
02089       cblist->next = statecbs;
02090       statecbs = cblist;
02091 
02092       AST_LIST_UNLOCK(&hints);
02093       return 0;
02094    }
02095 
02096    if (!context || !exten)
02097       return -1;
02098 
02099    /* This callback type is for only one hint, so get the hint */
02100    e = ast_hint_extension(NULL, context, exten);
02101    if (!e) {
02102       return -1;
02103    }
02104 
02105    /* Find the hint in the list of hints */
02106    AST_LIST_LOCK(&hints);
02107 
02108    AST_LIST_TRAVERSE(&hints, hint, list) {
02109       if (hint->exten == e)
02110          break;
02111    }
02112 
02113    if (!hint) {
02114       /* We have no hint, sorry */
02115       AST_LIST_UNLOCK(&hints);
02116       return -1;
02117    }
02118 
02119    /* Now insert the callback in the callback list  */
02120    if (!(cblist = ast_calloc(1, sizeof(*cblist)))) {
02121       AST_LIST_UNLOCK(&hints);
02122       return -1;
02123    }
02124    cblist->id = stateid++;    /* Unique ID for this callback */
02125    cblist->callback = callback;  /* Pointer to callback routine */
02126    cblist->data = data;    /* Data for the callback */
02127 
02128    cblist->next = hint->callbacks;
02129    hint->callbacks = cblist;
02130 
02131    AST_LIST_UNLOCK(&hints);
02132    return cblist->id;
02133 }

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

02137 {
02138    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
02139    int ret = -1;
02140 
02141    if (!id && !callback)
02142       return -1;
02143 
02144    AST_LIST_LOCK(&hints);
02145 
02146    if (!id) {  /* id == 0 is a callback without extension */
02147       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
02148          if ((*p_cur)->callback == callback)
02149             break;
02150       }
02151    } else { /* callback with extension, find the callback based on ID */
02152       struct ast_hint *hint;
02153       AST_LIST_TRAVERSE(&hints, hint, list) {
02154          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
02155             if ((*p_cur)->id == id)
02156                break;
02157          }
02158          if (*p_cur) /* found in the inner loop */
02159             break;
02160       }
02161    }
02162    if (p_cur && *p_cur) {
02163       struct ast_state_cb *cur = *p_cur;
02164       *p_cur = cur->next;
02165       free(cur);
02166       ret = 0;
02167    }
02168    AST_LIST_UNLOCK(&hints);
02169    return ret;
02170 }

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

02288 {
02289    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
02290 }

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

02293 {
02294    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
02295 }

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

01571 {
01572    char *args = func_args(function);
01573    struct ast_custom_function *acfptr = ast_custom_function_find(function);
01574 
01575    if (acfptr == NULL)
01576       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01577    else if (!acfptr->read)
01578       ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
01579    else
01580       return acfptr->read(chan, function, args, workspace, len);
01581    return -1;
01582 }

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

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

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 6319 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().

06320 {
06321    return con ? con->name : NULL;
06322 }

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6357 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06358 {
06359    return c ? c->registrar : NULL;
06360 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

Definition at line 6387 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().

06388 {
06389    return e ? e->app : NULL;
06390 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6392 of file pbx.c.

References ast_exten::data.

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

06393 {
06394    return e ? e->data : NULL;
06395 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6382 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().

06383 {
06384    return e ? e->cidmatch : NULL;
06385 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 6324 of file pbx.c.

References exten.

Referenced by handle_show_hints().

06325 {
06326    return exten ? exten->parent : NULL;
06327 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6334 of file pbx.c.

References exten.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06335 {
06336    return exten ? exten->label : NULL;
06337 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6377 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().

06378 {
06379    return e ? e->matchcid : 0;
06380 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

Definition at line 6329 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().

06330 {
06331    return exten ? exten->exten : NULL;
06332 }

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 6349 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().

06350 {
06351    return exten ? exten->priority : -1;
06352 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6362 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

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

02266 {
02267    struct ast_exten *e = ast_hint_extension(c, context, exten);
02268 
02269    if (e) {
02270       if (hint)
02271          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02272       if (name) {
02273          const char *tmp = ast_get_extension_app_data(e);
02274          if (tmp)
02275             ast_copy_string(name, tmp, namesize);
02276       }
02277       return -1;
02278    }
02279    return 0;
02280 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

Definition at line 6344 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().

06345 {
06346    return ip ? ip->pattern : NULL;
06347 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6372 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06373 {
06374    return ip ? ip->registrar : NULL;
06375 }

const char* ast_get_include_name ( struct ast_include include  ) 

Definition at line 6339 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().

06340 {
06341    return inc ? inc->name : NULL;
06342 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6367 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06368 {
06369    return i ? i->registrar : NULL;
06370 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6402 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06403 {
06404    return sw ? sw->data : NULL;
06405 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6397 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06398 {
06399    return sw ? sw->name : NULL;
06400 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6407 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06408 {
06409    return sw ? sw->registrar : NULL;
06410 }

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

06501 {
06502    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06503 }

void ast_hint_state_changed ( const char *  device  ) 

Definition at line 2015 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().

02016 {
02017    struct ast_hint *hint;
02018 
02019    ast_rdlock_contexts();
02020    AST_LIST_LOCK(&hints);
02021 
02022    AST_LIST_TRAVERSE(&hints, hint, list) {
02023       struct ast_state_cb *cblist;
02024       char buf[AST_MAX_EXTENSION];
02025       char *parse = buf;
02026       char *cur;
02027       int state;
02028 
02029       ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
02030       while ( (cur = strsep(&parse, "&")) ) {
02031          if (!strcasecmp(cur, device))
02032             break;
02033       }
02034       if (!cur)
02035          continue;
02036 
02037       /* Get device state for this hint */
02038       state = ast_extension_state2(hint->exten);
02039 
02040       if ((state == -1) || (state == hint->laststate))
02041          continue;
02042 
02043       /* Device state changed since last check - notify the watchers */
02044 
02045       /* For general callbacks */
02046       for (cblist = statecbs; cblist; cblist = cblist->next)
02047          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02048 
02049       /* For extension callbacks */
02050       for (cblist = hint->callbacks; cblist; cblist = cblist->next)
02051          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02052 
02053       hint->laststate = state;   /* record we saw the change */
02054    }
02055 
02056    AST_LIST_UNLOCK(&hints);
02057    ast_unlock_contexts();
02058 }

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

04578 {
04579    struct ast_context *con = ast_context_find(context);
04580    if (con) {
04581       struct ast_ignorepat *pat;
04582       for (pat = con->ignorepats; pat; pat = pat->next) {
04583          if (ast_extension_match(pat->pattern, pattern))
04584             return 1;
04585       }
04586    }
04587 
04588    return 0;
04589 }

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

06307 {
06308    return ast_mutex_lock(&con->lock);
06309 }

int ast_lock_contexts ( void   ) 

Locks the context list.

Return values:
0 on success
-1 on error

Definition at line 6283 of file pbx.c.

References ast_rwlock_wrlock(), and conlock.

Referenced by find_matching_endwhile().

06284 {
06285    return ast_rwlock_wrlock(&conlock);
06286 }

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

References E_MATCHMORE, and pbx_extension_helper().

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

02303 {
02304    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
02305 }

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

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

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

06511 {
06512    char *exten, *pri, *context;
06513    char *stringp;
06514    int ipri;
06515    int mode = 0;
06516 
06517    if (ast_strlen_zero(goto_string)) {
06518       ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
06519       return -1;
06520    }
06521    stringp = ast_strdupa(goto_string);
06522    context = strsep(&stringp, "|"); /* guaranteed non-null */
06523    exten = strsep(&stringp, "|");
06524    pri = strsep(&stringp, "|");
06525    if (!exten) {  /* Only a priority in this one */
06526       pri = context;
06527       exten = NULL;
06528       context = NULL;
06529    } else if (!pri) {   /* Only an extension and priority in this one */
06530       pri = exten;
06531       exten = context;
06532       context = NULL;
06533    }
06534    if (*pri == '+') {
06535       mode = 1;
06536       pri++;
06537    } else if (*pri == '-') {
06538       mode = -1;
06539       pri++;
06540    }
06541    if (sscanf(pri, "%30d", &ipri) != 1) {
06542       if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
06543          pri, chan->cid.cid_num)) < 1) {
06544          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
06545          return -1;
06546       } else
06547          mode = 0;
06548    }
06549    /* At this point we have a priority and maybe an extension and a context */
06550 
06551    if (mode)
06552       ipri = chan->priority + (ipri * mode);
06553 
06554    ast_explicit_goto(chan, context, exten, ipri);
06555    return 0;
06556 
06557 }

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

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

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

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

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

02663 {
02664    enum ast_pbx_result res = AST_PBX_SUCCESS;
02665 
02666    if (increase_call_count(c))
02667       return AST_PBX_CALL_LIMIT;
02668 
02669    res = __ast_pbx_run(c);
02670    decrease_call_count();
02671 
02672    return res;
02673 }

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

02636 {
02637    pthread_t t;
02638    pthread_attr_t attr;
02639 
02640    if (!c) {
02641       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02642       return AST_PBX_FAILED;
02643    }
02644 
02645    if (increase_call_count(c))
02646       return AST_PBX_CALL_LIMIT;
02647 
02648    /* Start a new thread, and get something handling this channel. */
02649    pthread_attr_init(&attr);
02650    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02651    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02652       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02653       pthread_attr_destroy(&attr);
02654       decrease_call_count();
02655       return AST_PBX_FAILED;
02656    }
02657    pthread_attr_destroy(&attr);
02658 
02659    return AST_PBX_SUCCESS;
02660 }

int ast_processed_calls ( void   ) 

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

Definition at line 2680 of file pbx.c.

References totalcalls.

02681 {
02682    return totalcalls;
02683 }

int ast_rdlock_contexts ( void   ) 

Definition at line 6288 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().

06289 {
06290    return ast_rwlock_rdlock(&conlock);
06291 }

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

02970 {
02971    struct ast_app *tmp, *cur = NULL;
02972    char tmps[80];
02973    int length;
02974 
02975    AST_LIST_LOCK(&apps);
02976    AST_LIST_TRAVERSE(&apps, tmp, list) {
02977       if (!strcasecmp(app, tmp->name)) {
02978          ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
02979          AST_LIST_UNLOCK(&apps);
02980          return -1;
02981       }
02982    }
02983 
02984    length = sizeof(*tmp) + strlen(app) + 1;
02985 
02986    if (!(tmp = ast_calloc(1, length))) {
02987       AST_LIST_UNLOCK(&apps);
02988       return -1;
02989    }
02990 
02991    strcpy(tmp->name, app);
02992    tmp->execute = execute;
02993    tmp->synopsis = synopsis;
02994    tmp->description = description;
02995 
02996    /* Store in alphabetical order */
02997    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
02998       if (strcasecmp(tmp->name, cur->name) < 0) {
02999          AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list);
03000          break;
03001       }
03002    }
03003    AST_LIST_TRAVERSE_SAFE_END
03004    if (!cur)
03005       AST_LIST_INSERT_TAIL(&apps, tmp, list);
03006 
03007    if (option_verbose > 1)
03008       ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
03009 
03010    AST_LIST_UNLOCK(&apps);
03011 
03012    return 0;
03013 }

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

03020 {
03021    struct ast_switch *tmp;
03022 
03023    AST_LIST_LOCK(&switches);
03024    AST_LIST_TRAVERSE(&switches, tmp, list) {
03025       if (!strcasecmp(tmp->name, sw->name)) {
03026          AST_LIST_UNLOCK(&switches);
03027          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
03028          return -1;
03029       }
03030    }
03031    AST_LIST_INSERT_TAIL(&switches, sw, list);
03032    AST_LIST_UNLOCK(&switches);
03033 
03034    return 0;
03035 }

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

References E_SPAWN, and pbx_extension_helper().

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

02308 {
02309    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
02310 }

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

06312 {
06313    return ast_mutex_unlock(&con->lock);
06314 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 6298 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().

06299 {
06300    return ast_rwlock_unlock(&conlock);
06301 }

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

03885 {
03886    struct ast_app *tmp;
03887 
03888    AST_LIST_LOCK(&apps);
03889    AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) {
03890       if (!strcasecmp(app, tmp->name)) {
03891          AST_LIST_REMOVE_CURRENT(&apps, list);
03892          if (option_verbose > 1)
03893             ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
03894          free(tmp);
03895          break;
03896       }
03897    }
03898    AST_LIST_TRAVERSE_SAFE_END
03899    AST_LIST_UNLOCK(&apps);
03900 
03901    return tmp ? 0 : -1;
03902 }

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

03038 {
03039    AST_LIST_LOCK(&switches);
03040    AST_LIST_REMOVE(&switches, sw, list);
03041    AST_LIST_UNLOCK(&switches);
03042 }

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

Definition at line 6420 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().

06422 {
06423    if (!exten)
06424       return con ? con->root : NULL;
06425    else
06426       return exten->next;
06427 }

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

Definition at line 6453 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().

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

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

Definition at line 6444 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().

06446 {
06447    if (!inc)
06448       return con ? con->includes : NULL;
06449    else
06450       return inc->next;
06451 }

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

Definition at line 6429 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().

06431 {
06432    if (!sw)
06433       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06434    else
06435       return AST_LIST_NEXT(sw, list);
06436 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

Definition at line 6415 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().

06416 {
06417    return con ? con->next : contexts;
06418 }

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

Definition at line 6438 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().

06440 {
06441    return priority ? priority->peer : exten;
06442 }

int ast_wrlock_contexts ( void   ) 

Definition at line 6293 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().

06294 {
06295    return ast_rwlock_wrlock(&conlock);
06296 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 6059 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().

06060 {
06061    struct ast_var_t *vardata;
06062 
06063    ast_mutex_lock(&globalslock);
06064    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
06065       ast_var_delete(vardata);
06066    ast_mutex_unlock(&globalslock);
06067 }

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

Note:
Will lock the channel.

Definition at line 5836 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(), 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(), 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().

05837 {
05838    struct ast_var_t *variables;
05839    const char *ret = NULL;
05840    int i;
05841    struct varshead *places[2] = { NULL, &globals };
05842 
05843    if (!name)
05844       return NULL;
05845 
05846    if (chan) {
05847       ast_channel_lock(chan);
05848       places[0] = &chan->varshead;
05849    }
05850 
05851    for (i = 0; i < 2; i++) {
05852       if (!places[i])
05853          continue;
05854       if (places[i] == &globals)
05855          ast_mutex_lock(&globalslock);
05856       AST_LIST_TRAVERSE(places[i], variables, entries) {
05857          if (!strcmp(name, ast_var_name(variables))) {
05858             ret = ast_var_value(variables);
05859             break;
05860          }
05861       }
05862       if (places[i] == &globals)
05863          ast_mutex_unlock(&globalslock);
05864       if (ret)
05865          break;
05866    }
05867 
05868    if (chan)
05869       ast_channel_unlock(chan);
05870 
05871    return ret;
05872 }

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

Note:
Will lock the channel.

Definition at line 5874 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().

05875 {
05876    struct ast_var_t *newvariable;
05877    struct varshead *headp;
05878 
05879    if (name[strlen(name)-1] == ')') {
05880       char *function = ast_strdupa(name);
05881 
05882       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05883       ast_func_write(chan, function, value);
05884       return;
05885    }
05886 
05887    if (chan) {
05888       ast_channel_lock(chan);
05889       headp = &chan->varshead;
05890    } else {
05891       ast_mutex_lock(&globalslock);
05892       headp = &globals;
05893    }
05894 
05895    if (value) {
05896       if ((option_verbose > 1) && (headp == &globals))
05897          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05898       newvariable = ast_var_assign(name, value);
05899       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05900    }
05901 
05902    if (chan)
05903       ast_channel_unlock(chan);
05904    else
05905       ast_mutex_unlock(&globalslock);
05906 }

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

Note:
Will lock the channel.

Definition at line 5805 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().

05806 {
05807    struct ast_var_t *variables;
05808    const char *var, *val;
05809    int total = 0;
05810 
05811    if (!chan)
05812       return 0;
05813 
05814    memset(buf, 0, size);
05815 
05816    ast_channel_lock(chan);
05817 
05818    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05819       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05820          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05821          ) {
05822          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05823             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05824             break;
05825          } else
05826             total++;
05827       } else
05828          break;
05829    }
05830 
05831    ast_channel_unlock(chan);
05832 
05833    return total;
05834 }

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

05909 {
05910    struct ast_var_t *newvariable;
05911    struct varshead *headp;
05912    const char *nametail = name;
05913 
05914    if (name[strlen(name)-1] == ')') {
05915       char *function = ast_strdupa(name);
05916 
05917       ast_func_write(chan, function, value);
05918       return;
05919    }
05920 
05921    if (chan) {
05922       ast_channel_lock(chan);
05923       headp = &chan->varshead;
05924    } else {
05925       ast_mutex_lock(&globalslock);
05926       headp = &globals;
05927    }
05928 
05929    /* For comparison purposes, we have to strip leading underscores */
05930    if (*nametail == '_') {
05931       nametail++;
05932       if (*nametail == '_')
05933          nametail++;
05934    }
05935 
05936    AST_LIST_TRAVERSE (headp, newvariable, entries) {
05937       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
05938          /* there is already such a variable, delete it */
05939          AST_LIST_REMOVE(headp, newvariable, entries);
05940          ast_var_delete(newvariable);
05941          break;
05942       }
05943    }
05944 
05945    if (value) {
05946       if ((option_verbose > 1) && (headp == &globals))
05947          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05948       newvariable = ast_var_assign(name, value);
05949       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05950    }
05951 
05952    if (chan)
05953       ast_channel_unlock(chan);
05954    else
05955       ast_mutex_unlock(&globalslock);
05956 }

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

06070 {
06071    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
06072       return 0;
06073    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
06074       return atoi(condition);
06075    else  /* Strings are true */
06076       return 1;
06077 }

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(), milliwatt_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(), milliwatt_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 1174 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().

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

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

References autofallthrough.

Referenced by pbx_load_module().

02686 {
02687    int oldval = autofallthrough;
02688    autofallthrough = newval;
02689    return oldval;
02690 }

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

Definition at line 1794 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().

01795 {
01796    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
01797 }

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

Definition at line 1799 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

01800 {
01801    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01802 }


Generated on Fri Sep 11 13:45:37 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7