Thu Dec 17 13:34:02 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 2695 of file pbx.c.

References countcalls.

Referenced by handle_chanlist(), and handle_chanlist_deprecated().

02696 {
02697    return countcalls;
02698 }

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

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

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

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

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

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

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

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

Definition at line 4707 of file pbx.c.

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

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

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

References __ast_goto_if_exists().

Referenced by asyncgoto_exec().

06526 {
06527    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06528 }

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

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

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

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

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

int ast_check_timing ( const struct ast_timing i  ) 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

References __ast_context_create().

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

03971 {
03972    return __ast_context_create(extcontexts, name, registrar, 0);
03973 }

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

05413 {
05414    ast_wrlock_contexts();
05415    __ast_context_destroy(con,registrar);
05416    ast_unlock_contexts();
05417 }

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

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

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

Definition at line 3975 of file pbx.c.

References __ast_context_create().

Referenced by pbx_load_config(), and pbx_load_users().

03976 {
03977    return __ast_context_create(extcontexts, name, registrar, 1);
03978 }

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

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

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

References ast_context_remove_extension_callerid().

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

02839 {
02840    return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar);
02841 }

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

References ast_context_remove_extension_callerid2().

Referenced by do_parking_thread(), and park_exec().

02866 {
02867    return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar);
02868 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

06483 {
06484    struct ast_include *inc = NULL;
06485    int res = 0;
06486 
06487    while ( (inc = ast_walk_context_includes(con, inc)) ) {
06488       if (ast_context_find(inc->rname))
06489          continue;
06490 
06491       res = -1;
06492       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
06493          ast_get_context_name(con), inc->rname);
06494       break;
06495    }
06496 
06497    return res;
06498 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

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

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

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

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

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

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

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

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

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

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

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

References E_MATCH, and pbx_extension_helper().

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

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

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

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

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

Definition at line 929 of file pbx.c.

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

Referenced by realtime_switch_common().

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

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

00925 {
00926    return extension_match_core(pattern, data, E_MATCH);
00927 }

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

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

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

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

References extension_states.

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

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

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

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

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

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

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

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

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

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

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

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

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

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

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

const char* ast_get_context_name ( struct ast_context con  ) 

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

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

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6377 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06378 {
06379    return c ? c->registrar : NULL;
06380 }

const char* ast_get_extension_app ( struct ast_exten e  ) 

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

06408 {
06409    return e ? e->app : NULL;
06410 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6412 of file pbx.c.

References ast_exten::data.

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

06413 {
06414    return e ? e->data : NULL;
06415 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

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

06403 {
06404    return e ? e->cidmatch : NULL;
06405 }

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 6344 of file pbx.c.

References exten.

Referenced by handle_show_hints().

06345 {
06346    return exten ? exten->parent : NULL;
06347 }

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6354 of file pbx.c.

References exten.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06355 {
06356    return exten ? exten->label : NULL;
06357 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

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

06398 {
06399    return e ? e->matchcid : 0;
06400 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

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

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

int ast_get_extension_priority ( struct ast_exten exten  ) 

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

06370 {
06371    return exten ? exten->priority : -1;
06372 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6382 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

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

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

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

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

06365 {
06366    return ip ? ip->pattern : NULL;
06367 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6392 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06393 {
06394    return ip ? ip->registrar : NULL;
06395 }

const char* ast_get_include_name ( struct ast_include include  ) 

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

06360 {
06361    return inc ? inc->name : NULL;
06362 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6387 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06388 {
06389    return i ? i->registrar : NULL;
06390 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6422 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06423 {
06424    return sw ? sw->data : NULL;
06425 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6417 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06418 {
06419    return sw ? sw->name : NULL;
06420 }

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6427 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06428 {
06429    return sw ? sw->registrar : NULL;
06430 }

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

06521 {
06522    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06523 }

void ast_hint_state_changed ( const char *  device  ) 

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

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

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

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

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

06327 {
06328    return ast_mutex_lock(&con->lock);
06329 }

int ast_lock_contexts ( void   ) 

Locks the context list.

Return values:
0 on success
-1 on error

Definition at line 6303 of file pbx.c.

References ast_rwlock_wrlock(), and conlock.

Referenced by find_matching_endwhile().

06304 {
06305    return ast_rwlock_wrlock(&conlock);
06306 }

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

References E_MATCHMORE, and pbx_extension_helper().

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

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

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

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

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

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

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

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

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

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

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

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

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

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

int ast_processed_calls ( void   ) 

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

Definition at line 2700 of file pbx.c.

References totalcalls.

02701 {
02702    return totalcalls;
02703 }

int ast_rdlock_contexts ( void   ) 

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

06309 {
06310    return ast_rwlock_rdlock(&conlock);
06311 }

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

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

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

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

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

References E_SPAWN, and pbx_extension_helper().

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

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

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

06332 {
06333    return ast_mutex_unlock(&con->lock);
06334 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

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

06319 {
06320    return ast_rwlock_unlock(&conlock);
06321 }

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

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

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

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

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

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

06442 {
06443    if (!exten)
06444       return con ? con->root : NULL;
06445    else
06446       return exten->next;
06447 }

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

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

06475 {
06476    if (!ip)
06477       return con ? con->ignorepats : NULL;
06478    else
06479       return ip->next;
06480 }

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

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

06466 {
06467    if (!inc)
06468       return con ? con->includes : NULL;
06469    else
06470       return inc->next;
06471 }

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

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

06451 {
06452    if (!sw)
06453       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06454    else
06455       return AST_LIST_NEXT(sw, list);
06456 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

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

06436 {
06437    return con ? con->next : contexts;
06438 }

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

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

06460 {
06461    return priority ? priority->peer : exten;
06462 }

int ast_wrlock_contexts ( void   ) 

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

06314 {
06315    return ast_rwlock_wrlock(&conlock);
06316 }

void pbx_builtin_clear_globals ( void   ) 

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

06080 {
06081    struct ast_var_t *vardata;
06082 
06083    ast_mutex_lock(&globalslock);
06084    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
06085       ast_var_delete(vardata);
06086    ast_mutex_unlock(&globalslock);
06087 }

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

Note:
Will lock the channel.

Definition at line 5856 of file pbx.c.

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

Referenced by __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_call_forward(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dahdi_r2_answer(), dahdi_r2_get_channel_category(), dundi_exec(), dundi_helper(), feature_interpret(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), macro_fixup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), park_space_reserve(), 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().

05857 {
05858    struct ast_var_t *variables;
05859    const char *ret = NULL;
05860    int i;
05861    struct varshead *places[2] = { NULL, &globals };
05862 
05863    if (!name)
05864       return NULL;
05865 
05866    if (chan) {
05867       ast_channel_lock(chan);
05868       places[0] = &chan->varshead;
05869    }
05870 
05871    for (i = 0; i < 2; i++) {
05872       if (!places[i])
05873          continue;
05874       if (places[i] == &globals)
05875          ast_mutex_lock(&globalslock);
05876       AST_LIST_TRAVERSE(places[i], variables, entries) {
05877          if (!strcmp(name, ast_var_name(variables))) {
05878             ret = ast_var_value(variables);
05879             break;
05880          }
05881       }
05882       if (places[i] == &globals)
05883          ast_mutex_unlock(&globalslock);
05884       if (ret)
05885          break;
05886    }
05887 
05888    if (chan)
05889       ast_channel_unlock(chan);
05890 
05891    return ret;
05892 }

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

Note:
Will lock the channel.

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

05895 {
05896    struct ast_var_t *newvariable;
05897    struct varshead *headp;
05898 
05899    if (name[strlen(name)-1] == ')') {
05900       char *function = ast_strdupa(name);
05901 
05902       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05903       ast_func_write(chan, function, value);
05904       return;
05905    }
05906 
05907    if (chan) {
05908       ast_channel_lock(chan);
05909       headp = &chan->varshead;
05910    } else {
05911       ast_mutex_lock(&globalslock);
05912       headp = &globals;
05913    }
05914 
05915    if (value) {
05916       if ((option_verbose > 1) && (headp == &globals))
05917          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05918       newvariable = ast_var_assign(name, value);
05919       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05920    }
05921 
05922    if (chan)
05923       ast_channel_unlock(chan);
05924    else
05925       ast_mutex_unlock(&globalslock);
05926 }

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

Note:
Will lock the channel.

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

05826 {
05827    struct ast_var_t *variables;
05828    const char *var, *val;
05829    int total = 0;
05830 
05831    if (!chan)
05832       return 0;
05833 
05834    memset(buf, 0, size);
05835 
05836    ast_channel_lock(chan);
05837 
05838    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05839       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05840          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05841          ) {
05842          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05843             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05844             break;
05845          } else
05846             total++;
05847       } else
05848          break;
05849    }
05850 
05851    ast_channel_unlock(chan);
05852 
05853    return total;
05854 }

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

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

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

06090 {
06091    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
06092       return 0;
06093    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
06094       return atoi(condition);
06095    else  /* Strings are true */
06096       return 1;
06097 }

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

Execute an application.

Parameters:
c channel to execute on
app which app to execute
data the data passed into the app
This application executes an application on a given channel. It saves the stack and executes the given appliation passing in the given data.

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

Definition at line 537 of file pbx.c.

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

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

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

struct ast_app* pbx_findapp ( const char *  app  ) 

Look up an application.

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

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

Definition at line 575 of file pbx.c.

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

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

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

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

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

Note:
Will lock the channel.

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

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

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

References autofallthrough.

Referenced by pbx_load_module().

02706 {
02707    int oldval = autofallthrough;
02708    autofallthrough = newval;
02709    return oldval;
02710 }

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

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

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

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

Definition at line 1817 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

01818 {
01819    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01820 }


Generated on Thu Dec 17 13:34:03 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7