Mon Mar 20 08:20:29 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

pbx.h File Reference

Core PBX routines and definitions. More...

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

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_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

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 __ast_pbx_run(), agi_handle_command(), and macro_exec().

#define AST_PBX_NO_HANGUP_PEER   11
 

Definition at line 41 of file pbx.h.

#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_hint_extension().


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

Enumeration values:
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
 

Enumeration values:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 209 of file pbx.h.

Referenced by ast_pbx_run(), ast_pbx_start(), and handle_request_invite().

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

Referenced by handle_chanlist().

02551 {
02552    return countcalls;
02553 }

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

04486 {
04487    struct ast_context *c;
04488 
04489    if (ast_lock_contexts()) {
04490       errno = EBUSY;
04491       return -1;
04492    }
04493 
04494    c = ast_walk_contexts(NULL);
04495    while (c) {
04496       if (!strcmp(context, ast_get_context_name(c))) {
04497          int ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04498             application, data, datad, registrar);
04499          ast_unlock_contexts();
04500          return ret;
04501       }
04502       c = ast_walk_contexts(c);
04503    }
04504 
04505    ast_unlock_contexts();
04506    errno = ENOENT;
04507    return -1;
04508 }

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

References ast_exten::app, 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, ext_strncpy(), ast_exten::exten, free, globals, ast_exten::label, ast_context::lock, LOG_ERROR, LOG_WARNING, malloc, ast_exten::matchcid, ast_context::name, ast_exten::next, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::peer, ast_exten::priority, ast_exten::registrar, ast_context::root, and ast_exten::stuff.

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

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

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

Definition at line 4529 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(), i4l_read(), misdn_tx2ast_frm(), monitor_handle_owned(), socket_read(), and zt_read().

04530 {
04531    int res = 0;
04532 
04533    ast_mutex_lock(&chan->lock);
04534 
04535    if (chan->pbx) {
04536       /* This channel is currently in the PBX */
04537       ast_explicit_goto(chan, context, exten, priority);
04538       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
04539    } else {
04540       /* In order to do it when the channel doesn't really exist within
04541          the PBX, we have to make a new channel, masquerade, and start the PBX
04542          at the new location */
04543       struct ast_channel *tmpchan;
04544       tmpchan = ast_channel_alloc(0);
04545       if (tmpchan) {
04546          snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name);
04547          ast_setstate(tmpchan, chan->_state);
04548          /* Make formats okay */
04549          tmpchan->readformat = chan->readformat;
04550          tmpchan->writeformat = chan->writeformat;
04551          /* Setup proper location */
04552          ast_explicit_goto(tmpchan,
04553                  (!ast_strlen_zero(context)) ? context : chan->context,
04554                  (!ast_strlen_zero(exten)) ? exten : chan->exten,
04555                  priority);
04556 
04557          /* Masquerade into temp channel */
04558          ast_channel_masquerade(tmpchan, chan);
04559       
04560          /* Grab the locks and get going */
04561          ast_mutex_lock(&tmpchan->lock);
04562          ast_do_masquerade(tmpchan);
04563          ast_mutex_unlock(&tmpchan->lock);
04564          /* Start the PBX going on our stolen channel */
04565          if (ast_pbx_start(tmpchan)) {
04566             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
04567             ast_hangup(tmpchan);
04568             res = -1;
04569          }
04570       } else {
04571          res = -1;
04572       }
04573    }
04574    ast_mutex_unlock(&chan->lock);
04575    return res;
04576 }

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

Definition at line 4578 of file pbx.c.

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

04579 {
04580    struct ast_channel *chan;
04581    int res = -1;
04582 
04583    chan = ast_get_channel_by_name_locked(channame);
04584    if (chan) {
04585       res = ast_async_goto(chan, context, exten, priority);
04586       ast_mutex_unlock(&chan->lock);
04587    }
04588    return res;
04589 }

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

Definition at line 6426 of file pbx.c.

References __ast_goto_if_exists().

06426                                                                                                  {
06427    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06428 }

int ast_build_timing struct ast_timing i,
char *  info
 

Definition at line 4062 of file pbx.c.

References ast_strlen_zero(), ast_timing::daymask, ast_timing::dowmask, 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().

04063 {
04064    char info_save[256];
04065    char *info;
04066    char *c;
04067 
04068    /* Check for empty just in case */
04069    if (ast_strlen_zero(info_in))
04070       return 0;
04071    /* make a copy just in case we were passed a static string */
04072    ast_copy_string(info_save, info_in, sizeof(info_save));
04073    info = info_save;
04074    /* Assume everything except time */
04075    i->monthmask = (1 << 12) - 1;
04076    i->daymask = (1 << 30) - 1 + (1 << 30);
04077    i->dowmask = (1 << 7) - 1;
04078    /* Avoid using str tok */
04079    FIND_NEXT;
04080    /* Info has the time range, start with that */
04081    get_timerange(i, info);
04082    info = c;
04083    if (!info)
04084       return 1;
04085    FIND_NEXT;
04086    /* Now check for day of week */
04087    i->dowmask = get_dow(info);
04088 
04089    info = c;
04090    if (!info)
04091       return 1;
04092    FIND_NEXT;
04093    /* Now check for the day of the month */
04094    i->daymask = get_day(info);
04095    info = c;
04096    if (!info)
04097       return 1;
04098    FIND_NEXT;
04099    /* And finally go for the month */
04100    i->monthmask = get_month(info);
04101 
04102    return 1;
04103 }

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

02207 {
02208    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_CANMATCH);
02209 }

int ast_check_timing struct ast_timing i  ) 
 

Definition at line 4105 of file pbx.c.

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

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

04106 {
04107    struct tm tm;
04108    time_t t;
04109 
04110    time(&t);
04111    localtime_r(&t,&tm);
04112 
04113    /* If it's not the right month, return */
04114    if (!(i->monthmask & (1 << tm.tm_mon))) {
04115       return 0;
04116    }
04117 
04118    /* If it's not that time of the month.... */
04119    /* Warning, tm_mday has range 1..31! */
04120    if (!(i->daymask & (1 << (tm.tm_mday-1))))
04121       return 0;
04122 
04123    /* If it's not the right day of the week */
04124    if (!(i->dowmask & (1 << tm.tm_wday)))
04125       return 0;
04126 
04127    /* Sanity check the hour just to be safe */
04128    if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) {
04129       ast_log(LOG_WARNING, "Insane time...\n");
04130       return 0;
04131    }
04132 
04133    /* Now the tough part, we calculate if it fits
04134       in the right time based on min/hour */
04135    if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2))))
04136       return 0;
04137 
04138    /* If we got this far, then we're good */
04139    return 1;
04140 }

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

04402 {
04403    struct ast_context *c;
04404 
04405    if (ast_lock_contexts()) {
04406       errno = EBUSY;
04407       return -1;
04408    }
04409 
04410    c = ast_walk_contexts(NULL);
04411    while (c) {
04412       if (!strcmp(ast_get_context_name(c), con)) {
04413          int ret = ast_context_add_ignorepat2(c, value, registrar);
04414          ast_unlock_contexts();
04415          return ret;
04416       } 
04417       c = ast_walk_contexts(c);
04418    }
04419 
04420    ast_unlock_contexts();
04421    errno = ENOENT;
04422    return -1;
04423 }

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

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

04426 {
04427    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04428    int length;
04429    length = sizeof(struct ast_ignorepat);
04430    length += strlen(value) + 1;
04431    ignorepat = malloc(length);
04432    if (!ignorepat) {
04433       ast_log(LOG_ERROR, "Out of memory\n");
04434       errno = ENOMEM;
04435       return -1;
04436    }
04437    memset(ignorepat, 0, length);
04438    strcpy(ignorepat->pattern, value);
04439    ignorepat->next = NULL;
04440    ignorepat->registrar = registrar;
04441    ast_mutex_lock(&con->lock);
04442    ignorepatc = con->ignorepats;
04443    while(ignorepatc) {
04444       ignorepatl = ignorepatc;
04445       if (!strcasecmp(ignorepatc->pattern, value)) {
04446          /* Already there */
04447          ast_mutex_unlock(&con->lock);
04448          errno = EEXIST;
04449          return -1;
04450       }
04451       ignorepatc = ignorepatc->next;
04452    }
04453    if (ignorepatl) 
04454       ignorepatl->next = ignorepat;
04455    else
04456       con->ignorepats = ignorepat;
04457    ast_mutex_unlock(&con->lock);
04458    return 0;
04459    
04460 }

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

03785 {
03786    struct ast_context *c;
03787 
03788    if (ast_lock_contexts()) {
03789       errno = EBUSY;
03790       return -1;
03791    }
03792 
03793    /* walk contexts ... */
03794    c = ast_walk_contexts(NULL);
03795    while (c) {
03796       /* ... search for the right one ... */
03797       if (!strcmp(ast_get_context_name(c), context)) {
03798          int ret = ast_context_add_include2(c, include, registrar);
03799          /* ... unlock contexts list and return */
03800          ast_unlock_contexts();
03801          return ret;
03802       }
03803       c = ast_walk_contexts(c);
03804    }
03805 
03806    /* we can't find the right context */
03807    ast_unlock_contexts();
03808    errno = ENOENT;
03809    return -1;
03810 }

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

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

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

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

04226 {
04227    struct ast_context *c;
04228 
04229    if (ast_lock_contexts()) {
04230       errno = EBUSY;
04231       return -1;
04232    }
04233 
04234    /* walk contexts ... */
04235    c = ast_walk_contexts(NULL);
04236    while (c) {
04237       /* ... search for the right one ... */
04238       if (!strcmp(ast_get_context_name(c), context)) {
04239          int ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04240          /* ... unlock contexts list and return */
04241          ast_unlock_contexts();
04242          return ret;
04243       }
04244       c = ast_walk_contexts(c);
04245    }
04246 
04247    /* we can't find the right context */
04248    ast_unlock_contexts();
04249    errno = ENOENT;
04250    return -1;
04251 }

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 4260 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, ast_sw::tmpdata, and VERBOSE_PREFIX_3.

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

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

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

References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_context::ignorepats, ast_context::includes, ast_context::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, ast_context::name, name, ast_context::next, option_verbose, ast_context::registrar, ast_context::root, and VERBOSE_PREFIX_3.

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

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

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

References __ast_context_destroy().

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

05357 {
05358    __ast_context_destroy(con,registrar);
05359 }

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

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

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

00728 {
00729    struct ast_context *tmp;
00730    ast_mutex_lock(&conlock);
00731    if (name) {
00732       tmp = contexts;
00733       while(tmp) {
00734          if (!strcasecmp(name, tmp->name))
00735             break;
00736          tmp = tmp->next;
00737       }
00738    } else
00739       tmp = contexts;
00740    ast_mutex_unlock(&conlock);
00741    return tmp;
00742 }

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

02714 {
02715    struct ast_context *c;
02716 
02717    if (ast_lock_contexts()) return -1;
02718 
02719    /* walk contexts ... */
02720    c = ast_walk_contexts(NULL);
02721    while (c) {
02722       /* ... search for the right one ... */
02723       if (!strcmp(ast_get_context_name(c), context)) {
02724          /* ... remove extension ... */
02725          int ret = ast_context_remove_extension2(c, extension, priority,
02726             registrar);
02727          /* ... unlock contexts list and return */
02728          ast_unlock_contexts();
02729          return ret;
02730       }
02731       c = ast_walk_contexts(c);
02732    }
02733 
02734    /* we can't find the right context */
02735    ast_unlock_contexts();
02736    return -1;
02737 }

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

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

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

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

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

04343 {
04344    struct ast_context *c;
04345 
04346    if (ast_lock_contexts()) {
04347       errno = EBUSY;
04348       return -1;
04349    }
04350 
04351    c = ast_walk_contexts(NULL);
04352    while (c) {
04353       if (!strcmp(ast_get_context_name(c), context)) {
04354          int ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04355          ast_unlock_contexts();
04356          return ret;
04357       }
04358       c = ast_walk_contexts(c);
04359    }
04360 
04361    ast_unlock_contexts();
04362    errno = ENOENT;
04363    return -1;
04364 }

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

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

04367 {
04368    struct ast_ignorepat *ip, *ipl = NULL;
04369 
04370    if (ast_mutex_lock(&con->lock)) {
04371       errno = EBUSY;
04372       return -1;
04373    }
04374 
04375    ip = con->ignorepats;
04376    while (ip) {
04377       if (!strcmp(ip->pattern, ignorepat) &&
04378          (!registrar || (registrar == ip->registrar))) {
04379          if (ipl) {
04380             ipl->next = ip->next;
04381             free(ip);
04382          } else {
04383             con->ignorepats = ip->next;
04384             free(ip);
04385          }
04386          ast_mutex_unlock(&con->lock);
04387          return 0;
04388       }
04389       ipl = ip; ip = ip->next;
04390    }
04391 
04392    ast_mutex_unlock(&con->lock);
04393    errno = EINVAL;
04394    return -1;
04395 }

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

See add_include

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

02570 {
02571    struct ast_context *c;
02572 
02573    if (ast_lock_contexts()) return -1;
02574 
02575    /* walk contexts and search for the right one ...*/
02576    c = ast_walk_contexts(NULL);
02577    while (c) {
02578       /* we found one ... */
02579       if (!strcmp(ast_get_context_name(c), context)) {
02580          int ret;
02581          /* remove include from this context ... */   
02582          ret = ast_context_remove_include2(c, include, registrar);
02583 
02584          ast_unlock_contexts();
02585 
02586          /* ... return results */
02587          return ret;
02588       }
02589       c = ast_walk_contexts(c);
02590    }
02591 
02592    /* we can't find the right one context */
02593    ast_unlock_contexts();
02594    return -1;
02595 }

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

See add_include2

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

02606 {
02607    struct ast_include *i, *pi = NULL;
02608 
02609    if (ast_mutex_lock(&con->lock)) return -1;
02610 
02611    /* walk includes */
02612    i = con->includes;
02613    while (i) {
02614       /* find our include */
02615       if (!strcmp(i->name, include) && 
02616          (!registrar || !strcmp(i->registrar, registrar))) {
02617          /* remove from list */
02618          if (pi)
02619             pi->next = i->next;
02620          else
02621             con->includes = i->next;
02622          /* free include and return */
02623          free(i);
02624          ast_mutex_unlock(&con->lock);
02625          return 0;
02626       }
02627       pi = i;
02628       i = i->next;
02629    }
02630 
02631    /* we can't find the right include */
02632    ast_mutex_unlock(&con->lock);
02633    return -1;
02634 }

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

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

02642 {
02643    struct ast_context *c;
02644 
02645    if (ast_lock_contexts()) return -1;
02646 
02647    /* walk contexts and search for the right one ...*/
02648    c = ast_walk_contexts(NULL);
02649    while (c) {
02650       /* we found one ... */
02651       if (!strcmp(ast_get_context_name(c), context)) {
02652          int ret;
02653          /* remove switch from this context ... */ 
02654          ret = ast_context_remove_switch2(c, sw, data, registrar);
02655 
02656          ast_unlock_contexts();
02657 
02658          /* ... return results */
02659          return ret;
02660       }
02661       c = ast_walk_contexts(c);
02662    }
02663 
02664    /* we can't find the right one context */
02665    ast_unlock_contexts();
02666    return -1;
02667 }

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

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

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

06391 {
06392    struct ast_include *inc;
06393    int res = 0;
06394 
06395    for (inc = ast_walk_context_includes(con, NULL); inc; inc = ast_walk_context_includes(con, inc))
06396       if (!ast_context_find(inc->rname)) {
06397          res = -1;
06398          ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n",
06399                ast_get_context_name(con), inc->rname);
06400       }
06401    return res;
06402 }

struct ast_custom_function* ast_custom_function_find char *  name  ) 
 

Definition at line 1256 of file pbx.c.

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

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

01257 {
01258    struct ast_custom_function *acfptr;
01259 
01260    /* try to lock functions list ... */
01261    if (ast_mutex_lock(&acflock)) {
01262       ast_log(LOG_ERROR, "Unable to lock function list\n");
01263       return NULL;
01264    }
01265 
01266    for (acfptr = acf_root; acfptr; acfptr = acfptr->next) {
01267       if (!strcmp(name, acfptr->name)) {
01268          break;
01269       }
01270    }
01271 
01272    ast_mutex_unlock(&acflock);
01273    
01274    return acfptr;
01275 }

int ast_custom_function_register struct ast_custom_function acf  ) 
 

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

01313 {
01314    if (!acf)
01315       return -1;
01316 
01317    /* try to lock functions list ... */
01318    if (ast_mutex_lock(&acflock)) {
01319       ast_log(LOG_ERROR, "Unable to lock function list. Failed registering function %s\n", acf->name);
01320       return -1;
01321    }
01322 
01323    if (ast_custom_function_find(acf->name)) {
01324       ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name);
01325       ast_mutex_unlock(&acflock);
01326       return -1;
01327    }
01328 
01329    acf->next = acf_root;
01330    acf_root = acf;
01331 
01332    ast_mutex_unlock(&acflock);
01333 
01334    if (option_verbose > 1)
01335       ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name);
01336 
01337    return 0;
01338 }

int ast_custom_function_unregister struct ast_custom_function acf  ) 
 

Definition at line 1277 of file pbx.c.

References acf_root, 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 unload_module().

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

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

References HELPER_EXEC, and pbx_extension_helper().

Referenced by loopback_exec().

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

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 2191 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_app_dtget(), ast_pbx_outgoing_exten(), ast_waitstream_exten(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), console_dial(), console_transfer(), disa_exec(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), i4l_read(), 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(), rpt_exec(), skinny_ss(), socket_read(), ss_thread(), and zt_read().

02192 {
02193    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXISTS);
02194 }

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

Definition at line 4510 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_async_goto(), ast_parseable_goto(), builtin_atxfer(), disa_exec(), and handle_setpriority().

04511 {
04512    if (!chan)
04513       return -1;
04514 
04515    if (!ast_strlen_zero(context))
04516       ast_copy_string(chan->context, context, sizeof(chan->context));
04517    if (!ast_strlen_zero(exten))
04518       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04519    if (priority > -1) {
04520       chan->priority = priority;
04521       /* see flag description in channel.h for explanation */
04522       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04523          chan->priority--;
04524    }
04525    
04526    return 0;
04527 }

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

Definition at line 706 of file pbx.c.

References ast_strlen_zero(), and EXTENSION_MATCH_CORE.

Referenced by pbx_find_extension(), and realtime_switch_common().

00707 {
00708    int match;
00709    /* If "data" is longer, it can'be a subset of pattern unless
00710       pattern is a pattern match */
00711    if ((strlen(pattern) < strlen(data)) && (pattern[0] != '_'))
00712       return 0;
00713    
00714    if ((ast_strlen_zero((char *)data) || !strncasecmp(pattern, data, strlen(data))) && 
00715       (!needmore || (strlen(pattern) > strlen(data)))) {
00716       return 1;
00717    }
00718    EXTENSION_MATCH_CORE(data,pattern,match);
00719    /* If there's more or we don't care about more, or if it's a possible early match, 
00720       return non-zero; otherwise it's a miss */
00721    if (!needmore || *pattern || match == 2) {
00722       return match;
00723    } else
00724       return 0;
00725 }

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

References EXTENSION_MATCH_CORE.

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

00694 {
00695    int match;
00696    /* If they're the same return */
00697    if (!strcmp(pattern, data))
00698       return 1;
00699    EXTENSION_MATCH_CORE(data,pattern,match);
00700    /* Must be at the end of both */
00701    if (*data || (*pattern && (*pattern != '/')))
00702       match = 0;
00703    return match;
00704 }

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

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

01864 {
01865    struct ast_exten *e;
01866 
01867    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */ 
01868    if (!e) 
01869       return -1;           /* No hint, return -1 */
01870 
01871    return ast_extension_state2(e);        /* Check all devices in the hint */
01872 }

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

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

01851 {
01852    int i;
01853 
01854    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
01855       if (extension_states[i].extension_state == extension_state) {
01856          return extension_states[i].text;
01857       }
01858    }
01859    return "Unknown"; 
01860 }

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

References ast_hint_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_state_cb::id, malloc, ast_hint::next, ast_state_cb::next, statecbs, and stateid.

Referenced by handle_request_subscribe(), and init_manager().

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

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

References ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, free, ast_state_cb::id, ast_hint::next, ast_state_cb::next, and statecbs.

Referenced by __sip_destroy().

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

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

References HELPER_FINDLABEL, and pbx_extension_helper().

Referenced by ast_parseable_goto(), and handle_setpriority().

02197 {
02198    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, HELPER_FINDLABEL);
02199 }

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

Definition at line 2201 of file pbx.c.

References HELPER_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_module().

02202 {
02203    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, HELPER_FINDLABEL);
02204 }

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

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

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

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

const char* ast_get_context_name struct ast_context con  ) 
 

Definition at line 6246 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(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().

06247 {
06248    return con ? con->name : NULL;
06249 }

const char* ast_get_context_registrar struct ast_context c  ) 
 

Definition at line 6279 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06280 {
06281    return c ? c->registrar : NULL;
06282 }

const char* ast_get_extension_app struct ast_exten e  ) 
 

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

06310 {
06311    return e ? e->app : NULL;
06312 }

void* ast_get_extension_app_data struct ast_exten e  ) 
 

Definition at line 6314 of file pbx.c.

References ast_exten::data.

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

06315 {
06316    return e ? e->data : NULL;
06317 }

const char* ast_get_extension_cidmatch struct ast_exten e  ) 
 

Definition at line 6304 of file pbx.c.

References ast_exten::cidmatch.

Referenced by find_matching_priority(), and handle_save_dialplan().

06305 {
06306    return e ? e->cidmatch : NULL;
06307 }

const char* ast_get_extension_label struct ast_exten e  ) 
 

Definition at line 6256 of file pbx.c.

References ast_exten::label.

Referenced by show_dialplan_helper().

06257 {
06258    return exten ? exten->label : NULL;
06259 }

int ast_get_extension_matchcid struct ast_exten e  ) 
 

Definition at line 6299 of file pbx.c.

References ast_exten::matchcid.

Referenced by find_matching_priority(), and handle_save_dialplan().

06300 {
06301    return e ? e->matchcid : 0;
06302 }

const char* ast_get_extension_name struct ast_exten exten  ) 
 

Definition at line 6251 of file pbx.c.

References ast_exten::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().

06252 {
06253    return exten ? exten->exten : NULL;
06254 }

int ast_get_extension_priority struct ast_exten exten  ) 
 

Definition at line 6271 of file pbx.c.

References ast_exten::priority.

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

06272 {
06273    return exten ? exten->priority : -1;
06274 }

const char* ast_get_extension_registrar struct ast_exten e  ) 
 

Definition at line 6284 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06285 {
06286    return e ? e->registrar : NULL;
06287 }

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

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

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

02173 {
02174    struct ast_exten *e;
02175    void *tmp;
02176 
02177    e = ast_hint_extension(c, context, exten);
02178    if (e) {
02179       if (hint) 
02180           ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02181       if (name) {
02182          tmp = ast_get_extension_app_data(e);
02183          if (tmp)
02184             ast_copy_string(name, (char *) tmp, namesize);
02185       }
02186        return -1;
02187    }
02188    return 0;   
02189 }

const char* ast_get_ignorepat_name struct ast_ignorepat ip  ) 
 

Definition at line 6266 of file pbx.c.

References ast_ignorepat::pattern.

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

06267 {
06268    return ip ? ip->pattern : NULL;
06269 }

const char* ast_get_ignorepat_registrar struct ast_ignorepat ip  ) 
 

Definition at line 6294 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06295 {
06296    return ip ? ip->registrar : NULL;
06297 }

const char* ast_get_include_name struct ast_include include  ) 
 

Definition at line 6261 of file pbx.c.

References ast_include::name.

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

06262 {
06263    return inc ? inc->name : NULL;
06264 }

const char* ast_get_include_registrar struct ast_include i  ) 
 

Definition at line 6289 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06290 {
06291    return i ? i->registrar : NULL;
06292 }

const char* ast_get_switch_data struct ast_sw sw  ) 
 

Definition at line 6324 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06325 {
06326    return sw ? sw->data : NULL;
06327 }

const char* ast_get_switch_name struct ast_sw sw  ) 
 

Definition at line 6319 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

const char* ast_get_switch_registrar struct ast_sw sw  ) 
 

Definition at line 6329 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

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

Definition at line 6422 of file pbx.c.

References __ast_goto_if_exists().

Referenced by aqm_exec(), auth_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), dial_exec_full(), do_directory(), dundi_lookup_exec(), 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().

06422                                                                                            {
06423    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06424 }

void ast_hint_state_changed const char *  device  ) 
 

Definition at line 1874 of file pbx.c.

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

Referenced by do_state_change().

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

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

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

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

04463 {
04464    struct ast_context *con;
04465    struct ast_ignorepat *pat;
04466 
04467    con = ast_context_find(context);
04468    if (con) {
04469       pat = con->ignorepats;
04470       while (pat) {
04471          if (ast_extension_match(pat->pattern, pattern))
04472             return 1;
04473          pat = pat->next;
04474       }
04475    } 
04476    return 0;
04477 }

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

06234 {
06235    return ast_mutex_lock(&con->lock);
06236 }

int ast_lock_contexts void   ) 
 

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

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

06221 {
06222    return ast_mutex_lock(&conlock);
06223 }

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

References HELPER_MATCHMORE, and pbx_extension_helper().

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

02212 {
02213    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_MATCHMORE);
02214 }

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

References __ast_context_destroy(), AST_EXTENSION_REMOVED, ast_hint_extension(), AST_LIST_HEAD_INIT, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, calloc, contexts, ast_state_cb::data, ast_exten::exten, ast_hint::exten, free, ast_hint::laststate, LOG_WARNING, ast_context::name, ast_state_cb::next, ast_context::next, ast_hint::next, ast_exten::parent, and ast_context::registrar.

Referenced by pbx_load_module().

03688 {
03689    struct ast_context *tmp, *lasttmp = NULL;
03690    struct store_hints store;
03691    struct store_hint *this;
03692    struct ast_hint *hint;
03693    struct ast_exten *exten;
03694    int length;
03695    struct ast_state_cb *thiscb, *prevcb;
03696 
03697    /* preserve all watchers for hints associated with this registrar */
03698    AST_LIST_HEAD_INIT(&store);
03699    ast_mutex_lock(&hintlock);
03700    for (hint = hints; hint; hint = hint->next) {
03701       if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) {
03702          length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this);
03703          this = calloc(1, length);
03704          if (!this) {
03705             ast_log(LOG_WARNING, "Could not allocate memory to preserve hint\n");
03706             continue;
03707          }
03708          this->callbacks = hint->callbacks;
03709          hint->callbacks = NULL;
03710          this->laststate = hint->laststate;
03711          this->context = this->data;
03712          strcpy(this->data, hint->exten->parent->name);
03713          this->exten = this->data + strlen(this->context) + 1;
03714          strcpy(this->exten, hint->exten->exten);
03715          AST_LIST_INSERT_HEAD(&store, this, list);
03716       }
03717    }
03718    ast_mutex_unlock(&hintlock);
03719 
03720    tmp = *extcontexts;
03721    ast_mutex_lock(&conlock);
03722    if (registrar) {
03723       __ast_context_destroy(NULL,registrar);
03724       while (tmp) {
03725          lasttmp = tmp;
03726          tmp = tmp->next;
03727       }
03728    } else {
03729       while (tmp) {
03730          __ast_context_destroy(tmp,tmp->registrar);
03731          lasttmp = tmp;
03732          tmp = tmp->next;
03733       }
03734    }
03735    if (lasttmp) {
03736       lasttmp->next = contexts;
03737       contexts = *extcontexts;
03738       *extcontexts = NULL;
03739    } else 
03740       ast_log(LOG_WARNING, "Requested contexts didn't get merged\n");
03741    ast_mutex_unlock(&conlock);
03742 
03743    /* restore the watchers for hints that can be found; notify those that
03744       cannot be restored
03745    */
03746    while ((this = AST_LIST_REMOVE_HEAD(&store, list))) {
03747       exten = ast_hint_extension(NULL, this->context, this->exten);
03748       /* Find the hint in the list of hints */
03749       ast_mutex_lock(&hintlock);
03750       for (hint = hints; hint; hint = hint->next) {
03751          if (hint->exten == exten)
03752             break;
03753       }
03754       if (!exten || !hint) {
03755          /* this hint has been removed, notify the watchers */
03756          prevcb = NULL;
03757          thiscb = this->callbacks;
03758          while (thiscb) {
03759             prevcb = thiscb;      
03760             thiscb = thiscb->next;
03761             prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data);
03762             free(prevcb);
03763             }
03764       } else {
03765          thiscb = this->callbacks;
03766          while (thiscb->next)
03767             thiscb = thiscb->next;
03768          thiscb->next = hint->callbacks;
03769          hint->callbacks = this->callbacks;
03770          hint->laststate = this->laststate;
03771       }
03772       ast_mutex_unlock(&hintlock);
03773       free(this);
03774    }
03775 
03776    return;  
03777 }

int ast_parseable_goto struct ast_channel chan,
const char *  goto_string
 

Definition at line 6430 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, LOG_WARNING, ast_channel::priority, s, and strsep().

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

06431 {
06432    char *s;
06433    char *exten, *pri, *context;
06434    char *stringp=NULL;
06435    int ipri;
06436    int mode = 0;
06437 
06438    if (ast_strlen_zero(goto_string)) {
06439       ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
06440       return -1;
06441    }
06442    s = ast_strdupa(goto_string);
06443    stringp=s;
06444    context = strsep(&stringp, "|");
06445    exten = strsep(&stringp, "|");
06446    if (!exten) {
06447       /* Only a priority in this one */
06448       pri = context;
06449       exten = NULL;
06450       context = NULL;
06451    } else {
06452       pri = strsep(&stringp, "|");
06453       if (!pri) {
06454          /* Only an extension and priority in this one */
06455          pri = exten;
06456          exten = context;
06457          context = NULL;
06458       }
06459    }
06460    if (*pri == '+') {
06461       mode = 1;
06462       pri++;
06463    } else if (*pri == '-') {
06464       mode = -1;
06465       pri++;
06466    }
06467    if (sscanf(pri, "%d", &ipri) != 1) {
06468       if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, (exten && strcasecmp(exten, "BYEXTENSION")) ? exten : chan->exten, 
06469          pri, chan->cid.cid_num)) < 1) {
06470          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
06471          return -1;
06472       } else
06473          mode = 0;
06474    } 
06475    /* At this point we have a priority and maybe an extension and a context */
06476 
06477    if (exten && !strcasecmp(exten, "BYEXTENSION"))
06478       exten = NULL;
06479 
06480    if (mode) 
06481       ipri = chan->priority + (ipri * mode);
06482 
06483    ast_explicit_goto(chan, context, exten, ipri);
06484    ast_cdr_update(chan);
06485    return 0;
06486 
06487 }

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

References __ast_request_and_dial(), ast_channel::_state, async_stat::app, app_tmp::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_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, app_tmp::chan, app_tmp::data, free, ast_channel::hangupcause, ast_channel::lock, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, app_tmp::t, async_stat::timeout, type, outgoing_helper::vars, and VERBOSE_PREFIX_4.

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

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

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 4960 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_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, type, and VERBOSE_PREFIX_4.

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

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

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

References __ast_pbx_run(), ast_pbx_result, decrease_call_count(), and increase_call_count().

Referenced by ast_pbx_outgoing_exten(), async_wait(), mgcp_ss(), skinny_ss(), and ss_thread().

02538 {
02539    enum ast_pbx_result res = AST_PBX_SUCCESS;
02540 
02541    if (increase_call_count(c))
02542       return AST_PBX_CALL_LIMIT;
02543 
02544    res = __ast_pbx_run(c);
02545    decrease_call_count();
02546 
02547    return res;
02548 }

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

References ast_log(), ast_pbx_result, ast_pthread_create, increase_call_count(), LOG_WARNING, and pbx_thread().

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

02514 {
02515    pthread_t t;
02516    pthread_attr_t attr;
02517 
02518    if (!c) {
02519       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02520       return AST_PBX_FAILED;
02521    }
02522       
02523    if (increase_call_count(c))
02524       return AST_PBX_CALL_LIMIT;
02525 
02526    /* Start a new thread, and get something handling this channel. */
02527    pthread_attr_init(&attr);
02528    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02529    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02530       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02531       return AST_PBX_FAILED;
02532    }
02533 
02534    return AST_PBX_SUCCESS;
02535 }

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

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

Referenced by load_module(), and load_pbx().

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

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

02909 {
02910    struct ast_switch *tmp, *prev=NULL;
02911    if (ast_mutex_lock(&switchlock)) {
02912       ast_log(LOG_ERROR, "Unable to lock switch lock\n");
02913       return -1;
02914    }
02915    tmp = switches;
02916    while(tmp) {
02917       if (!strcasecmp(tmp->name, sw->name))
02918          break;
02919       prev = tmp;
02920       tmp = tmp->next;
02921    }
02922    if (tmp) {  
02923       ast_mutex_unlock(&switchlock);
02924       ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
02925       return -1;
02926    }
02927    sw->next = NULL;
02928    if (prev) 
02929       prev->next = sw;
02930    else
02931       switches = sw;
02932    ast_mutex_unlock(&switchlock);
02933    return 0;
02934 }

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

References HELPER_SPAWN, and pbx_extension_helper().

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

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

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 6238 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(), handle_save_dialplan(), and show_dialplan_helper().

06239 {
06240    return ast_mutex_unlock(&con->lock);
06241 }

int ast_unlock_contexts void   ) 
 

Returns 0 on success, -1 on failure

Definition at line 6225 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(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper().

06226 {
06227    return ast_mutex_unlock(&conlock);
06228 }

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

03602 {
03603    struct ast_app *tmp, *tmpl = NULL;
03604    if (ast_mutex_lock(&applock)) {
03605       ast_log(LOG_ERROR, "Unable to lock application list\n");
03606       return -1;
03607    }
03608    tmp = apps;
03609    while(tmp) {
03610       if (!strcasecmp(app, tmp->name)) {
03611          if (tmpl)
03612             tmpl->next = tmp->next;
03613          else
03614             apps = tmp->next;
03615          if (option_verbose > 1)
03616             ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name);
03617          free(tmp);
03618          ast_mutex_unlock(&applock);
03619          return 0;
03620       }
03621       tmpl = tmp;
03622       tmp = tmp->next;
03623    }
03624    ast_mutex_unlock(&applock);
03625    return -1;
03626 }

void ast_unregister_switch struct ast_switch sw  ) 
 

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

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

02937 {
02938    struct ast_switch *tmp, *prev=NULL;
02939    if (ast_mutex_lock(&switchlock)) {
02940       ast_log(LOG_ERROR, "Unable to lock switch lock\n");
02941       return;
02942    }
02943    tmp = switches;
02944    while(tmp) {
02945       if (tmp == sw) {
02946          if (prev)
02947             prev->next = tmp->next;
02948          else
02949             switches = tmp->next;
02950          tmp->next = NULL;
02951          break;         
02952       }
02953       prev = tmp;
02954       tmp = tmp->next;
02955    }
02956    ast_mutex_unlock(&switchlock);
02957 }

struct ast_exten* ast_walk_context_extensions struct ast_context con,
struct ast_exten priority
 

Definition at line 6345 of file pbx.c.

References ast_exten::next, and ast_context::root.

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

06347 {
06348    if (!exten)
06349       return con ? con->root : NULL;
06350    else
06351       return exten->next;
06352 }

struct ast_ignorepat* ast_walk_context_ignorepats struct ast_context con,
struct ast_ignorepat ip
 

Definition at line 6381 of file pbx.c.

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

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

06383 {
06384    if (!ip)
06385       return con ? con->ignorepats : NULL;
06386    else
06387       return ip->next;
06388 }

struct ast_include* ast_walk_context_includes struct ast_context con,
struct ast_include inc
 

Definition at line 6372 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(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().

06374 {
06375    if (!inc)
06376       return con ? con->includes : NULL;
06377    else
06378       return inc->next;
06379 }

struct ast_sw* ast_walk_context_switches struct ast_context con,
struct ast_sw sw
 

Definition at line 6354 of file pbx.c.

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

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06356 {
06357    if (!sw)
06358       return con ? con->alts : NULL;
06359    else
06360       return sw->next;
06361 }

struct ast_context* ast_walk_contexts struct ast_context con  ) 
 

Definition at line 6337 of file pbx.c.

References 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(), find_matching_priority(), handle_save_dialplan(), pbx_load_module(), and show_dialplan_helper().

06338 {
06339    if (!con)
06340       return contexts;
06341    else
06342       return con->next;
06343 }

struct ast_exten* ast_walk_extension_priorities struct ast_exten exten,
struct ast_exten priority
 

Definition at line 6363 of file pbx.c.

References ast_exten::peer.

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

06365 {
06366    if (!priority)
06367       return exten;
06368    else
06369       return priority->peer;
06370 }

void pbx_builtin_clear_globals void   ) 
 

Definition at line 6083 of file pbx.c.

References AST_LIST_EMPTY, AST_LIST_REMOVE_HEAD, ast_var_delete(), and globals.

Referenced by reload().

06084 {
06085    struct ast_var_t *vardata;
06086    while (!AST_LIST_EMPTY(&globals)) {
06087       vardata = AST_LIST_REMOVE_HEAD(&globals, entries);
06088       ast_var_delete(vardata);
06089    }
06090 }

char* pbx_builtin_getvar_helper struct ast_channel chan,
const char *  name
 

Definition at line 5892 of file pbx.c.

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

Referenced by __ast_pbx_run(), __login_exec(), _while_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(), chanspy_exec(), 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(), set_config_flags(), sip_addheader(), sip_answer(), try_calling(), wait_for_answer(), zt_call(), and zt_hangup().

05893 {
05894    struct ast_var_t *variables;
05895    struct varshead *headp;
05896 
05897    if (chan)
05898       headp=&chan->varshead;
05899    else
05900       headp=&globals;
05901 
05902    if (name) {
05903       AST_LIST_TRAVERSE(headp,variables,entries) {
05904          if (!strcmp(name, ast_var_name(variables)))
05905             return ast_var_value(variables);
05906       }
05907       if (headp != &globals) {
05908          /* Check global variables if we haven't already */
05909          headp = &globals;
05910          AST_LIST_TRAVERSE(headp,variables,entries) {
05911             if (!strcmp(name, ast_var_name(variables)))
05912                return ast_var_value(variables);
05913          }
05914       }
05915    }
05916    return NULL;
05917 }

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

Definition at line 5919 of file pbx.c.

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

Referenced by gosub_exec().

05920 {
05921    struct ast_var_t *newvariable;
05922    struct varshead *headp;
05923 
05924    if (name[strlen(name)-1] == ')') {
05925       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05926       return ast_func_write(chan, name, value);
05927    }
05928 
05929    headp = (chan) ? &chan->varshead : &globals;
05930 
05931    if (value) {
05932       if ((option_verbose > 1) && (headp == &globals))
05933          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05934       newvariable = ast_var_assign(name, value);   
05935       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05936    }
05937 }

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

Definition at line 5865 of file pbx.c.

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

Referenced by dumpchan_exec(), and handle_showchan().

05866 {
05867    struct ast_var_t *variables;
05868    char *var, *val;
05869    int total = 0;
05870 
05871    if (!chan)
05872       return 0;
05873 
05874    memset(buf, 0, size);
05875 
05876    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05877       if(variables &&
05878          (var=ast_var_name(variables)) && (val=ast_var_value(variables)) &&
05879          !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
05880          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05881             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05882             break;
05883          } else
05884             total++;
05885       } else 
05886          break;
05887    }
05888    
05889    return total;
05890 }

int pbx_builtin_setvar struct ast_channel chan,
void *  data
 

Referenced by handle_globals(), and pbx_builtin_setvar_old().

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

Definition at line 5939 of file pbx.c.

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

Referenced by __ast_pbx_run(), __login_exec(), _while_exec(), 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(), conf_run(), controlplayback_exec(), count_exec(), curl_exec(), cut_exec(), dial_exec_full(), disa_exec(), do_waiting(), 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(), i4l_read(), 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().

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

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

References ast_channel::appl, ast_cdr_setapp(), ast_log(), ast_channel::cdr, ast_channel::data, ast_app::execute, LOG_WARNING, and ast_app::name.

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

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

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

References 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(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and realtime_exec().

00568 {
00569    struct ast_app *tmp;
00570 
00571    if (ast_mutex_lock(&applock)) {
00572       ast_log(LOG_WARNING, "Unable to obtain application lock\n");
00573       return NULL;
00574    }
00575    tmp = apps;
00576    while(tmp) {
00577       if (!strcasecmp(tmp->name, app))
00578          break;
00579       tmp = tmp->next;
00580    }
00581    ast_mutex_unlock(&applock);
00582    return tmp;
00583 }

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

References ast_channel::accountcode, ast_get_hint(), AST_LIST_TRAVERSE, ast_log(), 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, globals, ast_channel::hangupcause, ast_channel::language, LOG_WARNING, ast_channel::name, parse_variable_name(), ast_channel::priority, substring(), ast_channel::uniqueid, var, and ast_channel::varshead.

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

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

int pbx_set_autofallthrough int  newval  ) 
 

Definition at line 2555 of file pbx.c.

References autofallthrough.

Referenced by pbx_load_module().

02556 {
02557    int oldval;
02558    oldval = autofallthrough;
02559    if (oldval != newval)
02560       autofallthrough = newval;
02561    return oldval;
02562 }

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

Definition at line 1586 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_find_extension(), pbx_load_module(), pbx_substitute_variables(), realtime_exec(), rpt_exec(), sendmail(), and sendpage().

01587 {
01588    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
01589 }

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

Definition at line 1591 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

01592 {
01593    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01594 }


Variable Documentation

const struct cfextension_states extension_states[] [static]
 


Generated on Mon Mar 20 08:20:29 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1