Sat Mar 24 23:29:53 2007

Asterisk developer's documentation


pbx.h File Reference

Core PBX routines and definitions. More...

#include "asterisk/sched.h"
#include "asterisk/channel.h"

Include dependency graph for pbx.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_custom_function
struct  ast_pbx
struct  ast_switch
struct  ast_timing
struct  cfextension_states

Defines

#define AST_MAX_APP   32
#define AST_PBX_KEEP   0
#define AST_PBX_KEEPALIVE   10
#define AST_PBX_NO_HANGUP_PEER   11
#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)

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
}
enum  ast_pbx_result { AST_PBX_SUCCESS = 0, AST_PBX_FAILED = -1, AST_PBX_CALL_LIMIT = -2 }

Functions

int ast_active_calls (void)
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)
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)
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, char *context, char *exten, int priority)
int ast_build_timing (struct ast_timing *i, char *info)
int ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
int ast_check_timing (struct ast_timing *i)
int ast_context_add_ignorepat (const char *context, const char *ignorepat, const char *registrar)
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)
int ast_context_add_include2 (struct ast_context *con, const char *include, const char *registrar)
int ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar)
int ast_context_add_switch2 (struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
ast_contextast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar)
void ast_context_destroy (struct ast_context *con, const char *registrar)
ast_contextast_context_find (const char *name)
int ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar)
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_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)
int ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar)
int ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar)
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_verify_includes (struct ast_context *con)
ast_custom_functionast_custom_function_find (char *name)
int ast_custom_function_register (struct ast_custom_function *acf)
int ast_custom_function_unregister (struct ast_custom_function *acf)
int ast_exec_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
int ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
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)
int ast_extension_patmatch (const char *pattern, const char *data)
int ast_extension_state (struct ast_channel *c, char *context, char *exten)
 ast_extension_state: Check extension state for an extension by using hint
const char * ast_extension_state2str (int extension_state)
 ast_extension_state2str: Return extension_state as string
int ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data)
 ast_extension_state_add: Add watcher for extension states
int ast_extension_state_del (int id, ast_state_cb_type callback)
 ast_extension_state_del: Remove a watcher from the callback list
int ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
int ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
char * ast_func_read (struct ast_channel *chan, const char *in, char *workspace, size_t len)
void ast_func_write (struct ast_channel *chan, const char *in, const char *value)
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)
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)
 ast_get_hint: Get hint for channel
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, char *context, char *exten, int priority)
void ast_hint_state_changed (const char *device)
int ast_ignore_pattern (const char *context, const char *pattern)
int ast_lock_context (struct ast_context *con)
int ast_lock_contexts (void)
int ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
void ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar)
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)
enum ast_pbx_result ast_pbx_start (struct ast_channel *c)
int ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
 Dynamically register a new dial plan application.
int ast_register_switch (struct ast_switch *sw)
int ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
int ast_unlock_context (struct ast_context *con)
int ast_unlock_contexts (void)
int ast_unregister_application (const char *app)
void ast_unregister_switch (struct ast_switch *sw)
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)
void pbx_builtin_clear_globals (void)
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 (char *condition)
int pbx_exec (struct ast_channel *c, struct ast_app *app, void *data, int newstack)
ast_apppbx_findapp (const char *app)
 Find application handle in linked list.
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 and functions in the dialplan ---
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)

Variables

static const struct cfextension_states extension_states []


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

Referenced by handle_show_application(), and handle_show_function().

#define AST_PBX_KEEP   0
 

Definition at line 33 of file pbx.h.

#define AST_PBX_KEEPALIVE   10
 

Special return values from applications to the PBX

Definition at line 40 of file pbx.h.

Referenced by agi_handle_command(), builtin_blindtransfer(), macro_exec(), park_call_exec(), and run_agi().

#define AST_PBX_NO_HANGUP_PEER   11
 

Definition at line 41 of file pbx.h.

Referenced by builtin_blindtransfer(), and park_exec().

#define AST_PBX_REPLACE   1
 

Definition at line 34 of file pbx.h.

#define PRIORITY_HINT   -1
 

Special Priority for an hint

Definition at line 44 of file pbx.h.

Referenced by ast_add_extension2(), ast_context_remove_extension2(), ast_hint_extension(), destroy_exten(), handle_context_add_extension(), handle_context_remove_extension(), handle_save_dialplan(), pbx_load_module(), and show_dialplan_helper().


Typedef Documentation

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

Definition at line 83 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

Definition at line 47 of file pbx.h.

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

enum ast_pbx_result
 

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 209 of file pbx.h.

00209                     {
00210    AST_PBX_SUCCESS = 0,
00211    AST_PBX_FAILED = -1,
00212    AST_PBX_CALL_LIMIT = -2,
00213 };


Function Documentation

int ast_active_calls void   ) 
 

Definition at line 2559 of file pbx.c.

Referenced by handle_chanlist().

02560 {
02561    return countcalls;
02562 }

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
 

Parameters:
context context to add the extension to
replace 
extension extension to add
priority priority level of extension addition
label extension label
callerid callerid of extension
application application to run on the extension with that priority level
data data to pass to the application
datad 
registrar who registered the extension Add and extension to an extension context. Callerid is a pattern to match CallerID, or NULL to match any callerid Returns 0 on success, -1 on failure

Definition at line 4502 of file pbx.c.

References ast_add_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by handle_context_add_extension(), and register_peer_exten().

04504 {
04505    struct ast_context *c;
04506 
04507    if (ast_lock_contexts()) {
04508       errno = EBUSY;
04509       return -1;
04510    }
04511 
04512    c = ast_walk_contexts(NULL);
04513    while (c) {
04514       if (!strcmp(context, ast_get_context_name(c))) {
04515          int ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04516             application, data, datad, registrar);
04517          ast_unlock_contexts();
04518          return ret;
04519       }
04520       c = ast_walk_contexts(c);
04521    }
04522 
04523    ast_unlock_contexts();
04524    errno = ENOENT;
04525    return -1;
04526 }

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
 

For details about the arguements, check ast_add_extension()

Definition at line 4641 of file pbx.c.

References ast_add_hint(), ast_change_hint(), AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, ext_strncpy(), ast_exten::exten, free, ast_context::lock, LOG, LOG_ERROR, LOG_WARNING, malloc, ast_exten::matchcid, ast_context::name, ast_exten::next, null_datad(), pbx_substitute_variables_varshead(), ast_exten::peer, ast_exten::priority, PRIORITY_HINT, ast_context::registrar, ast_context::root, and VAR_BUF_SIZE.

Referenced by __build_step(), ast_add_extension(), do_parking_thread(), fillin_process(), handle_macro(), load_config(), and pbx_load_module().

04645 {
04646 
04647 #define LOG do {  if (option_debug) {\
04648       if (tmp->matchcid) { \
04649          ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \
04650       } else { \
04651          ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
04652       } \
04653    } else if (option_verbose > 2) { \
04654       if (tmp->matchcid) { \
04655          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \
04656       } else {  \
04657          ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \
04658       } \
04659    } } while(0)
04660 
04661    /*
04662     * This is a fairly complex routine.  Different extensions are kept
04663     * in order by the extension number.  Then, extensions of different
04664     * priorities (same extension) are kept in a list, according to the
04665     * peer pointer.
04666     */
04667    struct ast_exten *tmp, *e, *el = NULL, *ep = NULL;
04668    int res;
04669    int length;
04670    char *p;
04671    char expand_buf[VAR_BUF_SIZE] = { 0, };
04672 
04673    /* if we are adding a hint, and there are global variables, and the hint
04674       contains variable references, then expand them
04675    */
04676    ast_mutex_lock(&globalslock);
04677    if ((priority == PRIORITY_HINT) && AST_LIST_FIRST(&globals) && strstr(application, "${")) {
04678       pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf));
04679       application = expand_buf;
04680    }
04681    ast_mutex_unlock(&globalslock);
04682 
04683    length = sizeof(struct ast_exten);
04684    length += strlen(extension) + 1;
04685    length += strlen(application) + 1;
04686    if (label)
04687       length += strlen(label) + 1;
04688    if (callerid)
04689       length += strlen(callerid) + 1;
04690    else
04691       length ++;
04692 
04693    /* Be optimistic:  Build the extension structure first */
04694    if (datad == NULL)
04695       datad = null_datad;
04696    tmp = malloc(length);
04697    if (tmp) {
04698       memset(tmp, 0, length);
04699       p = tmp->stuff;
04700       if (label) {
04701          tmp->label = p;
04702          strcpy(tmp->label, label);
04703          p += strlen(label) + 1;
04704       }
04705       tmp->exten = p;
04706       p += ext_strncpy(tmp->exten, extension, strlen(extension) + 1) + 1;
04707       tmp->priority = priority;
04708       tmp->cidmatch = p;
04709       if (callerid) {
04710          p += ext_strncpy(tmp->cidmatch, callerid, strlen(callerid) + 1) + 1;
04711          tmp->matchcid = 1;
04712       } else {
04713          tmp->cidmatch[0] = '\0';
04714          tmp->matchcid = 0;
04715          p++;
04716       }
04717       tmp->app = p;
04718       strcpy(tmp->app, application);
04719       tmp->parent = con;
04720       tmp->data = data;
04721       tmp->datad = datad;
04722       tmp->registrar = registrar;
04723       tmp->peer = NULL;
04724       tmp->next =  NULL;
04725    } else {
04726       ast_log(LOG_ERROR, "Out of memory\n");
04727       errno = ENOMEM;
04728       return -1;
04729    }
04730    if (ast_mutex_lock(&con->lock)) {
04731       free(tmp);
04732       /* And properly destroy the data */
04733       datad(data);
04734       ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name);
04735       errno = EBUSY;
04736       return -1;
04737    }
04738    e = con->root;
04739    while(e) {
04740       /* Make sure patterns are always last! */
04741       if ((e->exten[0] != '_') && (extension[0] == '_'))
04742          res = -1;
04743       else if ((e->exten[0] == '_') && (extension[0] != '_'))
04744          res = 1;
04745       else
04746          res= strcmp(e->exten, extension);
04747       if (!res) {
04748          if (!e->matchcid && !tmp->matchcid)
04749             res = 0;
04750          else if (tmp->matchcid && !e->matchcid)
04751             res = 1;
04752          else if (e->matchcid && !tmp->matchcid)
04753             res = -1;
04754          else
04755             res = strcasecmp(e->cidmatch, tmp->cidmatch);
04756       }
04757       if (res == 0) {
04758          /* We have an exact match, now we find where we are
04759             and be sure there's no duplicates */
04760          while(e) {
04761             if (e->priority == tmp->priority) {
04762                /* Can't have something exactly the same.  Is this a
04763                   replacement?  If so, replace, otherwise, bonk. */
04764                if (replace) {
04765                   if (ep) {
04766                      /* We're in the peer list, insert ourselves */
04767                      ep->peer = tmp;
04768                      tmp->peer = e->peer;
04769                   } else if (el) {
04770                      /* We're the first extension. Take over e's functions */
04771                      el->next = tmp;
04772                      tmp->next = e->next;
04773                      tmp->peer = e->peer;
04774                   } else {
04775                      /* We're the very first extension.  */
04776                      con->root = tmp;
04777                      tmp->next = e->next;
04778                      tmp->peer = e->peer;
04779                   }
04780                   if (tmp->priority == PRIORITY_HINT)
04781                       ast_change_hint(e,tmp);
04782                   /* Destroy the old one */
04783                   e->datad(e->data);
04784                   free(e);
04785                   ast_mutex_unlock(&con->lock);
04786                   if (tmp->priority == PRIORITY_HINT)
04787                       ast_change_hint(e, tmp);
04788                   /* And immediately return success. */
04789                   LOG;
04790                   return 0;
04791                } else {
04792                   ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name);
04793                   tmp->datad(tmp->data);
04794                   free(tmp);
04795                   ast_mutex_unlock(&con->lock);
04796                   errno = EEXIST;
04797                   return -1;
04798                }
04799             } else if (e->priority > tmp->priority) {
04800                /* Slip ourselves in just before e */
04801                if (ep) {
04802                   /* Easy enough, we're just in the peer list */
04803                   ep->peer = tmp;
04804                   tmp->peer = e;
04805                } else if (el) {
04806                   /* We're the first extension in this peer list */
04807                   el->next = tmp;
04808                   tmp->next = e->next;
04809                   e->next = NULL;
04810                   tmp->peer = e;
04811                } else {
04812                   /* We're the very first extension altogether */
04813                   tmp->next = con->root->next;
04814                   /* Con->root must always exist or we couldn't get here */
04815                   tmp->peer = con->root;
04816                   con->root = tmp;
04817                }
04818                ast_mutex_unlock(&con->lock);
04819 
04820                /* And immediately return success. */
04821                if (tmp->priority == PRIORITY_HINT)
04822                    ast_add_hint(tmp);
04823                
04824                LOG;
04825                return 0;
04826             }
04827             ep = e;
04828             e = e->peer;
04829          }
04830          /* If we make it here, then it's time for us to go at the very end.
04831             ep *must* be defined or we couldn't have gotten here. */
04832          ep->peer = tmp;
04833          ast_mutex_unlock(&con->lock);
04834          if (tmp->priority == PRIORITY_HINT)
04835             ast_add_hint(tmp);
04836          
04837          /* And immediately return success. */
04838          LOG;
04839          return 0;
04840             
04841       } else if (res > 0) {
04842          /* Insert ourselves just before 'e'.  We're the first extension of
04843             this kind */
04844          tmp->next = e;
04845          if (el) {
04846             /* We're in the list somewhere */
04847             el->next = tmp;
04848          } else {
04849             /* We're at the top of the list */
04850             con->root = tmp;
04851          }
04852          ast_mutex_unlock(&con->lock);
04853          if (tmp->priority == PRIORITY_HINT)
04854             ast_add_hint(tmp);
04855 
04856          /* And immediately return success. */
04857          LOG;
04858          return 0;
04859       }        
04860          
04861       el = e;
04862       e = e->next;
04863    }
04864    /* If we fall all the way through to here, then we need to be on the end. */
04865    if (el)
04866       el->next = tmp;
04867    else
04868       con->root = tmp;
04869    ast_mutex_unlock(&con->lock);
04870    if (tmp->priority == PRIORITY_HINT)
04871       ast_add_hint(tmp);
04872    LOG;
04873    return 0;   
04874 }

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

Definition at line 4547 of file pbx.c.

References ast_channel::_state, ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_strlen_zero(), ast_channel::context, ast_channel::exten, ast_channel::lock, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::readformat, and ast_channel::writeformat.

Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), handle_request_bye(), handle_request_refer(), misdn_tx2ast_frm(), monitor_handle_owned(), socket_read(), and zt_read().

04548 {
04549    int res = 0;
04550 
04551    ast_mutex_lock(&chan->lock);
04552 
04553    if (chan->pbx) {
04554       /* This channel is currently in the PBX */
04555       ast_explicit_goto(chan, context, exten, priority);
04556       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
04557    } else {
04558       /* In order to do it when the channel doesn't really exist within
04559          the PBX, we have to make a new channel, masquerade, and start the PBX
04560          at the new location */
04561       struct ast_channel *tmpchan;
04562       tmpchan = ast_channel_alloc(0);
04563       if (tmpchan) {
04564          snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name);
04565          ast_setstate(tmpchan, chan->_state);
04566          /* Make formats okay */
04567          tmpchan->readformat = chan->readformat;
04568          tmpchan->writeformat = chan->writeformat;
04569          /* Setup proper location */
04570          ast_explicit_goto(tmpchan,
04571                  (!ast_strlen_zero(context)) ? context : chan->context,
04572                  (!ast_strlen_zero(exten)) ? exten : chan->exten,
04573                  priority);
04574 
04575          /* Masquerade into temp channel */
04576          ast_channel_masquerade(tmpchan, chan);
04577       
04578          /* Grab the locks and get going */
04579          ast_mutex_lock(&tmpchan->lock);
04580          ast_do_masquerade(tmpchan);
04581          ast_mutex_unlock(&tmpchan->lock);
04582          /* Start the PBX going on our stolen channel */
04583          if (ast_pbx_start(tmpchan)) {
04584             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
04585             ast_hangup(tmpchan);
04586             res = -1;
04587          }
04588       } else {
04589          res = -1;
04590       }
04591    }
04592    ast_mutex_unlock(&chan->lock);
04593    return res;
04594 }

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

Definition at line 4596 of file pbx.c.

References ast_async_goto(), ast_get_channel_by_name_locked(), ast_mutex_unlock(), and ast_channel::lock.

04597 {
04598    struct ast_channel *chan;
04599    int res = -1;
04600 
04601    chan = ast_get_channel_by_name_locked(channame);
04602    if (chan) {
04603       res = ast_async_goto(chan, context, exten, priority);
04604       ast_mutex_unlock(&chan->lock);
04605    }
04606    return res;
04607 }

int ast_async_goto_if_exists struct ast_channel chan,
char *  context,
char *  exten,
int  priority
 

Definition at line 6466 of file pbx.c.

References __ast_goto_if_exists().

06466                                                                                                  {
06467    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06468 }

int ast_build_timing struct ast_timing i,
char *  info
 

Definition at line 4080 of file pbx.c.

References ast_strlen_zero(), ast_timing::daymask, ast_timing::dowmask, FIND_NEXT, get_day(), get_dow(), get_month(), get_timerange(), and ast_timing::monthmask.

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

04081 {
04082    char info_save[256];
04083    char *info;
04084    char *c;
04085 
04086    /* Check for empty just in case */
04087    if (ast_strlen_zero(info_in))
04088       return 0;
04089    /* make a copy just in case we were passed a static string */
04090    ast_copy_string(info_save, info_in, sizeof(info_save));
04091    info = info_save;
04092    /* Assume everything except time */
04093    i->monthmask = (1 << 12) - 1;
04094    i->daymask = (1 << 30) - 1 + (1 << 30);
04095    i->dowmask = (1 << 7) - 1;
04096    /* Avoid using str tok */
04097    FIND_NEXT;
04098    /* Info has the time range, start with that */
04099    get_timerange(i, info);
04100    info = c;
04101    if (!info)
04102       return 1;
04103    FIND_NEXT;
04104    /* Now check for day of week */
04105    i->dowmask = get_dow(info);
04106 
04107    info = c;
04108    if (!info)
04109       return 1;
04110    FIND_NEXT;
04111    /* Now check for the day of the month */
04112    i->daymask = get_day(info);
04113    info = c;
04114    if (!info)
04115       return 1;
04116    FIND_NEXT;
04117    /* And finally go for the month */
04118    i->monthmask = get_month(info);
04119 
04120    return 1;
04121 }

int ast_canmatch_extension struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid
 

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

References HELPER_CANMATCH, and pbx_extension_helper().

Referenced by background_detect_exec(), cb_events(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), loopback_canmatch(), mgcp_ss(), monitor_handle_notowned(), phone_check_exception(), rpt(), skinny_ss(), ss_thread(), and valid_exit().

02216 {
02217    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_CANMATCH);
02218 }

int ast_check_timing struct ast_timing i  ) 
 

Definition at line 4123 of file pbx.c.

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

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

04124 {
04125    struct tm tm;
04126    time_t t;
04127 
04128    time(&t);
04129    localtime_r(&t,&tm);
04130 
04131    /* If it's not the right month, return */
04132    if (!(i->monthmask & (1 << tm.tm_mon))) {
04133       return 0;
04134    }
04135 
04136    /* If it's not that time of the month.... */
04137    /* Warning, tm_mday has range 1..31! */
04138    if (!(i->daymask & (1 << (tm.tm_mday-1))))
04139       return 0;
04140 
04141    /* If it's not the right day of the week */
04142    if (!(i->dowmask & (1 << tm.tm_wday)))
04143       return 0;
04144 
04145    /* Sanity check the hour just to be safe */
04146    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
04147       ast_log(LOG_WARNING, "Insane time...\n");
04148       return 0;
04149    }
04150 
04151    /* Now the tough part, we calculate if it fits
04152       in the right time based on min/hour */
04153    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
04154       return 0;
04155 
04156    /* If we got this far, then we're good */
04157    return 1;
04158 }

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

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. Returns 0 on success, -1 on failure

Definition at line 4419 of file pbx.c.

References ast_context_add_ignorepat2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by handle_context_add_ignorepat().

04420 {
04421    struct ast_context *c;
04422 
04423    if (ast_lock_contexts()) {
04424       errno = EBUSY;
04425       return -1;
04426    }
04427 
04428    c = ast_walk_contexts(NULL);
04429    while (c) {
04430       if (!strcmp(ast_get_context_name(c), con)) {
04431          int ret = ast_context_add_ignorepat2(c, value, registrar);
04432          ast_unlock_contexts();
04433          return ret;
04434       } 
04435       c = ast_walk_contexts(c);
04436    }
04437 
04438    ast_unlock_contexts();
04439    errno = ENOENT;
04440    return -1;
04441 }

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

Definition at line 4443 of file pbx.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_context::ignorepats, ast_context::lock, LOG_ERROR, malloc, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.

Referenced by ast_context_add_ignorepat(), handle_context(), and pbx_load_module().

04444 {
04445    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04446    int length;
04447    length = sizeof(struct ast_ignorepat);
04448    length += strlen(value) + 1;
04449    ignorepat = malloc(length);
04450    if (!ignorepat) {
04451       ast_log(LOG_ERROR, "Out of memory\n");
04452       errno = ENOMEM;
04453       return -1;
04454    }
04455    memset(ignorepat, 0, length);
04456    strcpy(ignorepat->pattern, value);
04457    ignorepat->next = NULL;
04458    ignorepat->registrar = registrar;
04459    ast_mutex_lock(&con->lock);
04460    ignorepatc = con->ignorepats;
04461    while(ignorepatc) {
04462       ignorepatl = ignorepatc;
04463       if (!strcasecmp(ignorepatc->pattern, value)) {
04464          /* Already there */
04465          ast_mutex_unlock(&con->lock);
04466          errno = EEXIST;
04467          return -1;
04468       }
04469       ignorepatc = ignorepatc->next;
04470    }
04471    if (ignorepatl) 
04472       ignorepatl->next = ignorepat;
04473    else
04474       con->ignorepats = ignorepat;
04475    ast_mutex_unlock(&con->lock);
04476    return 0;
04477    
04478 }

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

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 Returns 0 on success, -1 on error

Definition at line 3802 of file pbx.c.

References ast_context_add_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by handle_context_add_include().

03803 {
03804    struct ast_context *c;
03805 
03806    if (ast_lock_contexts()) {
03807       errno = EBUSY;
03808       return -1;
03809    }
03810 
03811    /* walk contexts ... */
03812    c = ast_walk_contexts(NULL);
03813    while (c) {
03814       /* ... search for the right one ... */
03815       if (!strcmp(ast_get_context_name(c), context)) {
03816          int ret = ast_context_add_include2(c, include, registrar);
03817          /* ... unlock contexts list and return */
03818          ast_unlock_contexts();
03819          return ret;
03820       }
03821       c = ast_walk_contexts(c);
03822    }
03823 
03824    /* we can't find the right context */
03825    ast_unlock_contexts();
03826    errno = ENOENT;
03827    return -1;
03828 }

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

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 Returns 0 on success, -1 on failure

Definition at line 4167 of file pbx.c.

References ast_build_timing(), ast_get_context_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, ast_include::hastime, ast_context::includes, ast_context::lock, LOG_ERROR, malloc, 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(), handle_context(), and pbx_load_module().

04169 {
04170    struct ast_include *new_include;
04171    char *c;
04172    struct ast_include *i, *il = NULL; /* include, include_last */
04173    int length;
04174    char *p;
04175    
04176    length = sizeof(struct ast_include);
04177    length += 2 * (strlen(value) + 1);
04178 
04179    /* allocate new include structure ... */
04180    if (!(new_include = malloc(length))) {
04181       ast_log(LOG_ERROR, "Out of memory\n");
04182       errno = ENOMEM;
04183       return -1;
04184    }
04185    
04186    /* ... fill in this structure ... */
04187    memset(new_include, 0, length);
04188    p = new_include->stuff;
04189    new_include->name = p;
04190    strcpy(new_include->name, value);
04191    p += strlen(value) + 1;
04192    new_include->rname = p;
04193    strcpy(new_include->rname, value);
04194    c = new_include->rname;
04195    /* Strip off timing info */
04196    while(*c && (*c != '|')) 
04197       c++; 
04198    /* Process if it's there */
04199    if (*c) {
04200            new_include->hastime = ast_build_timing(&(new_include->timing), c+1);
04201       *c = '\0';
04202    }
04203    new_include->next      = NULL;
04204    new_include->registrar = registrar;
04205 
04206    /* ... try to lock this context ... */
04207    if (ast_mutex_lock(&con->lock)) {
04208       free(new_include);
04209       errno = EBUSY;
04210       return -1;
04211    }
04212 
04213    /* ... go to last include and check if context is already included too... */
04214    i = con->includes;
04215    while (i) {
04216       if (!strcasecmp(i->name, new_include->name)) {
04217          free(new_include);
04218          ast_mutex_unlock(&con->lock);
04219          errno = EEXIST;
04220          return -1;
04221       }
04222       il = i;
04223       i = i->next;
04224    }
04225 
04226    /* ... include new context into context list, unlock, return */
04227    if (il)
04228       il->next = new_include;
04229    else
04230       con->includes = new_include;
04231    if (option_verbose > 2)
04232       ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 
04233    ast_mutex_unlock(&con->lock);
04234 
04235    return 0;
04236 }

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

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 It returns 0 on success, -1 on failure

Definition at line 4243 of file pbx.c.

References ast_context_add_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

04244 {
04245    struct ast_context *c;
04246 
04247    if (ast_lock_contexts()) {
04248       errno = EBUSY;
04249       return -1;
04250    }
04251 
04252    /* walk contexts ... */
04253    c = ast_walk_contexts(NULL);
04254    while (c) {
04255       /* ... search for the right one ... */
04256       if (!strcmp(ast_get_context_name(c), context)) {
04257          int ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04258          /* ... unlock contexts list and return */
04259          ast_unlock_contexts();
04260          return ret;
04261       }
04262       c = ast_walk_contexts(c);
04263    }
04264 
04265    /* we can't find the right context */
04266    ast_unlock_contexts();
04267    errno = ENOENT;
04268    return -1;
04269 }

int ast_context_add_switch2 struct ast_context con,
const char *  sw,
const char *  data,
int  eval,
const char *  registrar
 

See ast_context_add_switch()

Definition at line 4278 of file pbx.c.

References ast_context::alts, ast_get_context_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, ast_sw::eval, free, ast_context::lock, LOG_ERROR, malloc, ast_sw::name, ast_sw::next, option_verbose, ast_sw::registrar, ast_sw::stuff, SWITCH_DATA_LENGTH, ast_sw::tmpdata, and VERBOSE_PREFIX_3.

Referenced by ast_context_add_switch(), handle_context(), and pbx_load_module().

04280 {
04281    struct ast_sw *new_sw;
04282    struct ast_sw *i, *il = NULL; /* sw, sw_last */
04283    int length;
04284    char *p;
04285    
04286    length = sizeof(struct ast_sw);
04287    length += strlen(value) + 1;
04288    if (data)
04289       length += strlen(data);
04290    length++;
04291    if (eval) {
04292       /* Create buffer for evaluation of variables */
04293       length += SWITCH_DATA_LENGTH;
04294       length++;
04295    }
04296 
04297    /* allocate new sw structure ... */
04298    if (!(new_sw = malloc(length))) {
04299       ast_log(LOG_ERROR, "Out of memory\n");
04300       errno = ENOMEM;
04301       return -1;
04302    }
04303    
04304    /* ... fill in this structure ... */
04305    memset(new_sw, 0, length);
04306    p = new_sw->stuff;
04307    new_sw->name = p;
04308    strcpy(new_sw->name, value);
04309    p += strlen(value) + 1;
04310    new_sw->data = p;
04311    if (data) {
04312       strcpy(new_sw->data, data);
04313       p += strlen(data) + 1;
04314    } else {
04315       strcpy(new_sw->data, "");
04316       p++;
04317    }
04318    if (eval) 
04319       new_sw->tmpdata = p;
04320    new_sw->next      = NULL;
04321    new_sw->eval     = eval;
04322    new_sw->registrar = registrar;
04323 
04324    /* ... try to lock this context ... */
04325    if (ast_mutex_lock(&con->lock)) {
04326       free(new_sw);
04327       errno = EBUSY;
04328       return -1;
04329    }
04330 
04331    /* ... go to last sw and check if context is already swd too... */
04332    i = con->alts;
04333    while (i) {
04334       if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
04335          free(new_sw);
04336          ast_mutex_unlock(&con->lock);
04337          errno = EEXIST;
04338          return -1;
04339       }
04340       il = i;
04341       i = i->next;
04342    }
04343 
04344    /* ... sw new context into context list, unlock, return */
04345    if (il)
04346       il->next = new_sw;
04347    else
04348       con->alts = new_sw;
04349    if (option_verbose > 2)
04350       ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 
04351    ast_mutex_unlock(&con->lock);
04352 
04353    return 0;
04354 }

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

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. It returns NULL on failure, and an ast_context structure on success

Definition at line 3637 of file pbx.c.

References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), contexts, ast_context::includes, local_contexts, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, ast_context::name, ast_context::next, option_verbose, and VERBOSE_PREFIX_3.

Referenced by do_parking_thread(), handle_context(), handle_macro(), load_config(), pbx_load_module(), reload_config(), and set_config().

03638 {
03639    struct ast_context *tmp, **local_contexts;
03640    int length;
03641    length = sizeof(struct ast_context);
03642    length += strlen(name) + 1;
03643    if (!extcontexts) {
03644       local_contexts = &contexts;
03645       ast_mutex_lock(&conlock);
03646    } else
03647       local_contexts = extcontexts;
03648 
03649    tmp = *local_contexts;
03650    while(tmp) {
03651       if (!strcasecmp(tmp->name, name)) {
03652          ast_mutex_unlock(&conlock);
03653          ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
03654          if (!extcontexts)
03655             ast_mutex_unlock(&conlock);
03656          return NULL;
03657       }
03658       tmp = tmp->next;
03659    }
03660    tmp = malloc(length);
03661    if (tmp) {
03662       memset(tmp, 0, length);
03663       ast_mutex_init(&tmp->lock);
03664       strcpy(tmp->name, name);
03665       tmp->root = NULL;
03666       tmp->registrar = registrar;
03667       tmp->next = *local_contexts;
03668       tmp->includes = NULL;
03669       tmp->ignorepats = NULL;
03670       *local_contexts = tmp;
03671       if (option_debug)
03672          ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
03673       else if (option_verbose > 2)
03674          ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
03675    } else
03676       ast_log(LOG_ERROR, "Out of memory\n");
03677    
03678    if (!extcontexts)
03679       ast_mutex_unlock(&conlock);
03680    return tmp;
03681 }

void ast_context_destroy struct ast_context con,
const char *  registrar
 

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

References __ast_context_destroy().

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

05382 {
05383    __ast_context_destroy(con,registrar);
05384 }

struct ast_context* ast_context_find const char *  name  ) 
 

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

References ast_mutex_lock(), ast_mutex_unlock(), contexts, ast_context::name, and ast_context::next.

Referenced by ast_context_verify_includes(), ast_ignore_pattern(), do_parking_thread(), load_config(), macro_exec(), park_exec(), reload_config(), and set_config().

00737 {
00738    struct ast_context *tmp;
00739    ast_mutex_lock(&conlock);
00740    if (name) {
00741       tmp = contexts;
00742       while(tmp) {
00743          if (!strcasecmp(name, tmp->name))
00744             break;
00745          tmp = tmp->next;
00746       }
00747    } else
00748       tmp = contexts;
00749    ast_mutex_unlock(&conlock);
00750    return tmp;
00751 }

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

Parameters:
context context to remove extension from
extension which extension to remove
priority priority of extension to remove
registrar registrar of the extension This function removes an extension from a given context. Returns 0 on success, -1 on failure

Definition at line 2722 of file pbx.c.

References ast_context_remove_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by handle_context_remove_extension(), and register_peer_exten().

02723 {
02724    struct ast_context *c;
02725 
02726    if (ast_lock_contexts()) return -1;
02727 
02728    /* walk contexts ... */
02729    c = ast_walk_contexts(NULL);
02730    while (c) {
02731       /* ... search for the right one ... */
02732       if (!strcmp(ast_get_context_name(c), context)) {
02733          /* ... remove extension ... */
02734          int ret = ast_context_remove_extension2(c, extension, priority,
02735             registrar);
02736          /* ... unlock contexts list and return */
02737          ast_unlock_contexts();
02738          return ret;
02739       }
02740       c = ast_walk_contexts(c);
02741    }
02742 
02743    /* we can't find the right context */
02744    ast_unlock_contexts();
02745    return -1;
02746 }

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

References ast_mutex_lock(), ast_mutex_unlock(), ast_remove_hint(), exten, free, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, and ast_context::root.

Referenced by ast_context_remove_extension(), do_parking_thread(), load_config(), and park_exec().

02759 {
02760    struct ast_exten *exten, *prev_exten = NULL;
02761 
02762    if (ast_mutex_lock(&con->lock)) return -1;
02763 
02764    /* go through all extensions in context and search the right one ... */
02765    exten = con->root;
02766    while (exten) {
02767 
02768       /* look for right extension */
02769       if (!strcmp(exten->exten, extension) &&
02770          (!registrar || !strcmp(exten->registrar, registrar))) {
02771          struct ast_exten *peer;
02772 
02773          /* should we free all peers in this extension? (priority == 0)? */
02774          if (priority == 0) {
02775             /* remove this extension from context list */
02776             if (prev_exten)
02777                prev_exten->next = exten->next;
02778             else
02779                con->root = exten->next;
02780 
02781             /* fire out all peers */
02782             peer = exten; 
02783             while (peer) {
02784                exten = peer->peer;
02785                
02786                if (!peer->priority==PRIORITY_HINT) 
02787                    ast_remove_hint(peer);
02788 
02789                peer->datad(peer->data);
02790                free(peer);
02791 
02792                peer = exten;
02793             }
02794 
02795             ast_mutex_unlock(&con->lock);
02796             return 0;
02797          } else {
02798             /* remove only extension with exten->priority == priority */
02799             struct ast_exten *previous_peer = NULL;
02800 
02801             peer = exten;
02802             while (peer) {
02803                /* is this our extension? */
02804                if (peer->priority == priority &&
02805                   (!registrar || !strcmp(peer->registrar, registrar) )) {
02806                   /* we are first priority extension? */
02807                   if (!previous_peer) {
02808                      /* exists previous extension here? */
02809                      if (prev_exten) {
02810                         /* yes, so we must change next pointer in
02811                          * previous connection to next peer
02812                          */
02813                         if (peer->peer) {
02814                            prev_exten->next = peer->peer;
02815                            peer->peer->next = exten->next;
02816                         } else
02817                            prev_exten->next = exten->next;
02818                      } else {
02819                         /* no previous extension, we are first
02820                          * extension, so change con->root ...
02821                          */
02822                         if (peer->peer)
02823                            con->root = peer->peer;
02824                         else
02825                            con->root = exten->next; 
02826                      }
02827                   } else {
02828                      /* we are not first priority in extension */
02829                      previous_peer->peer = peer->peer;
02830                   }
02831 
02832                   /* now, free whole priority extension */
02833                   if (peer->priority==PRIORITY_HINT)
02834                       ast_remove_hint(peer);
02835                   peer->datad(peer->data);
02836                   free(peer);
02837 
02838                   ast_mutex_unlock(&con->lock);
02839                   return 0;
02840                } else {
02841                   /* this is not right extension, skip to next peer */
02842                   previous_peer = peer;
02843                   peer = peer->peer;
02844                }
02845             }
02846 
02847             ast_mutex_unlock(&con->lock);
02848             return -1;
02849          }
02850       }
02851 
02852       prev_exten = exten;
02853       exten = exten->next;
02854    }
02855 
02856    /* we can't find right extension */
02857    ast_mutex_unlock(&con->lock);
02858    return -1;
02859 }

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

Parameters:
context context from which to remove the pattern
ignorepat the pattern to remove
registrar the registrar of the ignore pattern This removes the given ignorepattern Returns 0 on success, -1 on failure

Definition at line 4360 of file pbx.c.

References ast_context_remove_ignorepat2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by handle_context_remove_ignorepat().

04361 {
04362    struct ast_context *c;
04363 
04364    if (ast_lock_contexts()) {
04365       errno = EBUSY;
04366       return -1;
04367    }
04368 
04369    c = ast_walk_contexts(NULL);
04370    while (c) {
04371       if (!strcmp(ast_get_context_name(c), context)) {
04372          int ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04373          ast_unlock_contexts();
04374          return ret;
04375       }
04376       c = ast_walk_contexts(c);
04377    }
04378 
04379    ast_unlock_contexts();
04380    errno = ENOENT;
04381    return -1;
04382 }

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

Definition at line 4384 of file pbx.c.

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

Referenced by ast_context_remove_ignorepat().

04385 {
04386    struct ast_ignorepat *ip, *ipl = NULL;
04387 
04388    if (ast_mutex_lock(&con->lock)) {
04389       errno = EBUSY;
04390       return -1;
04391    }
04392 
04393    ip = con->ignorepats;
04394    while (ip) {
04395       if (!strcmp(ip->pattern, ignorepat) &&
04396          (!registrar || (registrar == ip->registrar))) {
04397          if (ipl) {
04398             ipl->next = ip->next;
04399             free(ip);
04400          } else {
04401             con->ignorepats = ip->next;
04402             free(ip);
04403          }
04404          ast_mutex_unlock(&con->lock);
04405          return 0;
04406       }
04407       ipl = ip; ip = ip->next;
04408    }
04409 
04410    ast_mutex_unlock(&con->lock);
04411    errno = EINVAL;
04412    return -1;
04413 }

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

See add_include

Definition at line 2578 of file pbx.c.

References ast_context_remove_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by handle_context_dont_include().

02579 {
02580    struct ast_context *c;
02581 
02582    if (ast_lock_contexts()) return -1;
02583 
02584    /* walk contexts and search for the right one ...*/
02585    c = ast_walk_contexts(NULL);
02586    while (c) {
02587       /* we found one ... */
02588       if (!strcmp(ast_get_context_name(c), context)) {
02589          int ret;
02590          /* remove include from this context ... */   
02591          ret = ast_context_remove_include2(c, include, registrar);
02592 
02593          ast_unlock_contexts();
02594 
02595          /* ... return results */
02596          return ret;
02597       }
02598       c = ast_walk_contexts(c);
02599    }
02600 
02601    /* we can't find the right one context */
02602    ast_unlock_contexts();
02603    return -1;
02604 }

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

See add_include2

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

02615 {
02616    struct ast_include *i, *pi = NULL;
02617 
02618    if (ast_mutex_lock(&con->lock)) return -1;
02619 
02620    /* walk includes */
02621    i = con->includes;
02622    while (i) {
02623       /* find our include */
02624       if (!strcmp(i->name, include) && 
02625          (!registrar || !strcmp(i->registrar, registrar))) {
02626          /* remove from list */
02627          if (pi)
02628             pi->next = i->next;
02629          else
02630             con->includes = i->next;
02631          /* free include and return */
02632          free(i);
02633          ast_mutex_unlock(&con->lock);
02634          return 0;
02635       }
02636       pi = i;
02637       i = i->next;
02638    }
02639 
02640    /* we can't find the right include */
02641    ast_mutex_unlock(&con->lock);
02642    return -1;
02643 }

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

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

References ast_context_remove_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

02651 {
02652    struct ast_context *c;
02653 
02654    if (ast_lock_contexts()) return -1;
02655 
02656    /* walk contexts and search for the right one ...*/
02657    c = ast_walk_contexts(NULL);
02658    while (c) {
02659       /* we found one ... */
02660       if (!strcmp(ast_get_context_name(c), context)) {
02661          int ret;
02662          /* remove switch from this context ... */ 
02663          ret = ast_context_remove_switch2(c, sw, data, registrar);
02664 
02665          ast_unlock_contexts();
02666 
02667          /* ... return results */
02668          return ret;
02669       }
02670       c = ast_walk_contexts(c);
02671    }
02672 
02673    /* we can't find the right one context */
02674    ast_unlock_contexts();
02675    return -1;
02676 }

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

References ast_context::alts, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_context::lock, ast_sw::name, ast_sw::next, and ast_sw::registrar.

Referenced by ast_context_remove_switch().

02687 {
02688    struct ast_sw *i, *pi = NULL;
02689 
02690    if (ast_mutex_lock(&con->lock)) return -1;
02691 
02692    /* walk switchs */
02693    i = con->alts;
02694    while (i) {
02695       /* find our switch */
02696       if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 
02697          (!registrar || !strcmp(i->registrar, registrar))) {
02698          /* remove from list */
02699          if (pi)
02700             pi->next = i->next;
02701          else
02702             con->alts = i->next;
02703          /* free switch and return */
02704          free(i);
02705          ast_mutex_unlock(&con->lock);
02706          return 0;
02707       }
02708       pi = i;
02709       i = i->next;
02710    }
02711 
02712    /* we can't find the right switch */
02713    ast_mutex_unlock(&con->lock);
02714    return -1;
02715 }

int ast_context_verify_includes struct ast_context con  ) 
 

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

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

06431 {
06432    struct ast_include *inc;
06433    int res = 0;
06434 
06435    for (inc = ast_walk_context_includes(con, NULL); inc; inc = ast_walk_context_includes(con, inc))
06436       if (!ast_context_find(inc->rname)) {
06437          res = -1;
06438          ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n",
06439                ast_get_context_name(con), inc->rname);
06440       }
06441    return res;
06442 }

struct ast_custom_function* ast_custom_function_find char *  name  ) 
 

Definition at line 1265 of file pbx.c.

References acf_root, ast_log(), ast_mutex_lock(), LOG_ERROR, ast_custom_function::name, and ast_custom_function::next.

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

01266 {
01267    struct ast_custom_function *acfptr;
01268 
01269    /* try to lock functions list ... */
01270    if (ast_mutex_lock(&acflock)) {
01271       ast_log(LOG_ERROR, "Unable to lock function list\n");
01272       return NULL;
01273    }
01274 
01275    for (acfptr = acf_root; acfptr; acfptr = acfptr->next) {
01276       if (!strcmp(name, acfptr->name)) {
01277          break;
01278       }
01279    }
01280 
01281    ast_mutex_unlock(&acflock);
01282    
01283    return acfptr;
01284 }

int ast_custom_function_register struct ast_custom_function acf  ) 
 

Definition at line 1321 of file pbx.c.

References acf_root, ast_custom_function_find(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), LOG_ERROR, ast_custom_function::name, ast_custom_function::next, option_verbose, and VERBOSE_PREFIX_2.

Referenced by load_module().

01322 {
01323    if (!acf)
01324       return -1;
01325 
01326    /* try to lock functions list ... */
01327    if (ast_mutex_lock(&acflock)) {
01328       ast_log(LOG_ERROR, "Unable to lock function list. Failed registering function %s\n", acf->name);
01329       return -1;
01330    }
01331 
01332    if (ast_custom_function_find(acf->name)) {
01333       ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
01334       ast_mutex_unlock(&acflock);
01335       return -1;
01336    }
01337 
01338    acf->next = acf_root;
01339    acf_root = acf;
01340 
01341    ast_mutex_unlock(&acflock);
01342 
01343    if (option_verbose > 1)
01344       ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
01345 
01346    return 0;
01347 }

int ast_custom_function_unregister struct ast_custom_function acf  ) 
 

Definition at line 1286 of file pbx.c.

References acf_root, ast_log(), ast_mutex_lock(), LOG_ERROR, and ast_custom_function::next.

Referenced by unload_module().

01287 {
01288    struct ast_custom_function *acfptr, *lastacf = NULL;
01289    int res = -1;
01290 
01291    if (!acf)
01292       return -1;
01293 
01294    /* try to lock functions list ... */
01295    if (ast_mutex_lock(&acflock)) {
01296       ast_log(LOG_ERROR, "Unable to lock function list\n");
01297       return -1;
01298    }
01299 
01300    for (acfptr = acf_root; acfptr; acfptr = acfptr->next) {
01301       if (acfptr == acf) {
01302          if (lastacf) {
01303             lastacf->next = acf->next;
01304          } else {
01305             acf_root = acf->next;
01306          }
01307          res = 0;
01308          break;
01309       }
01310       lastacf = acfptr;
01311    }
01312 
01313    ast_mutex_unlock(&acflock);
01314 
01315    if (!res && (option_verbose > 1))
01316       ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name);
01317 
01318    return res;
01319 }

int ast_exec_extension struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid
 

Parameters:
c channel to execute upon
context which context extension is in
exten extension to execute
priority priority to execute within the given extension
callerid Caller-ID If it's not available, do whatever you should do for default extensions and halt the thread if necessary. This function does not return, except on error.

Definition at line 2230 of file pbx.c.

References HELPER_EXEC, and pbx_extension_helper().

Referenced by loopback_exec().

02231 {
02232    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXEC);
02233 }

int ast_exists_extension struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid
 

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

References HELPER_EXISTS, and pbx_extension_helper().

Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), agentmonitoroutgoing_exec(), ast_pbx_outgoing_exten(), ast_waitstream_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), console_dial(), console_transfer(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), leave_voicemail(), local_alloc(), loopback_exists(), macro_exec(), mgcp_ss(), misdn_tx2ast_frm(), monitor_handle_notowned(), monitor_handle_owned(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), register_peer_exten(), rpt(), skinny_ss(), socket_read(), ss_thread(), and zt_read().

02201 {
02202    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXISTS);
02203 }

int ast_explicit_goto struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority
 

Definition at line 4528 of file pbx.c.

References 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(), builtin_atxfer(), and handle_setpriority().

04529 {
04530    if (!chan)
04531       return -1;
04532 
04533    if (!ast_strlen_zero(context))
04534       ast_copy_string(chan->context, context, sizeof(chan->context));
04535    if (!ast_strlen_zero(exten))
04536       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04537    if (priority > -1) {
04538       chan->priority = priority;
04539       /* see flag description in channel.h for explanation */
04540       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04541          chan->priority--;
04542    }
04543    
04544    return 0;
04545 }

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

Definition at line 715 of file pbx.c.

References ast_strlen_zero(), EXTENSION_MATCH_CORE, and match().

Referenced by realtime_switch_common().

00716 {
00717    int match;
00718    /* If "data" is longer, it can'be a subset of pattern unless
00719       pattern is a pattern match */
00720    if ((strlen(pattern) < strlen(data)) && (pattern[0] != '_'))
00721       return 0;
00722    
00723    if ((ast_strlen_zero((char *)data) || !strncasecmp(pattern, data, strlen(data))) && 
00724       (!needmore || (strlen(pattern) > strlen(data)))) {
00725       return 1;
00726    }
00727    EXTENSION_MATCH_CORE(data,pattern,match);
00728    /* If there's more or we don't care about more, or if it's a possible early match, 
00729       return non-zero; otherwise it's a miss */
00730    if (!needmore || *pattern || match == 2) {
00731       return match;
00732    } else
00733       return 0;
00734 }

int ast_extension_match const char *  pattern,
const char *  extension
 

Parameters:
pattern pattern to match
extension extension to check against the pattern. Checks whether or not the given extension matches the given pattern. Returns 1 on match, 0 on failure

Definition at line 702 of file pbx.c.

References EXTENSION_MATCH_CORE, and match().

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

00703 {
00704    int match;
00705    /* If they're the same return */
00706    if (!strcmp(pattern, data))
00707       return 1;
00708    EXTENSION_MATCH_CORE(data,pattern,match);
00709    /* Must be at the end of both */
00710    if (*data || (*pattern && (*pattern != '/')))
00711       match = 0;
00712    return match;
00713 }

int ast_extension_patmatch const char *  pattern,
const char *  data
 

int ast_extension_state struct ast_channel c,
char *  context,
char *  exten
 

ast_extension_state: Check extension state for an extension by using hint

Parameters:
c this is not important
context which context to look in
exten which extension to get state Returns extension state !! = AST_EXTENSION_???

Definition at line 1872 of file pbx.c.

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

01873 {
01874    struct ast_exten *e;
01875 
01876    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */ 
01877    if (!e) 
01878       return -1;           /* No hint, return -1 */
01879 
01880    return ast_extension_state2(e);        /* Check all devices in the hint */
01881 }

const char* ast_extension_state2str int  extension_state  ) 
 

ast_extension_state2str: Return extension_state as string

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

Definition at line 1859 of file pbx.c.

References extension_states.

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

01860 {
01861    int i;
01862 
01863    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
01864       if (extension_states[i].extension_state == extension_state) {
01865          return extension_states[i].text;
01866       }
01867    }
01868    return "Unknown"; 
01869 }

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

ast_extension_state_add: Add watcher for extension states

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 for extension is changed Return -1 on failure, ID on success

Definition at line 1926 of file pbx.c.

References ast_hint_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_state_cb::data, hints, ast_state_cb::id, list, malloc, ast_imager::next, ast_state_cb::next, and statecbs.

Referenced by handle_request_subscribe(), and init_manager().

01928 {
01929    struct ast_hint *list;
01930    struct ast_state_cb *cblist;
01931    struct ast_exten *e;
01932 
01933    /* If there's no context and extension:  add callback to statecbs list */
01934    if (!context && !exten) {
01935       ast_mutex_lock(&hintlock);
01936 
01937       cblist = statecbs;
01938       while (cblist) {
01939          if (cblist->callback == callback) {
01940             cblist->data = data;
01941             ast_mutex_unlock(&hintlock);
01942             return 0;
01943          }
01944          cblist = cblist->next;
01945       }
01946    
01947       /* Now insert the callback */
01948       cblist = malloc(sizeof(struct ast_state_cb));
01949       if (!cblist) {
01950          ast_mutex_unlock(&hintlock);
01951          return -1;
01952       }
01953       memset(cblist, 0, sizeof(struct ast_state_cb));
01954       cblist->id = 0;
01955       cblist->callback = callback;
01956       cblist->data = data;
01957    
01958       cblist->next = statecbs;
01959       statecbs = cblist;
01960 
01961       ast_mutex_unlock(&hintlock);
01962       return 0;
01963    }
01964 
01965    if (!context || !exten)
01966       return -1;
01967 
01968    /* This callback type is for only one hint, so get the hint */
01969    e = ast_hint_extension(NULL, context, exten);    
01970    if (!e) {
01971       return -1;
01972    }
01973 
01974    /* Find the hint in the list of hints */
01975    ast_mutex_lock(&hintlock);
01976    list = hints;        
01977 
01978    while (list) {
01979       if (list->exten == e)
01980          break;       
01981       list = list->next;    
01982    }
01983 
01984    if (!list) {
01985       /* We have no hint, sorry */
01986       ast_mutex_unlock(&hintlock);
01987       return -1;
01988    }
01989 
01990    /* Now insert the callback in the callback list  */
01991    cblist = malloc(sizeof(struct ast_state_cb));
01992    if (!cblist) {
01993       ast_mutex_unlock(&hintlock);
01994       return -1;
01995    }
01996    memset(cblist, 0, sizeof(struct ast_state_cb));
01997    cblist->id = stateid++;    /* Unique ID for this callback */
01998    cblist->callback = callback;  /* Pointer to callback routine */
01999    cblist->data = data;    /* Data for the callback */
02000 
02001    cblist->next = list->callbacks;
02002    list->callbacks = cblist;
02003 
02004    ast_mutex_unlock(&hintlock);
02005    return cblist->id;
02006 }

int ast_extension_state_del int  id,
ast_state_cb_type  callback
 

ast_extension_state_del: Remove a watcher from the callback list

Parameters:
id of the callback to delete
callback callback Removes the callback from list of callbacks Return 0 on success, -1 on failure

Definition at line 2009 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, free, hints, ast_state_cb::id, list, ast_imager::next, ast_state_cb::next, and statecbs.

Referenced by __sip_destroy().

02010 {
02011    struct ast_hint *list;
02012    struct ast_state_cb *cblist, *cbprev;
02013 
02014    if (!id && !callback)
02015       return -1;
02016 
02017    ast_mutex_lock(&hintlock);
02018 
02019    /* id is zero is a callback without extension */
02020    if (!id) {
02021       cbprev = NULL;
02022       cblist = statecbs;
02023       while (cblist) {
02024          if (cblist->callback == callback) {
02025             if (!cbprev)
02026                   statecbs = cblist->next;
02027             else
02028                   cbprev->next = cblist->next;
02029 
02030             free(cblist);
02031 
02032                ast_mutex_unlock(&hintlock);
02033             return 0;
02034             }
02035             cbprev = cblist;
02036             cblist = cblist->next;
02037       }
02038 
02039       ast_mutex_unlock(&hintlock);
02040       return -1;
02041    }
02042 
02043    /* id greater than zero is a callback with extension */
02044    /* Find the callback based on ID */
02045    list = hints;
02046    while (list) {
02047       cblist = list->callbacks;
02048       cbprev = NULL;
02049       while (cblist) {
02050             if (cblist->id==id) {
02051             if (!cbprev)
02052                   list->callbacks = cblist->next;     
02053             else
02054                   cbprev->next = cblist->next;
02055       
02056             free(cblist);
02057       
02058             ast_mutex_unlock(&hintlock);
02059             return 0;      
02060             }     
02061             cbprev = cblist;           
02062             cblist = cblist->next;
02063       }
02064       list = list->next;
02065    }
02066 
02067    ast_mutex_unlock(&hintlock);
02068    return -1;
02069 }

int ast_findlabel_extension struct ast_channel c,
const char *  context,
const char *  exten,
const char *  label,
const char *  callerid
 

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 If an priority which matches given label in extension or -1 if not found. \

Definition at line 2205 of file pbx.c.

References HELPER_FINDLABEL, and pbx_extension_helper().

Referenced by ast_parseable_goto(), and handle_setpriority().

02206 {
02207    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, HELPER_FINDLABEL);
02208 }

int ast_findlabel_extension2 struct ast_channel c,
struct ast_context con,
const char *  exten,
const char *  label,
const char *  callerid
 

Definition at line 2210 of file pbx.c.

References HELPER_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_module().

02211 {
02212    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, HELPER_FINDLABEL);
02213 }

char* ast_func_read struct ast_channel chan,
const char *  in,
char *  workspace,
size_t  len
 

Parameters:
chan Channel to execute on
in Data containing the function call string
workspace A pointer to safe memory to use for a return value
len the number of bytes in workspace This application executes an function in read mode on a given channel. It returns a pointer to workspace if the buffer contains any new data or NULL if there was a problem.

Definition at line 1349 of file pbx.c.

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

Referenced by handle_getvariable(), and pbx_substitute_variables_helper_full().

01350 {
01351    char *args = NULL, *function, *p;
01352    char *ret = "0";
01353    struct ast_custom_function *acfptr;
01354 
01355    function = ast_strdupa(in);
01356    if (!function) {
01357       ast_log(LOG_ERROR, "Out of memory\n");
01358       return ret;
01359    }
01360    if ((args = strchr(function, '('))) {
01361       *args = '\0';
01362       args++;
01363       if ((p = strrchr(args, ')'))) {
01364          *p = '\0';
01365       } else {
01366          ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
01367       }
01368    } else {
01369       ast_log(LOG_WARNING, "Function doesn't contain parentheses.  Assuming null argument.\n");
01370    }
01371 
01372    if ((acfptr = ast_custom_function_find(function))) {
01373       /* run the custom function */
01374       if (acfptr->read) {
01375          return acfptr->read(chan, function, args, workspace, len);
01376       } else {
01377          ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
01378       }
01379    } else {
01380       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01381    }
01382    return ret;
01383 }

void ast_func_write struct ast_channel chan,
const char *  in,
const char *  value
 

Parameters:
chan Channel to execute on
in Data containing the function call string
value A value parameter to pass for writing This application executes an function in write mode on a given channel. It has no return value.

Definition at line 1385 of file pbx.c.

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

Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

01386 {
01387    char *args = NULL, *function, *p;
01388    struct ast_custom_function *acfptr;
01389 
01390    function = ast_strdupa(in);
01391    if (!function) {
01392       ast_log(LOG_ERROR, "Out of memory\n");
01393       return;
01394    }
01395    if ((args = strchr(function, '('))) {
01396       *args = '\0';
01397       args++;
01398       if ((p = strrchr(args, ')'))) {
01399          *p = '\0';
01400       } else {
01401          ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
01402       }
01403    } else {
01404       ast_log(LOG_WARNING, "Function doesn't contain parentheses.  Assuming null argument.\n");
01405    }
01406 
01407    if ((acfptr = ast_custom_function_find(function))) {
01408       /* run the custom function */
01409       if (acfptr->write) {
01410          acfptr->write(chan, function, args, value);
01411       } else {
01412          ast_log(LOG_ERROR, "Function %s is read-only, it cannot be written to\n", function);
01413       }
01414    } else {
01415       ast_log(LOG_ERROR, "Function %s not registered\n", function);
01416    }
01417 }

const char* ast_get_context_name struct ast_context con  ) 
 

Definition at line 6286 of file pbx.c.

References ast_context::name.

Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_include2(), ast_context_add_switch(), ast_context_add_switch2(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper().

06287 {
06288    return con ? con->name : NULL;
06289 }

const char* ast_get_context_registrar struct ast_context c  ) 
 

Definition at line 6319 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06320 {
06321    return c ? c->registrar : NULL;
06322 }

const char* ast_get_extension_app struct ast_exten e  ) 
 

Definition at line 6349 of file pbx.c.

References ast_exten::app.

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

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

void* ast_get_extension_app_data struct ast_exten e  ) 
 

Definition at line 6354 of file pbx.c.

References ast_exten::data.

Referenced by ast_get_hint(), handle_save_dialplan(), and show_dialplan_helper().

06355 {
06356    return e ? e->data : NULL;
06357 }

const char* ast_get_extension_cidmatch struct ast_exten e  ) 
 

Definition at line 6344 of file pbx.c.

References ast_exten::cidmatch.

Referenced by find_matching_priority(), and handle_save_dialplan().

06345 {
06346    return e ? e->cidmatch : NULL;
06347 }

const char* ast_get_extension_label struct ast_exten e  ) 
 

Definition at line 6296 of file pbx.c.

References exten.

Referenced by show_dialplan_helper().

06297 {
06298    return exten ? exten->label : NULL;
06299 }

int ast_get_extension_matchcid struct ast_exten e  ) 
 

Definition at line 6339 of file pbx.c.

References ast_exten::matchcid.

Referenced by find_matching_priority(), and handle_save_dialplan().

06340 {
06341    return e ? e->matchcid : 0;
06342 }

const char* ast_get_extension_name struct ast_exten exten  ) 
 

Definition at line 6291 of file pbx.c.

References exten.

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

06292 {
06293    return exten ? exten->exten : NULL;
06294 }

int ast_get_extension_priority struct ast_exten exten  ) 
 

Definition at line 6311 of file pbx.c.

References exten.

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

06312 {
06313    return exten ? exten->priority : -1;
06314 }

const char* ast_get_extension_registrar struct ast_exten e  ) 
 

Definition at line 6324 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06325 {
06326    return e ? e->registrar : NULL;
06327 }

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

ast_get_hint: Get hint for channel

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

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

Referenced by action_extensionstate(), get_cid_name(), pbx_retrieve_variable(), and transmit_state_notify().

02182 {
02183    struct ast_exten *e;
02184    void *tmp;
02185 
02186    e = ast_hint_extension(c, context, exten);
02187    if (e) {
02188       if (hint) 
02189           ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02190       if (name) {
02191          tmp = ast_get_extension_app_data(e);
02192          if (tmp)
02193             ast_copy_string(name, (char *) tmp, namesize);
02194       }
02195        return -1;
02196    }
02197    return 0;   
02198 }

const char* ast_get_ignorepat_name struct ast_ignorepat ip  ) 
 

Definition at line 6306 of file pbx.c.

References ast_ignorepat::pattern.

Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), and handle_save_dialplan().

06307 {
06308    return ip ? ip->pattern : NULL;
06309 }

const char* ast_get_ignorepat_registrar struct ast_ignorepat ip  ) 
 

Definition at line 6334 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan().

06335 {
06336    return ip ? ip->registrar : NULL;
06337 }

const char* ast_get_include_name struct ast_include include  ) 
 

Definition at line 6301 of file pbx.c.

References ast_include::name.

Referenced by complete_context_add_include(), complete_context_dont_include(), handle_save_dialplan(), and show_dialplan_helper().

06302 {
06303    return inc ? inc->name : NULL;
06304 }

const char* ast_get_include_registrar struct ast_include i  ) 
 

Definition at line 6329 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan().

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

const char* ast_get_switch_data struct ast_sw sw  ) 
 

Definition at line 6364 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan().

06365 {
06366    return sw ? sw->data : NULL;
06367 }

const char* ast_get_switch_name struct ast_sw sw  ) 
 

Definition at line 6359 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan().

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

const char* ast_get_switch_registrar struct ast_sw sw  ) 
 

Definition at line 6369 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan().

06370 {
06371    return sw ? sw->registrar : NULL;
06372 }

int ast_goto_if_exists struct ast_channel chan,
char *  context,
char *  exten,
int  priority
 

Definition at line 6462 of file pbx.c.

References __ast_goto_if_exists().

Referenced by aqm_exec(), background_detect_exec(), chanavail_exec(), controlplayback_exec(), dial_exec_full(), do_directory(), enumlookup_exec(), get_exec(), group_check_exec(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), md5check_exec(), onedigit_goto(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), sip_getheader(), system_exec_helper(), transfer_exec(), txtcidname_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer().

06462                                                                                            {
06463    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06464 }

void ast_hint_state_changed const char *  device  ) 
 

Definition at line 1883 of file pbx.c.

References ast_extension_state2(), ast_get_extension_app(), AST_MAX_EXTENSION, ast_mutex_lock(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, hints, ast_hint::laststate, ast_context::name, ast_state_cb::next, ast_hint::next, ast_exten::parent, parse(), statecbs, and strsep().

Referenced by do_state_change().

01884 {
01885    struct ast_hint *hint;
01886    struct ast_state_cb *cblist;
01887    char buf[AST_MAX_EXTENSION];
01888    char *parse;
01889    char *cur;
01890    int state;
01891 
01892    ast_mutex_lock(&hintlock);
01893 
01894    for (hint = hints; hint; hint = hint->next) {
01895       ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
01896       parse = buf;
01897       for (cur = strsep(&parse, "&"); cur; cur = strsep(&parse, "&")) {
01898          if (strcasecmp(cur, device))
01899             continue;
01900 
01901          /* Get device state for this hint */
01902          state = ast_extension_state2(hint->exten);
01903          
01904          if ((state == -1) || (state == hint->laststate))
01905             continue;
01906 
01907          /* Device state changed since last check - notify the watchers */
01908          
01909          /* For general callbacks */
01910          for (cblist = statecbs; cblist; cblist = cblist->next)
01911             cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
01912          
01913          /* For extension callbacks */
01914          for (cblist = hint->callbacks; cblist; cblist = cblist->next)
01915             cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
01916          
01917          hint->laststate = state;
01918          break;
01919       }
01920    }
01921 
01922    ast_mutex_unlock(&hintlock);
01923 }

int ast_ignore_pattern const char *  context,
const char *  pattern
 

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. Returns 0 if the pattern should not be ignored, or non-zero if the pattern should be ignored

Definition at line 4480 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(), dp_lookup(), dundi_lookup_local(), mgcp_ss(), skinny_ss(), and ss_thread().

04481 {
04482    struct ast_context *con;
04483    struct ast_ignorepat *pat;
04484 
04485    con = ast_context_find(context);
04486    if (con) {
04487       pat = con->ignorepats;
04488       while (pat) {
04489          if (ast_extension_match(pat->pattern, pattern))
04490             return 1;
04491          pat = pat->next;
04492       }
04493    } 
04494    return 0;
04495 }

int ast_lock_context struct ast_context con  ) 
 

Parameters:
con context to lock Locks the context. Returns 0 on success, -1 on failure

Definition at line 6273 of file pbx.c.

References ast_mutex_lock(), and ast_context::lock.

Referenced by complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_ignorepat(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper().

06274 {
06275    return ast_mutex_lock(&con->lock);
06276 }

int ast_lock_contexts void   ) 
 

Locks the context list Returns 0 on success, -1 on error

Definition at line 6260 of file pbx.c.

References ast_mutex_lock().

Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper().

06261 {
06262    return ast_mutex_lock(&conlock);
06263 }

int ast_matchmore_extension struct ast_channel c,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid
 

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

References HELPER_MATCHMORE, and pbx_extension_helper().

Referenced by ast_app_dtget(), dp_lookup(), dundi_lookup_local(), loopback_matchmore(), mgcp_ss(), skinny_ss(), and ss_thread().

02221 {
02222    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_MATCHMORE);
02223 }

void ast_merge_contexts_and_delete struct ast_context **  extcontexts,
const char *  registrar
 

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

References AST_LIST_HEAD_INIT, ast_log(), ast_mutex_lock(), ast_hint::callbacks, calloc, ast_exten::exten, ast_hint::exten, store_hint::exten, hints, LOG_WARNING, ast_context::name, ast_hint::next, ast_exten::parent, and ast_context::registrar.

Referenced by pbx_load_module().

03697 {
03698    struct ast_context *tmp, *lasttmp = NULL;
03699    struct store_hints store;
03700    struct store_hint *this;
03701    struct ast_hint *hint;
03702    struct ast_exten *exten;
03703    int length;
03704    struct ast_state_cb *thiscb, *prevcb;
03705 
03706    AST_LIST_HEAD_INIT(&store);
03707 
03708    /* it is very important that this function hold the hintlock _and_ the conlock
03709       during its operation; not only do we need to ensure that the list of contexts
03710       and extensions does not change, but also that no hint callbacks (watchers) are
03711       added or removed during the merge/delete process
03712 
03713       in addition, the locks _must_ be taken in this order, because there are already
03714       other code paths that use this order
03715    */
03716    ast_mutex_lock(&conlock);
03717    ast_mutex_lock(&hintlock);
03718 
03719    /* preserve all watchers for hints associated with this registrar */
03720    for (hint = hints; hint; hint = hint->next) {
03721       if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) {
03722          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
03723          this = calloc(1, length);
03724          if (!this) {
03725             ast_log(LOG_WARNING, "Could not allocate memory to preserve hint\n");
03726             continue;
03727          }
03728          this->callbacks = hint->callbacks;
03729          hint->callbacks = NULL;
03730          this->laststate = hint->laststate;
03731          this->context = this->data;
03732          strcpy(this->data, hint->exten->parent->name);
03733          this->exten = this->data + strlen(this->context) + 1;
03734          strcpy(this->exten, hint->exten->exten);
03735          AST_LIST_INSERT_HEAD(&store, this, list);
03736       }
03737    }
03738 
03739    tmp = *extcontexts;
03740    if (registrar) {
03741       __ast_context_destroy(NULL,registrar);
03742       while (tmp) {
03743          lasttmp = tmp;
03744          tmp = tmp->next;
03745       }
03746    } else {
03747       while (tmp) {
03748          __ast_context_destroy(tmp,tmp->registrar);
03749          lasttmp = tmp;
03750          tmp = tmp->next;
03751       }
03752    }
03753    if (lasttmp) {
03754       lasttmp->next = contexts;
03755       contexts = *extcontexts;
03756       *extcontexts = NULL;
03757    } else 
03758       ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
03759 
03760    /* restore the watchers for hints that can be found; notify those that
03761       cannot be restored
03762    */
03763    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
03764       exten = ast_hint_extension(NULL, this->context, this->exten);
03765       /* Find the hint in the list of hints */
03766       for (hint = hints; hint; hint = hint->next) {
03767          if (hint->exten == exten)
03768             break;
03769       }
03770       if (!exten || !hint) {
03771          /* this hint has been removed, notify the watchers */
03772          prevcb = NULL;
03773          thiscb = this->callbacks;
03774          while (thiscb) {
03775             prevcb = thiscb;      
03776             thiscb = thiscb->next;
03777             prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data);
03778             free(prevcb);
03779             }
03780       } else {
03781          thiscb = this->callbacks;
03782          while (thiscb->next)
03783             thiscb = thiscb->next;
03784          thiscb->next = hint->callbacks;
03785          hint->callbacks = this->callbacks;
03786          hint->laststate = this->laststate;
03787       }
03788       free(this);
03789    }
03790 
03791    ast_mutex_unlock(&hintlock);
03792    ast_mutex_unlock(&conlock);
03793 
03794    return;  
03795 }

int ast_parseable_goto struct ast_channel chan,
const char *  goto_string
 

Definition at line 6470 of file pbx.c.

References ast_cdr_update(), 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, exten, LOG_WARNING, ast_channel::priority, s, and strsep().

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

06471 {
06472    char *s;
06473    char *exten, *pri, *context;
06474    char *stringp=NULL;
06475    int ipri;
06476    int mode = 0;
06477 
06478    if (ast_strlen_zero(goto_string)) {
06479       ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
06480       return -1;
06481    }
06482    s = ast_strdupa(goto_string);
06483    stringp=s;
06484    context = strsep(&stringp, "|");
06485    exten = strsep(&stringp, "|");
06486    if (!exten) {
06487       /* Only a priority in this one */
06488       pri = context;
06489       exten = NULL;
06490       context = NULL;
06491    } else {
06492       pri = strsep(&stringp, "|");
06493       if (!pri) {
06494          /* Only an extension and priority in this one */
06495          pri = exten;
06496          exten = context;
06497          context = NULL;
06498       }
06499    }
06500    if (*pri == '+') {
06501       mode = 1;
06502       pri++;
06503    } else if (*pri == '-') {
06504       mode = -1;
06505       pri++;
06506    }
06507    if (sscanf(pri, "%d", &ipri) != 1) {
06508       if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, (exten && strcasecmp(exten, "BYEXTENSION")) ? exten : chan->exten, 
06509          pri, chan->cid.cid_num)) < 1) {
06510          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
06511          return -1;
06512       } else
06513          mode = 0;
06514    } 
06515    /* At this point we have a priority and maybe an extension and a context */
06516 
06517    if (exten && !strcasecmp(exten, "BYEXTENSION"))
06518       exten = NULL;
06519 
06520    if (mode) 
06521       ipri = chan->priority + (ipri * mode);
06522 
06523    ast_explicit_goto(chan, context, exten, ipri);
06524    ast_cdr_update(chan);
06525    return 0;
06526 
06527 }

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
 

Definition at line 5153 of file pbx.c.

References __ast_request_and_dial(), async_stat::app, async_stat::appdata, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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(), ast_channel::cdr, async_stat::chan, free, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4.

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

05154 {
05155    struct ast_channel *chan;
05156    struct async_stat *as;
05157    struct app_tmp *tmp;
05158    int res = -1, cdr_res = -1;
05159    struct outgoing_helper oh;
05160    pthread_attr_t attr;
05161 
05162    memset(&oh, 0, sizeof(oh));
05163    oh.vars = vars;
05164    oh.account = account;   
05165 
05166    if (locked_channel) 
05167       *locked_channel = NULL;
05168    if (ast_strlen_zero(app)) {
05169       res = -1;
05170       goto outgoing_app_cleanup; 
05171    }
05172    if (sync) {
05173       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05174       if (chan) {
05175          if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */
05176             ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name);
05177          } else {
05178             chan->cdr = ast_cdr_alloc();   /* allocate a cdr for the channel */
05179             if(!chan->cdr) {
05180                /* allocation of the cdr failed */
05181                ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
05182                free(chan->pbx);
05183                res = -1;
05184                goto outgoing_app_cleanup;
05185             }
05186             /* allocation of the cdr was successful */
05187             ast_cdr_init(chan->cdr, chan);  /* initilize our channel's cdr */
05188             ast_cdr_start(chan->cdr);
05189          }
05190          ast_set_variables(chan, vars);
05191          if (account)
05192             ast_cdr_setaccount(chan, account);
05193          if (chan->_state == AST_STATE_UP) {
05194             res = 0;
05195             if (option_verbose > 3)
05196                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05197             tmp = malloc(sizeof(struct app_tmp));
05198             if (tmp) {
05199                memset(tmp, 0, sizeof(struct app_tmp));
05200                ast_copy_string(tmp->app, app, sizeof(tmp->app));
05201                if (appdata)
05202                   ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
05203                tmp->chan = chan;
05204                if (sync > 1) {
05205                   if (locked_channel)
05206                      ast_mutex_unlock(&chan->lock);
05207                   ast_pbx_run_app(tmp);
05208                } else {
05209                   pthread_attr_init(&attr);
05210                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05211                   if (locked_channel) 
05212                      ast_mutex_lock(&chan->lock);
05213                   if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
05214                      ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
05215                      free(tmp);
05216                      if (locked_channel) 
05217                         ast_mutex_unlock(&chan->lock);
05218                      ast_hangup(chan);
05219                      res = -1;
05220                   } else {
05221                      if (locked_channel) 
05222                         *locked_channel = chan;
05223                   }
05224                }
05225             } else {
05226                ast_log(LOG_ERROR, "Out of memory :(\n");
05227                res = -1;
05228             }
05229          } else {
05230             if (option_verbose > 3)
05231                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05232             if (chan->cdr) { /* update the cdr */
05233                /* here we update the status of the call, which sould be busy.
05234                 * if that fails then we set the status to failed */
05235                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05236                   ast_cdr_failed(chan->cdr);
05237             }
05238             ast_hangup(chan);
05239          }
05240       }
05241       
05242       if (res < 0) { /* the call failed for some reason */
05243          if (*reason == 0) { /* if the call failed (not busy or no answer)
05244                         * update the cdr with the failed message */
05245             cdr_res = ast_pbx_outgoing_cdr_failed();
05246             if (cdr_res != 0) {
05247                res = cdr_res;
05248                goto outgoing_app_cleanup;
05249             }
05250          }
05251       }
05252 
05253    } else {
05254       as = malloc(sizeof(struct async_stat));
05255       if (!as) {
05256          res = -1;
05257          goto outgoing_app_cleanup;
05258       }
05259       memset(as, 0, sizeof(struct async_stat));
05260       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
05261       if (!chan) {
05262          free(as);
05263          res = -1;
05264          goto outgoing_app_cleanup;
05265       }
05266       as->chan = chan;
05267       ast_copy_string(as->app, app, sizeof(as->app));
05268       if (appdata)
05269          ast_copy_string(as->appdata,  appdata, sizeof(as->appdata));
05270       as->timeout = timeout;
05271       ast_set_variables(chan, vars);
05272       if (account)
05273          ast_cdr_setaccount(chan, account);
05274       /* Start a new thread, and get something handling this channel. */
05275       pthread_attr_init(&attr);
05276       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05277       if (locked_channel) 
05278          ast_mutex_lock(&chan->lock);
05279       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05280          ast_log(LOG_WARNING, "Failed to start async wait\n");
05281          free(as);
05282          if (locked_channel) 
05283             ast_mutex_unlock(&chan->lock);
05284          ast_hangup(chan);
05285          res = -1;
05286          goto outgoing_app_cleanup;
05287       } else {
05288          if (locked_channel)
05289             *locked_channel = chan;
05290       }
05291       res = 0;
05292    }
05293 outgoing_app_cleanup:
05294    ast_variables_destroy(vars);
05295    return res;
05296 }

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
 

Definition at line 4979 of file pbx.c.

References __ast_request_and_dial(), ast_channel::_state, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_alloc(), ast_exists_extension(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, async_stat::context, ast_channel::context, async_stat::exten, ast_channel::exten, free, ast_channel::hangupcause, LOAD_OH, ast_channel::lock, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, async_stat::priority, ast_channel::priority, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4.

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

04980 {
04981    struct ast_channel *chan;
04982    struct async_stat *as;
04983    int res = -1, cdr_res = -1;
04984    struct outgoing_helper oh;
04985    pthread_attr_t attr;
04986 
04987    if (sync) {
04988       LOAD_OH(oh);
04989       chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
04990       if (channel) {
04991          *channel = chan;
04992          if (chan)
04993             ast_mutex_lock(&chan->lock);
04994       }
04995       if (chan) {
04996          if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */
04997             ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name);
04998          } else {
04999             chan->cdr = ast_cdr_alloc();   /* allocate a cdr for the channel */
05000             if (!chan->cdr) {
05001                /* allocation of the cdr failed */
05002                ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
05003                free(chan->pbx);
05004                res = -1;
05005                goto outgoing_exten_cleanup;
05006             }
05007             /* allocation of the cdr was successful */
05008             ast_cdr_init(chan->cdr, chan);  /* initilize our channel's cdr */
05009             ast_cdr_start(chan->cdr);
05010          }
05011          if (chan->_state == AST_STATE_UP) {
05012                res = 0;
05013             if (option_verbose > 3)
05014                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
05015 
05016             if (sync > 1) {
05017                if (channel)
05018                   ast_mutex_unlock(&chan->lock);
05019                if (ast_pbx_run(chan)) {
05020                   ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name);
05021                   if (channel)
05022                      *channel = NULL;
05023                   ast_hangup(chan);
05024                   res = -1;
05025                }
05026             } else {
05027                if (ast_pbx_start(chan)) {
05028                   ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name);
05029                   if (channel) {
05030                      *channel = NULL;
05031                      ast_mutex_unlock(&chan->lock);
05032                   }
05033                   ast_hangup(chan);
05034                   res = -1;
05035                } 
05036             }
05037          } else {
05038             if (option_verbose > 3)
05039                ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
05040 
05041             if(chan->cdr) { /* update the cdr */
05042                /* here we update the status of the call, which sould be busy.
05043                 * if that fails then we set the status to failed */
05044                if (ast_cdr_disposition(chan->cdr, chan->hangupcause))
05045                   ast_cdr_failed(chan->cdr);
05046             }
05047          
05048             if (channel) {
05049                *channel = NULL;
05050                ast_mutex_unlock(&chan->lock);
05051             }
05052             ast_hangup(chan);
05053          }
05054       }
05055 
05056       if (res < 0) { /* the call failed for some reason */
05057          if (*reason == 0) { /* if the call failed (not busy or no answer)
05058                         * update the cdr with the failed message */
05059             cdr_res = ast_pbx_outgoing_cdr_failed();
05060             if (cdr_res != 0) {
05061                res = cdr_res;
05062                goto outgoing_exten_cleanup;
05063             }
05064          }
05065          
05066          /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */
05067          /* check if "failed" exists */
05068          if (ast_exists_extension(chan, context, "failed", 1, NULL)) {
05069             chan = ast_channel_alloc(0);
05070             if (chan) {
05071                ast_copy_string(chan->name, "OutgoingSpoolFailed", sizeof(chan->name));
05072                if (!ast_strlen_zero(context))
05073                   ast_copy_string(chan->context, context, sizeof(chan->context));
05074                ast_copy_string(chan->exten, "failed", sizeof(chan->exten));
05075                chan->priority = 1;
05076                ast_set_variables(chan, vars);
05077                if (account)
05078                   ast_cdr_setaccount(chan, account);
05079                ast_pbx_run(chan);   
05080             } else 
05081                ast_log(LOG_WARNING, "Can't allocate the channel structure, skipping execution of extension 'failed'\n");
05082          }
05083       }
05084    } else {
05085       as = malloc(sizeof(struct async_stat));
05086       if (!as) {
05087          res = -1;
05088          goto outgoing_exten_cleanup;
05089       }  
05090       memset(as, 0, sizeof(struct async_stat));
05091       chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
05092       if (channel) {
05093          *channel = chan;
05094          if (chan)
05095             ast_mutex_lock(&chan->lock);
05096       }
05097       if (!chan) {
05098          free(as);
05099          res = -1;
05100          goto outgoing_exten_cleanup;
05101       }
05102       as->chan = chan;
05103       ast_copy_string(as->context, context, sizeof(as->context));
05104       ast_copy_string(as->exten,  exten, sizeof(as->exten));
05105       as->priority = priority;
05106       as->timeout = timeout;
05107       ast_set_variables(chan, vars);
05108       if (account)
05109          ast_cdr_setaccount(chan, account);
05110       pthread_attr_init(&attr);
05111       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05112       if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
05113          ast_log(LOG_WARNING, "Failed to start async wait\n");
05114          free(as);
05115          if (channel) {
05116             *channel = NULL;
05117             ast_mutex_unlock(&chan->lock);
05118          }
05119          ast_hangup(chan);
05120          res = -1;
05121          goto outgoing_exten_cleanup;
05122       }
05123       res = 0;
05124    }
05125 outgoing_exten_cleanup:
05126    ast_variables_destroy(vars);
05127    return res;
05128 }

enum ast_pbx_result ast_pbx_run struct ast_channel c  ) 
 

Parameters:
c channel to run the pbx on
Returns:
Zero on success, non-zero on failure This executes the PBX on a given channel. It allocates a new PBX structure for the channel, and provides all PBX functionality.

Definition at line 2546 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(), mgcp_ss(), skinny_ss(), and ss_thread().

02547 {
02548    enum ast_pbx_result res = AST_PBX_SUCCESS;
02549 
02550    if (increase_call_count(c))
02551       return AST_PBX_CALL_LIMIT;
02552 
02553    res = __ast_pbx_run(c);
02554    decrease_call_count();
02555 
02556    return res;
02557 }

enum ast_pbx_result ast_pbx_start struct ast_channel c  ) 
 

Parameters:
c channel to start the pbx on
Returns:
Zero on success, non-zero on failure

Definition at line 2522 of file pbx.c.

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

Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_modem_new(), ast_pbx_outgoing_exten(), cb_events(), check_goto_on_transfer(), do_immediate_setup(), do_parking_thread(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), phone_new(), rpt_call(), sip_new(), skinny_new(), vpb_new(), and zt_new().

02523 {
02524    pthread_t t;
02525    pthread_attr_t attr;
02526 
02527    if (!c) {
02528       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02529       return AST_PBX_FAILED;
02530    }
02531       
02532    if (increase_call_count(c))
02533       return AST_PBX_CALL_LIMIT;
02534 
02535    /* Start a new thread, and get something handling this channel. */
02536    pthread_attr_init(&attr);
02537    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02538    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02539       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02540       return AST_PBX_FAILED;
02541    }
02542 
02543    return AST_PBX_SUCCESS;
02544 }

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

Dynamically register a new dial plan application.

Parameters:
app Short name of the application
execute a function callback to execute the application
synopsis a short description of the application
description long description of the application Include a one-line synopsis (e.g. 'hangs up a channel') and a more lengthy, multiline description with more detail, including under what conditions the application will return 0 or -1. This registers an application with asterisks internal application list. Please note: The individual applications themselves are responsible for registering and unregistering CLI commands. It returns 0 on success, -1 on failure.

Definition at line 2863 of file pbx.c.

References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), COLOR_BRCYAN, LOG_ERROR, LOG_WARNING, malloc, ast_app::name, ast_app::next, option_verbose, term_color(), and VERBOSE_PREFIX_2.

Referenced by load_module(), and load_pbx().

02864 {
02865    struct ast_app *tmp, *prev, *cur;
02866    char tmps[80];
02867    int length;
02868    length = sizeof(struct ast_app);
02869    length += strlen(app) + 1;
02870    if (ast_mutex_lock(&applock)) {
02871       ast_log(LOG_ERROR, "Unable to lock application list\n");
02872       return -1;
02873    }
02874    tmp = apps;
02875    while(tmp) {
02876       if (!strcasecmp(app, tmp->name)) {
02877          ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
02878          ast_mutex_unlock(&applock);
02879          return -1;
02880       }
02881       tmp = tmp->next;
02882    }
02883    tmp = malloc(length);
02884    if (tmp) {
02885       memset(tmp, 0, length);
02886       strcpy(tmp->name, app);
02887       tmp->execute = execute;
02888       tmp->synopsis = synopsis;
02889       tmp->description = description;
02890       /* Store in alphabetical order */
02891       cur = apps;
02892       prev = NULL;
02893       while(cur) {
02894          if (strcasecmp(tmp->name, cur->name) < 0)
02895             break;
02896          prev = cur;
02897          cur = cur->next;
02898       }
02899       if (prev) {
02900          tmp->next = prev->next;
02901          prev->next = tmp;
02902       } else {
02903          tmp->next = apps;
02904          apps = tmp;
02905       }
02906    } else {
02907       ast_log(LOG_ERROR, "Out of memory\n");
02908       ast_mutex_unlock(&applock);
02909       return -1;
02910    }
02911    if (option_verbose > 1)
02912       ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
02913    ast_mutex_unlock(&applock);
02914    return 0;
02915 }

int ast_register_switch struct ast_switch sw  ) 
 

Parameters:
sw switch to register This function registers a populated ast_switch structure with the asterisk switching architecture. It returns 0 on success, and other than 0 on failure

Definition at line 2917 of file pbx.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, LOG_WARNING, ast_switch::name, ast_switch::next, and switches.

Referenced by load_module().

02918 {
02919    struct ast_switch *tmp, *prev=NULL;
02920    if (ast_mutex_lock(&switchlock)) {
02921       ast_log(LOG_ERROR, "Unable to lock switch lock\n");
02922       return -1;
02923    }
02924    tmp = switches;
02925    while(tmp) {
02926       if (!strcasecmp(tmp->name, sw->name))
02927          break;
02928       prev = tmp;
02929       tmp = tmp->next;
02930    }
02931    if (tmp) {  
02932       ast_mutex_unlock(&switchlock);
02933       ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
02934       return -1;
02935    }
02936    sw->next = NULL;
02937    if (prev) 
02938       prev->next = sw;
02939    else
02940       switches = sw;
02941    ast_mutex_unlock(&switchlock);
02942    return 0;
02943 }

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

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. It returns 0 on success, -1 on failure.

Definition at line 2225 of file pbx.c.

References HELPER_SPAWN, and pbx_extension_helper().

Referenced by __ast_pbx_run(), loopback_exec(), and macro_exec().

02226 {
02227    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_SPAWN);
02228 }

int ast_unlock_context struct ast_context con  ) 
 

Parameters:
con context to unlock Unlocks the given context Returns 0 on success, -1 on failure

Definition at line 6278 of file pbx.c.

References ast_mutex_unlock(), and ast_context::lock.

Referenced by complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_ignorepat(), dundi_precache_full(), find_matching_endwhile(), and handle_save_dialplan().

06279 {
06280    return ast_mutex_unlock(&con->lock);
06281 }

int ast_unlock_contexts void   ) 
 

Returns 0 on success, -1 on failure

Definition at line 6265 of file pbx.c.

References ast_mutex_unlock().

Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), and handle_save_dialplan().

06266 {
06267    return ast_mutex_unlock(&conlock);
06268 }

int ast_unregister_application const char *  app  ) 
 

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 registration mechanisms. It returns 0 on success, and -1 on failure.

Definition at line 3610 of file pbx.c.

References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, LOG_ERROR, ast_app::name, ast_app::next, option_verbose, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

03611 {
03612    struct ast_app *tmp, *tmpl = NULL;
03613    if (ast_mutex_lock(&applock)) {
03614       ast_log(LOG_ERROR, "Unable to lock application list\n");
03615       return -1;
03616    }
03617    tmp = apps;
03618    while(tmp) {
03619       if (!strcasecmp(app, tmp->name)) {
03620          if (tmpl)
03621             tmpl->next = tmp->next;
03622          else
03623             apps = tmp->next;
03624          if (option_verbose > 1)
03625             ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
03626          free(tmp);
03627          ast_mutex_unlock(&applock);
03628          return 0;
03629       }
03630       tmpl = tmp;
03631       tmp = tmp->next;
03632    }
03633    ast_mutex_unlock(&applock);
03634    return -1;
03635 }

void ast_unregister_switch struct ast_switch sw  ) 
 

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

Definition at line 2945 of file pbx.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_switch::next, and switches.

Referenced by __unload_module(), and unload_module().

02946 {
02947    struct ast_switch *tmp, *prev=NULL;
02948    if (ast_mutex_lock(&switchlock)) {
02949       ast_log(LOG_ERROR, "Unable to lock switch lock\n");
02950       return;
02951    }
02952    tmp = switches;
02953    while(tmp) {
02954       if (tmp == sw) {
02955          if (prev)
02956             prev->next = tmp->next;
02957          else
02958             switches = tmp->next;
02959          tmp->next = NULL;
02960          break;         
02961       }
02962       prev = tmp;
02963       tmp = tmp->next;
02964    }
02965    ast_mutex_unlock(&switchlock);
02966 }

struct ast_exten* ast_walk_context_extensions struct ast_context con,
struct ast_exten priority
 

Definition at line 6385 of file pbx.c.

References exten, and ast_context::root.

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

06387 {
06388    if (!exten)
06389       return con ? con->root : NULL;
06390    else
06391       return exten->next;
06392 }

struct ast_ignorepat* ast_walk_context_ignorepats struct ast_context con,
struct ast_ignorepat ip
 

Definition at line 6421 of file pbx.c.

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

Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), and handle_save_dialplan().

06423 {
06424    if (!ip)
06425       return con ? con->ignorepats : NULL;
06426    else
06427       return ip->next;
06428 }

struct ast_include* ast_walk_context_includes struct ast_context con,
struct ast_include inc
 

Definition at line 6412 of file pbx.c.

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

Referenced by ast_context_verify_includes(), complete_context_add_include(), complete_context_dont_include(), handle_save_dialplan(), and show_dialplan_helper().

06414 {
06415    if (!inc)
06416       return con ? con->includes : NULL;
06417    else
06418       return inc->next;
06419 }

struct ast_sw* ast_walk_context_switches struct ast_context con,
struct ast_sw sw
 

Definition at line 6394 of file pbx.c.

References ast_context::alts, and ast_sw::next.

Referenced by handle_save_dialplan().

06396 {
06397    if (!sw)
06398       return con ? con->alts : NULL;
06399    else
06400       return sw->next;
06401 }

struct ast_context* ast_walk_contexts struct ast_context con  ) 
 

Definition at line 6377 of file pbx.c.

References contexts, and ast_context::next.

Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), pbx_load_module(), and show_dialplan_helper().

06378 {
06379    if (!con)
06380       return contexts;
06381    else
06382       return con->next;
06383 }

struct ast_exten* ast_walk_extension_priorities struct ast_exten exten,
struct ast_exten priority
 

Definition at line 6403 of file pbx.c.

References exten, and ast_exten::priority.

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

06405 {
06406    if (!priority)
06407       return exten;
06408    else
06409       return priority->peer;
06410 }

void pbx_builtin_clear_globals void   ) 
 

Definition at line 6122 of file pbx.c.

References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), and ast_var_delete().

Referenced by reload().

06123 {
06124    struct ast_var_t *vardata;
06125 
06126    ast_mutex_lock(&globalslock);
06127    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
06128       ast_var_delete(vardata);
06129    ast_mutex_unlock(&globalslock);
06130 }

char* pbx_builtin_getvar_helper struct ast_channel chan,
const char *  name
 

Definition at line 5917 of file pbx.c.

References AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), and ast_channel::varshead.

Referenced by __login_exec(), action_getvar(), agentmonitoroutgoing_exec(), ast_app_group_get_count(), ast_app_group_match_get_count(), ast_bridge_call(), ast_feature_interpret(), ast_monitor_stop(), ast_osp_lookup(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), check_goto_on_transfer(), conf_exec(), conf_run(), dial_exec_full(), do_chanreads(), dundi_exec(), dundi_helper(), get_index(), group_check_exec(), group_count_exec(), group_count_function_read(), group_function_read(), iax2_exec(), leave_voicemail(), macro_exec(), misdn_answer(), misdn_hangup(), oh323_hangup(), ospfinished_exec(), ospnext_exec(), queue_exec(), retrydial_exec(), return_exec(), sip_addheader(), try_suggested_sip_codec(), wait_for_answer(), zt_call(), and zt_hangup().

05918 {
05919         struct ast_var_t *variables;
05920         char *ret = NULL;
05921         int i;
05922         struct varshead *places[2] = { NULL, &globals };
05923         
05924         if (!name)
05925                 return NULL;
05926         if (chan)
05927                 places[0] = &chan->varshead;
05928 
05929         for (i = 0; i < 2; i++) {
05930                 if (!places[i])
05931                         continue;
05932                 if (places[i] == &globals)
05933                         ast_mutex_lock(&globalslock);
05934                 AST_LIST_TRAVERSE(places[i], variables, entries) {
05935                         if (!strcmp(name, ast_var_name(variables))) {
05936                                 ret = ast_var_value(variables);
05937                                 break;
05938                         }
05939                 }
05940                 if (places[i] == &globals)
05941                         ast_mutex_unlock(&globalslock);
05942                 if (ret)
05943                         break;
05944         }
05945 
05946         return ret;                
05947 }

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

Definition at line 5949 of file pbx.c.

References ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_var_assign(), ast_verbose(), LOG_WARNING, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.

Referenced by gosub_exec().

05950 {
05951    struct ast_var_t *newvariable;
05952    struct varshead *headp;
05953 
05954    if (name[strlen(name)-1] == ')') {
05955       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05956       return ast_func_write(chan, name, value);
05957    }
05958 
05959    headp = (chan) ? &chan->varshead : &globals;
05960 
05961    if (value) {
05962       if ((option_verbose > 1) && (headp == &globals))
05963          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05964       newvariable = ast_var_assign(name, value);
05965       if (headp == &globals)
05966          ast_mutex_lock(&globalslock);
05967       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05968       if (headp == &globals)
05969          ast_mutex_unlock(&globalslock);
05970    }
05971 }

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

Definition at line 5890 of file pbx.c.

References ast_build_string(), AST_LIST_TRAVERSE, ast_log(), ast_strlen_zero(), ast_var_name(), ast_var_value(), LOG_ERROR, total, var, and ast_channel::varshead.

Referenced by dumpchan_exec(), and handle_showchan().

05891 {
05892    struct ast_var_t *variables;
05893    char *var, *val;
05894    int total = 0;
05895 
05896    if (!chan)
05897       return 0;
05898 
05899    memset(buf, 0, size);
05900 
05901    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05902       if(variables &&
05903          (var=ast_var_name(variables)) && (val=ast_var_value(variables)) &&
05904          !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
05905          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05906             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05907             break;
05908          } else
05909             total++;
05910       } else 
05911          break;
05912    }
05913    
05914    return total;
05915 }

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
 

Definition at line 5973 of file pbx.c.

References ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.

Referenced by action_setvar(), aPGSQL_connect(), aPGSQL_fetch(), aPGSQL_query(), aqm_exec(), ast_app_group_set_channel(), ast_bridge_call(), ast_iax2_new(), ast_monitor_start(), ast_set_variables(), background_detect_exec(), builtin_blindtransfer(), builtin_function_set(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), curl_exec(), cut_exec(), dundi_lookup_exec(), enumlookup_exec(), eval_exec(), function_db_exists(), function_db_read(), get_exec(), get_refer_info(), group_check_exec(), group_count_exec(), group_match_count_exec(), handle_setvariable(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), macro_exec(), math_exec(), md5_exec(), md5check_exec(), misdn_call(), misdn_tx2ast_frm(), mixmonitor_exec(), monitor_handle_owned(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_importvar(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_extension_helper(), pbx_load_module(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), read_exec(), readfile_exec(), realtime_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_getheader(), sip_new(), sort_exec(), start_monitor_exec(), system_exec_helper(), transfer_exec(), txtcidname_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_new(), and zt_read().

05974 {
05975    struct ast_var_t *newvariable;
05976    struct varshead *headp;
05977    const char *nametail = name;
05978 
05979    if (name[strlen(name)-1] == ')')
05980       return ast_func_write(chan, name, value);
05981 
05982    headp = (chan) ? &chan->varshead : &globals;
05983 
05984    /* For comparison purposes, we have to strip leading underscores */
05985    if (*nametail == '_') {
05986       nametail++;
05987       if (*nametail == '_') 
05988          nametail++;
05989    }
05990 
05991    if (headp == &globals)
05992       ast_mutex_lock(&globalslock);
05993    AST_LIST_TRAVERSE (headp, newvariable, entries) {
05994       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
05995          /* there is already such a variable, delete it */
05996          AST_LIST_REMOVE(headp, newvariable, entries);
05997          ast_var_delete(newvariable);
05998          break;
05999       }
06000    }
06001    
06002    if (value) {
06003       if ((option_verbose > 1) && (headp == &globals))
06004          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
06005       newvariable = ast_var_assign(name, value);   
06006       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
06007    }
06008    
06009    if (headp == &globals)
06010       ast_mutex_unlock(&globalslock);
06011 }

int pbx_checkcondition char *  condition  ) 
 

Definition at line 6132 of file pbx.c.

Referenced by gosubif_exec(), and pbx_builtin_gotoif().

06133 {
06134    if (condition) {
06135       if (*condition == '\0') {
06136          /* Empty strings are false */
06137          return 0;
06138       } else if (*condition >= '0' && *condition <= '9') {
06139          /* Numbers are evaluated for truth */
06140          return atoi(condition);
06141       } else {
06142          /* Strings are true */
06143          return 1;
06144       }
06145    } else {
06146       /* NULL is also false */
06147       return 0;
06148    }
06149 }

int pbx_exec struct ast_channel c,
struct ast_app app,
void *  data,
int  newstack
 

Parameters:
c channel to execute on
app which app to execute
data the data passed into the app
newstack stack pointer This application executes an application on a given channel. It saves the stack and executes the given appliation passing in the given data. It returns 0 on success, and -1 on failure
Parameters:
c  Channel
app  Application
data  Data for execution
newstack  Force stack increment

Definition at line 531 of file pbx.c.

References app, ast_channel::appl, ast_cdr_setapp(), ast_log(), ast_channel::cdr, ast_channel::data, and LOG_WARNING.

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

00535 {
00536    int res;
00537    
00538    char *saved_c_appl;
00539    char *saved_c_data;
00540    
00541    int (*execute)(struct ast_channel *chan, void *data) = app->execute; 
00542 
00543    if (newstack) {
00544       if (c->cdr)
00545          ast_cdr_setapp(c->cdr, app->name, data);
00546 
00547       /* save channel values */
00548       saved_c_appl= c->appl;
00549       saved_c_data= c->data;
00550 
00551       c->appl = app->name;
00552       c->data = data;      
00553       res = execute(c, data);
00554       /* restore channel values */
00555       c->appl= saved_c_appl;
00556       c->data= saved_c_data;
00557       return res;
00558    } else
00559       ast_log(LOG_WARNING, "You really didn't want to call this function with newstack set to 0\n");
00560    return -1;
00561 }

struct ast_app* pbx_findapp const char *  app  ) 
 

Find application handle in linked list.

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

References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, ast_app::name, and ast_app::next.

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

00577 {
00578    struct ast_app *tmp;
00579 
00580    if (ast_mutex_lock(&applock)) {
00581       ast_log(LOG_WARNING, "Unable to obtain application lock\n");
00582       return NULL;
00583    }
00584    tmp = apps;
00585    while(tmp) {
00586       if (!strcasecmp(tmp->name, app))
00587          break;
00588       tmp = tmp->next;
00589    }
00590    ast_mutex_unlock(&applock);
00591    return tmp;
00592 }

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 and functions in the dialplan ---

Definition at line 979 of file pbx.c.

References ast_channel::accountcode, ast_get_hint(), AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, ast_channel::hangupcause, ast_channel::language, LOG_WARNING, ast_channel::name, offset, parse_variable_name(), pbx_retrieve_variable(), ast_channel::priority, substring(), ast_channel::uniqueid, and ast_channel::varshead.

Referenced by function_fieldqty(), handle_getvariable(), pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().

00980 {
00981    char tmpvar[80];
00982    time_t thistime;
00983    struct tm brokentime;
00984    int offset, offset2, isfunc;
00985    struct ast_var_t *variables;
00986 
00987    if (c) 
00988       headp=&c->varshead;
00989    *ret=NULL;
00990    ast_copy_string(tmpvar, var, sizeof(tmpvar));
00991    if (parse_variable_name(tmpvar, &offset, &offset2, &isfunc)) {
00992       pbx_retrieve_variable(c, tmpvar, ret, workspace, workspacelen, headp);
00993       if (!(*ret)) 
00994          return;
00995       *ret = substring(*ret, offset, offset2, workspace, workspacelen);
00996    } else if (c && !strncmp(var, "CALL", 4)) {
00997       if (!strncmp(var + 4, "ER", 2)) {
00998          if (!strncmp(var + 6, "ID", 2)) {
00999             if (!var[8]) {          /* CALLERID */
01000                if (c->cid.cid_num) {
01001                   if (c->cid.cid_name) {
01002                      snprintf(workspace, workspacelen, "\"%s\" <%s>", c->cid.cid_name, c->cid.cid_num);
01003                   } else {
01004                      ast_copy_string(workspace, c->cid.cid_num, workspacelen);
01005                   }
01006                   *ret = workspace;
01007                } else if (c->cid.cid_name) {
01008                   ast_copy_string(workspace, c->cid.cid_name, workspacelen);
01009                   *ret = workspace;
01010                } else
01011                   *ret = NULL;
01012             } else if (!strcmp(var + 8, "NUM")) {
01013                /* CALLERIDNUM */
01014                if (c->cid.cid_num) {
01015                   ast_copy_string(workspace, c->cid.cid_num, workspacelen);
01016                   *ret = workspace;
01017                } else
01018                   *ret = NULL;
01019             } else if (!strcmp(var + 8, "NAME")) {
01020                /* CALLERIDNAME */
01021                if (c->cid.cid_name) {
01022                   ast_copy_string(workspace, c->cid.cid_name, workspacelen);
01023                   *ret = workspace;
01024                } else
01025                   *ret = NULL;
01026             } else
01027                goto icky;
01028          } else if (!strcmp(var + 6, "ANI")) {
01029             /* CALLERANI */
01030             if (c->cid.cid_ani) {
01031                ast_copy_string(workspace, c->cid.cid_ani, workspacelen);
01032                *ret = workspace;
01033             } else
01034                *ret = NULL;
01035          } else
01036             goto icky;
01037       } else if (!strncmp(var + 4, "ING", 3)) {
01038          if (!strcmp(var + 7, "PRES")) {
01039             /* CALLINGPRES */
01040             snprintf(workspace, workspacelen, "%d", c->cid.cid_pres);
01041             *ret = workspace;
01042          } else if (!strcmp(var + 7, "ANI2")) {
01043             /* CALLINGANI2 */
01044             snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2);
01045             *ret = workspace;
01046          } else if (!strcmp(var + 7, "TON")) {
01047             /* CALLINGTON */
01048             snprintf(workspace, workspacelen, "%d", c->cid.cid_ton);
01049             *ret = workspace;
01050          } else if (!strcmp(var + 7, "TNS")) {
01051             /* CALLINGTNS */
01052             snprintf(workspace, workspacelen, "%d", c->cid.cid_tns);
01053             *ret = workspace;
01054          } else
01055             goto icky;
01056       } else
01057          goto icky;
01058    } else if (c && !strcmp(var, "DNID")) {
01059       if (c->cid.cid_dnid) {
01060          ast_copy_string(workspace, c->cid.cid_dnid, workspacelen);
01061          *ret = workspace;
01062       } else
01063          *ret = NULL;
01064    } else if (c && !strcmp(var, "HINT")) {
01065       if (!ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten))
01066          *ret = NULL;
01067       else
01068          *ret = workspace;
01069    } else if (c && !strcmp(var, "HINTNAME")) {
01070       if (!ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten))
01071          *ret = NULL;
01072       else
01073          *ret = workspace;
01074    } else if (c && !strcmp(var, "EXTEN")) {
01075       ast_copy_string(workspace, c->exten, workspacelen);
01076       *ret = workspace;
01077    } else if (c && !strcmp(var, "RDNIS")) {
01078       if (c->cid.cid_rdnis) {
01079          ast_copy_string(workspace, c->cid.cid_rdnis, workspacelen);
01080          *ret = workspace;
01081       } else
01082          *ret = NULL;
01083    } else if (c && !strcmp(var, "CONTEXT")) {
01084       ast_copy_string(workspace, c->context, workspacelen);
01085       *ret = workspace;
01086    } else if (c && !strcmp(var, "PRIORITY")) {
01087       snprintf(workspace, workspacelen, "%d", c->priority);
01088       *ret = workspace;
01089    } else if (c && !strcmp(var, "CHANNEL")) {
01090       ast_copy_string(workspace, c->name, workspacelen);
01091       *ret = workspace;
01092    } else if (!strcmp(var, "EPOCH")) {
01093       snprintf(workspace, workspacelen, "%u",(int)time(NULL));
01094       *ret = workspace;
01095    } else if (!strcmp(var, "DATETIME")) {
01096       thistime=time(NULL);
01097       localtime_r(&thistime, &brokentime);
01098       snprintf(workspace, workspacelen, "%02d%02d%04d-%02d:%02d:%02d",
01099          brokentime.tm_mday,
01100          brokentime.tm_mon+1,
01101          brokentime.tm_year+1900,
01102          brokentime.tm_hour,
01103          brokentime.tm_min,
01104          brokentime.tm_sec
01105       );
01106       *ret = workspace;
01107    } else if (!strcmp(var, "TIMESTAMP")) {
01108       thistime=time(NULL);
01109       localtime_r(&thistime, &brokentime);
01110       /* 20031130-150612 */
01111       snprintf(workspace, workspacelen, "%04d%02d%02d-%02d%02d%02d",
01112          brokentime.tm_year+1900,
01113          brokentime.tm_mon+1,
01114          brokentime.tm_mday,
01115          brokentime.tm_hour,
01116          brokentime.tm_min,
01117          brokentime.tm_sec
01118       );
01119       *ret = workspace;
01120    } else if (c && !strcmp(var, "UNIQUEID")) {
01121       snprintf(workspace, workspacelen, "%s", c->uniqueid);
01122       *ret = workspace;
01123    } else if (c && !strcmp(var, "HANGUPCAUSE")) {
01124       snprintf(workspace, workspacelen, "%d", c->hangupcause);
01125       *ret = workspace;
01126    } else if (c && !strcmp(var, "ACCOUNTCODE")) {
01127       ast_copy_string(workspace, c->accountcode, workspacelen);
01128       *ret = workspace;
01129    } else if (c && !strcmp(var, "LANGUAGE")) {
01130       ast_copy_string(workspace, c->language, workspacelen);
01131       *ret = workspace;
01132    } else {
01133 icky:
01134       if (headp) {
01135          AST_LIST_TRAVERSE(headp,variables,entries) {
01136 #if 0
01137             ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",var,ast_var_name(variables));
01138 #endif
01139             if (strcasecmp(ast_var_name(variables),var)==0) {
01140                *ret=ast_var_value(variables);
01141                if (*ret) {
01142                   ast_copy_string(workspace, *ret, workspacelen);
01143                   *ret = workspace;
01144                }
01145                break;
01146             }
01147          }
01148       }
01149       if (!(*ret)) {
01150          /* Try globals */
01151          ast_mutex_lock(&globalslock);
01152          AST_LIST_TRAVERSE(&globals,variables,entries) {
01153             if (strcasecmp(ast_var_name(variables),var)==0) {
01154                *ret = ast_var_value(variables);
01155                if (*ret) {
01156                   ast_copy_string(workspace, *ret, workspacelen);
01157                   *ret = workspace;
01158                }
01159             }
01160          }
01161          ast_mutex_unlock(&globalslock);
01162       }
01163    }
01164 }

int pbx_set_autofallthrough int  newval  ) 
 

Definition at line 2564 of file pbx.c.

Referenced by pbx_load_module().

02565 {
02566    int oldval;
02567    oldval = autofallthrough;
02568    if (oldval != newval)
02569       autofallthrough = newval;
02570    return oldval;
02571 }

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

Definition at line 1595 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

Referenced by custom_log(), cut_internal(), eval_exec(), exec_exec(), function_eval(), handle_getvariablefull(), mixmonitor_thread(), pbx_builtin_importvar(), pbx_load_module(), pbx_substitute_variables(), realtime_exec(), sendmail(), and sendpage().

01596 {
01597    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
01598 }

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

Definition at line 1600 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

01601 {
01602    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01603 }


Variable Documentation

const struct cfextension_states extension_states[] [static]
 

Referenced by ast_extension_state2str().


Generated on Sat Mar 24 23:29:55 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6