Sat Sep 16 05:48:04 2006

Asterisk developer's documentation


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_checkcondition (char *condition)
int pbx_exec (struct ast_channel *c, struct ast_app *app, void *data, int newstack)
ast_apppbx_findapp (const char *app)
 Find application handle in linked list.
void pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
 pbx_retrieve_variable: Support for Asterisk built-in variables and functions in the dialplan ---
int pbx_set_autofallthrough (int newval)
void pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count)
void pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count)

Variables

static 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(), builtin_blindtransfer(), dial_exec_full(), feature_exec_app(), macro_exec(), park_call_exec(), queue_exec(), rpt_exec(), and run_agi().

#define AST_PBX_NO_HANGUP_PEER   11

Definition at line 41 of file pbx.h.

Referenced by builtin_blindtransfer(), dial_exec_full(), feature_exec_app(), park_exec(), and try_calling().

#define AST_PBX_REPLACE   1

Definition at line 34 of file pbx.h.

#define PRIORITY_HINT   -1

Special Priority for an hint

Definition at line 44 of file pbx.h.

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


Typedef Documentation

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

Definition at line 83 of file pbx.h.


Enumeration Type Documentation

enum ast_extension_states

Extension states

Enumerator:
AST_EXTENSION_REMOVED  Extension removed
AST_EXTENSION_DEACTIVATED  Extension hint removed
AST_EXTENSION_NOT_INUSE  No device INUSE or BUSY
AST_EXTENSION_INUSE  One or more devices INUSE
AST_EXTENSION_BUSY  All devices BUSY
AST_EXTENSION_UNAVAILABLE  All devices UNAVAILABLE/UNREGISTERED
AST_EXTENSION_RINGING  All devices RINGING

Definition at line 47 of file pbx.h.

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

enum ast_pbx_result

Enumerator:
AST_PBX_SUCCESS 
AST_PBX_FAILED 
AST_PBX_CALL_LIMIT 

Definition at line 209 of file pbx.h.

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


Function Documentation

int ast_active_calls ( void   ) 

Definition at line 2562 of file pbx.c.

References countcalls.

Referenced by handle_chanlist().

02563 {
02564    return countcalls;
02565 }

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 4505 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(), park_add_hints(), and register_peer_exten().

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

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

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

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

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

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

Definition at line 4550 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(), monitor_handle_owned(), process_ast_dsp(), socket_read(), and zt_read().

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

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

Definition at line 4599 of file pbx.c.

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

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

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

Definition at line 6471 of file pbx.c.

References __ast_goto_if_exists().

06471                                                                                                  {
06472    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06473 }

int ast_build_timing ( struct ast_timing i,
char *  info 
)

Definition at line 4083 of file pbx.c.

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

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

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

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

02219 {
02220    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_CANMATCH);
02221 }

int ast_check_timing ( struct ast_timing i  ) 

Definition at line 4126 of file pbx.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), contexts, ast_context::includes, local_contexts, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, ast_context::name, ast_context::next, option_debug, option_verbose, 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().

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

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

References __ast_context_destroy().

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

05387 {
05388    __ast_context_destroy(con,registrar);
05389 }

struct ast_context* ast_context_find ( const char *  name  ) 

Parameters:
name name of the context to find Will search for the context with the given name. Returns the ast_context on success, NULL on failure.

Definition at line 736 of file pbx.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

See add_include

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

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

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

See add_include2

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

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

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

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

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

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

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

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

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

struct ast_custom_function* ast_custom_function_find ( char *  name  ) 

Definition at line 1267 of file pbx.c.

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

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

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

int ast_custom_function_register ( struct ast_custom_function acf  ) 

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

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

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

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

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

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

References HELPER_EXEC, and pbx_extension_helper().

Referenced by loopback_exec().

02234 {
02235    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXEC);
02236 }

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 2203 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(), leave_voicemail(), local_alloc(), local_devicestate(), loopback_exists(), macro_exec(), mgcp_ss(), monitor_handle_notowned(), monitor_handle_owned(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), process_ast_dsp(), register_peer_exten(), rpt(), rpt_exec(), skinny_ss(), socket_read(), ss_thread(), and zt_read().

02204 {
02205    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXISTS);
02206 }

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

Definition at line 4531 of file pbx.c.

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

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

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

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

Definition at line 715 of file pbx.c.

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

Referenced by pbx_find_extension(), and realtime_switch_common().

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

int ast_extension_match ( const char *  pattern,
const char *  extension 
)

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

Definition at line 702 of file pbx.c.

References EXTENSION_MATCH_CORE, and match().

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

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

int ast_extension_patmatch ( const char *  pattern,
const char *  data 
)

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

ast_extension_state: Check extension state for an extension by using hint

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

Definition at line 1875 of file pbx.c.

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

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

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

References extension_states.

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

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

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

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

Referenced by handle_request_subscribe(), and init_manager().

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

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

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

Referenced by __sip_destroy().

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

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

References HELPER_FINDLABEL, and pbx_extension_helper().

Referenced by ast_parseable_goto(), and handle_setpriority().

02209 {
02210    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, HELPER_FINDLABEL);
02211 }

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

Definition at line 2213 of file pbx.c.

References HELPER_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_module().

02214 {
02215    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, HELPER_FINDLABEL);
02216 }

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

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

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

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

const char* ast_get_context_name ( struct ast_context con  ) 

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

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

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6324 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

const char* ast_get_extension_app ( struct ast_exten e  ) 

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

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

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6359 of file pbx.c.

References ast_exten::data.

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

06360 {
06361    return e ? e->data : NULL;
06362 }

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6349 of file pbx.c.

References ast_exten::cidmatch.

Referenced by find_matching_priority(), and handle_save_dialplan().

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

const char* ast_get_extension_label ( struct ast_exten e  ) 

Definition at line 6301 of file pbx.c.

References exten.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06302 {
06303    return exten ? exten->label : NULL;
06304 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6344 of file pbx.c.

References ast_exten::matchcid.

Referenced by find_matching_priority(), and handle_save_dialplan().

06345 {
06346    return e ? e->matchcid : 0;
06347 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

Definition at line 6296 of file pbx.c.

References exten.

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

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

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 6316 of file pbx.c.

References exten.

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

06317 {
06318    return exten ? exten->priority : -1;
06319 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6329 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

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

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

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

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

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

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

06312 {
06313    return ip ? ip->pattern : NULL;
06314 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6339 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06340 {
06341    return ip ? ip->registrar : NULL;
06342 }

const char* ast_get_include_name ( struct ast_include include  ) 

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

06307 {
06308    return inc ? inc->name : NULL;
06309 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6334 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6369 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6364 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6374 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06375 {
06376    return sw ? sw->registrar : NULL;
06377 }

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

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

06467                                                                                            {
06468    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06469 }

void ast_hint_state_changed ( const char *  device  ) 

Definition at line 1886 of file pbx.c.

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

Referenced by do_state_change().

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

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

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

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

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

int ast_lock_contexts ( void   ) 

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

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

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

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

References HELPER_MATCHMORE, and pbx_extension_helper().

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

02224 {
02225    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_MATCHMORE);
02226 }

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

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

Referenced by pbx_load_module().

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

int ast_parseable_goto ( struct ast_channel chan,
const char *  goto_string 
)

Definition at line 6475 of file pbx.c.

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

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

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

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

References __ast_request_and_dial(), async_stat::app, async_stat::appdata, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, free, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4.

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

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

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

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

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

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

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

References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().

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

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

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

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

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

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

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

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

Referenced by load_module(), and load_pbx().

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

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

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

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

References HELPER_SPAWN, and pbx_extension_helper().

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

02229 {
02230    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_SPAWN);
02231 }

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

06284 {
06285    return ast_mutex_unlock(&con->lock);
06286 }

int ast_unlock_contexts ( void   ) 

Returns 0 on success, -1 on failure

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

06271 {
06272    return ast_mutex_unlock(&conlock);
06273 }

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

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

void ast_unregister_switch ( struct ast_switch sw  ) 

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

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

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

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

Definition at line 6390 of file pbx.c.

References exten, and ast_context::root.

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

06392 {
06393    if (!exten)
06394       return con ? con->root : NULL;
06395    else
06396       return exten->next;
06397 }

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

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

06428 {
06429    if (!ip)
06430       return con ? con->ignorepats : NULL;
06431    else
06432       return ip->next;
06433 }

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

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

06419 {
06420    if (!inc)
06421       return con ? con->includes : NULL;
06422    else
06423       return inc->next;
06424 }

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

Definition at line 6399 of file pbx.c.

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

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06401 {
06402    if (!sw)
06403       return con ? con->alts : NULL;
06404    else
06405       return sw->next;
06406 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

Definition at line 6382 of file pbx.c.

References contexts, and ast_context::next.

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

06383 {
06384    if (!con)
06385       return contexts;
06386    else
06387       return con->next;
06388 }

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

Definition at line 6408 of file pbx.c.

References exten, and ast_exten::priority.

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

06410 {
06411    if (!priority)
06412       return exten;
06413    else
06414       return priority->peer;
06415 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 6127 of file pbx.c.

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

Referenced by reload().

06128 {
06129    struct ast_var_t *vardata;
06130 
06131    ast_mutex_lock(&globalslock);
06132    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
06133       ast_var_delete(vardata);
06134    ast_mutex_unlock(&globalslock);
06135 }

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

Definition at line 5922 of file pbx.c.

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

Referenced by __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(), get_refer_info(), group_check_exec(), group_count_exec(), group_count_function_read(), group_function_read(), iax2_exec(), import_ch(), leave_voicemail(), macro_exec(), misdn_answer(), misdn_hangup(), oh323_hangup(), ospfinished_exec(), ospnext_exec(), queue_exec(), retrydial_exec(), return_exec(), rxfax_exec(), set_config_flags(), sip_addheader(), try_calling(), try_suggested_sip_codec(), txfax_exec(), wait_for_answer(), zt_call(), and zt_hangup().

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

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

Definition at line 5954 of file pbx.c.

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

Referenced by gosub_exec().

05955 {
05956    struct ast_var_t *newvariable;
05957    struct varshead *headp;
05958 
05959    if (name[strlen(name)-1] == ')') {
05960       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05961       return ast_func_write(chan, name, value);
05962    }
05963 
05964    headp = (chan) ? &chan->varshead : &globals;
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       if (headp == &globals)
05971          ast_mutex_lock(&globalslock);
05972       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05973       if (headp == &globals)
05974          ast_mutex_unlock(&globalslock);
05975    }
05976 }

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

Definition at line 5897 of file pbx.c.

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

Referenced by dumpchan_exec(), and handle_showchan().

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

int pbx_builtin_setvar ( struct ast_channel chan,
void *  data 
)

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

Definition at line 5978 of file pbx.c.

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

Referenced by _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(), controlplayback_exec(), count_exec(), curl_exec(), cut_exec(), dial_exec_full(), disa_exec(), do_waiting(), dundi_lookup_exec(), enumlookup_exec(), eval_exec(), export_ch(), function_db_exists(), function_db_read(), get_exec(), get_refer_info(), group_check_exec(), group_count_exec(), group_match_count_exec(), handle_setvariable(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), macro_exec(), math_exec(), md5_exec(), md5check_exec(), misdn_call(), 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(), phase_e_handler(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), 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().

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

int pbx_checkcondition ( char *  condition  ) 

Definition at line 6137 of file pbx.c.

Referenced by _while_exec(), builtin_function_if(), execif_exec(), gosubif_exec(), macroif_exec(), and pbx_builtin_gotoif().

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

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

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

Definition at line 531 of file pbx.c.

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

Referenced by ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), 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().

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

struct ast_app* pbx_findapp ( const char *  app  ) 

Find application handle in linked list.

Parameters:
app name of the app This function searches for the ast_app structure within the apps that are registered for the one with the name you passed in. Returns the ast_app structure that matches on success, or NULL on failure

Definition at line 576 of file pbx.c.

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

Referenced by ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), 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().

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

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

pbx_retrieve_variable: Support for Asterisk built-in variables and functions in the dialplan ---

Definition at line 979 of file pbx.c.

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

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

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

int pbx_set_autofallthrough ( int  newval  ) 

Definition at line 2567 of file pbx.c.

References autofallthrough.

Referenced by pbx_load_module().

02568 {
02569    int oldval;
02570    oldval = autofallthrough;
02571    if (oldval != newval)
02572       autofallthrough = newval;
02573    return oldval;
02574 }

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

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

01599 {
01600    pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count);
01601 }

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

Definition at line 1603 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

01604 {
01605    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01606 }


Variable Documentation

struct cfextension_states extension_states[] [static]

Referenced by ast_extension_state2str().


Generated on Sat Sep 16 05:48:04 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7