Tue Nov 4 13:20:40 2008

Asterisk developer's documentation


pbx.c File Reference

Core PBX routines. More...

#include "asterisk.h"
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include <limits.h>
#include "asterisk/lock.h"
#include "asterisk/cli.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/options.h"
#include "asterisk/logger.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/cdr.h"
#include "asterisk/config.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/ast_expr.h"
#include "asterisk/linkedlists.h"
#include "asterisk/say.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/musiconhold.h"
#include "asterisk/app.h"
#include "asterisk/devicestate.h"
#include "asterisk/stringfields.h"
#include "asterisk/threadstorage.h"

Go to the source code of this file.

Data Structures

struct  app_tmp
struct  ast_app
 ast_app: A registered application More...
struct  ast_context
 ast_context: An extension context More...
struct  ast_exten
 ast_exten: An extension The dialplan is saved as a linked list with each context having it's own linked list of extensions - one item per priority. More...
struct  ast_hint
 Structure for dial plan hints. More...
struct  ast_ignorepat
 ast_ignorepat: Ignore patterns in dial plan More...
struct  ast_include
 ast_include: include= support in extensions.conf More...
struct  ast_state_cb
 ast_state_cb: An extension state notify register item More...
struct  ast_sw
 ast_sw: Switch statement in extensions.conf More...
struct  async_stat
struct  cfextension_states
struct  dialplan_counters
struct  pbx_builtin
 Declaration of builtin applications. More...
struct  pbx_find_info
struct  store_hint

Defines

#define AST_PBX_MAX_STACK   128
#define BACKGROUND_MATCHEXTEN   (1 << 2)
#define BACKGROUND_NOANSWER   (1 << 1)
#define BACKGROUND_PLAYBACK   (1 << 3)
#define BACKGROUND_SKIP   (1 << 0)
#define EXT_DATA_SIZE   8192
#define SAY_STUBS
#define STATUS_NO_CONTEXT   1
#define STATUS_NO_EXTENSION   2
#define STATUS_NO_LABEL   4
#define STATUS_NO_PRIORITY   3
#define STATUS_SUCCESS   5
#define SWITCH_DATA_LENGTH   256
#define VAR_BUF_SIZE   4096
#define VAR_HARDTRAN   3
#define VAR_NORMAL   1
#define VAR_SOFTTRAN   2
#define WAITEXTEN_MOH   (1 << 0)

Enumerations

enum  ext_match_t {
  E_MATCHMORE = 0x00, E_CANMATCH = 0x01, E_MATCH = 0x02, E_MATCH_MASK = 0x03,
  E_SPAWN = 0x12, E_FINDLABEL = 0x22
}

Functions

static struct ast_context__ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar, int existsokay)
void __ast_context_destroy (struct ast_context *con, const char *registrar)
static int __ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, int async)
static int __ast_pbx_run (struct ast_channel *c)
static int _extension_match_core (const char *pattern, const char *data, enum ext_match_t mode)
static int add_pri (struct ast_context *con, struct ast_exten *tmp, struct ast_exten *el, struct ast_exten *e, int replace)
 add the extension in the priority chain. returns 0 on success, -1 on failure
int ast_active_calls (void)
 Retrieve the number of active calls.
int ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add and extension to an extension context.
int ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
 Add an extension to an extension context, this time with an ast_context *.
static int ast_add_hint (struct ast_exten *e)
 ast_add_hint: Add hint to hint list, check initial extension state
 AST_APP_OPTIONS (resetcdr_opts,{AST_APP_OPTION('w', AST_CDR_FLAG_POSTED), AST_APP_OPTION('a', AST_CDR_FLAG_LOCKED), AST_APP_OPTION('v', AST_CDR_FLAG_KEEP_VARS),})
 AST_APP_OPTIONS (waitexten_opts,{AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 0),})
 AST_APP_OPTIONS (background_opts,{AST_APP_OPTION('s', BACKGROUND_SKIP), AST_APP_OPTION('n', BACKGROUND_NOANSWER), AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN), AST_APP_OPTION('p', BACKGROUND_PLAYBACK),})
int ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_async_goto_by_name (const char *channame, const char *context, const char *exten, int priority)
int ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_build_timing (struct ast_timing *i, const char *info_in)
int ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks for a valid matching extension.
static int ast_change_hint (struct ast_exten *oe, struct ast_exten *ne)
 ast_change_hint: Change hint for an extension
int ast_check_timing (const struct ast_timing *i)
int ast_context_add_ignorepat (const char *context, const char *value, const char *registrar)
 Add an ignorepat.
int ast_context_add_ignorepat2 (struct ast_context *con, const char *value, const char *registrar)
int ast_context_add_include (const char *context, const char *include, const char *registrar)
 Add a context include.
int ast_context_add_include2 (struct ast_context *con, const char *value, const char *registrar)
 Add a context include.
int ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar)
 Add a switch.
int ast_context_add_switch2 (struct ast_context *con, const char *value, const char *data, int eval, const char *registrar)
 Adds a switch (first param is a ast_context).
ast_contextast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar)
 Register a new context.
void ast_context_destroy (struct ast_context *con, const char *registrar)
 Destroy a context (matches the specified context (or ANY context if NULL).
ast_contextast_context_find (const char *name)
 Find a context.
ast_contextast_context_find_or_create (struct ast_context **extcontexts, const char *name, const char *registrar)
int ast_context_lockmacro (const char *context)
 locks the macrolock in the given given context
int ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar)
 Simply remove extension from context.
int ast_context_remove_extension2 (struct ast_context *con, const char *extension, int priority, const char *registrar)
 This functionc locks given context, search for the right extension and fires out all peer in this extensions with given priority. If priority is set to 0, all peers are removed. After that, unlock context and return.
int ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar)
int ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar)
int ast_context_remove_include (const char *context, const char *include, const char *registrar)
 Remove a context include.
int ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar)
 Removes an include by an ast_context structure.
int ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar)
 Remove a switch.
int ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar)
 This function locks given context, removes switch, unlock context and return.
int ast_context_unlockmacro (const char *context)
 Unlocks the macrolock in the given context.
int ast_context_verify_includes (struct ast_context *con)
 Verifies includes in an ast_contect structure.
ast_custom_functionast_custom_function_find (const char *name)
int ast_custom_function_register (struct ast_custom_function *acf)
 Reigster a custom function.
int ast_custom_function_unregister (struct ast_custom_function *acf)
 Unregister a custom function.
int ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Determine whether an extension exists.
int ast_explicit_goto (struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_extension_close (const char *pattern, const char *data, int needmore)
int ast_extension_match (const char *pattern, const char *data)
 Determine if a given extension matches a given pattern (in NXX format).
int ast_extension_state (struct ast_channel *c, const char *context, const char *exten)
 Uses hint and devicestate callback to get the state of an extension.
static int ast_extension_state2 (struct ast_exten *e)
 ast_extensions_state2: Check state of extension by using hints
const char * ast_extension_state2str (int extension_state)
 Return string representation of the state of an extension.
int ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data)
 Registers a state change callback.
int ast_extension_state_del (int id, ast_state_cb_type callback)
 Deletes a registered state change callback by ID.
int ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
 Find the priority of an extension that has the specified label.
int ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
 Find the priority of an extension that has the specified label.
int ast_func_read (struct ast_channel *chan, char *function, char *workspace, size_t len)
 executes a read operation on a function
int ast_func_write (struct ast_channel *chan, char *function, const char *value)
 executes a write operation on a function
const char * ast_get_context_name (struct ast_context *con)
const char * ast_get_context_registrar (struct ast_context *c)
const char * ast_get_extension_app (struct ast_exten *e)
void * ast_get_extension_app_data (struct ast_exten *e)
const char * ast_get_extension_cidmatch (struct ast_exten *e)
ast_contextast_get_extension_context (struct ast_exten *exten)
const char * ast_get_extension_label (struct ast_exten *exten)
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 hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
 If an extension exists, return non-zero.
const char * ast_get_ignorepat_name (struct ast_ignorepat *ip)
const char * ast_get_ignorepat_registrar (struct ast_ignorepat *ip)
const char * ast_get_include_name (struct ast_include *inc)
const char * ast_get_include_registrar (struct ast_include *i)
const char * ast_get_switch_data (struct ast_sw *sw)
const char * ast_get_switch_name (struct ast_sw *sw)
const char * ast_get_switch_registrar (struct ast_sw *sw)
int ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority)
static struct ast_extenast_hint_extension (struct ast_channel *c, const char *context, const char *exten)
 ast_hint_extension: Find hint for given extension in context
void ast_hint_state_changed (const char *device)
int ast_ignore_pattern (const char *context, const char *pattern)
 Checks to see if a number should be ignored.
 AST_LIST_HEAD (store_hints, store_hint)
static AST_LIST_HEAD_STATIC (hints, ast_hint)
static AST_LIST_HEAD_STATIC (switches, ast_switch)
static AST_LIST_HEAD_STATIC (apps, ast_app)
static AST_LIST_HEAD_STATIC (acf_root, ast_custom_function)
int ast_lock_context (struct ast_context *con)
 Locks a given context.
int ast_lock_contexts ()
 Locks the context list.
int ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Looks to see if adding anything to this extension might match something. (exists ^ canmatch).
void ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar)
 Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.
 AST_MUTEX_DEFINE_STATIC (maxcalllock)
 AST_MUTEX_DEFINE_STATIC (globalslock)
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)
static int ast_pbx_outgoing_cdr_failed (void)
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 **channel)
enum ast_pbx_result ast_pbx_run (struct ast_channel *c)
 Execute the PBX in the current thread.
static void * ast_pbx_run_app (void *data)
 run the application and free the descriptor once done
enum ast_pbx_result ast_pbx_start (struct ast_channel *c)
 Create a new thread and start the PBX.
int ast_rdlock_contexts (void)
int ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
 Register an application.
int ast_register_switch (struct ast_switch *sw)
 Register an alternative dialplan switch.
static int ast_remove_hint (struct ast_exten *e)
 ast_remove_hint: Remove hint from extension
 AST_RWLOCK_DEFINE_STATIC (conlock)
int ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 Launch a new extension (i.e. new stack).
 AST_THREADSTORAGE (switch_data, switch_data_init)
int ast_unlock_context (struct ast_context *con)
int ast_unlock_contexts ()
 Unlocks contexts.
int ast_unregister_application (const char *app)
 Unregister an application.
void ast_unregister_switch (struct ast_switch *sw)
 Unregister an alternative switch.
ast_extenast_walk_context_extensions (struct ast_context *con, struct ast_exten *exten)
ast_ignorepatast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip)
ast_includeast_walk_context_includes (struct ast_context *con, struct ast_include *inc)
ast_swast_walk_context_switches (struct ast_context *con, struct ast_sw *sw)
ast_contextast_walk_contexts (struct ast_context *con)
ast_extenast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority)
int ast_wrlock_contexts (void)
static void * async_wait (void *data)
static int collect_digits (struct ast_channel *c, int waittime, char *buf, int buflen, int pos)
 collect digits from the channel into the buffer, return -1 on error, 0 on timeout or done.
static char * complete_show_application (const char *line, const char *word, int pos, int state)
static char * complete_show_applications (const char *line, const char *word, int pos, int state)
static char * complete_show_applications_deprecated (const char *line, const char *word, int pos, int state)
static char * complete_show_dialplan_context (const char *line, const char *word, int pos, int state)
static char * complete_show_function (const char *line, const char *word, int pos, int state)
static void decrease_call_count (void)
static void destroy_exten (struct ast_exten *e)
static int ext_cmp (const char *a, const char *b)
 the full routine to compare extensions in rules.
static int ext_cmp1 (const char **p)
 helper functions to sort extensions and patterns in the desired way, so that more specific patterns appear first.
static int ext_strncpy (char *dst, const char *src, int len)
 copy a string skipping whitespace
static int extension_match_core (const char *pattern, const char *data, enum ext_match_t mode)
static struct ast_contextfind_context_locked (const char *context)
static char * func_args (char *function)
 return a pointer to the arguments of the function, and terminates the function name with '\0'
static unsigned get_range (char *src, int max, char *const names[], const char *msg)
 helper function to return a range up to max (7, 12, 31 respectively). names, if supplied, is an array of names that should be mapped to numbers.
static void get_timerange (struct ast_timing *i, char *times)
 store a bitmask of valid times, one bit each 2 minute
static int handle_set_global (int fd, int argc, char *argv[])
static int handle_set_global_deprecated (int fd, int argc, char *argv[])
 CLI support for setting global variables.
static int handle_show_application (int fd, int argc, char *argv[])
static int handle_show_application_deprecated (int fd, int argc, char *argv[])
static int handle_show_applications (int fd, int argc, char *argv[])
static int handle_show_applications_deprecated (int fd, int argc, char *argv[])
static int handle_show_dialplan (int fd, int argc, char *argv[])
static int handle_show_function (int fd, int argc, char *argv[])
static int handle_show_function_deprecated (int fd, int argc, char *argv[])
static int handle_show_functions (int fd, int argc, char *argv[])
static int handle_show_functions_deprecated (int fd, int argc, char *argv[])
static int handle_show_globals (int fd, int argc, char *argv[])
 CLI support for listing global variables in a parseable way.
static int handle_show_hints (int fd, int argc, char *argv[])
 handle_show_hints: CLI support for listing registred dial plan hints
static int handle_show_switches (int fd, int argc, char *argv[])
 handle_show_switches: CLI support for listing registred dial plan switches
static int include_valid (struct ast_include *i)
static int increase_call_count (const struct ast_channel *c)
int load_pbx (void)
static int lookup_name (const char *s, char *const names[], int max)
 Helper for get_range. return the index of the matching entry, starting from 1. If names is not supplied, try numeric values.
static int matchcid (const char *cidpattern, const char *callerid)
static int parse_variable_name (char *var, int *offset, int *length, int *isfunc)
 extract offset:length from variable name. Returns 1 if there is a offset:length part, which is trimmed off (values go into variables)
static int pbx_builtin_answer (struct ast_channel *, void *)
static int pbx_builtin_background (struct ast_channel *, void *)
static int pbx_builtin_busy (struct ast_channel *, void *)
void pbx_builtin_clear_globals (void)
static int pbx_builtin_congestion (struct ast_channel *, void *)
static int pbx_builtin_execiftime (struct ast_channel *, void *)
const char * pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name)
static int pbx_builtin_goto (struct ast_channel *, void *)
static int pbx_builtin_gotoif (struct ast_channel *, void *)
static int pbx_builtin_gotoiftime (struct ast_channel *, void *)
static int pbx_builtin_hangup (struct ast_channel *, void *)
static int pbx_builtin_importvar (struct ast_channel *, void *)
static int pbx_builtin_noop (struct ast_channel *, void *)
static int pbx_builtin_progress (struct ast_channel *, void *)
void pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value)
static int pbx_builtin_resetcdr (struct ast_channel *, void *)
static int pbx_builtin_ringing (struct ast_channel *, void *)
static int pbx_builtin_saycharacters (struct ast_channel *, void *)
static int pbx_builtin_saydate (struct ast_channel *, void *)
static int pbx_builtin_saydigits (struct ast_channel *, void *)
static int pbx_builtin_saynumber (struct ast_channel *, void *)
static int pbx_builtin_sayphonetic (struct ast_channel *, void *)
static int pbx_builtin_saytime (struct ast_channel *, void *)
int pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size)
static int pbx_builtin_setamaflags (struct ast_channel *, void *)
static int pbx_builtin_setglobalvar (struct ast_channel *, void *)
int pbx_builtin_setvar (struct ast_channel *, void *)
void pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value)
static int pbx_builtin_wait (struct ast_channel *, void *)
static int pbx_builtin_waitexten (struct ast_channel *, void *)
int pbx_checkcondition (const char *condition)
 Evaluate a condition.
static void pbx_destroy (struct ast_pbx *p)
int pbx_exec (struct ast_channel *c, struct ast_app *app, void *data)
 Execute an application.
static int pbx_extension_helper (struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
 The return value depends on the action:.
static struct ast_extenpbx_find_extension (struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
ast_apppbx_findapp (const char *app)
 Look up an application.
static struct ast_switchpbx_findswitch (const char *sw)
void pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
 pbx_retrieve_variable: Support for Asterisk built-in variables ---
int pbx_set_autofallthrough (int newval)
static void pbx_substitute_variables (char *passdata, int datalen, struct ast_channel *c, struct ast_exten *e)
void pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count)
static void pbx_substitute_variables_helper_full (struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count)
void pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count)
static void * pbx_thread (void *data)
static void print_ext (struct ast_exten *e, char *buf, int buflen)
 helper function to print an extension
static void set_ext_pri (struct ast_channel *c, const char *exten, int pri)
static int show_dialplan_helper (int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[])
static char * substring (const char *value, int offset, int length, char *workspace, size_t workspace_len)
 takes a substring. It is ok to call with value == workspace.
static void wait_for_hangup (struct ast_channel *chan, void *data)

Variables

static int autofallthrough = 1
static struct pbx_builtin builtins []
 Declaration of builtin applications.
static struct ast_cli_entry cli_set_global_deprecated
static struct ast_cli_entry cli_show_application_deprecated
static struct ast_cli_entry cli_show_applications_deprecated
static struct ast_cli_entry cli_show_dialplan_deprecated
static struct ast_cli_entry cli_show_function_deprecated
static struct ast_cli_entry cli_show_functions_deprecated
static struct ast_cli_entry cli_show_globals_deprecated
static struct ast_cli_entry cli_show_hints_deprecated
static struct ast_cli_entry cli_show_switches_deprecated
static struct ast_contextcontexts
static int countcalls
static char * days []
static struct cfextension_states extension_states []
static struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE
static char * months []
static struct ast_cli_entry pbx_cli []
static char set_global_help []
static char show_application_help []
static char show_applications_help []
static char show_dialplan_help []
static char show_function_help []
static char show_functions_help []
static char show_globals_help []
static char show_hints_help []
static char show_switches_help []
ast_state_cbstatecbs
static int stateid = 1


Detailed Description

Core PBX routines.

Author:
Mark Spencer <markster@digium.com>

Definition in file pbx.c.


Define Documentation

#define AST_PBX_MAX_STACK   128

Go no deeper than this through includes (not counting loops)

Definition at line 571 of file pbx.c.

Referenced by handle_show_dialplan(), pbx_find_extension(), and show_dialplan_helper().

#define BACKGROUND_MATCHEXTEN   (1 << 2)

Definition at line 91 of file pbx.c.

Referenced by pbx_builtin_background().

#define BACKGROUND_NOANSWER   (1 << 1)

Definition at line 90 of file pbx.c.

Referenced by pbx_builtin_background().

#define BACKGROUND_PLAYBACK   (1 << 3)

Definition at line 92 of file pbx.c.

Referenced by pbx_builtin_background().

#define BACKGROUND_SKIP   (1 << 0)

Definition at line 89 of file pbx.c.

Referenced by pbx_builtin_background().

#define EXT_DATA_SIZE   8192

Note:
I M P O R T A N T :
The speed of extension handling will likely be among the most important aspects of this PBX. The switching scheme as it exists right now isn't terribly bad (it's O(N+M), where N is the # of extensions and M is the avg # of priorities, but a constant search time here would be great ;-)

Definition at line 78 of file pbx.c.

Referenced by pbx_extension_helper(), and realtime_exec().

#define SAY_STUBS

Definition at line 55 of file pbx.c.

#define STATUS_NO_CONTEXT   1

Definition at line 933 of file pbx.c.

Referenced by pbx_extension_helper(), and pbx_find_extension().

#define STATUS_NO_EXTENSION   2

Definition at line 934 of file pbx.c.

Referenced by pbx_extension_helper(), and pbx_find_extension().

#define STATUS_NO_LABEL   4

Definition at line 936 of file pbx.c.

Referenced by pbx_extension_helper(), and pbx_find_extension().

#define STATUS_NO_PRIORITY   3

Definition at line 935 of file pbx.c.

Referenced by pbx_extension_helper(), and pbx_find_extension().

#define STATUS_SUCCESS   5

Definition at line 937 of file pbx.c.

Referenced by pbx_find_extension().

#define SWITCH_DATA_LENGTH   256

Definition at line 81 of file pbx.c.

#define VAR_BUF_SIZE   4096

Definition at line 83 of file pbx.c.

Referenced by ast_add_extension2(), pbx_builtin_importvar(), and pbx_substitute_variables_helper_full().

#define VAR_HARDTRAN   3

Definition at line 87 of file pbx.c.

#define VAR_NORMAL   1

Definition at line 85 of file pbx.c.

#define VAR_SOFTTRAN   2

Definition at line 86 of file pbx.c.

#define WAITEXTEN_MOH   (1 << 0)

Definition at line 101 of file pbx.c.

Referenced by pbx_builtin_waitexten().


Enumeration Type Documentation

enum ext_match_t

When looking up extensions, we can have different requests identified by the 'action' argument, as follows. Note that the coding is such that the low 4 bits are the third argument to extension_match_core.

Enumerator:
E_MATCHMORE 
E_CANMATCH 
E_MATCH 
E_MATCH_MASK 
E_SPAWN 
E_FINDLABEL 

Definition at line 776 of file pbx.c.

00776                  {
00777    E_MATCHMORE =  0x00, /* extension can match but only with more 'digits' */
00778    E_CANMATCH =   0x01, /* extension can match with or without more 'digits' */
00779    E_MATCH =   0x02, /* extension is an exact match */
00780    E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
00781    E_SPAWN =   0x12, /* want to spawn an extension. Requires exact match */
00782    E_FINDLABEL =  0x22  /* returns the priority for a given label. Requires exact match */
00783 };


Function Documentation

static struct ast_context* __ast_context_create ( struct ast_context **  extcontexts,
const char *  name,
const char *  registrar,
int  existsokay 
) [static]

Definition at line 3898 of file pbx.c.

References ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), contexts, local_contexts, LOG_WARNING, name, and ast_context::next.

Referenced by ast_context_create(), and ast_context_find_or_create().

03899 {
03900    struct ast_context *tmp, **local_contexts;
03901    int length = sizeof(struct ast_context) + strlen(name) + 1;
03902 
03903    if (!extcontexts) {
03904       ast_rdlock_contexts();
03905       local_contexts = &contexts;
03906    } else
03907       local_contexts = extcontexts;
03908 
03909    for (tmp = *local_contexts; tmp; tmp = tmp->next) {
03910       if (!strcasecmp(tmp->name, name)) {
03911          if (!existsokay) {
03912             ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
03913             tmp = NULL;
03914          }
03915          if (!extcontexts)
03916             ast_unlock_contexts();
03917          return tmp;
03918       }
03919    }
03920    
03921    if (!extcontexts)
03922       ast_unlock_contexts();
03923 
03924    if ((tmp = ast_calloc(1, length))) {
03925       ast_mutex_init(&tmp->lock);
03926       ast_mutex_init(&tmp->macrolock);
03927       strcpy(tmp->name, name);
03928       tmp->registrar = registrar;
03929       if (!extcontexts)
03930          ast_wrlock_contexts();
03931       tmp->next = *local_contexts;
03932       *local_contexts = tmp;
03933       if (!extcontexts)
03934          ast_unlock_contexts();
03935       if (option_debug)
03936          ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name);
03937       if (option_verbose > 2)
03938          ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name);
03939    }
03940 
03941    return tmp;
03942 }

void __ast_context_destroy ( struct ast_context con,
const char *  registrar 
)

Definition at line 5327 of file pbx.c.

References AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), contexts, destroy_exten(), el, free, ast_exten::next, ast_include::next, ast_context::next, ast_ignorepat::next, and ast_exten::peer.

Referenced by ast_context_destroy(), and ast_merge_contexts_and_delete().

05328 {
05329    struct ast_context *tmp, *tmpl=NULL;
05330    struct ast_include *tmpi;
05331    struct ast_sw *sw;
05332    struct ast_exten *e, *el, *en;
05333    struct ast_ignorepat *ipi;
05334 
05335    for (tmp = contexts; tmp; ) {
05336       struct ast_context *next;  /* next starting point */
05337       for (; tmp; tmpl = tmp, tmp = tmp->next) {
05338          if (option_debug)
05339             ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar);
05340          if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) &&
05341               (!con || !strcasecmp(tmp->name, con->name)) )
05342             break;   /* found it */
05343       }
05344       if (!tmp)   /* not found, we are done */
05345          break;
05346       ast_mutex_lock(&tmp->lock);
05347       if (option_debug)
05348          ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar);
05349       next = tmp->next;
05350       if (tmpl)
05351          tmpl->next = next;
05352       else
05353          contexts = next;
05354       /* Okay, now we're safe to let it go -- in a sense, we were
05355          ready to let it go as soon as we locked it. */
05356       ast_mutex_unlock(&tmp->lock);
05357       for (tmpi = tmp->includes; tmpi; ) { /* Free includes */
05358          struct ast_include *tmpil = tmpi;
05359          tmpi = tmpi->next;
05360          free(tmpil);
05361       }
05362       for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */
05363          struct ast_ignorepat *ipl = ipi;
05364          ipi = ipi->next;
05365          free(ipl);
05366       }
05367       while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list)))
05368          free(sw);
05369       for (e = tmp->root; e;) {
05370          for (en = e->peer; en;) {
05371             el = en;
05372             en = en->peer;
05373             destroy_exten(el);
05374          }
05375          el = e;
05376          e = e->next;
05377          destroy_exten(el);
05378       }
05379       ast_mutex_destroy(&tmp->lock);
05380       free(tmp);
05381       /* if we have a specific match, we are done, otherwise continue */
05382       tmp = con ? NULL : next;
05383    }
05384 }

static int __ast_goto_if_exists ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority,
int  async 
) [static]

Definition at line 6458 of file pbx.c.

References ast_async_goto(), ast_exists_extension(), ast_explicit_goto(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, and ast_channel::exten.

Referenced by ast_async_goto_if_exists(), and ast_goto_if_exists().

06459 {
06460    int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority);
06461 
06462    if (!chan)
06463       return -2;
06464 
06465    if (context == NULL)
06466       context = chan->context;
06467    if (exten == NULL)
06468       exten = chan->exten;
06469 
06470    goto_func = (async) ? ast_async_goto : ast_explicit_goto;
06471    if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num))
06472       return goto_func(chan, context, exten, priority);
06473    else
06474       return -3;
06475 }

static int __ast_pbx_run ( struct ast_channel c  )  [static]

Definition at line 2384 of file pbx.c.

References ast_channel::_softhangup, ast_channel::amaflags, ast_calloc, ast_cdr_alloc(), ast_cdr_init(), ast_cdr_start(), ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, ast_log(), AST_PBX_KEEPALIVE, ast_set_flag, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_TIMEOUT, ast_spawn_extension(), ast_test_flag, ast_verbose(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_pbx::dtimeout, error(), ast_channel::exten, free, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, ast_channel::pbx, ast_channel::priority, ast_pbx::rtimeout, set_ext_pri(), ast_cdr::start, and VERBOSE_PREFIX_2.

Referenced by ast_pbx_run(), and pbx_thread().

02385 {
02386    int found = 0; /* set if we find at least one match */
02387    int res = 0;
02388    int autoloopflag;
02389    int error = 0;    /* set an error conditions */
02390 
02391    /* A little initial setup here */
02392    if (c->pbx) {
02393       ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
02394       /* XXX and now what ? */
02395       free(c->pbx);
02396    }
02397    if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx))))
02398       return -1;
02399    if (c->amaflags) {
02400       if (!c->cdr) {
02401          c->cdr = ast_cdr_alloc();
02402          if (!c->cdr) {
02403             ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
02404             free(c->pbx);
02405             return -1;
02406          }
02407          ast_cdr_init(c->cdr, c);
02408       }
02409    }
02410    /* Set reasonable defaults */
02411    c->pbx->rtimeout = 10;
02412    c->pbx->dtimeout = 5;
02413 
02414    autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP);   /* save value to restore at the end */
02415    ast_set_flag(c, AST_FLAG_IN_AUTOLOOP);
02416 
02417    /* Start by trying whatever the channel is set to */
02418    if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
02419       /* If not successful fall back to 's' */
02420       if (option_verbose > 1)
02421          ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
02422       /* XXX the original code used the existing priority in the call to
02423        * ast_exists_extension(), and reset it to 1 afterwards.
02424        * I believe the correct thing is to set it to 1 immediately.
02425        */
02426       set_ext_pri(c, "s", 1);
02427       if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
02428          /* JK02: And finally back to default if everything else failed */
02429          if (option_verbose > 1)
02430             ast_verbose( VERBOSE_PREFIX_2 "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
02431          ast_copy_string(c->context, "default", sizeof(c->context));
02432       }
02433    }
02434    if (c->cdr && ast_tvzero(c->cdr->start))
02435       ast_cdr_start(c->cdr);
02436    for (;;) {
02437       char dst_exten[256]; /* buffer to accumulate digits */
02438       int pos = 0;      /* XXX should check bounds */
02439       int digit = 0;
02440 
02441       /* loop on priorities in this context/exten */
02442       while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
02443          found = 1;
02444          if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
02445             /* Something bad happened, or a hangup has been requested. */
02446             if (strchr("0123456789ABCDEF*#", res)) {
02447                if (option_debug)
02448                   ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
02449                pos = 0;
02450                dst_exten[pos++] = digit = res;
02451                dst_exten[pos] = '\0';
02452                break;
02453             }
02454             if (res == AST_PBX_KEEPALIVE) {
02455                if (option_debug)
02456                   ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
02457                if (option_verbose > 1)
02458                   ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
02459                error = 1;
02460                break;
02461             }
02462             if (option_debug)
02463                ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
02464             if (option_verbose > 1)
02465                ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
02466             if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
02467                c->_softhangup = 0;
02468             } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
02469                /* atimeout, nothing bad */
02470             } else {
02471                if (c->cdr)
02472                   ast_cdr_update(c);
02473                error = 1;
02474                break;
02475             }
02476          }
02477          if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
02478             c->_softhangup = 0;
02479          } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c,c->context,"T",1,c->cid.cid_num)) {
02480             set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */
02481             /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
02482             c->whentohangup = 0;
02483             c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
02484          } else if (c->_softhangup) {
02485             if (option_debug)
02486                ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
02487                   c->exten, c->priority);
02488             error = 1;
02489             break;
02490          }
02491          c->priority++;
02492       } /* end while  - from here on we can use 'break' to go out */
02493       if (error)
02494          break;
02495 
02496       /* XXX we get here on non-existing extension or a keypress or hangup ? */
02497 
02498       if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
02499          /* If there is no match at priority 1, it is not a valid extension anymore.
02500           * Try to continue at "i", 1 or exit if the latter does not exist.
02501           */
02502          if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
02503             if (option_verbose > 2)
02504                ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
02505             pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
02506             set_ext_pri(c, "i", 1);
02507          } else {
02508             ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
02509                c->name, c->exten, c->context);
02510             error = 1; /* we know what to do with it */
02511             break;
02512          }
02513       } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
02514          /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */
02515          c->_softhangup = 0;
02516       } else { /* keypress received, get more digits for a full extension */
02517          int waittime = 0;
02518          if (digit)
02519             waittime = c->pbx->dtimeout;
02520          else if (!autofallthrough)
02521             waittime = c->pbx->rtimeout;
02522          if (!waittime) {
02523             const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
02524             if (!status)
02525                status = "UNKNOWN";
02526             if (option_verbose > 2)
02527                ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status);
02528             if (!strcasecmp(status, "CONGESTION"))
02529                res = pbx_builtin_congestion(c, "10");
02530             else if (!strcasecmp(status, "CHANUNAVAIL"))
02531                res = pbx_builtin_congestion(c, "10");
02532             else if (!strcasecmp(status, "BUSY"))
02533                res = pbx_builtin_busy(c, "10");
02534             error = 1; /* XXX disable message */
02535             break;   /* exit from the 'for' loop */
02536          }
02537 
02538          if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos))
02539             break;
02540          if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */
02541             set_ext_pri(c, dst_exten, 1);
02542          else {
02543             /* No such extension */
02544             if (!ast_strlen_zero(dst_exten)) {
02545                /* An invalid extension */
02546                if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
02547                   if (option_verbose > 2)
02548                      ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name);
02549                   pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
02550                   set_ext_pri(c, "i", 1);
02551                } else {
02552                   ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context);
02553                   found = 1; /* XXX disable message */
02554                   break;
02555                }
02556             } else {
02557                /* A simple timeout */
02558                if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) {
02559                   if (option_verbose > 2)
02560                      ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name);
02561                   set_ext_pri(c, "t", 1);
02562                } else {
02563                   ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
02564                   found = 1; /* XXX disable message */
02565                   break;
02566                }
02567             }
02568          }
02569          if (c->cdr) {
02570             if (option_verbose > 2)
02571                ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name);
02572             ast_cdr_update(c);
02573          }
02574       }
02575    }
02576    if (!found && !error)
02577       ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
02578    if (res != AST_PBX_KEEPALIVE)
02579       ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING);
02580    if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
02581       if (c->cdr && ast_opt_end_cdr_before_h_exten)
02582          ast_cdr_end(c->cdr);
02583       set_ext_pri(c, "h", 1);
02584       while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
02585          if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
02586             /* Something bad happened, or a hangup has been requested. */
02587             if (option_debug)
02588                ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
02589             if (option_verbose > 1)
02590                ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
02591             break;
02592          }
02593          c->priority++;
02594       }
02595    }
02596    ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP);
02597 
02598    pbx_destroy(c->pbx);
02599    c->pbx = NULL;
02600    if (res != AST_PBX_KEEPALIVE)
02601       ast_hangup(c);
02602    return 0;
02603 }

static int _extension_match_core ( const char *  pattern,
const char *  data,
enum ext_match_t  mode 
) [static]

Definition at line 794 of file pbx.c.

References ast_log(), E_MATCH, E_MATCH_MASK, E_MATCHMORE, and LOG_WARNING.

Referenced by extension_match_core().

00795 {
00796    mode &= E_MATCH_MASK;   /* only consider the relevant bits */
00797 
00798    if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */
00799       return 1;
00800 
00801    if (pattern[0] != '_') { /* not a pattern, try exact or partial match */
00802       int ld = strlen(data), lp = strlen(pattern);
00803 
00804       if (lp < ld)      /* pattern too short, cannot match */
00805          return 0;
00806       /* depending on the mode, accept full or partial match or both */
00807       if (mode == E_MATCH)
00808          return !strcmp(pattern, data); /* 1 on match, 0 on fail */
00809       if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */
00810          return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */
00811       else
00812          return 0;
00813    }
00814    pattern++; /* skip leading _ */
00815    /*
00816     * XXX below we stop at '/' which is a separator for the CID info. However we should
00817     * not store '/' in the pattern at all. When we insure it, we can remove the checks.
00818     */
00819    while (*data && *pattern && *pattern != '/') {
00820       const char *end;
00821 
00822       if (*data == '-') { /* skip '-' in data (just a separator) */
00823          data++;
00824          continue;
00825       }
00826       switch (toupper(*pattern)) {
00827       case '[':   /* a range */
00828          end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */
00829          if (end == NULL) {
00830             ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
00831             return 0;   /* unconditional failure */
00832          }
00833          for (pattern++; pattern != end; pattern++) {
00834             if (pattern+2 < end && pattern[1] == '-') { /* this is a range */
00835                if (*data >= pattern[0] && *data <= pattern[2])
00836                   break;   /* match found */
00837                else {
00838                   pattern += 2; /* skip a total of 3 chars */
00839                   continue;
00840                }
00841             } else if (*data == pattern[0])
00842                break;   /* match found */
00843          }
00844          if (pattern == end)
00845             return 0;
00846          pattern = end; /* skip and continue */
00847          break;
00848       case 'N':
00849          if (*data < '2' || *data > '9')
00850             return 0;
00851          break;
00852       case 'X':
00853          if (*data < '0' || *data > '9')
00854             return 0;
00855          break;
00856       case 'Z':
00857          if (*data < '1' || *data > '9')
00858             return 0;
00859          break;
00860       case '.':   /* Must match, even with more digits */
00861          return 1;
00862       case '!':   /* Early match */
00863          return 2;
00864       case ' ':
00865       case '-':   /* Ignore these in patterns */
00866          data--; /* compensate the final data++ */
00867          break;
00868       default:
00869          if (*data != *pattern)
00870             return 0;
00871       }
00872       data++;
00873       pattern++;
00874    }
00875    if (*data)        /* data longer than pattern, no match */
00876       return 0;
00877    /*
00878     * match so far, but ran off the end of the data.
00879     * Depending on what is next, determine match or not.
00880     */
00881    if (*pattern == '\0' || *pattern == '/')  /* exact match */
00882       return (mode == E_MATCHMORE) ? 0 : 1;  /* this is a failure for E_MATCHMORE */
00883    else if (*pattern == '!')        /* early match */
00884       return 2;
00885    else                 /* partial match */
00886       return (mode == E_MATCH) ? 0 : 1;   /* this is a failure for E_MATCH */
00887 }

static int add_pri ( struct ast_context con,
struct ast_exten tmp,
struct ast_exten el,
struct ast_exten e,
int  replace 
) [static]

add the extension in the priority chain. returns 0 on success, -1 on failure

Definition at line 4710 of file pbx.c.

References ast_change_hint(), ast_log(), ast_exten::data, ast_exten::datad, el, ast_exten::exten, free, LOG_WARNING, ast_exten::next, ast_exten::peer, ast_exten::priority, PRIORITY_HINT, and ast_context::root.

Referenced by ast_add_extension2().

04712 {
04713    struct ast_exten *ep;
04714 
04715    for (ep = NULL; e ; ep = e, e = e->peer) {
04716       if (e->priority >= tmp->priority)
04717          break;
04718    }
04719    if (!e) {   /* go at the end, and ep is surely set because the list is not empty */
04720       ep->peer = tmp;
04721       return 0;   /* success */
04722    }
04723    if (e->priority == tmp->priority) {
04724       /* Can't have something exactly the same.  Is this a
04725          replacement?  If so, replace, otherwise, bonk. */
04726       if (!replace) {
04727          ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name);
04728          if (tmp->datad)
04729             tmp->datad(tmp->data);
04730          free(tmp);
04731          return -1;
04732       }
04733       /* we are replacing e, so copy the link fields and then update
04734        * whoever pointed to e to point to us
04735        */
04736       tmp->next = e->next; /* not meaningful if we are not first in the peer list */
04737       tmp->peer = e->peer; /* always meaningful */
04738       if (ep)        /* We're in the peer list, just insert ourselves */
04739          ep->peer = tmp;
04740       else if (el)      /* We're the first extension. Take over e's functions */
04741          el->next = tmp;
04742       else        /* We're the very first extension.  */
04743          con->root = tmp;
04744       if (tmp->priority == PRIORITY_HINT)
04745          ast_change_hint(e,tmp);
04746       /* Destroy the old one */
04747       if (e->datad)
04748          e->datad(e->data);
04749       free(e);
04750    } else { /* Slip ourselves in just before e */
04751       tmp->peer = e;
04752       tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */
04753       if (ep)        /* Easy enough, we're just in the peer list */
04754          ep->peer = tmp;
04755       else {         /* we are the first in some peer list, so link in the ext list */
04756          if (el)
04757             el->next = tmp;   /* in the middle... */
04758          else
04759             con->root = tmp; /* ... or at the head */
04760          e->next = NULL;   /* e is no more at the head, so e->next must be reset */
04761       }
04762       /* And immediately return success. */
04763       if (tmp->priority == PRIORITY_HINT)
04764           ast_add_hint(tmp);
04765    }
04766    return 0;
04767 }

int ast_active_calls ( void   ) 

Retrieve the number of active calls.

Definition at line 2708 of file pbx.c.

References countcalls.

Referenced by handle_chanlist(), and handle_chanlist_deprecated().

02709 {
02710    return countcalls;
02711 }

int ast_add_extension ( const char *  context,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar 
)

Add and extension to an extension context.

Parameters:
context context to add the extension to
replace 
extension extension to add
priority priority level of extension addition
label extension label
callerid pattern to match CallerID, or NULL to match any CallerID
application application to run on the extension with that priority level
data data to pass to the application
datad 
registrar who registered the extension
Return values:
0 success
-1 failure

Definition at line 4585 of file pbx.c.

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

Referenced by handle_context_add_extension(), handle_context_add_extension_deprecated(), park_add_hints(), and register_peer_exten().

04588 {
04589    int ret = -1;
04590    struct ast_context *c = find_context_locked(context);
04591 
04592    if (c) {
04593       ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
04594          application, data, datad, registrar);
04595       ast_unlock_contexts();
04596    }
04597    return ret;
04598 }

int ast_add_extension2 ( struct ast_context con,
int  replace,
const char *  extension,
int  priority,
const char *  label,
const char *  callerid,
const char *  application,
void *  data,
void(*)(void *)  datad,
const char *  registrar 
)

Add an extension to an extension context, this time with an ast_context *.

We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.

The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.

EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set

Definition at line 4794 of file pbx.c.

References add_pri(), ast_exten::app, ast_add_hint(), ast_calloc, AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, errno, ext_cmp(), ext_strncpy(), ast_exten::exten, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.

Referenced by add_extensions(), ast_add_extension(), do_parking_thread(), park_call_full(), pbx_load_config(), and pbx_load_users().

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

static int ast_add_hint ( struct ast_exten e  )  [static]

ast_add_hint: Add hint to hint list, check initial extension state

Definition at line 2206 of file pbx.c.

References ast_calloc, ast_extension_state2(), ast_get_extension_app(), ast_get_extension_name(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_hint::exten, LOG_DEBUG, and option_debug.

Referenced by ast_add_extension2().

02207 {
02208    struct ast_hint *hint;
02209 
02210    if (!e)
02211       return -1;
02212 
02213    AST_LIST_LOCK(&hints);
02214 
02215    /* Search if hint exists, do nothing */
02216    AST_LIST_TRAVERSE(&hints, hint, list) {
02217       if (hint->exten == e) {
02218          AST_LIST_UNLOCK(&hints);
02219          if (option_debug > 1)
02220             ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
02221          return -1;
02222       }
02223    }
02224 
02225    if (option_debug > 1)
02226       ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e));
02227 
02228    if (!(hint = ast_calloc(1, sizeof(*hint)))) {
02229       AST_LIST_UNLOCK(&hints);
02230       return -1;
02231    }
02232    /* Initialize and insert new item at the top */
02233    hint->exten = e;
02234    hint->laststate = ast_extension_state2(e);
02235    AST_LIST_INSERT_HEAD(&hints, hint, list);
02236 
02237    AST_LIST_UNLOCK(&hints);
02238    return 0;
02239 }

AST_APP_OPTIONS ( resetcdr_opts   ) 

AST_APP_OPTIONS ( waitexten_opts   ) 

AST_APP_OPTIONS ( background_opts   ) 

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

Definition at line 4623 of file pbx.c.

References ast_channel::_state, ast_channel::amaflags, ast_cdr_discard(), ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::pbx, ast_channel::readformat, S_OR, and ast_channel::writeformat.

Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), console_transfer_deprecated(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), socket_process(), and zt_handle_dtmfup().

04624 {
04625    int res = 0;
04626 
04627    ast_channel_lock(chan);
04628 
04629    if (chan->pbx) { /* This channel is currently in the PBX */
04630       ast_explicit_goto(chan, context, exten, priority);
04631       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
04632    } else {
04633       /* In order to do it when the channel doesn't really exist within
04634          the PBX, we have to make a new channel, masquerade, and start the PBX
04635          at the new location */
04636       struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name);
04637       if (!tmpchan) {
04638          res = -1;
04639       } else {
04640          if (chan->cdr) {
04641             ast_cdr_discard(tmpchan->cdr);
04642             tmpchan->cdr = ast_cdr_dup(chan->cdr);  /* share the love */
04643          }
04644          /* Make formats okay */
04645          tmpchan->readformat = chan->readformat;
04646          tmpchan->writeformat = chan->writeformat;
04647          /* Setup proper location */
04648          ast_explicit_goto(tmpchan,
04649             S_OR(context, chan->context), S_OR(exten, chan->exten), priority);
04650 
04651          /* Masquerade into temp channel */
04652          ast_channel_masquerade(tmpchan, chan);
04653 
04654          /* Grab the locks and get going */
04655          ast_channel_lock(tmpchan);
04656          ast_do_masquerade(tmpchan);
04657          ast_channel_unlock(tmpchan);
04658          /* Start the PBX going on our stolen channel */
04659          if (ast_pbx_start(tmpchan)) {
04660             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name);
04661             ast_hangup(tmpchan);
04662             res = -1;
04663          }
04664       }
04665    }
04666    ast_channel_unlock(chan);
04667    return res;
04668 }

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

Definition at line 4670 of file pbx.c.

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

04671 {
04672    struct ast_channel *chan;
04673    int res = -1;
04674 
04675    chan = ast_get_channel_by_name_locked(channame);
04676    if (chan) {
04677       res = ast_async_goto(chan, context, exten, priority);
04678       ast_channel_unlock(chan);
04679    }
04680    return res;
04681 }

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

Note:
This function will handle locking the channel as needed.

Definition at line 6482 of file pbx.c.

References __ast_goto_if_exists().

Referenced by asyncgoto_exec().

06483 {
06484    return __ast_goto_if_exists(chan, context, exten, priority, 1);
06485 }

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

Definition at line 4268 of file pbx.c.

References ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, months, and strsep().

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

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

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

Looks for a valid matching extension.

Parameters:
c not really important
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid of extension being searched for
Returns:
If "exten" *could be* a valid extension in this context with or without some more digits, return non-zero. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 2330 of file pbx.c.

References E_CANMATCH, and pbx_extension_helper().

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

02331 {
02332    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
02333 }

static int ast_change_hint ( struct ast_exten oe,
struct ast_exten ne 
) [static]

ast_change_hint: Change hint for an extension

Definition at line 2242 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_hint::exten.

Referenced by add_pri().

02243 {
02244    struct ast_hint *hint;
02245    int res = -1;
02246 
02247    AST_LIST_LOCK(&hints);
02248    AST_LIST_TRAVERSE(&hints, hint, list) {
02249       if (hint->exten == oe) {
02250             hint->exten = ne;
02251          res = 0;
02252          break;
02253       }
02254    }
02255    AST_LIST_UNLOCK(&hints);
02256 
02257    return res;
02258 }

int ast_check_timing ( const struct ast_timing i  ) 

Definition at line 4294 of file pbx.c.

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

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

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

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

Add an ignorepat.

Parameters:
context which context to add the ignorpattern to
ignorepat ignorepattern to set up for the extension
registrar registrar of the ignore pattern
Adds an ignore pattern to a particular context.

Return values:
0 on success
-1 on failure

Definition at line 4521 of file pbx.c.

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

Referenced by handle_context_add_ignorepat(), and handle_context_add_ignorepat_deprecated().

04522 {
04523    int ret = -1;
04524    struct ast_context *c = find_context_locked(context);
04525 
04526    if (c) {
04527       ret = ast_context_add_ignorepat2(c, value, registrar);
04528       ast_unlock_contexts();
04529    }
04530    return ret;
04531 }

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

Definition at line 4533 of file pbx.c.

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

Referenced by ast_context_add_ignorepat(), and pbx_load_config().

04534 {
04535    struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
04536    int length;
04537    length = sizeof(struct ast_ignorepat);
04538    length += strlen(value) + 1;
04539    if (!(ignorepat = ast_calloc(1, length)))
04540       return -1;
04541    /* The cast to char * is because we need to write the initial value.
04542     * The field is not supposed to be modified otherwise
04543     */
04544    strcpy((char *)ignorepat->pattern, value);
04545    ignorepat->next = NULL;
04546    ignorepat->registrar = registrar;
04547    ast_mutex_lock(&con->lock);
04548    for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
04549       ignorepatl = ignorepatc;
04550       if (!strcasecmp(ignorepatc->pattern, value)) {
04551          /* Already there */
04552          ast_mutex_unlock(&con->lock);
04553          errno = EEXIST;
04554          return -1;
04555       }
04556    }
04557    if (ignorepatl)
04558       ignorepatl->next = ignorepat;
04559    else
04560       con->ignorepats = ignorepat;
04561    ast_mutex_unlock(&con->lock);
04562    return 0;
04563 
04564 }

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

Add a context include.

Parameters:
context context to add include to
include new include to add
registrar who's registering it
Adds an include taking a char * string as the context parameter

Return values:
0 on success
-1 on error

Definition at line 4074 of file pbx.c.

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

Referenced by handle_context_add_include(), and handle_context_add_include_deprecated().

04075 {
04076    int ret = -1;
04077    struct ast_context *c = find_context_locked(context);
04078 
04079    if (c) {
04080       ret = ast_context_add_include2(c, include, registrar);
04081       ast_unlock_contexts();
04082    }
04083    return ret;
04084 }

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

Add a context include.

Parameters:
con context to add the include to
include include to add
registrar who registered the context
Adds an include taking a struct ast_context as the first parameter

Return values:
0 on success
-1 on failure

Definition at line 4336 of file pbx.c.

References ast_build_timing(), ast_calloc, ast_get_context_name(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), errno, free, ast_include::hastime, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, option_verbose, ast_include::registrar, ast_include::rname, ast_include::stuff, ast_include::timing, and VERBOSE_PREFIX_3.

Referenced by ast_context_add_include(), and pbx_load_config().

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

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

Add a switch.

Parameters:
context context to which to add the switch
sw switch to add
data data to pass to switch
eval whether to evaluate variables when running switch
registrar whoever registered the switch
This function registers a switch with the asterisk switch architecture

Return values:
0 on success
-1 on failure

Definition at line 4398 of file pbx.c.

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

04399 {
04400    int ret = -1;
04401    struct ast_context *c = find_context_locked(context);
04402 
04403    if (c) { /* found, add switch to this context */
04404       ret = ast_context_add_switch2(c, sw, data, eval, registrar);
04405       ast_unlock_contexts();
04406    }
04407    return ret;
04408 }

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

Adds a switch (first param is a ast_context).

Note:
See ast_context_add_switch() for argument information, with the exception of the first argument. In this case, it's a pointer to an ast_context structure as opposed to the name.

Definition at line 4417 of file pbx.c.

References ast_calloc, ast_get_context_name(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, errno, ast_sw::eval, free, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, and VERBOSE_PREFIX_3.

Referenced by ast_context_add_switch(), and pbx_load_config().

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

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

Register a new context.

Parameters:
extcontexts pointer to the ast_context structure pointer
name name of the new context
registrar registrar of the context
This will first search for a context with your name. If it exists already, it will not create a new one. If it does not exist, it will create a new one with the given name and registrar.

Returns:
NULL on failure, and an ast_context structure on success

Definition at line 3944 of file pbx.c.

References __ast_context_create().

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

03945 {
03946    return __ast_context_create(extcontexts, name, registrar, 0);
03947 }

void ast_context_destroy ( struct ast_context con,
const char *  registrar 
)

Destroy a context (matches the specified context (or ANY context if NULL).

Parameters:
con context to destroy
registrar who registered it
You can optionally leave out either parameter. It will find it based on either the ast_context or the registrar name.

Returns:
nothing

Definition at line 5386 of file pbx.c.

References __ast_context_destroy(), ast_unlock_contexts(), and ast_wrlock_contexts().

Referenced by cleanup_stale_contexts(), sla_destroy(), and unload_module().

05387 {
05388    ast_wrlock_contexts();
05389    __ast_context_destroy(con,registrar);
05390    ast_unlock_contexts();
05391 }

struct ast_context* ast_context_find ( const char *  name  ) 

Find a context.

Parameters:
name name of the context to find
Will search for the context with the given name.

Returns:
the ast_context on success, NULL on failure.

Definition at line 917 of file pbx.c.

References ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), do_parking_thread(), park_call_full(), park_exec(), register_peer_exten(), and set_config().

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

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

Definition at line 3949 of file pbx.c.

References __ast_context_create().

Referenced by pbx_load_config(), and pbx_load_users().

03950 {
03951    return __ast_context_create(extcontexts, name, registrar, 1);
03952 }

int ast_context_lockmacro ( const char *  context  ) 

locks the macrolock in the given given context

Note:
This function locks contexts list by &conlist, searches for the right context structure, and locks the macrolock mutex in that context. macrolock is used to limit a macro to be executed by one call at a time.

Definition at line 2945 of file pbx.c.

References ast_get_context_name(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by _macro_exec().

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

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

Simply remove extension from context.

Parameters:
context context to remove extension from
extension which extension to remove
priority priority of extension to remove
registrar registrar of the extension
This function removes an extension from a given context.

Return values:
0 on success
-1 on failure

Definition at line 2846 of file pbx.c.

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

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

02847 {
02848    int ret = -1; /* default error return */
02849    struct ast_context *c = find_context_locked(context);
02850 
02851    if (c) { /* ... remove extension ... */
02852       ret = ast_context_remove_extension2(c, extension, priority, registrar);
02853       ast_unlock_contexts();
02854    }
02855    return ret;
02856 }

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

References ast_mutex_lock(), ast_mutex_unlock(), destroy_exten(), exten, ast_context::lock, ast_exten::next, ast_exten::peer, and ast_context::root.

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

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

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

Definition at line 4478 of file pbx.c.

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

Referenced by handle_context_remove_ignorepat(), and handle_context_remove_ignorepat_deprecated().

04479 {
04480    int ret = -1;
04481    struct ast_context *c = find_context_locked(context);
04482 
04483    if (c) {
04484       ret = ast_context_remove_ignorepat2(c, ignorepat, registrar);
04485       ast_unlock_contexts();
04486    }
04487    return ret;
04488 }

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

Definition at line 4490 of file pbx.c.

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

Referenced by ast_context_remove_ignorepat().

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

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

Remove a context include.

Note:
See ast_context_add_include for information on arguments
Return values:
0 on success
-1 on failure

Definition at line 2742 of file pbx.c.

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

Referenced by handle_context_dont_include_deprecated(), and handle_context_remove_include().

02743 {
02744    int ret = -1;
02745    struct ast_context *c = find_context_locked(context);
02746 
02747    if (c) {
02748       /* found, remove include from this context ... */
02749       ret = ast_context_remove_include2(c, include, registrar);
02750       ast_unlock_contexts();
02751    }
02752    return ret;
02753 }

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

Removes an include by an ast_context structure.

Note:
See ast_context_add_include2 for information on arguments
Return values:
0 on success
-1 on success

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

02764 {
02765    struct ast_include *i, *pi = NULL;
02766    int ret = -1;
02767 
02768    ast_mutex_lock(&con->lock);
02769 
02770    /* find our include */
02771    for (i = con->includes; i; pi = i, i = i->next) {
02772       if (!strcmp(i->name, include) &&
02773             (!registrar || !strcmp(i->registrar, registrar))) {
02774          /* remove from list */
02775          if (pi)
02776             pi->next = i->next;
02777          else
02778             con->includes = i->next;
02779          /* free include and return */
02780          free(i);
02781          ret = 0;
02782          break;
02783       }
02784    }
02785 
02786    ast_mutex_unlock(&con->lock);
02787    return ret;
02788 }

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

Remove a switch.

Note:
This function locks contexts list by &conlist, search for the rigt context structure, leave context list locked and call ast_context_remove_switch2 which removes switch, unlock contexts list and return ...

Definition at line 2795 of file pbx.c.

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

02796 {
02797    int ret = -1; /* default error return */
02798    struct ast_context *c = find_context_locked(context);
02799 
02800    if (c) {
02801       /* remove switch from this context ... */
02802       ret = ast_context_remove_switch2(c, sw, data, registrar);
02803       ast_unlock_contexts();
02804    }
02805    return ret;
02806 }

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

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_context::lock, ast_sw::name, and ast_sw::registrar.

Referenced by ast_context_remove_switch().

02817 {
02818    struct ast_sw *i;
02819    int ret = -1;
02820 
02821    ast_mutex_lock(&con->lock);
02822 
02823    /* walk switches */
02824    AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
02825       if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
02826          (!registrar || !strcmp(i->registrar, registrar))) {
02827          /* found, remove from list */
02828          AST_LIST_REMOVE_CURRENT(&con->alts, list);
02829          free(i); /* free switch and return */
02830          ret = 0;
02831          break;
02832       }
02833    }
02834    AST_LIST_TRAVERSE_SAFE_END
02835 
02836    ast_mutex_unlock(&con->lock);
02837 
02838    return ret;
02839 }

int ast_context_unlockmacro ( const char *  context  ) 

Unlocks the macrolock in the given context.

Note:
This function locks contexts list by &conlist, searches for the right context structure, and unlocks the macrolock mutex in that context. macrolock is used to limit a macro to be executed by one call at a time.

Definition at line 2973 of file pbx.c.

References ast_get_context_name(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

Referenced by _macro_exec().

02974 {
02975    struct ast_context *c = NULL;
02976    int ret = -1;
02977 
02978    ast_rdlock_contexts();
02979 
02980    while ((c = ast_walk_contexts(c))) {
02981       if (!strcmp(ast_get_context_name(c), context)) {
02982          ret = 0;
02983          break;
02984       }
02985    }
02986 
02987    ast_unlock_contexts();
02988 
02989    /* if we found context, unlock macrolock */
02990    if (ret == 0) 
02991       ret = ast_mutex_unlock(&c->macrolock);
02992 
02993    return ret;
02994 }

int ast_context_verify_includes ( struct ast_context con  ) 

Verifies includes in an ast_contect structure.

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

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

06440 {
06441    struct ast_include *inc = NULL;
06442    int res = 0;
06443 
06444    while ( (inc = ast_walk_context_includes(con, inc)) ) {
06445       if (ast_context_find(inc->rname))
06446          continue;
06447 
06448       res = -1;
06449       ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n",
06450          ast_get_context_name(con), inc->rname);
06451       break;
06452    }
06453 
06454    return res;
06455 }

struct ast_custom_function* ast_custom_function_find ( const char *  name  ) 

Definition at line 1479 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_custom_function::name.

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

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

int ast_custom_function_register ( struct ast_custom_function acf  ) 

Reigster a custom function.

Definition at line 1515 of file pbx.c.

References ast_custom_function_find(), AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), LOG_ERROR, ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.

Referenced by load_module(), odbc_load_module(), and reload().

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

int ast_custom_function_unregister ( struct ast_custom_function acf  ) 

Unregister a custom function.

Definition at line 1493 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), ast_custom_function::name, option_verbose, and VERBOSE_PREFIX_2.

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

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

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

Determine whether an extension exists.

Parameters:
c this is not important
context which context to look in
exten which extension to search for
priority priority of the action within the extension
callerid callerid to search for
Returns:
If an extension within the given context(or callerid) with the given priority is found a non zero value will be returned. Otherwise, 0 is returned.

Definition at line 2315 of file pbx.c.

References E_MATCH, and pbx_extension_helper().

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

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

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

Note:
This function will handle locking the channel as needed.

Definition at line 4600 of file pbx.c.

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

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

04601 {
04602    if (!chan)
04603       return -1;
04604 
04605    ast_channel_lock(chan);
04606 
04607    if (!ast_strlen_zero(context))
04608       ast_copy_string(chan->context, context, sizeof(chan->context));
04609    if (!ast_strlen_zero(exten))
04610       ast_copy_string(chan->exten, exten, sizeof(chan->exten));
04611    if (priority > -1) {
04612       chan->priority = priority;
04613       /* see flag description in channel.h for explanation */
04614       if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP))
04615          chan->priority--;
04616    }
04617 
04618    ast_channel_unlock(chan);
04619 
04620    return 0;
04621 }

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

Definition at line 910 of file pbx.c.

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

Referenced by realtime_switch_common().

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

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

Determine if a given extension matches a given pattern (in NXX format).

Parameters:
pattern pattern to match
extension extension to check against the pattern.
Checks whether or not the given extension matches the given pattern.

Return values:
1 on match
0 on failure

Definition at line 905 of file pbx.c.

References E_MATCH, and extension_match_core().

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

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

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

Uses hint and devicestate callback to get the state of an extension.

Parameters:
c this is not important
context which context to look in
exten which extension to get state
Returns:
extension state as defined in the ast_extension_states enum

Definition at line 2039 of file pbx.c.

References ast_extension_state2(), and ast_hint_extension().

Referenced by action_extensionstate(), and handle_request_subscribe().

02040 {
02041    struct ast_exten *e;
02042 
02043    e = ast_hint_extension(c, context, exten);   /* Do we have a hint for this extension ? */
02044    if (!e)
02045       return -1;           /* No hint, return -1 */
02046 
02047    return ast_extension_state2(e);        /* Check all devices in the hint */
02048 }

static int ast_extension_state2 ( struct ast_exten e  )  [static]

ast_extensions_state2: Check state of extension by using hints

Definition at line 1942 of file pbx.c.

References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_extension_app(), AST_MAX_EXTENSION, busy, inuse, ring(), and strsep().

Referenced by ast_add_hint(), ast_extension_state(), and ast_hint_state_changed().

01943 {
01944    char hint[AST_MAX_EXTENSION];
01945    char *cur, *rest;
01946    int allunavailable = 1, allbusy = 1, allfree = 1, allonhold = 1;
01947    int busy = 0, inuse = 0, ring = 0;
01948 
01949    if (!e)
01950       return -1;
01951 
01952    ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint));
01953 
01954    rest = hint;   /* One or more devices separated with a & character */
01955    while ( (cur = strsep(&rest, "&")) ) {
01956       int res = ast_device_state(cur);
01957       switch (res) {
01958       case AST_DEVICE_NOT_INUSE:
01959          allunavailable = 0;
01960          allbusy = 0;
01961          allonhold = 0;
01962          break;
01963       case AST_DEVICE_INUSE:
01964          inuse = 1;
01965          allunavailable = 0;
01966          allfree = 0;
01967          allonhold = 0;
01968          break;
01969       case AST_DEVICE_RINGING:
01970          ring = 1;
01971          allunavailable = 0;
01972          allfree = 0;
01973          allonhold = 0;
01974          break;
01975       case AST_DEVICE_RINGINUSE:
01976          inuse = 1;
01977          ring = 1;
01978          allunavailable = 0;
01979          allfree = 0;
01980          allonhold = 0;
01981          break;
01982       case AST_DEVICE_ONHOLD:
01983          allunavailable = 0;
01984          allfree = 0;
01985          break;
01986       case AST_DEVICE_BUSY:
01987          allunavailable = 0;
01988          allfree = 0;
01989          allonhold = 0;
01990          busy = 1;
01991          break;
01992       case AST_DEVICE_UNAVAILABLE:
01993       case AST_DEVICE_INVALID:
01994          allbusy = 0;
01995          allfree = 0;
01996          allonhold = 0;
01997          break;
01998       default:
01999          allunavailable = 0;
02000          allbusy = 0;
02001          allfree = 0;
02002          allonhold = 0;
02003       }
02004    }
02005 
02006    if (!inuse && ring)
02007       return AST_EXTENSION_RINGING;
02008    if (inuse && ring)
02009       return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING);
02010    if (inuse)
02011       return AST_EXTENSION_INUSE;
02012    if (allfree)
02013       return AST_EXTENSION_NOT_INUSE;
02014    if (allonhold)
02015       return AST_EXTENSION_ONHOLD;
02016    if (allbusy)
02017       return AST_EXTENSION_BUSY;
02018    if (allunavailable)
02019       return AST_EXTENSION_UNAVAILABLE;
02020    if (busy)
02021       return AST_EXTENSION_INUSE;
02022 
02023    return AST_EXTENSION_NOT_INUSE;
02024 }

const char* ast_extension_state2str ( int  extension_state  ) 

Return string representation of the state of an extension.

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

Definition at line 2027 of file pbx.c.

References extension_states.

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

02028 {
02029    int i;
02030 
02031    for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) {
02032       if (extension_states[i].extension_state == extension_state)
02033          return extension_states[i].text;
02034    }
02035    return "Unknown";
02036 }

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

Registers a state change callback.

Parameters:
context which context to look in
exten which extension to get state
callback callback to call if state changed
data to pass to callback
The callback is called if the state of an extension is changed.

Return values:
-1 on failure
ID on success

Definition at line 2094 of file pbx.c.

References ast_calloc, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_state_cb::callback, ast_state_cb::data, ast_state_cb::next, and statecbs.

Referenced by handle_request_subscribe(), and init_manager().

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

int ast_extension_state_del ( int  id,
ast_state_cb_type  callback 
)

Deletes a registered state change callback by ID.

Parameters:
id of the callback to delete
callback callback
Removes the callback from list of callbacks

Return values:
0 success
-1 failure

Definition at line 2169 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, free, ast_state_cb::next, and statecbs.

Referenced by __sip_destroy(), and handle_request_subscribe().

02170 {
02171    struct ast_state_cb **p_cur = NULL; /* address of pointer to us */
02172    int ret = -1;
02173 
02174    if (!id && !callback)
02175       return -1;
02176 
02177    AST_LIST_LOCK(&hints);
02178 
02179    if (!id) {  /* id == 0 is a callback without extension */
02180       for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) {
02181          if ((*p_cur)->callback == callback)
02182             break;
02183       }
02184    } else { /* callback with extension, find the callback based on ID */
02185       struct ast_hint *hint;
02186       AST_LIST_TRAVERSE(&hints, hint, list) {
02187          for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) {
02188             if ((*p_cur)->id == id)
02189                break;
02190          }
02191          if (*p_cur) /* found in the inner loop */
02192             break;
02193       }
02194    }
02195    if (p_cur && *p_cur) {
02196       struct ast_state_cb *cur = *p_cur;
02197       *p_cur = cur->next;
02198       free(cur);
02199       ret = 0;
02200    }
02201    AST_LIST_UNLOCK(&hints);
02202    return ret;
02203 }

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

Find the priority of an extension that has the specified label.

Parameters:
c this is not important
context which context to look in
exten which extension to search for
label label of the action within the extension to match to priority
callerid callerid to search for
Returns:
the priority which matches the given label in the extension or -1 if not found.

Definition at line 2320 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by action_originate(), action_redirect(), ast_parseable_goto(), asyncgoto_exec(), and handle_setpriority().

02321 {
02322    return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
02323 }

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

Find the priority of an extension that has the specified label.

Note:
This function is the same as ast_findlabel_extension, except that it accepts a pointer to an ast_context structure to specify the context instead of the name of the context. Otherwise, the functions behave the same.

Definition at line 2325 of file pbx.c.

References E_FINDLABEL, and pbx_extension_helper().

Referenced by pbx_load_config().

02326 {
02327    return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
02328 }

int ast_func_read ( struct ast_channel chan,
char *  function,
char *  workspace,
size_t  len 
)

executes a read operation on a function

Parameters:
chan Channel to execute on
function Data containing the function call string (will be modified)
workspace A pointer to safe memory to use for a return value
len the number of bytes in workspace
This application executes a function in read mode on a given channel.

Returns:
zero on success, non-zero on failure

Definition at line 1569 of file pbx.c.

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

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

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

int ast_func_write ( struct ast_channel chan,
char *  function,
const char *  value 
)

executes a write operation on a function

Parameters:
chan Channel to execute on
function Data containing the function call string (will be modified)
value A value parameter to pass for writing
This application executes a function in write mode on a given channel.

Returns:
zero on success, non-zero on failure

Definition at line 1583 of file pbx.c.

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

Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().

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

const char* ast_get_context_name ( struct ast_context con  ) 

Definition at line 6296 of file pbx.c.

Referenced by _macro_exec(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().

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

const char* ast_get_context_registrar ( struct ast_context c  ) 

Definition at line 6334 of file pbx.c.

References ast_context::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

const char* ast_get_extension_app ( struct ast_exten e  ) 

Definition at line 6364 of file pbx.c.

References ast_exten::app.

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

06365 {
06366    return e ? e->app : NULL;
06367 }

void* ast_get_extension_app_data ( struct ast_exten e  ) 

Definition at line 6369 of file pbx.c.

References ast_exten::data.

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

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

const char* ast_get_extension_cidmatch ( struct ast_exten e  ) 

Definition at line 6359 of file pbx.c.

References ast_exten::cidmatch.

Referenced by find_matching_priority(), and handle_save_dialplan().

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

struct ast_context* ast_get_extension_context ( struct ast_exten exten  ) 

Definition at line 6301 of file pbx.c.

References exten.

Referenced by handle_show_hints().

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

const char* ast_get_extension_label ( struct ast_exten exten  ) 

Definition at line 6311 of file pbx.c.

References exten.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06312 {
06313    return exten ? exten->label : NULL;
06314 }

int ast_get_extension_matchcid ( struct ast_exten e  ) 

Definition at line 6354 of file pbx.c.

References ast_exten::matchcid.

Referenced by find_matching_priority(), and handle_save_dialplan().

06355 {
06356    return e ? e->matchcid : 0;
06357 }

const char* ast_get_extension_name ( struct ast_exten exten  ) 

Definition at line 6306 of file pbx.c.

References exten.

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

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

int ast_get_extension_priority ( struct ast_exten exten  ) 

Definition at line 6326 of file pbx.c.

References exten.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), and print_ext().

06327 {
06328    return exten ? exten->priority : -1;
06329 }

const char* ast_get_extension_registrar ( struct ast_exten e  ) 

Definition at line 6339 of file pbx.c.

References ast_exten::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

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

If an extension exists, return non-zero.

Parameters:
hint buffer for hint
maxlen size of hint buffer
name buffer for name portion of hint
maxnamelen size of name buffer
c this is not important
context which context to look in
exten which extension to search for
Returns:
If an extension within the given context with the priority PRIORITY_HINT is found a non zero value will be returned. Otherwise, 0 is returned.

Definition at line 2298 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(), get_destination(), pbx_retrieve_variable(), and transmit_state_notify().

02299 {
02300    struct ast_exten *e = ast_hint_extension(c, context, exten);
02301 
02302    if (e) {
02303       if (hint)
02304          ast_copy_string(hint, ast_get_extension_app(e), hintsize);
02305       if (name) {
02306          const char *tmp = ast_get_extension_app_data(e);
02307          if (tmp)
02308             ast_copy_string(name, tmp, namesize);
02309       }
02310       return -1;
02311    }
02312    return 0;
02313 }

const char* ast_get_ignorepat_name ( struct ast_ignorepat ip  ) 

Definition at line 6321 of file pbx.c.

References ast_ignorepat::pattern.

Referenced by complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), handle_save_dialplan(), lookup_c_ip(), and show_dialplan_helper().

06322 {
06323    return ip ? ip->pattern : NULL;
06324 }

const char* ast_get_ignorepat_registrar ( struct ast_ignorepat ip  ) 

Definition at line 6349 of file pbx.c.

References ast_ignorepat::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

const char* ast_get_include_name ( struct ast_include inc  ) 

Definition at line 6316 of file pbx.c.

References ast_include::name.

Referenced by complete_context_dont_include_deprecated(), complete_context_remove_include(), find_matching_priority(), handle_save_dialplan(), lookup_ci(), and show_dialplan_helper().

06317 {
06318    return inc ? inc->name : NULL;
06319 }

const char* ast_get_include_registrar ( struct ast_include i  ) 

Definition at line 6344 of file pbx.c.

References ast_include::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06345 {
06346    return i ? i->registrar : NULL;
06347 }

const char* ast_get_switch_data ( struct ast_sw sw  ) 

Definition at line 6379 of file pbx.c.

References ast_sw::data.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06380 {
06381    return sw ? sw->data : NULL;
06382 }

const char* ast_get_switch_name ( struct ast_sw sw  ) 

Definition at line 6374 of file pbx.c.

References ast_sw::name.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

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

const char* ast_get_switch_registrar ( struct ast_sw sw  ) 

Definition at line 6384 of file pbx.c.

References ast_sw::registrar.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06385 {
06386    return sw ? sw->registrar : NULL;
06387 }

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

Note:
This function will handle locking the channel as needed.

Definition at line 6477 of file pbx.c.

References __ast_goto_if_exists().

Referenced by aqm_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), do_directory(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), onedigit_goto(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), system_exec_helper(), transfer_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer().

06478 {
06479    return __ast_goto_if_exists(chan, context, exten, priority, 0);
06480 }

static struct ast_exten* ast_hint_extension ( struct ast_channel c,
const char *  context,
const char *  exten 
) [static]

ast_hint_extension: Find hint for given extension in context

Definition at line 1929 of file pbx.c.

References ast_rdlock_contexts(), ast_unlock_contexts(), E_MATCH, pbx_find_extension(), PRIORITY_HINT, and pbx_find_info::stacklen.

Referenced by ast_extension_state(), and ast_get_hint().

01930 {
01931    struct ast_exten *e;
01932    struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
01933 
01934    ast_rdlock_contexts();
01935    e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH);
01936    ast_unlock_contexts();
01937 
01938    return e;
01939 }

void ast_hint_state_changed ( const char *  device  ) 

Definition at line 2050 of file pbx.c.

References ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_exten::exten, ast_hint::laststate, ast_state_cb::next, ast_exten::parent, parse(), statecbs, and strsep().

Referenced by do_state_change().

02051 {
02052    struct ast_hint *hint;
02053 
02054    AST_LIST_LOCK(&hints);
02055 
02056    AST_LIST_TRAVERSE(&hints, hint, list) {
02057       struct ast_state_cb *cblist;
02058       char buf[AST_MAX_EXTENSION];
02059       char *parse = buf;
02060       char *cur;
02061       int state;
02062 
02063       ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
02064       while ( (cur = strsep(&parse, "&")) ) {
02065          if (!strcasecmp(cur, device))
02066             break;
02067       }
02068       if (!cur)
02069          continue;
02070 
02071       /* Get device state for this hint */
02072       state = ast_extension_state2(hint->exten);
02073 
02074       if ((state == -1) || (state == hint->laststate))
02075          continue;
02076 
02077       /* Device state changed since last check - notify the watchers */
02078 
02079       /* For general callbacks */
02080       for (cblist = statecbs; cblist; cblist = cblist->next)
02081          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02082 
02083       /* For extension callbacks */
02084       for (cblist = hint->callbacks; cblist; cblist = cblist->next)
02085          cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
02086 
02087       hint->laststate = state;   /* record we saw the change */
02088    }
02089 
02090    AST_LIST_UNLOCK(&hints);
02091 }

int ast_ignore_pattern ( const char *  context,
const char *  pattern 
)

Checks to see if a number should be ignored.

Parameters:
context context to search within
pattern to check whether it should be ignored or not
Check if a number should be ignored with respect to dialtone cancellation.

Return values:
0 if the pattern should not be ignored
non-zero if the pattern should be ignored

Definition at line 4566 of file pbx.c.

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

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

04567 {
04568    struct ast_context *con = ast_context_find(context);
04569    if (con) {
04570       struct ast_ignorepat *pat;
04571       for (pat = con->ignorepats; pat; pat = pat->next) {
04572          if (ast_extension_match(pat->pattern, pattern))
04573             return 1;
04574       }
04575    }
04576 
04577    return 0;
04578 }

AST_LIST_HEAD ( store_hints  ,
store_hint   
)

static AST_LIST_HEAD_STATIC ( hints  ,
ast_hint   
) [static]

static AST_LIST_HEAD_STATIC ( switches  ,
ast_switch   
) [static]

static AST_LIST_HEAD_STATIC ( apps  ,
ast_app   
) [static]

static AST_LIST_HEAD_STATIC ( acf_root  ,
ast_custom_function   
) [static]

int ast_lock_context ( struct ast_context con  ) 

Locks a given context.

Parameters:
con context to lock
Return values:
0 on success
-1 on failure

Definition at line 6283 of file pbx.c.

References ast_mutex_lock(), and ast_context::lock.

Referenced by _macro_exec(), complete_context_dont_include_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), and show_dialplan_helper().

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

int ast_lock_contexts ( void   ) 

Locks the context list.

Return values:
0 on success
-1 on error

Definition at line 6260 of file pbx.c.

References ast_rwlock_wrlock().

Referenced by find_matching_endwhile().

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

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

Looks to see if adding anything to this extension might match something. (exists ^ canmatch).

Parameters:
c not really important XXX
context context to serach within
exten extension to check
priority priority of extension path
callerid callerid of extension being searched for
Returns:
If "exten" *could match* a valid extension in this context with some more digits, return non-zero. Does NOT return non-zero if this is an exact-match only. Basically, when this returns 0, no matter what you add to exten, it's not going to be a valid extension anymore

Definition at line 2335 of file pbx.c.

References E_MATCHMORE, and pbx_extension_helper().

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

02336 {
02337    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
02338 }

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

Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added.

Parameters:
extcontexts pointer to the ast_context structure pointer
registrar of the context; if it's set the routine will delete all contexts that belong to that registrar; if NULL only the contexts that are specified in extcontexts

Definition at line 3967 of file pbx.c.

References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_unlock_contexts(), ast_wrlock_contexts(), ast_state_cb::callback, ast_hint::callbacks, store_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, E_MATCH, store_hint::exten, ast_hint::exten, ast_exten::exten, free, store_hint::laststate, ast_hint::laststate, LOG_WARNING, ast_context::next, ast_state_cb::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.

Referenced by pbx_load_module().

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

AST_MUTEX_DEFINE_STATIC ( maxcalllock   ) 

AST_MUTEX_DEFINE_STATIC ( globalslock   ) 

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

Note:
I can find neither parsable nor parseable at dictionary.com, but google gives me 169000 hits for parseable and only 49,800 for parsable

This function will handle locking the channel as needed.

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

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

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

int ast_pbx_outgoing_app ( const char *  type,
int  format,
void *  data,
int  timeout,
const char *  app,
const char *  appdata,
int *  reason,
int  sync,
const char *  cid_num,
const char *  cid_name,
struct ast_variable vars,
const char *  account,
struct ast_channel **  locked_channel 
)

Synchronously or asynchronously make an outbound call and send it to a particular application with given extension

Definition at line 5186 of file pbx.c.

References __ast_request_and_dial(), ast_calloc, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_lock, ast_channel_unlock, ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run_app(), ast_pthread_create, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, errno, free, LOG_WARNING, option_verbose, ast_channel::pbx, outgoing_helper::vars, and VERBOSE_PREFIX_4.

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

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

static int ast_pbx_outgoing_cdr_failed ( void   )  [static]

Function to post an empty cdr after a spool call fails.

This function posts an empty cdr for a failed spool call

Definition at line 4995 of file pbx.c.

References ast_cdr_detach(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_start(), ast_channel_alloc(), ast_channel_free(), AST_STATE_DOWN, and ast_channel::cdr.

Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

04996 {
04997    /* allocate a channel */
04998    struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0);
04999 
05000    if (!chan)
05001       return -1;  /* failure */
05002 
05003    if (!chan->cdr) {
05004       /* allocation of the cdr failed */
05005       ast_channel_free(chan);   /* free the channel */
05006       return -1;                /* return failure */
05007    }
05008 
05009    /* allocation of the cdr was successful */
05010    ast_cdr_init(chan->cdr, chan);  /* initilize our channel's cdr */
05011    ast_cdr_start(chan->cdr);       /* record the start and stop time */
05012    ast_cdr_end(chan->cdr);
05013    ast_cdr_failed(chan->cdr);      /* set the status to failed */
05014    ast_cdr_detach(chan->cdr);      /* post and free the record */
05015    ast_channel_free(chan);         /* free the channel */
05016 
05017    return 0;  /* success */
05018 }

int ast_pbx_outgoing_exten ( const char *  type,
int  format,
void *  data,
int  timeout,
const char *  context,
const char *  exten,
int  priority,
int *  reason,
int  sync,
const char *  cid_num,
const char *  cid_name,
struct ast_variable vars,
const char *  account,
struct ast_channel **  locked_channel 
)

Synchronously or asynchronously make an outbound call and send it to a particular extension

Definition at line 5020 of file pbx.c.

References __ast_request_and_dial(), ast_channel::_state, ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_alloc(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, option_verbose, pbx_builtin_setvar_helper(), set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.

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

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

enum ast_pbx_result ast_pbx_run ( struct ast_channel c  ) 

Execute the PBX in the current thread.

Parameters:
c channel to run the pbx on
This executes the PBX on a given channel. It allocates a new PBX structure for the channel, and provides all PBX functionality. See ast_pbx_start for an asynchronous function to run the PBX in a new thread as opposed to the current one.

Returns:
Zero on success, non-zero on failure

Definition at line 2695 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_newcall(), and ss_thread().

02696 {
02697    enum ast_pbx_result res = AST_PBX_SUCCESS;
02698 
02699    if (increase_call_count(c))
02700       return AST_PBX_CALL_LIMIT;
02701 
02702    res = __ast_pbx_run(c);
02703    decrease_call_count();
02704 
02705    return res;
02706 }

static void* ast_pbx_run_app ( void *  data  )  [static]

run the application and free the descriptor once done

Definition at line 5170 of file pbx.c.

References app_tmp::app, app, ast_hangup(), ast_log(), ast_verbose(), app_tmp::chan, app_tmp::data, free, LOG_WARNING, option_verbose, pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_4.

Referenced by ast_pbx_outgoing_app().

05171 {
05172    struct app_tmp *tmp = data;
05173    struct ast_app *app;
05174    app = pbx_findapp(tmp->app);
05175    if (app) {
05176       if (option_verbose > 3)
05177          ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name);
05178       pbx_exec(tmp->chan, app, tmp->data);
05179    } else
05180       ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app);
05181    ast_hangup(tmp->chan);
05182    free(tmp);
05183    return NULL;
05184 }

enum ast_pbx_result ast_pbx_start ( struct ast_channel c  ) 

Create a new thread and start the PBX.

Parameters:
c channel to start the pbx on
See ast_pbx_run for a synchronous function to run the PBX in the current thread, as opposed to starting a new one.

Returns:
Zero on success, non-zero on failure

Definition at line 2669 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_pbx_outgoing_exten(), check_goto_on_transfer(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), and zt_new().

02670 {
02671    pthread_t t;
02672    pthread_attr_t attr;
02673 
02674    if (!c) {
02675       ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
02676       return AST_PBX_FAILED;
02677    }
02678 
02679    if (increase_call_count(c))
02680       return AST_PBX_CALL_LIMIT;
02681 
02682    /* Start a new thread, and get something handling this channel. */
02683    pthread_attr_init(&attr);
02684    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02685    if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
02686       ast_log(LOG_WARNING, "Failed to create new channel thread\n");
02687       pthread_attr_destroy(&attr);
02688       return AST_PBX_FAILED;
02689    }
02690    pthread_attr_destroy(&attr);
02691 
02692    return AST_PBX_SUCCESS;
02693 }

int ast_rdlock_contexts ( void   ) 

Definition at line 6265 of file pbx.c.

References ast_rwlock_rdlock().

Referenced by __ast_context_create(), _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().

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

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

Register an application.

Parameters:
app Short name of the application
execute a function callback to execute the application. It should return non-zero if the channel needs to be hung up.
synopsis a short description (one line synopsis) of the application
description long description with all of the details about the use of the application
This registers an application with Asterisk's internal application list.
Note:
The individual applications themselves are responsible for registering and unregistering and unregistering their own CLI commands.
Return values:
0 success
-1 failure.

Definition at line 2997 of file pbx.c.

References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, LOG_WARNING, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.

Referenced by load_module(), and load_pbx().

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

int ast_register_switch ( struct ast_switch sw  ) 

Register an alternative dialplan switch.

Parameters:
sw switch to register
This function registers a populated ast_switch structure with the asterisk switching architecture.

Returns:
0 on success, and other than 0 on failure

Definition at line 3047 of file pbx.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), LOG_WARNING, and ast_switch::name.

Referenced by load_module().

03048 {
03049    struct ast_switch *tmp;
03050 
03051    AST_LIST_LOCK(&switches);
03052    AST_LIST_TRAVERSE(&switches, tmp, list) {
03053       if (!strcasecmp(tmp->name, sw->name)) {
03054          AST_LIST_UNLOCK(&switches);
03055          ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
03056          return -1;
03057       }
03058    }
03059    AST_LIST_INSERT_TAIL(&switches, sw, list);
03060    AST_LIST_UNLOCK(&switches);
03061 
03062    return 0;
03063 }

static int ast_remove_hint ( struct ast_exten e  )  [static]

ast_remove_hint: Remove hint from extension

Definition at line 2261 of file pbx.c.

References AST_EXTENSION_DEACTIVATED, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, free, ast_state_cb::next, and ast_exten::parent.

Referenced by destroy_exten().

02262 {
02263    /* Cleanup the Notifys if hint is removed */
02264    struct ast_hint *hint;
02265    struct ast_state_cb *cblist, *cbprev;
02266    int res = -1;
02267 
02268    if (!e)
02269       return -1;
02270 
02271    AST_LIST_LOCK(&hints);
02272    AST_LIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) {
02273       if (hint->exten == e) {
02274          cbprev = NULL;
02275          cblist = hint->callbacks;
02276          while (cblist) {
02277             /* Notify with -1 and remove all callbacks */
02278             cbprev = cblist;
02279             cblist = cblist->next;
02280             cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data);
02281             free(cbprev);
02282             }
02283             hint->callbacks = NULL;
02284          AST_LIST_REMOVE_CURRENT(&hints, list);
02285             free(hint);
02286             res = 0;
02287          break;
02288       }
02289    }
02290    AST_LIST_TRAVERSE_SAFE_END
02291    AST_LIST_UNLOCK(&hints);
02292 
02293    return res;
02294 }

AST_RWLOCK_DEFINE_STATIC ( conlock   ) 

Lock for the ast_context list

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

Launch a new extension (i.e. new stack).

Parameters:
c not important
context which context to generate the extension within
exten new extension to add
priority priority of new extension
callerid callerid of extension
This adds a new extension to the asterisk extension list.

Return values:
0 on success
-1 on failure.

Definition at line 2340 of file pbx.c.

References E_SPAWN, and pbx_extension_helper().

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

02341 {
02342    return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
02343 }

AST_THREADSTORAGE ( switch_data  ,
switch_data_init   
)

int ast_unlock_context ( struct ast_context con  ) 

Return values:
Unlocks the given context
Parameters:
con context to unlock
Return values:
0 on success
-1 on failure

Definition at line 6288 of file pbx.c.

References ast_mutex_unlock(), and ast_context::lock.

Referenced by _macro_exec(), complete_context_dont_include_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), lookup_c_ip(), lookup_ci(), and show_dialplan_helper().

06289 {
06290    return ast_mutex_unlock(&con->lock);
06291 }

int ast_unlock_contexts ( void   ) 

Unlocks contexts.

Return values:
0 on success
-1 on failure

Definition at line 6275 of file pbx.c.

References ast_rwlock_unlock().

Referenced by __ast_context_create(), _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_destroy(), ast_context_find(), ast_context_lockmacro(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_merge_contexts_and_delete(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().

06276 {
06277    return ast_rwlock_unlock(&conlock);
06278 }

int ast_unregister_application ( const char *  app  ) 

Unregister an application.

Parameters:
app name of the application (does not have to be the same string as the one that was registered)
This unregisters an application from Asterisk's internal application list.

Return values:
0 success
-1 failure

Definition at line 3878 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free, option_verbose, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

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

void ast_unregister_switch ( struct ast_switch sw  ) 

Unregister an alternative switch.

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

Returns:
nothing

Definition at line 3065 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.

Referenced by __unload_module(), and unload_module().

03066 {
03067    AST_LIST_LOCK(&switches);
03068    AST_LIST_REMOVE(&switches, sw, list);
03069    AST_LIST_UNLOCK(&switches);
03070 }

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

Definition at line 6397 of file pbx.c.

References exten, and ast_context::root.

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

06399 {
06400    if (!exten)
06401       return con ? con->root : NULL;
06402    else
06403       return exten->next;
06404 }

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

Definition at line 6430 of file pbx.c.

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

Referenced by complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), handle_save_dialplan(), lookup_c_ip(), and show_dialplan_helper().

06432 {
06433    if (!ip)
06434       return con ? con->ignorepats : NULL;
06435    else
06436       return ip->next;
06437 }

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

Definition at line 6421 of file pbx.c.

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

Referenced by ast_context_verify_includes(), complete_context_dont_include_deprecated(), complete_context_remove_include(), find_matching_priority(), handle_save_dialplan(), lookup_ci(), and show_dialplan_helper().

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

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

Definition at line 6406 of file pbx.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

Referenced by handle_save_dialplan(), and show_dialplan_helper().

06408 {
06409    if (!sw)
06410       return con ? AST_LIST_FIRST(&con->alts) : NULL;
06411    else
06412       return AST_LIST_NEXT(sw, list);
06413 }

struct ast_context* ast_walk_contexts ( struct ast_context con  ) 

Definition at line 6392 of file pbx.c.

References contexts, and ast_context::next.

Referenced by _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), pbx_load_module(), and show_dialplan_helper().

06393 {
06394    return con ? con->next : contexts;
06395 }

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

Definition at line 6415 of file pbx.c.

References exten, and ast_exten::priority.

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

06417 {
06418    return priority ? priority->peer : exten;
06419 }

int ast_wrlock_contexts ( void   ) 

Definition at line 6270 of file pbx.c.

References ast_rwlock_wrlock().

Referenced by ast_context_destroy(), ast_merge_contexts_and_delete(), and complete_context_dont_include_deprecated().

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

static void* async_wait ( void *  data  )  [static]

Definition at line 4932 of file pbx.c.

References ast_channel::_state, app, async_stat::app, async_stat::appdata, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_pbx_run(), ast_read(), AST_STATE_UP, ast_strlen_zero(), ast_verbose(), ast_waitfor(), async_stat::chan, ast_channel::context, async_stat::context, ast_channel::exten, async_stat::exten, f, free, LOG_ERROR, LOG_WARNING, option_verbose, pbx_exec(), pbx_findapp(), ast_channel::priority, async_stat::priority, async_stat::timeout, and VERBOSE_PREFIX_3.

Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

04933 {
04934    struct async_stat *as = data;
04935    struct ast_channel *chan = as->chan;
04936    int timeout = as->timeout;
04937    int res;
04938    struct ast_frame *f;
04939    struct ast_app *app;
04940 
04941    while (timeout && (chan->_state != AST_STATE_UP)) {
04942       res = ast_waitfor(chan, timeout);
04943       if (res < 1)
04944          break;
04945       if (timeout > -1)
04946          timeout = res;
04947       f = ast_read(chan);
04948       if (!f)
04949          break;
04950       if (f->frametype == AST_FRAME_CONTROL) {
04951          if ((f->subclass == AST_CONTROL_BUSY)  ||
04952              (f->subclass == AST_CONTROL_CONGESTION) ) {
04953             ast_frfree(f);
04954             break;
04955          }
04956       }
04957       ast_frfree(f);
04958    }
04959    if (chan->_state == AST_STATE_UP) {
04960       if (!ast_strlen_zero(as->app)) {
04961          app = pbx_findapp(as->app);
04962          if (app) {
04963             if (option_verbose > 2)
04964                ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name);
04965             pbx_exec(chan, app, as->appdata);
04966          } else
04967             ast_log(LOG_WARNING, "No such application '%s'\n", as->app);
04968       } else {
04969          if (!ast_strlen_zero(as->context))
04970             ast_copy_string(chan->context, as->context, sizeof(chan->context));
04971          if (!ast_strlen_zero(as->exten))
04972             ast_copy_string(chan->exten, as->exten, sizeof(chan->exten));
04973          if (as->priority > 0)
04974             chan->priority = as->priority;
04975          /* Run the PBX */
04976          if (ast_pbx_run(chan)) {
04977             ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name);
04978          } else {
04979             /* PBX will have taken care of this */
04980             chan = NULL;
04981          }
04982       }
04983    }
04984    free(as);
04985    if (chan)
04986       ast_hangup(chan);
04987    return NULL;
04988 }

static int collect_digits ( struct ast_channel c,
int  waittime,
char *  buf,
int  buflen,
int  pos 
) [static]

collect digits from the channel into the buffer, return -1 on error, 0 on timeout or done.

Definition at line 2358 of file pbx.c.

References ast_channel::_softhangup, ast_matchmore_extension(), AST_SOFTHANGUP_ASYNCGOTO, ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_pbx::dtimeout, and ast_channel::pbx.

02359 {
02360    int digit;
02361 
02362    buf[pos] = '\0';  /* make sure it is properly terminated */
02363    while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) {
02364       /* As long as we're willing to wait, and as long as it's not defined,
02365          keep reading digits until we can't possibly get a right answer anymore.  */
02366       digit = ast_waitfordigit(c, waittime * 1000);
02367       if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
02368          c->_softhangup = 0;
02369       } else {
02370          if (!digit) /* No entry */
02371             break;
02372          if (digit < 0) /* Error, maybe a  hangup */
02373             return -1;
02374          if (pos < buflen - 1) { /* XXX maybe error otherwise ? */
02375             buf[pos++] = digit;
02376             buf[pos] = '\0';
02377          }
02378          waittime = c->pbx->dtimeout;
02379       }
02380    }
02381    return 0;
02382 }

static char* complete_show_application ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 3123 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and strdup.

03124 {
03125    struct ast_app *a;
03126    char *ret = NULL;
03127    int which = 0;
03128    int wordlen = strlen(word);
03129 
03130    /* return the n-th [partial] matching entry */
03131    AST_LIST_LOCK(&apps);
03132    AST_LIST_TRAVERSE(&apps, a, list) {
03133       if (!strncasecmp(word, a->name, wordlen) && ++which > state) {
03134          ret = strdup(a->name);
03135          break;
03136       }
03137    }
03138    AST_LIST_UNLOCK(&apps);
03139 
03140    return ret;
03141 }

static char* complete_show_applications ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 3484 of file pbx.c.

References ast_cli_complete().

03485 {
03486    static char* choices[] = { "like", "describing", NULL };
03487 
03488    return (pos != 3) ? NULL : ast_cli_complete(word, choices, state);
03489 }

static char* complete_show_applications_deprecated ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 3477 of file pbx.c.

References ast_cli_complete().

03478 {
03479    static char* choices[] = { "like", "describing", NULL };
03480 
03481    return (pos != 2) ? NULL : ast_cli_complete(word, choices, state);
03482 }

static char* complete_show_dialplan_context ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 3494 of file pbx.c.

References ast_get_context_name(), ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), and ast_walk_contexts().

03496 {
03497    struct ast_context *c = NULL;
03498    char *ret = NULL;
03499    int which = 0;
03500    int wordlen;
03501 
03502    /* we are do completion of [exten@]context on second position only */
03503    if (pos != 2)
03504       return NULL;
03505 
03506    ast_rdlock_contexts();
03507 
03508    wordlen = strlen(word);
03509 
03510    /* walk through all contexts and return the n-th match */
03511    while ( (c = ast_walk_contexts(c)) ) {
03512       if (!strncasecmp(word, ast_get_context_name(c), wordlen) && ++which > state) {
03513          ret = ast_strdup(ast_get_context_name(c));
03514          break;
03515       }
03516    }
03517 
03518    ast_unlock_contexts();
03519 
03520    return ret;
03521 }

static char* complete_show_function ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 1459 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_custom_function::name, and strdup.

01460 {
01461    struct ast_custom_function *acf;
01462    char *ret = NULL;
01463    int which = 0;
01464    int wordlen = strlen(word);
01465 
01466    /* case-insensitive for convenience in this 'complete' function */
01467    AST_LIST_LOCK(&acf_root);
01468    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01469       if (!strncasecmp(word, acf->name, wordlen) && ++which > state) {
01470          ret = strdup(acf->name);
01471          break;
01472       }
01473    }
01474    AST_LIST_UNLOCK(&acf_root);
01475 
01476    return ret;
01477 }

static void decrease_call_count ( void   )  [static]

Definition at line 2631 of file pbx.c.

References ast_mutex_lock(), ast_mutex_unlock(), and countcalls.

Referenced by ast_pbx_run(), and pbx_thread().

02632 {
02633    ast_mutex_lock(&maxcalllock);
02634    if (countcalls > 0)
02635       countcalls--;
02636    ast_mutex_unlock(&maxcalllock);
02637 }

static void destroy_exten ( struct ast_exten e  )  [static]

Definition at line 2639 of file pbx.c.

References ast_remove_hint(), free, ast_exten::priority, and PRIORITY_HINT.

Referenced by __ast_context_destroy(), and ast_context_remove_extension2().

02640 {
02641    if (e->priority == PRIORITY_HINT)
02642       ast_remove_hint(e);
02643 
02644    if (e->datad)
02645       e->datad(e->data);
02646    free(e);
02647 }

static int ext_cmp ( const char *  a,
const char *  b 
) [static]

the full routine to compare extensions in rules.

Definition at line 744 of file pbx.c.

References ext_cmp1().

Referenced by ast_add_extension2().

00745 {
00746    /* make sure non-patterns come first.
00747     * If a is not a pattern, it either comes first or
00748     * we use strcmp to compare the strings.
00749     */
00750    int ret = 0;
00751 
00752    if (a[0] != '_')
00753       return (b[0] == '_') ? -1 : strcmp(a, b);
00754 
00755    /* Now we know a is a pattern; if b is not, a comes first */
00756    if (b[0] != '_')
00757       return 1;
00758 #if 0 /* old mode for ext matching */
00759    return strcmp(a, b);
00760 #endif
00761    /* ok we need full pattern sorting routine */
00762    while (!ret && a && b)
00763       ret = ext_cmp1(&a) - ext_cmp1(&b);
00764    if (ret == 0)
00765       return 0;
00766    else
00767       return (ret > 0) ? 1 : -1;
00768 }

static int ext_cmp1 ( const char **  p  )  [static]

helper functions to sort extensions and patterns in the desired way, so that more specific patterns appear first.

ext_cmp1 compares individual characters (or sets of), returning an int where bits 0-7 are the ASCII code of the first char in the set, while bit 8-15 are the cardinality of the set minus 1. This way more specific patterns (smaller cardinality) appear first. Wildcards have a special value, so that we can directly compare them to sets by subtracting the two values. In particular: 0x000xx one character, xx 0x0yyxx yy character set starting with xx 0x10000 '.' (one or more of anything) 0x20000 '!' (zero or more of anything) 0x30000 NUL (end of string) 0x40000 error in set. The pointer to the string is advanced according to needs. NOTES: 1. the empty set is equivalent to NUL. 2. given that a full set has always 0 as the first element, we could encode the special cases as 0xffXX where XX is 1, 2, 3, 4 as used above.

Definition at line 672 of file pbx.c.

References ast_log(), and LOG_WARNING.

Referenced by ext_cmp().

00673 {
00674    uint32_t chars[8];
00675    int c, cmin = 0xff, count = 0;
00676    const char *end;
00677 
00678    /* load, sign extend and advance pointer until we find
00679     * a valid character.
00680     */
00681    while ( (c = *(*p)++) && (c == ' ' || c == '-') )
00682       ;  /* ignore some characters */
00683 
00684    /* always return unless we have a set of chars */
00685    switch (c) {
00686    default: /* ordinary character */
00687       return 0x0000 | (c & 0xff);
00688 
00689    case 'N':   /* 2..9 */
00690       return 0x0700 | '2' ;
00691 
00692    case 'X':   /* 0..9 */
00693       return 0x0900 | '0';
00694 
00695    case 'Z':   /* 1..9 */
00696       return 0x0800 | '1';
00697 
00698    case '.':   /* wildcard */
00699       return 0x10000;
00700 
00701    case '!':   /* earlymatch */
00702       return 0x20000;   /* less specific than NULL */
00703 
00704    case '\0':  /* empty string */
00705       *p = NULL;
00706       return 0x30000;
00707 
00708    case '[':   /* pattern */
00709       break;
00710    }
00711    /* locate end of set */
00712    end = strchr(*p, ']');  
00713 
00714    if (end == NULL) {
00715       ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");
00716       return 0x40000;   /* XXX make this entry go last... */
00717    }
00718 
00719    bzero(chars, sizeof(chars));  /* clear all chars in the set */
00720    for (; *p < end  ; (*p)++) {
00721       unsigned char c1, c2;   /* first-last char in range */
00722       c1 = (unsigned char)((*p)[0]);
00723       if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
00724          c2 = (unsigned char)((*p)[2]);
00725          *p += 2; /* skip a total of 3 chars */
00726       } else         /* individual character */
00727          c2 = c1;
00728       if (c1 < cmin)
00729          cmin = c1;
00730       for (; c1 <= c2; c1++) {
00731          uint32_t mask = 1 << (c1 % 32);
00732          if ( (chars[ c1 / 32 ] & mask) == 0)
00733             count += 0x100;
00734          chars[ c1 / 32 ] |= mask;
00735       }
00736    }
00737    (*p)++;
00738    return count == 0 ? 0x30000 : (count | cmin);
00739 }

static int ext_strncpy ( char *  dst,
const char *  src,
int  len 
) [static]

copy a string skipping whitespace

Definition at line 4684 of file pbx.c.

Referenced by ast_add_extension2().

04685 {
04686    int count=0;
04687 
04688    while (*src && (count < len - 1)) {
04689       switch(*src) {
04690       case ' ':
04691          /* otherwise exten => [a-b],1,... doesn't work */
04692          /*    case '-': */
04693          /* Ignore */
04694          break;
04695       default:
04696          *dst = *src;
04697          dst++;
04698       }
04699       src++;
04700       count++;
04701    }
04702    *dst = '\0';
04703 
04704    return count;
04705 }

static int extension_match_core ( const char *  pattern,
const char *  data,
enum ext_match_t  mode 
) [static]

Definition at line 893 of file pbx.c.

References _extension_match_core(), ast_add_profile(), and ast_mark().

Referenced by ast_extension_close(), ast_extension_match(), and pbx_find_extension().

00894 {
00895    int i;
00896    static int prof_id = -2;   /* marker for 'unallocated' id */
00897    if (prof_id == -2)
00898       prof_id = ast_add_profile("ext_match", 0);
00899    ast_mark(prof_id, 1);
00900    i = _extension_match_core(pattern, data, mode);
00901    ast_mark(prof_id, 0);
00902    return i;
00903 }

static struct ast_context* find_context_locked ( const char *  context  )  [static]

Definition at line 2723 of file pbx.c.

References ast_get_context_name(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().

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

02724 {
02725    struct ast_context *c = NULL;
02726 
02727    ast_rdlock_contexts();
02728    while ( (c = ast_walk_contexts(c)) ) {
02729       if (!strcmp(ast_get_context_name(c), context))
02730          return c;
02731    }
02732    ast_unlock_contexts();
02733 
02734    return NULL;
02735 }

static char* func_args ( char *  function  )  [static]

return a pointer to the arguments of the function, and terminates the function name with '\0'

Definition at line 1552 of file pbx.c.

References ast_log(), and LOG_WARNING.

Referenced by ast_func_read(), and ast_func_write().

01553 {
01554    char *args = strchr(function, '(');
01555 
01556    if (!args)
01557       ast_log(LOG_WARNING, "Function doesn't contain parentheses.  Assuming null argument.\n");
01558    else {
01559       char *p;
01560       *args++ = '\0';
01561       if ((p = strrchr(args, ')')) )
01562          *p = '\0';
01563       else
01564          ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
01565    }
01566    return args;
01567 }

static unsigned get_range ( char *  src,
int  max,
char *const   names[],
const char *  msg 
) [static]

helper function to return a range up to max (7, 12, 31 respectively). names, if supplied, is an array of names that should be mapped to numbers.

Definition at line 4108 of file pbx.c.

References ast_log(), ast_strlen_zero(), LOG_WARNING, lookup_name(), and s.

Referenced by ast_build_timing().

04109 {
04110    int s, e; /* start and ending position */
04111    unsigned int mask = 0;
04112 
04113    /* Check for whole range */
04114    if (ast_strlen_zero(src) || !strcmp(src, "*")) {
04115       s = 0;
04116       e = max - 1;
04117    } else {
04118       /* Get start and ending position */
04119       char *c = strchr(src, '-');
04120       if (c)
04121          *c++ = '\0';
04122       /* Find the start */
04123       s = lookup_name(src, names, max);
04124       if (!s) {
04125          ast_log(LOG_WARNING, "Invalid %s '%s', assuming none\n", msg, src);
04126          return 0;
04127       }
04128       s--;
04129       if (c) { /* find end of range */
04130          e = lookup_name(c, names, max);
04131          if (!e) {
04132             ast_log(LOG_WARNING, "Invalid end %s '%s', assuming none\n", msg, c);
04133             return 0;
04134          }
04135          e--;
04136       } else
04137          e = s;
04138    }
04139    /* Fill the mask. Remember that ranges are cyclic */
04140    mask = 1 << e; /* initialize with last element */
04141    while (s != e) {
04142       if (s >= max) {
04143          s = 0;
04144          mask |= (1 << s);
04145       } else {
04146          mask |= (1 << s);
04147          s++;
04148       }
04149    }
04150    return mask;
04151 }

static void get_timerange ( struct ast_timing i,
char *  times 
) [static]

store a bitmask of valid times, one bit each 2 minute

Definition at line 4154 of file pbx.c.

References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask.

Referenced by ast_build_timing().

04155 {
04156    char *e;
04157    int x;
04158    int s1, s2;
04159    int e1, e2;
04160    /* int cth, ctm; */
04161 
04162    /* start disabling all times, fill the fields with 0's, as they may contain garbage */
04163    memset(i->minmask, 0, sizeof(i->minmask));
04164 
04165    /* 2-minutes per bit, since the mask has only 32 bits :( */
04166    /* Star is all times */
04167    if (ast_strlen_zero(times) || !strcmp(times, "*")) {
04168       for (x=0; x<24; x++)
04169          i->minmask[x] = 0x3fffffff; /* 30 bits */
04170       return;
04171    }
04172    /* Otherwise expect a range */
04173    e = strchr(times, '-');
04174    if (!e) {
04175       ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n");
04176       return;
04177    }
04178    *e++ = '\0';
04179    /* XXX why skip non digits ? */
04180    while (*e && !isdigit(*e))
04181       e++;
04182    if (!*e) {
04183       ast_log(LOG_WARNING, "Invalid time range.  Assuming no restrictions based on time.\n");
04184       return;
04185    }
04186    if (sscanf(times, "%d:%d", &s1, &s2) != 2) {
04187       ast_log(LOG_WARNING, "%s isn't a time.  Assuming no restrictions based on time.\n", times);
04188       return;
04189    }
04190    if (sscanf(e, "%d:%d", &e1, &e2) != 2) {
04191       ast_log(LOG_WARNING, "%s isn't a time.  Assuming no restrictions based on time.\n", e);
04192       return;
04193    }
04194    /* XXX this needs to be optimized */
04195 #if 1
04196    s1 = s1 * 30 + s2/2;
04197    if ((s1 < 0) || (s1 >= 24*30)) {
04198       ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times);
04199       return;
04200    }
04201    e1 = e1 * 30 + e2/2;
04202    if ((e1 < 0) || (e1 >= 24*30)) {
04203       ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e);
04204       return;
04205    }
04206    /* Go through the time and enable each appropriate bit */
04207    for (x=s1;x != e1;x = (x + 1) % (24 * 30)) {
04208       i->minmask[x/30] |= (1 << (x % 30));
04209    }
04210    /* Do the last one */
04211    i->minmask[x/30] |= (1 << (x % 30));
04212 #else
04213    for (cth=0; cth<24; cth++) {
04214       /* Initialize masks to blank */
04215       i->minmask[cth] = 0;
04216       for (ctm=0; ctm<30; ctm++) {
04217          if (
04218          /* First hour with more than one hour */
04219                (((cth == s1) && (ctm >= s2)) &&
04220                 ((cth < e1)))
04221          /* Only one hour */
04222          ||    (((cth == s1) && (ctm >= s2)) &&
04223                 ((cth == e1) && (ctm <= e2)))
04224          /* In between first and last hours (more than 2 hours) */
04225          ||    ((cth > s1) &&
04226                 (cth < e1))
04227          /* Last hour with more than one hour */
04228          ||    ((cth > s1) &&
04229                 ((cth == e1) && (ctm <= e2)))
04230          )
04231             i->minmask[cth] |= (1 << (ctm / 2));
04232       }
04233    }
04234 #endif
04235    /* All done */
04236    return;
04237 }

static int handle_set_global ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 3779 of file pbx.c.

References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

03780 {
03781    if (argc != 5)
03782       return RESULT_SHOWUSAGE;
03783 
03784    pbx_builtin_setvar_helper(NULL, argv[3], argv[4]);
03785    ast_cli(fd, "\n    -- Global variable %s set to %s\n", argv[3], argv[4]);
03786 
03787    return RESULT_SUCCESS;
03788 }

static int handle_set_global_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

CLI support for setting global variables.

Definition at line 3767 of file pbx.c.

References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

03768 {
03769    if (argc != 4)
03770       return RESULT_SHOWUSAGE;
03771 
03772    pbx_builtin_setvar_helper(NULL, argv[2], argv[3]);
03773    ast_cli(fd, "\n    -- Global variable %s set to %s\n", argv[2], argv[3]);
03774 
03775    return RESULT_SUCCESS;
03776 }

static int handle_show_application ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 3213 of file pbx.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_MAX_APP, COLOR_CYAN, COLOR_MAGENTA, ast_app::description, RESULT_SHOWUSAGE, ast_app::synopsis, and term_color().

03214 {
03215    struct ast_app *a;
03216    int app, no_registered_app = 1;
03217 
03218    if (argc < 4)
03219       return RESULT_SHOWUSAGE;
03220 
03221    /* ... go through all applications ... */
03222    AST_LIST_LOCK(&apps);
03223    AST_LIST_TRAVERSE(&apps, a, list) {
03224       /* ... compare this application name with all arguments given
03225        * to 'show application' command ... */
03226       for (app = 3; app < argc; app++) {
03227          if (!strcasecmp(a->name, argv[app])) {
03228             /* Maximum number of characters added by terminal coloring is 22 */
03229             char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
03230             char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
03231             int synopsis_size, description_size;
03232 
03233             no_registered_app = 0;
03234 
03235             if (a->synopsis)
03236                synopsis_size = strlen(a->synopsis) + 23;
03237             else
03238                synopsis_size = strlen("Not available") + 23;
03239             synopsis = alloca(synopsis_size);
03240 
03241             if (a->description)
03242                description_size = strlen(a->description) + 23;
03243             else
03244                description_size = strlen("Not available") + 23;
03245             description = alloca(description_size);
03246 
03247             if (synopsis && description) {
03248                snprintf(info, 64 + AST_MAX_APP, "\n  -= Info about application '%s' =- \n\n", a->name);
03249                term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
03250                term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
03251                term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
03252                term_color(synopsis,
03253                            a->synopsis ? a->synopsis : "Not available",
03254                            COLOR_CYAN, 0, synopsis_size);
03255                term_color(description,
03256                            a->description ? a->description : "Not available",
03257                            COLOR_CYAN, 0, description_size);
03258 
03259                ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description);
03260             } else {
03261                /* ... one of our applications, show info ...*/
03262                ast_cli(fd,"\n  -= Info about application '%s' =- \n\n"
03263                   "[Synopsis]\n  %s\n\n"
03264                   "[Description]\n%s\n",
03265                   a->name,
03266                   a->synopsis ? a->synopsis : "Not available",
03267                   a->description ? a->description : "Not available");
03268             }
03269          }
03270       }
03271    }
03272    AST_LIST_UNLOCK(&apps);
03273 
03274    /* we found at least one app? no? */
03275    if (no_registered_app) {
03276       ast_cli(fd, "Your application(s) is (are) not registered\n");
03277       return RESULT_FAILURE;
03278    }
03279 
03280    return RESULT_SUCCESS;
03281 }

static int handle_show_application_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 3143 of file pbx.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_MAX_APP, COLOR_CYAN, COLOR_MAGENTA, ast_app::description, RESULT_SHOWUSAGE, ast_app::synopsis, and term_color().

03144 {
03145    struct ast_app *a;
03146    int app, no_registered_app = 1;
03147 
03148    if (argc < 3)
03149       return RESULT_SHOWUSAGE;
03150 
03151    /* ... go through all applications ... */
03152    AST_LIST_LOCK(&apps);
03153    AST_LIST_TRAVERSE(&apps, a, list) {
03154       /* ... compare this application name with all arguments given
03155        * to 'show application' command ... */
03156       for (app = 2; app < argc; app++) {
03157          if (!strcasecmp(a->name, argv[app])) {
03158             /* Maximum number of characters added by terminal coloring is 22 */
03159             char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
03160             char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
03161             int synopsis_size, description_size;
03162 
03163             no_registered_app = 0;
03164 
03165             if (a->synopsis)
03166                synopsis_size = strlen(a->synopsis) + 23;
03167             else
03168                synopsis_size = strlen("Not available") + 23;
03169             synopsis = alloca(synopsis_size);
03170 
03171             if (a->description)
03172                description_size = strlen(a->description) + 23;
03173             else
03174                description_size = strlen("Not available") + 23;
03175             description = alloca(description_size);
03176 
03177             if (synopsis && description) {
03178                snprintf(info, 64 + AST_MAX_APP, "\n  -= Info about application '%s' =- \n\n", a->name);
03179                term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
03180                term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
03181                term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
03182                term_color(synopsis,
03183                            a->synopsis ? a->synopsis : "Not available",
03184                            COLOR_CYAN, 0, synopsis_size);
03185                term_color(description,
03186                            a->description ? a->description : "Not available",
03187                            COLOR_CYAN, 0, description_size);
03188 
03189                ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description);
03190             } else {
03191                /* ... one of our applications, show info ...*/
03192                ast_cli(fd,"\n  -= Info about application '%s' =- \n\n"
03193                   "[Synopsis]\n  %s\n\n"
03194                   "[Description]\n%s\n",
03195                   a->name,
03196                   a->synopsis ? a->synopsis : "Not available",
03197                   a->description ? a->description : "Not available");
03198             }
03199          }
03200       }
03201    }
03202    AST_LIST_UNLOCK(&apps);
03203 
03204    /* we found at least one app? no? */
03205    if (no_registered_app) {
03206       ast_cli(fd, "Your application(s) is (are) not registered\n");
03207       return RESULT_FAILURE;
03208    }
03209 
03210    return RESULT_SUCCESS;
03211 }

static int handle_show_applications ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 3408 of file pbx.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::description, strcasestr(), and ast_app::synopsis.

03409 {
03410    struct ast_app *a;
03411    int like = 0, describing = 0;
03412    int total_match = 0;    /* Number of matches in like clause */
03413    int total_apps = 0;  /* Number of apps registered */
03414 
03415    AST_LIST_LOCK(&apps);
03416 
03417    if (AST_LIST_EMPTY(&apps)) {
03418       ast_cli(fd, "There are no registered applications\n");
03419       AST_LIST_UNLOCK(&apps);
03420       return -1;
03421    }
03422 
03423    /* core list applications like <keyword> */
03424    if ((argc == 5) && (!strcmp(argv[3], "like"))) {
03425       like = 1;
03426    } else if ((argc > 4) && (!strcmp(argv[3], "describing"))) {
03427       describing = 1;
03428    }
03429 
03430    /* core list applications describing <keyword1> [<keyword2>] [...] */
03431    if ((!like) && (!describing)) {
03432       ast_cli(fd, "    -= Registered Asterisk Applications =-\n");
03433    } else {
03434       ast_cli(fd, "    -= Matching Asterisk Applications =-\n");
03435    }
03436 
03437    AST_LIST_TRAVERSE(&apps, a, list) {
03438       int printapp = 0;
03439       total_apps++;
03440       if (like) {
03441          if (strcasestr(a->name, argv[4])) {
03442             printapp = 1;
03443             total_match++;
03444          }
03445       } else if (describing) {
03446          if (a->description) {
03447             /* Match all words on command line */
03448             int i;
03449             printapp = 1;
03450             for (i = 4; i < argc; i++) {
03451                if (!strcasestr(a->description, argv[i])) {
03452                   printapp = 0;
03453                } else {
03454                   total_match++;
03455                }
03456             }
03457          }
03458       } else {
03459          printapp = 1;
03460       }
03461 
03462       if (printapp) {
03463          ast_cli(fd,"  %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>");
03464       }
03465    }
03466    if ((!like) && (!describing)) {
03467       ast_cli(fd, "    -= %d Applications Registered =-\n",total_apps);
03468    } else {
03469       ast_cli(fd, "    -= %d Applications Matching =-\n",total_match);
03470    }
03471 
03472    AST_LIST_UNLOCK(&apps);
03473 
03474    return RESULT_SUCCESS;
03475 }

static int handle_show_applications_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 3340 of file pbx.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::description, strcasestr(), and ast_app::synopsis.

03341 {
03342    struct ast_app *a;
03343    int like = 0, describing = 0;
03344    int total_match = 0;    /* Number of matches in like clause */
03345    int total_apps = 0;  /* Number of apps registered */
03346 
03347    AST_LIST_LOCK(&apps);
03348 
03349    if (AST_LIST_EMPTY(&apps)) {
03350       ast_cli(fd, "There are no registered applications\n");
03351       AST_LIST_UNLOCK(&apps);
03352       return -1;
03353    }
03354 
03355    /* show applications like <keyword> */
03356    if ((argc == 4) && (!strcmp(argv[2], "like"))) {
03357       like = 1;
03358    } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) {
03359       describing = 1;
03360    }
03361 
03362    /* show applications describing <keyword1> [<keyword2>] [...] */
03363    if ((!like) && (!describing)) {
03364       ast_cli(fd, "    -= Registered Asterisk Applications =-\n");
03365    } else {
03366       ast_cli(fd, "    -= Matching Asterisk Applications =-\n");
03367    }
03368 
03369    AST_LIST_TRAVERSE(&apps, a, list) {
03370       int printapp = 0;
03371       total_apps++;
03372       if (like) {
03373          if (strcasestr(a->name, argv[3])) {
03374             printapp = 1;
03375             total_match++;
03376          }
03377       } else if (describing) {
03378          if (a->description) {
03379             /* Match all words on command line */
03380             int i;
03381             printapp = 1;
03382             for (i = 3; i < argc; i++) {
03383                if (!strcasestr(a->description, argv[i])) {
03384                   printapp = 0;
03385                } else {
03386                   total_match++;
03387                }
03388             }
03389          }
03390       } else {
03391          printapp = 1;
03392       }
03393 
03394       if (printapp) {
03395          ast_cli(fd,"  %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>");
03396       }
03397    }
03398    if ((!like) && (!describing)) {
03399       ast_cli(fd, "    -= %d Applications Registered =-\n",total_apps);
03400    } else {
03401       ast_cli(fd, "    -= %d Applications Matching =-\n",total_match);
03402    }
03403 
03404    AST_LIST_UNLOCK(&apps);
03405 
03406    return RESULT_SUCCESS;
03407 }

static int handle_show_dialplan ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 3694 of file pbx.c.

References ast_cli(), AST_PBX_MAX_STACK, ast_strdupa, ast_strlen_zero(), context, exten, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, show_dialplan_helper(), and strsep().

03695 {
03696    char *exten = NULL, *context = NULL;
03697    /* Variables used for different counters */
03698    struct dialplan_counters counters;
03699 
03700    const char *incstack[AST_PBX_MAX_STACK];
03701    memset(&counters, 0, sizeof(counters));
03702 
03703    if (argc != 2 && argc != 3)
03704       return RESULT_SHOWUSAGE;
03705 
03706    /* we obtain [exten@]context? if yes, split them ... */
03707    if (argc == 3) {
03708       if (strchr(argv[2], '@')) {   /* split into exten & context */
03709          context = ast_strdupa(argv[2]);
03710          exten = strsep(&context, "@");
03711          /* change empty strings to NULL */
03712          if (ast_strlen_zero(exten))
03713             exten = NULL;
03714       } else { /* no '@' char, only context given */
03715          context = argv[2];
03716       }
03717       if (ast_strlen_zero(context))
03718          context = NULL;
03719    }
03720    /* else Show complete dial plan, context and exten are NULL */
03721    show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack);
03722 
03723    /* check for input failure and throw some error messages */
03724    if (context && !counters.context_existence) {
03725       ast_cli(fd, "There is no existence of '%s' context\n", context);
03726       return RESULT_FAILURE;
03727    }
03728 
03729    if (exten && !counters.extension_existence) {
03730       if (context)
03731          ast_cli(fd, "There is no existence of %s@%s extension\n",
03732             exten, context);
03733       else
03734          ast_cli(fd,
03735             "There is no existence of '%s' extension in all contexts\n",
03736             exten);
03737       return RESULT_FAILURE;
03738    }
03739 
03740    ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n",
03741             counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions",
03742             counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities",
03743             counters.total_context, counters.total_context == 1 ? "context" : "contexts");
03744 
03745    /* everything ok */
03746    return RESULT_SUCCESS;
03747 }

static int handle_show_function ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1403 of file pbx.c.

References ast_cli(), ast_custom_function_find(), AST_MAX_APP, COLOR_CYAN, COLOR_MAGENTA, ast_custom_function::desc, ast_custom_function::name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_custom_function::synopsis, ast_custom_function::syntax, and term_color().

01404 {
01405    struct ast_custom_function *acf;
01406    /* Maximum number of characters added by terminal coloring is 22 */
01407    char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
01408    char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
01409    char stxtitle[40], *syntax = NULL;
01410    int synopsis_size, description_size, syntax_size;
01411 
01412    if (argc < 4)
01413       return RESULT_SHOWUSAGE;
01414 
01415    if (!(acf = ast_custom_function_find(argv[3]))) {
01416       ast_cli(fd, "No function by that name registered.\n");
01417       return RESULT_FAILURE;
01418 
01419    }
01420 
01421    if (acf->synopsis)
01422       synopsis_size = strlen(acf->synopsis) + 23;
01423    else
01424       synopsis_size = strlen("Not available") + 23;
01425    synopsis = alloca(synopsis_size);
01426 
01427    if (acf->desc)
01428       description_size = strlen(acf->desc) + 23;
01429    else
01430       description_size = strlen("Not available") + 23;
01431    description = alloca(description_size);
01432 
01433    if (acf->syntax)
01434       syntax_size = strlen(acf->syntax) + 23;
01435    else
01436       syntax_size = strlen("Not available") + 23;
01437    syntax = alloca(syntax_size);
01438 
01439    snprintf(info, 64 + AST_MAX_APP, "\n  -= Info about function '%s' =- \n\n", acf->name);
01440    term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
01441    term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
01442    term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
01443    term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
01444    term_color(syntax,
01445          acf->syntax ? acf->syntax : "Not available",
01446          COLOR_CYAN, 0, syntax_size);
01447    term_color(synopsis,
01448          acf->synopsis ? acf->synopsis : "Not available",
01449          COLOR_CYAN, 0, synopsis_size);
01450    term_color(description,
01451          acf->desc ? acf->desc : "Not available",
01452          COLOR_CYAN, 0, description_size);
01453 
01454    ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description);
01455 
01456    return RESULT_SUCCESS;
01457 }

static int handle_show_function_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1347 of file pbx.c.

References ast_cli(), ast_custom_function_find(), AST_MAX_APP, COLOR_CYAN, COLOR_MAGENTA, ast_custom_function::desc, ast_custom_function::name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_custom_function::synopsis, ast_custom_function::syntax, and term_color().

01348 {
01349    struct ast_custom_function *acf;
01350    /* Maximum number of characters added by terminal coloring is 22 */
01351    char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
01352    char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
01353    char stxtitle[40], *syntax = NULL;
01354    int synopsis_size, description_size, syntax_size;
01355 
01356    if (argc < 3)
01357       return RESULT_SHOWUSAGE;
01358 
01359    if (!(acf = ast_custom_function_find(argv[2]))) {
01360       ast_cli(fd, "No function by that name registered.\n");
01361       return RESULT_FAILURE;
01362 
01363    }
01364 
01365    if (acf->synopsis)
01366       synopsis_size = strlen(acf->synopsis) + 23;
01367    else
01368       synopsis_size = strlen("Not available") + 23;
01369    synopsis = alloca(synopsis_size);
01370 
01371    if (acf->desc)
01372       description_size = strlen(acf->desc) + 23;
01373    else
01374       description_size = strlen("Not available") + 23;
01375    description = alloca(description_size);
01376 
01377    if (acf->syntax)
01378       syntax_size = strlen(acf->syntax) + 23;
01379    else
01380       syntax_size = strlen("Not available") + 23;
01381    syntax = alloca(syntax_size);
01382 
01383    snprintf(info, 64 + AST_MAX_APP, "\n  -= Info about function '%s' =- \n\n", acf->name);
01384    term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
01385    term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
01386    term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
01387    term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
01388    term_color(syntax,
01389          acf->syntax ? acf->syntax : "Not available",
01390          COLOR_CYAN, 0, syntax_size);
01391    term_color(synopsis,
01392          acf->synopsis ? acf->synopsis : "Not available",
01393          COLOR_CYAN, 0, synopsis_size);
01394    term_color(description,
01395          acf->desc ? acf->desc : "Not available",
01396          COLOR_CYAN, 0, description_size);
01397 
01398    ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description);
01399 
01400    return RESULT_SUCCESS;
01401 }

static int handle_show_functions ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1319 of file pbx.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_custom_function::name, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_custom_function::synopsis, and ast_custom_function::syntax.

01320 {
01321    struct ast_custom_function *acf;
01322    int count_acf = 0;
01323    int like = 0;
01324 
01325    if (argc == 5 && (!strcmp(argv[3], "like")) ) {
01326       like = 1;
01327    } else if (argc != 3) {
01328       return RESULT_SHOWUSAGE;
01329    }
01330 
01331    ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed");
01332 
01333    AST_LIST_LOCK(&acf_root);
01334    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01335       if (!like || strstr(acf->name, argv[4])) {
01336          count_acf++;
01337          ast_cli(fd, "%-20.20s  %-35.35s  %s\n", acf->name, acf->syntax, acf->synopsis);
01338       }
01339    }
01340    AST_LIST_UNLOCK(&acf_root);
01341 
01342    ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : "");
01343 
01344    return RESULT_SUCCESS;
01345 }

static int handle_show_functions_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1292 of file pbx.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_custom_function::name, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_custom_function::synopsis, and ast_custom_function::syntax.

01293 {
01294    struct ast_custom_function *acf;
01295    int count_acf = 0;
01296    int like = 0;
01297 
01298    if (argc == 4 && (!strcmp(argv[2], "like")) ) {
01299       like = 1;
01300    } else if (argc != 2) {
01301       return RESULT_SHOWUSAGE;
01302    }
01303 
01304    ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed");
01305 
01306    AST_LIST_LOCK(&acf_root);
01307    AST_LIST_TRAVERSE(&acf_root, acf, acflist) {
01308       if (!like || strstr(acf->name, argv[3])) {
01309          count_acf++;
01310          ast_cli(fd, "%-20.20s  %-35.35s  %s\n", acf->name, acf->syntax, acf->synopsis);
01311       }
01312    }
01313    AST_LIST_UNLOCK(&acf_root);
01314 
01315    ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : "");
01316 
01317    return RESULT_SUCCESS;
01318 }

static int handle_show_globals ( int  fd,
int  argc,
char *  argv[] 
) [static]

CLI support for listing global variables in a parseable way.

Definition at line 3750 of file pbx.c.

References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), and RESULT_SUCCESS.

03751 {
03752    int i = 0;
03753    struct ast_var_t *newvariable;
03754 
03755    ast_mutex_lock(&globalslock);
03756    AST_LIST_TRAVERSE (&globals, newvariable, entries) {
03757       i++;
03758       ast_cli(fd, "   %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable));
03759    }
03760    ast_mutex_unlock(&globalslock);
03761    ast_cli(fd, "\n    -- %d variables\n", i);
03762 
03763    return RESULT_SUCCESS;
03764 }

static int handle_show_hints ( int  fd,
int  argc,
char *  argv[] 
) [static]

handle_show_hints: CLI support for listing registred dial plan hints

Definition at line 3284 of file pbx.c.

References ast_cli(), ast_extension_state2str(), ast_get_context_name(), ast_get_extension_app(), ast_get_extension_context(), ast_get_extension_name(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, ast_hint::exten, ast_hint::laststate, ast_state_cb::next, and RESULT_SUCCESS.

03285 {
03286    struct ast_hint *hint;
03287    int num = 0;
03288    int watchers;
03289    struct ast_state_cb *watcher;
03290 
03291    if (AST_LIST_EMPTY(&hints)) {
03292       ast_cli(fd, "There are no registered dialplan hints\n");
03293       return RESULT_SUCCESS;
03294    }
03295    /* ... we have hints ... */
03296    ast_cli(fd, "\n    -= Registered Asterisk Dial Plan Hints =-\n");
03297    AST_LIST_LOCK(&hints);
03298    AST_LIST_TRAVERSE(&hints, hint, list) {
03299       watchers = 0;
03300       for (watcher = hint->callbacks; watcher; watcher = watcher->next)
03301          watchers++;
03302       ast_cli(fd, "   %20s@%-20.20s: %-20.20s  State:%-15.15s Watchers %2d\n",
03303          ast_get_extension_name(hint->exten),
03304          ast_get_context_name(ast_get_extension_context(hint->exten)),
03305          ast_get_extension_app(hint->exten),
03306          ast_extension_state2str(hint->laststate), watchers);
03307       num++;
03308    }
03309    ast_cli(fd, "----------------\n");
03310    ast_cli(fd, "- %d hints registered\n", num);
03311    AST_LIST_UNLOCK(&hints);
03312    return RESULT_SUCCESS;
03313 }

static int handle_show_switches ( int  fd,
int  argc,
char *  argv[] 
) [static]

handle_show_switches: CLI support for listing registred dial plan switches

Definition at line 3316 of file pbx.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_switch::description, ast_switch::name, and RESULT_SUCCESS.

03317 {
03318    struct ast_switch *sw;
03319 
03320    AST_LIST_LOCK(&switches);
03321 
03322    if (AST_LIST_EMPTY(&switches)) {
03323       AST_LIST_UNLOCK(&switches);
03324       ast_cli(fd, "There are no registered alternative switches\n");
03325       return RESULT_SUCCESS;
03326    }
03327 
03328    ast_cli(fd, "\n    -= Registered Asterisk Alternative Switches =-\n");
03329    AST_LIST_TRAVERSE(&switches, sw, list)
03330       ast_cli(fd, "%s: %s\n", sw->name, sw->description);
03331 
03332    AST_LIST_UNLOCK(&switches);
03333 
03334    return RESULT_SUCCESS;
03335 }

static int include_valid ( struct ast_include i  )  [inline, static]

Definition at line 603 of file pbx.c.

References ast_check_timing(), ast_include::hastime, and ast_include::timing.

00604 {
00605    if (!i->hastime)
00606       return 1;
00607 
00608    return ast_check_timing(&(i->timing));
00609 }

static int increase_call_count ( const struct ast_channel c  )  [static]

Definition at line 2606 of file pbx.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), countcalls, getloadavg(), LOG_NOTICE, option_maxcalls, and option_maxload.

Referenced by ast_pbx_run(), and ast_pbx_start().

02607 {
02608    int failed = 0;
02609    double curloadavg;
02610    ast_mutex_lock(&maxcalllock);
02611    if (option_maxcalls) {
02612       if (countcalls >= option_maxcalls) {
02613          ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name);
02614          failed = -1;
02615       }
02616    }
02617    if (option_maxload) {
02618       getloadavg(&curloadavg, 1);
02619       if (curloadavg >= option_maxload) {
02620          ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg);
02621          failed = -1;
02622       }
02623    }
02624    if (!failed)
02625       countcalls++;
02626    ast_mutex_unlock(&maxcalllock);
02627 
02628    return failed;
02629 }

int load_pbx ( void   ) 

Provided by pbx.c

Definition at line 6234 of file pbx.c.

References ast_cli_register_multiple(), ast_log(), ast_register_application(), ast_verbose(), builtins, LOG_ERROR, option_verbose, pbx_cli, and VERBOSE_PREFIX_1.

Referenced by main().

06235 {
06236    int x;
06237 
06238    /* Initialize the PBX */
06239    if (option_verbose) {
06240       ast_verbose( "Asterisk PBX Core Initializing\n");
06241       ast_verbose( "Registering builtin applications:\n");
06242    }
06243    ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(struct ast_cli_entry));
06244 
06245    /* Register builtin applications */
06246    for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) {
06247       if (option_verbose)
06248          ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name);
06249       if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) {
06250          ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
06251          return -1;
06252       }
06253    }
06254    return 0;
06255 }

static int lookup_name ( const char *  s,
char *const   names[],
int  max 
) [static]

Helper for get_range. return the index of the matching entry, starting from 1. If names is not supplied, try numeric values.

Definition at line 4090 of file pbx.c.

Referenced by get_range().

04091 {
04092    int i;
04093 
04094    if (names) {
04095       for (i = 0; names[i]; i++) {
04096          if (!strcasecmp(s, names[i]))
04097             return i+1;
04098       }
04099    } else if (sscanf(s, "%d", &i) == 1 && i >= 1 && i <= max) {
04100       return i;
04101    }
04102    return 0; /* error return */
04103 }

static int matchcid ( const char *  cidpattern,
const char *  callerid 
) [static]

Definition at line 939 of file pbx.c.

References ast_extension_match(), and ast_strlen_zero().

Referenced by pbx_find_extension().

00940 {
00941    /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so
00942       failing to get a number should count as a match, otherwise not */
00943 
00944    if (ast_strlen_zero(callerid))
00945       return ast_strlen_zero(cidpattern) ? 1 : 0;
00946 
00947    return ast_extension_match(cidpattern, callerid);
00948 }

static int parse_variable_name ( char *  var,
int *  offset,
int *  length,
int *  isfunc 
) [static]

extract offset:length from variable name. Returns 1 if there is a offset:length part, which is trimmed off (values go into variables)

Definition at line 1105 of file pbx.c.

Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().

01106 {
01107    int parens=0;
01108 
01109    *offset = 0;
01110    *length = INT_MAX;
01111    *isfunc = 0;
01112    for (; *var; var++) {
01113       if (*var == '(') {
01114          (*isfunc)++;
01115          parens++;
01116       } else if (*var == ')') {
01117          parens--;
01118       } else if (*var == ':' && parens == 0) {
01119          *var++ = '\0';
01120          sscanf(var, "%d:%d", offset, length);
01121          return 1; /* offset:length valid */
01122       }
01123    }
01124    return 0;
01125 }

void pbx_builtin_clear_globals ( void   ) 

Definition at line 6036 of file pbx.c.

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

Referenced by handle_reload_extensions(), and reload().

06037 {
06038    struct ast_var_t *vardata;
06039 
06040    ast_mutex_lock(&globalslock);
06041    while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries)))
06042       ast_var_delete(vardata);
06043    ast_mutex_unlock(&globalslock);
06044 }

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

Note:
Will lock the channel.

Definition at line 5813 of file pbx.c.

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

Referenced by __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_channel_bridge(), ast_feature_interpret(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dundi_exec(), dundi_helper(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), ring_entry(), run_agi(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), wait_for_answer(), zt_call(), and zt_hangup().

05814 {
05815    struct ast_var_t *variables;
05816    const char *ret = NULL;
05817    int i;
05818    struct varshead *places[2] = { NULL, &globals };
05819 
05820    if (!name)
05821       return NULL;
05822 
05823    if (chan) {
05824       ast_channel_lock(chan);
05825       places[0] = &chan->varshead;
05826    }
05827 
05828    for (i = 0; i < 2; i++) {
05829       if (!places[i])
05830          continue;
05831       if (places[i] == &globals)
05832          ast_mutex_lock(&globalslock);
05833       AST_LIST_TRAVERSE(places[i], variables, entries) {
05834          if (!strcmp(name, ast_var_name(variables))) {
05835             ret = ast_var_value(variables);
05836             break;
05837          }
05838       }
05839       if (places[i] == &globals)
05840          ast_mutex_unlock(&globalslock);
05841       if (ret)
05842          break;
05843    }
05844 
05845    if (chan)
05846       ast_channel_unlock(chan);
05847 
05848    return ret;
05849 }

static int pbx_builtin_gotoif ( struct ast_channel ,
void *   
) [static]

Definition at line 6056 of file pbx.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_goto(), pbx_checkcondition(), and strsep().

06057 {
06058    char *condition, *branch1, *branch2, *branch;
06059    int rc;
06060    char *stringp;
06061 
06062    if (ast_strlen_zero(data)) {
06063       ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n");
06064       return 0;
06065    }
06066 
06067    stringp = ast_strdupa(data);
06068    condition = strsep(&stringp,"?");
06069    branch1 = strsep(&stringp,":");
06070    branch2 = strsep(&stringp,"");
06071    branch = pbx_checkcondition(condition) ? branch1 : branch2;
06072 
06073    if (ast_strlen_zero(branch)) {
06074       if (option_debug)
06075          ast_log(LOG_DEBUG, "Not taking any branch\n");
06076       return 0;
06077    }
06078 
06079    rc = pbx_builtin_goto(chan, branch);
06080 
06081    return rc;
06082 }

int pbx_builtin_importvar ( struct ast_channel ,
void *   
) [static]

Definition at line 5975 of file pbx.c.

References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), s, strsep(), and VAR_BUF_SIZE.

05976 {
05977    char *name;
05978    char *value;
05979    char *channel;
05980    char tmp[VAR_BUF_SIZE]="";
05981 
05982    if (ast_strlen_zero(data)) {
05983       ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
05984       return 0;
05985    }
05986 
05987    value = ast_strdupa(data);
05988    name = strsep(&value,"=");
05989    channel = strsep(&value,"|");
05990    if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */
05991       struct ast_channel *chan2 = ast_get_channel_by_name_locked(channel);
05992       if (chan2) {
05993          char *s = alloca(strlen(value) + 4);
05994          if (s) {
05995             sprintf(s, "${%s}", value);
05996             pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1);
05997          }
05998          ast_channel_unlock(chan2);
05999       }
06000       pbx_builtin_setvar_helper(chan, name, tmp);
06001    }
06002 
06003    return(0);
06004 }

static int pbx_builtin_noop ( struct ast_channel ,
void *   
) [static]

Definition at line 6031 of file pbx.c.

06032 {
06033    return 0;
06034 }

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

Note:
Will lock the channel.

Definition at line 5851 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_verbose(), LOG_WARNING, option_verbose, and VERBOSE_PREFIX_2.

Referenced by acf_odbc_read(), acf_odbc_write(), and gosub_exec().

05852 {
05853    struct ast_var_t *newvariable;
05854    struct varshead *headp;
05855 
05856    if (name[strlen(name)-1] == ')') {
05857       char *function = ast_strdupa(name);
05858 
05859       ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
05860       ast_func_write(chan, function, value);
05861       return;
05862    }
05863 
05864    if (chan) {
05865       ast_channel_lock(chan);
05866       headp = &chan->varshead;
05867    } else {
05868       ast_mutex_lock(&globalslock);
05869       headp = &globals;
05870    }
05871 
05872    if (value) {
05873       if ((option_verbose > 1) && (headp == &globals))
05874          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05875       newvariable = ast_var_assign(name, value);
05876       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05877    }
05878 
05879    if (chan)
05880       ast_channel_unlock(chan);
05881    else
05882       ast_mutex_unlock(&globalslock);
05883 }

static int pbx_builtin_saycharacters ( struct ast_channel ,
void *   
) [static]

Definition at line 6121 of file pbx.c.

References ast_say_character_str().

06122 {
06123    int res = 0;
06124 
06125    if (data)
06126       res = ast_say_character_str(chan, data, "", chan->language);
06127    return res;
06128 }

static int pbx_builtin_saydate ( struct ast_channel ,
void *   
) [static]

Definition at line 6139 of file pbx.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_say_date, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), LOG_WARNING, parse(), and pbx_builtin_setvar_helper().

06140 {
06141    int res = 0;
06142    char *parse;
06143    int unixdate = 0;
06144    char charascii[2];
06145 
06146    AST_DECLARE_APP_ARGS(args,
06147       AST_APP_ARG(datestr);
06148       AST_APP_ARG(digits);
06149    );
06150 
06151 
06152    if (ast_strlen_zero(data)) {
06153       ast_log(LOG_WARNING, "SayDate requires an argument (date)\n");
06154       return -1;
06155    }
06156 
06157    if (!(parse = ast_strdupa(data))) {
06158       ast_log(LOG_WARNING, "Memory Error!\n");
06159       return -1;
06160    }
06161 
06162    AST_STANDARD_APP_ARGS(args, parse);
06163 
06164    if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) {
06165       ast_log(LOG_WARNING, "SayDate escape digits must be a subset from '0123456789*#'\n");
06166       args.digits = "";
06167    }
06168 
06169    if (sscanf(args.datestr, "%d", &unixdate) != 1) {
06170       ast_log(LOG_WARNING, "Firt argument to SayDate must be numeric (date)\n");
06171       return -1;
06172    }
06173 
06174    res = ast_say_date(chan, (time_t)unixdate, args.digits, chan->language);
06175    if (res > 0) {
06176       if (isdigit(res) || (res == '*') || (res == '#')) {
06177          snprintf(charascii, 2, "%c", res);
06178          pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii);
06179          res = 0;
06180       } else {
06181          ast_log(LOG_WARNING, "SayDate: invalid return value (%d) detected\n", res);
06182       }
06183    }
06184    return res;
06185 }

static int pbx_builtin_saydigits ( struct ast_channel ,
void *   
) [static]

Definition at line 6112 of file pbx.c.

References ast_say_digit_str().

06113 {
06114    int res = 0;
06115 
06116    if (data)
06117       res = ast_say_digit_str(chan, data, "", chan->language);
06118    return res;
06119 }

static int pbx_builtin_saynumber ( struct ast_channel ,
void *   
) [static]

Definition at line 6084 of file pbx.c.

References ast_log(), ast_say_number(), ast_strlen_zero(), LOG_WARNING, and strsep().

06085 {
06086    char tmp[256];
06087    char *number = tmp;
06088    char *options;
06089 
06090    if (ast_strlen_zero(data)) {
06091       ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
06092       return -1;
06093    }
06094    ast_copy_string(tmp, data, sizeof(tmp));
06095    strsep(&number, "|");
06096    options = strsep(&number, "|");
06097    if (options) {
06098       if ( strcasecmp(options, "f") && strcasecmp(options,"m") &&
06099          strcasecmp(options, "c") && strcasecmp(options, "n") ) {
06100          ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
06101          return -1;
06102       }
06103    }
06104 
06105    if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) {
06106       ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
06107    }
06108 
06109    return 0;
06110 }

static int pbx_builtin_sayphonetic ( struct ast_channel ,
void *   
) [static]

Definition at line 6130 of file pbx.c.

References ast_say_phonetic_str().

06131 {
06132    int res = 0;
06133 
06134    if (data)
06135       res = ast_say_phonetic_str(chan, data, "", chan->language);
06136    return res;
06137 }

static int pbx_builtin_saytime ( struct ast_channel ,
void *   
) [static]

Definition at line 6187 of file pbx.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_say_time, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), LOG_WARNING, parse(), and pbx_builtin_setvar_helper().

06188 {
06189    int res = 0;
06190    char *parse;
06191    int secs = 0;
06192    char charascii[2];
06193 
06194    AST_DECLARE_APP_ARGS(args,
06195       AST_APP_ARG(timestr);
06196       AST_APP_ARG(digits);
06197    );
06198 
06199    if (ast_strlen_zero(data)) {
06200       ast_log(LOG_WARNING, "SayTime requires an argument (time in seconds)\n");
06201       return -1;
06202    }
06203 
06204    if (!(parse = ast_strdupa(data))) {
06205       ast_log(LOG_WARNING, "Memory Error!\n");
06206       return -1;
06207    }
06208 
06209    AST_STANDARD_APP_ARGS(args, parse);
06210 
06211    if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) {
06212       ast_log(LOG_WARNING, "SayTime escape digits must be a subset from '0123456789*#'\n");
06213       args.digits = "";
06214    }
06215 
06216    if (sscanf(args.timestr, "%d", &secs) != 1) {
06217       ast_log(LOG_WARNING, "Firt argument to SayTime must be numeric (time in seconds)\n");
06218       return -1;
06219    }
06220 
06221    res = ast_say_time(chan, (time_t)secs, args.digits, chan->language);
06222    if (res > 0) {
06223       if (isdigit(res) || (res == '*') || (res == '#')) {
06224          snprintf(charascii, 2, "%c", res);
06225          pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii);
06226          res = 0;
06227       } else {
06228          ast_log(LOG_WARNING, "SayTime: invalid return value (%d) detected\n", res);
06229       }
06230    }
06231    return res;
06232 }

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

Note:
Will lock the channel.

Definition at line 5782 of file pbx.c.

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

Referenced by dumpchan_exec(), handle_showchan(), handle_showchan_deprecated(), and vars2manager().

05783 {
05784    struct ast_var_t *variables;
05785    const char *var, *val;
05786    int total = 0;
05787 
05788    if (!chan)
05789       return 0;
05790 
05791    memset(buf, 0, size);
05792 
05793    ast_channel_lock(chan);
05794 
05795    AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
05796       if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
05797          /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
05798          ) {
05799          if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) {
05800             ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n");
05801             break;
05802          } else
05803             total++;
05804       } else
05805          break;
05806    }
05807 
05808    ast_channel_unlock(chan);
05809 
05810    return total;
05811 }

static int pbx_builtin_setglobalvar ( struct ast_channel chan,
void *  data 
) [static]

Todo:
XXX overwrites data ?

Todo:
XXX watch out, leading whitespace ?

Definition at line 6007 of file pbx.c.

References ast_log(), ast_strlen_zero(), LOG_WARNING, pbx_builtin_setvar_helper(), and strsep().

06008 {
06009    char *name;
06010    char *stringp = data;
06011    static int dep_warning = 0;
06012 
06013    if (ast_strlen_zero(data)) {
06014       ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
06015       return 0;
06016    }
06017 
06018    name = strsep(&stringp, "=");
06019 
06020    if (!dep_warning) {
06021       dep_warning = 1;
06022       ast_log(LOG_WARNING, "SetGlobalVar is deprecated.  Please use Set(GLOBAL(%s)=%s) instead.\n", name, stringp);
06023    }
06024 
06025    /*! \todo XXX watch out, leading whitespace ? */
06026    pbx_builtin_setvar_helper(NULL, name, stringp);
06027 
06028    return(0);
06029 }

int pbx_builtin_setvar ( struct ast_channel ,
void *   
)

Definition at line 5935 of file pbx.c.

References ast_app_separate_args(), ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, and pbx_builtin_setvar_helper().

Referenced by ast_compile_ael2().

05936 {
05937    char *name, *value, *mydata;
05938    int argc;
05939    char *argv[24];      /* this will only support a maximum of 24 variables being set in a single operation */
05940    int global = 0;
05941    int x;
05942 
05943    if (ast_strlen_zero(data)) {
05944       ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
05945       return 0;
05946    }
05947 
05948    mydata = ast_strdupa(data);
05949    argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
05950 
05951    /* check for a trailing flags argument */
05952    if ((argc > 1) && !strchr(argv[argc-1], '=')) {
05953       argc--;
05954       if (strchr(argv[argc], 'g')) {
05955          ast_log(LOG_WARNING, "The use of the 'g' flag is deprecated.  Please use Set(GLOBAL(foo)=bar) instead\n");
05956          global = 1;
05957       }
05958    }
05959 
05960    if (argc > 1)
05961       ast_log(LOG_WARNING, "Setting multiple variables at once within Set is deprecated.  Please separate each name/value pair into its own line.\n");
05962 
05963    for (x = 0; x < argc; x++) {
05964       name = argv[x];
05965       if ((value = strchr(name, '='))) {
05966          *value++ = '\0';
05967          pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
05968       } else
05969          ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
05970    }
05971 
05972    return(0);
05973 }

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

Note:
Will lock the channel.

Definition at line 5885 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), option_verbose, and VERBOSE_PREFIX_2.

Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), app_exec(), aqm_exec(), array(), ast_bridge_call(), ast_channel_bridge(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), disa_exec(), do_waiting(), export_aoc_vars(), export_ch(), function_db_delete(), function_db_exists(), function_db_read(), global_write(), handle_request_bye(), handle_request_refer(), handle_set_global(), handle_set_global_deprecated(), handle_setvariable(), hasvoicemail_exec(), isAnsweringMachine(), leave_voicemail(), local_hangup(), lookupblacklist_exec(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_load_config(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_exec(), realtime_update_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), try_calling(), tryexec_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_handle_dtmfup(), and zt_new().

05886 {
05887    struct ast_var_t *newvariable;
05888    struct varshead *headp;
05889    const char *nametail = name;
05890 
05891    if (name[strlen(name)-1] == ')') {
05892       char *function = ast_strdupa(name);
05893 
05894       ast_func_write(chan, function, value);
05895       return;
05896    }
05897 
05898    if (chan) {
05899       ast_channel_lock(chan);
05900       headp = &chan->varshead;
05901    } else {
05902       ast_mutex_lock(&globalslock);
05903       headp = &globals;
05904    }
05905 
05906    /* For comparison purposes, we have to strip leading underscores */
05907    if (*nametail == '_') {
05908       nametail++;
05909       if (*nametail == '_')
05910          nametail++;
05911    }
05912 
05913    AST_LIST_TRAVERSE (headp, newvariable, entries) {
05914       if (strcasecmp(ast_var_name(newvariable), nametail) == 0) {
05915          /* there is already such a variable, delete it */
05916          AST_LIST_REMOVE(headp, newvariable, entries);
05917          ast_var_delete(newvariable);
05918          break;
05919       }
05920    }
05921 
05922    if (value) {
05923       if ((option_verbose > 1) && (headp == &globals))
05924          ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
05925       newvariable = ast_var_assign(name, value);
05926       AST_LIST_INSERT_HEAD(headp, newvariable, entries);
05927    }
05928 
05929    if (chan)
05930       ast_channel_unlock(chan);
05931    else
05932       ast_mutex_unlock(&globalslock);
05933 }

int pbx_checkcondition ( const char *  condition  ) 

Evaluate a condition.

Return values:
0 if the condition is NULL or of zero length
int If the string is an integer, the integer representation of the integer is returned
1 Any other non-empty string

Definition at line 6046 of file pbx.c.

References ast_strlen_zero().

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

06047 {
06048    if (ast_strlen_zero(condition))  /* NULL or empty strings are false */
06049       return 0;
06050    else if (*condition >= '0' && *condition <= '9')   /* Numbers are evaluated for truth */
06051       return atoi(condition);
06052    else  /* Strings are true */
06053       return 1;
06054 }

static void pbx_destroy ( struct ast_pbx p  )  [static]

Definition at line 611 of file pbx.c.

References free.

00612 {
00613    free(p);
00614 }

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

Execute an application.

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

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

Definition at line 537 of file pbx.c.

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

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

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

static int pbx_extension_helper ( struct ast_channel c,
struct ast_context con,
const char *  context,
const char *  exten,
int  priority,
const char *  label,
const char *  callerid,
enum ext_match_t  action 
) [static]

The return value depends on the action:.

E_MATCH, E_CANMATCH, E_MATCHMORE require a real match, and return 0 on failure, -1 on match; E_FINDLABEL maps the label to a priority, and returns the priority on success, ... XXX E_SPAWN, spawn an application, and return 0 on success, -1 on failure.

Note:
The channel is auto-serviced in this function, because doing an extension match may block for a long time. For example, if the lookup has to use a network dialplan switch, such as DUNDi or IAX2, it may take a while. However, the channel auto-service code will queue up any important signalling frames to be processed after this is done.

Definition at line 1831 of file pbx.c.

References ast_exten::app, app, ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_verbose(), COLOR_BRCYAN, COLOR_BRMAGENTA, ast_channel::context, pbx_find_info::data, E_CANMATCH, E_FINDLABEL, E_MATCH, E_MATCHMORE, EVENT_FLAG_CALL, ast_switch::exec, EXT_DATA_SIZE, ast_channel::exten, pbx_find_info::foundcontext, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), ast_switch::name, option_debug, option_verbose, pbx_exec(), pbx_find_extension(), pbx_findapp(), pbx_substitute_variables(), ast_channel::priority, ast_exten::priority, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, pbx_find_info::swo, term_color(), and VERBOSE_PREFIX_3.

Referenced by ast_canmatch_extension(), ast_exists_extension(), ast_findlabel_extension(), ast_findlabel_extension2(), ast_matchmore_extension(), and ast_spawn_extension().

01834 {
01835    struct ast_exten *e;
01836    struct ast_app *app;
01837    int res;
01838    struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
01839    char passdata[EXT_DATA_SIZE];
01840 
01841    int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
01842 
01843    ast_rdlock_contexts();
01844    e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
01845    if (e) {
01846       if (matching_action) {
01847          ast_unlock_contexts();
01848          return -1;  /* success, we found it */
01849       } else if (action == E_FINDLABEL) { /* map the label to a priority */
01850          res = e->priority;
01851          ast_unlock_contexts();
01852          return res; /* the priority we were looking for */
01853       } else { /* spawn */
01854          app = pbx_findapp(e->app);
01855          ast_unlock_contexts();
01856          if (!app) {
01857             ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
01858             return -1;
01859          }
01860          if (c->context != context)
01861             ast_copy_string(c->context, context, sizeof(c->context));
01862          if (c->exten != exten)
01863             ast_copy_string(c->exten, exten, sizeof(c->exten));
01864          c->priority = priority;
01865          pbx_substitute_variables(passdata, sizeof(passdata), c, e);
01866          if (option_debug) {
01867             ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
01868          }
01869          if (option_verbose > 2) {
01870             char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE];
01871             ast_verbose( VERBOSE_PREFIX_3 "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n",
01872                exten, context, priority,
01873                term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
01874                term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
01875                term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)),
01876                "in new stack");
01877          }
01878          manager_event(EVENT_FLAG_CALL, "Newexten",
01879                "Channel: %s\r\n"
01880                "Context: %s\r\n"
01881                "Extension: %s\r\n"
01882                "Priority: %d\r\n"
01883                "Application: %s\r\n"
01884                "AppData: %s\r\n"
01885                "Uniqueid: %s\r\n",
01886                c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid);
01887          return pbx_exec(c, app, passdata);  /* 0 on success, -1 on failure */
01888       }
01889    } else if (q.swo) {  /* not found here, but in another switch */
01890       ast_unlock_contexts();
01891       if (matching_action) {
01892          return -1;
01893       } else {
01894          if (!q.swo->exec) {
01895             ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name);
01896             res = -1;
01897          }
01898          return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
01899       }
01900    } else { /* not found anywhere, see what happened */
01901       ast_unlock_contexts();
01902       switch (q.status) {
01903       case STATUS_NO_CONTEXT:
01904          if (!matching_action)
01905             ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context);
01906          break;
01907       case STATUS_NO_EXTENSION:
01908          if (!matching_action)
01909             ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context);
01910          break;
01911       case STATUS_NO_PRIORITY:
01912          if (!matching_action)
01913             ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
01914          break;
01915       case STATUS_NO_LABEL:
01916          if (context)
01917             ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context);
01918          break;
01919       default:
01920          if (option_debug)
01921             ast_log(LOG_DEBUG, "Shouldn't happen!\n");
01922       }
01923 
01924       return (matching_action) ? 0 : -1;
01925    }
01926 }

static struct ast_exten* pbx_find_extension ( struct ast_channel chan,
struct ast_context bypass,
struct pbx_find_info q,
const char *  context,
const char *  exten,
int  priority,
const char *  label,
const char *  callerid,
enum ext_match_t  action 
) [static]

Definition at line 966 of file pbx.c.

References ast_log(), AST_PBX_MAX_STACK, ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), ast_exten::cidmatch, pbx_find_info::data, E_FINDLABEL, E_MATCHMORE, ast_exten::exten, extension_match_core(), pbx_find_info::foundcontext, pbx_find_info::incstack, ast_exten::label, LOG_WARNING, match(), matchcid(), ast_exten::matchcid, ast_exten::priority, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, STATUS_SUCCESS, and pbx_find_info::swo.

Referenced by ast_hint_extension(), ast_merge_contexts_and_delete(), and pbx_extension_helper().

00970 {
00971    int x, res;
00972    struct ast_context *tmp;
00973    struct ast_exten *e, *eroot;
00974    struct ast_include *i;
00975    struct ast_sw *sw;
00976    char *tmpdata = NULL;
00977 
00978    /* Initialize status if appropriate */
00979    if (q->stacklen == 0) {
00980       q->status = STATUS_NO_CONTEXT;
00981       q->swo = NULL;
00982       q->data = NULL;
00983       q->foundcontext = NULL;
00984    }
00985    /* Check for stack overflow */
00986    if (q->stacklen >= AST_PBX_MAX_STACK) {
00987       ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n");
00988       return NULL;
00989    }
00990    /* Check first to see if we've already been checked */
00991    for (x = 0; x < q->stacklen; x++) {
00992       if (!strcasecmp(q->incstack[x], context))
00993          return NULL;
00994    }
00995    if (bypass) /* bypass means we only look there */
00996       tmp = bypass;
00997    else {   /* look in contexts */
00998       tmp = NULL;
00999       while ((tmp = ast_walk_contexts(tmp)) ) {
01000          if (!strcmp(tmp->name, context))
01001             break;
01002       }
01003       if (!tmp)
01004          return NULL;
01005    }
01006    if (q->status < STATUS_NO_EXTENSION)
01007       q->status = STATUS_NO_EXTENSION;
01008 
01009    /* scan the list trying to match extension and CID */
01010    eroot = NULL;
01011    while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) {
01012       int match = extension_match_core(eroot->exten, exten, action);
01013       /* 0 on fail, 1 on match, 2 on earlymatch */
01014 
01015       if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid)))
01016          continue;   /* keep trying */
01017       if (match == 2 && action == E_MATCHMORE) {
01018          /* We match an extension ending in '!'.
01019           * The decision in this case is final and is NULL (no match).
01020           */
01021          return NULL;
01022       }
01023       /* found entry, now look for the right priority */
01024       if (q->status < STATUS_NO_PRIORITY)
01025          q->status = STATUS_NO_PRIORITY;
01026       e = NULL;
01027       while ( (e = ast_walk_extension_priorities(eroot, e)) ) {
01028          /* Match label or priority */
01029          if (action == E_FINDLABEL) {
01030             if (q->status < STATUS_NO_LABEL)
01031                q->status = STATUS_NO_LABEL;
01032             if (label && e->label && !strcmp(label, e->label))
01033                break;   /* found it */
01034          } else if (e->priority == priority) {
01035             break;   /* found it */
01036          } /* else keep searching */
01037       }
01038       if (e) { /* found a valid match */
01039          q->status = STATUS_SUCCESS;
01040          q->foundcontext = context;
01041          return e;
01042       }
01043    }
01044    /* Check alternative switches */
01045    AST_LIST_TRAVERSE(&tmp->alts, sw, list) {
01046       struct ast_switch *asw = pbx_findswitch(sw->name);
01047       ast_switch_f *aswf = NULL;
01048       char *datap;
01049 
01050       if (!asw) {
01051          ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name);
01052          continue;
01053       }
01054       /* Substitute variables now */
01055       if (sw->eval) {
01056          if (!(tmpdata = ast_threadstorage_get(&switch_data, 512))) {
01057             ast_log(LOG_WARNING, "Can't evaluate switch?!");
01058             continue;
01059          }
01060          pbx_substitute_variables_helper(chan, sw->data, tmpdata, 512);
01061       }
01062 
01063       /* equivalent of extension_match_core() at the switch level */
01064       if (action == E_CANMATCH)
01065          aswf = asw->canmatch;
01066       else if (action == E_MATCHMORE)
01067          aswf = asw->matchmore;
01068       else /* action == E_MATCH */
01069          aswf = asw->exists;
01070       datap = sw->eval ? tmpdata : sw->data;
01071       if (!aswf)
01072          res = 0;
01073       else {
01074          if (chan)
01075             ast_autoservice_start(chan);
01076          res = aswf(chan, context, exten, priority, callerid, datap);
01077          if (chan)
01078             ast_autoservice_stop(chan);
01079       }
01080       if (res) {  /* Got a match */
01081          q->swo = asw;
01082          q->data = datap;
01083          q->foundcontext = context;
01084          /* XXX keep status = STATUS_NO_CONTEXT ? */
01085          return NULL;
01086       }
01087    }
01088    q->incstack[q->stacklen++] = tmp->name;   /* Setup the stack */
01089    /* Now try any includes we have in this context */
01090    for (i = tmp->includes; i; i = i->next) {
01091       if (include_valid(i)) {
01092          if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action)))
01093             return e;
01094          if (q->swo)
01095             return NULL;
01096       }
01097    }
01098    return NULL;
01099 }

struct ast_app* pbx_findapp ( const char *  app  ) 

Look up an application.

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

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

Definition at line 575 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

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

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

static struct ast_switch* pbx_findswitch ( const char *  sw  )  [static]

Definition at line 589 of file pbx.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_switch::name.

00590 {
00591    struct ast_switch *asw;
00592 
00593    AST_LIST_LOCK(&switches);
00594    AST_LIST_TRAVERSE(&switches, asw, list) {
00595       if (!strcasecmp(asw->name, sw))
00596          break;
00597    }
00598    AST_LIST_UNLOCK(&switches);
00599 
00600    return asw;
00601 }

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

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

Note:
Will lock the channel.

Definition at line 1173 of file pbx.c.

References ast_cause2str(), ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_get_hint(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani2, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, ast_channel::hangupcause, offset, parse_variable_name(), ast_channel::priority, s, and substring().

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

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

int pbx_set_autofallthrough ( int  newval  ) 

Set "autofallthrough" flag, if newval is <0, does not acutally set. If set to 1, sets to auto fall through. If newval set to 0, sets to no auto fall through (reads extension instead). Returns previous value.

Definition at line 2713 of file pbx.c.

References autofallthrough.

Referenced by pbx_load_module().

02714 {
02715    int oldval = autofallthrough;
02716    autofallthrough = newval;
02717    return oldval;
02718 }

static void pbx_substitute_variables ( char *  passdata,
int  datalen,
struct ast_channel c,
struct ast_exten e 
) [static]

Definition at line 1802 of file pbx.c.

References ast_exten::data, and pbx_substitute_variables_helper().

Referenced by pbx_extension_helper().

01803 {
01804    memset(passdata, 0, datalen);
01805 
01806    /* No variables or expressions in e->data, so why scan it? */
01807    if (e->data && !strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) {
01808       ast_copy_string(passdata, e->data, datalen);
01809       return;
01810    }
01811 
01812    pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1);
01813 }

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

Definition at line 1792 of file pbx.c.

References pbx_substitute_variables_helper_full(), and ast_channel::varshead.

Referenced by _macro_exec(), acf_odbc_read(), acf_odbc_write(), add_extensions(), custom_log(), cut_internal(), exec_exec(), function_eval(), function_fieldqty(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), pbx_builtin_importvar(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), sendpage(), try_calling(), and tryexec_exec().

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

static void pbx_substitute_variables_helper_full ( struct ast_channel c,
struct varshead *  headp,
const char *  cp1,
char *  cp2,
int  count 
) [static]

Definition at line 1598 of file pbx.c.

References ast_channel_alloc(), ast_channel_free(), ast_expr(), ast_func_read(), ast_log(), ast_strlen_zero(), len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, offset, option_debug, parse_variable_name(), pbx_retrieve_variable(), substring(), var, VAR_BUF_SIZE, and ast_channel::varshead.

Referenced by pbx_substitute_variables_helper(), and pbx_substitute_variables_varshead().

01599 {
01600    /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be
01601       zero-filled */
01602    char *cp4;
01603    const char *tmp, *whereweare;
01604    int length, offset, offset2, isfunction;
01605    char *workspace = NULL;
01606    char *ltmp = NULL, *var = NULL;
01607    char *nextvar, *nextexp, *nextthing;
01608    char *vars, *vare;
01609    int pos, brackets, needsub, len;
01610 
01611    whereweare=tmp=cp1;
01612    while (!ast_strlen_zero(whereweare) && count) {
01613       /* Assume we're copying the whole remaining string */
01614       pos = strlen(whereweare);
01615       nextvar = NULL;
01616       nextexp = NULL;
01617       nextthing = strchr(whereweare, '$');
01618       if (nextthing) {
01619          switch(nextthing[1]) {
01620          case '{':
01621             nextvar = nextthing;
01622             pos = nextvar - whereweare;
01623             break;
01624          case '[':
01625             nextexp = nextthing;
01626             pos = nextexp - whereweare;
01627             break;
01628          default:
01629             pos = 1;
01630          }
01631       }
01632 
01633       if (pos) {
01634          /* Can't copy more than 'count' bytes */
01635          if (pos > count)
01636             pos = count;
01637 
01638          /* Copy that many bytes */
01639          memcpy(cp2, whereweare, pos);
01640 
01641          count -= pos;
01642          cp2 += pos;
01643          whereweare += pos;
01644       }
01645 
01646       if (nextvar) {
01647          /* We have a variable.  Find the start and end, and determine
01648             if we are going to have to recursively call ourselves on the
01649             contents */
01650          vars = vare = nextvar + 2;
01651          brackets = 1;
01652          needsub = 0;
01653 
01654          /* Find the end of it */
01655          while (brackets && *vare) {
01656             if ((vare[0] == '$') && (vare[1] == '{')) {
01657                needsub++;
01658             } else if (vare[0] == '{') {
01659                brackets++;
01660             } else if (vare[0] == '}') {
01661                brackets--;
01662             } else if ((vare[0] == '$') && (vare[1] == '['))
01663                needsub++;
01664             vare++;
01665          }
01666          if (brackets)
01667             ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n");
01668          len = vare - vars - 1;
01669 
01670          /* Skip totally over variable string */
01671          whereweare += (len + 3);
01672 
01673          if (!var)
01674             var = alloca(VAR_BUF_SIZE);
01675 
01676          /* Store variable name (and truncate) */
01677          ast_copy_string(var, vars, len + 1);
01678 
01679          /* Substitute if necessary */
01680          if (needsub) {
01681             if (!ltmp)
01682                ltmp = alloca(VAR_BUF_SIZE);
01683 
01684             memset(ltmp, 0, VAR_BUF_SIZE);
01685             pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
01686             vars = ltmp;
01687          } else {
01688             vars = var;
01689          }
01690 
01691          if (!workspace)
01692             workspace = alloca(VAR_BUF_SIZE);
01693 
01694          workspace[0] = '\0';
01695 
01696          parse_variable_name(vars, &offset, &offset2, &isfunction);
01697          if (isfunction) {
01698             /* Evaluate function */
01699             if (c || !headp)
01700                cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
01701             else {
01702                struct varshead old;
01703                struct ast_channel *c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/%p", vars);
01704                if (c) {
01705                   memcpy(&old, &c->varshead, sizeof(old));
01706                   memcpy(&c->varshead, headp, sizeof(c->varshead));
01707                   cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
01708                   /* Don't deallocate the varshead that was passed in */
01709                   memcpy(&c->varshead, &old, sizeof(c->varshead));
01710                   ast_channel_free(c);
01711                } else
01712                   ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution.  Function results may be blank.\n");
01713             }
01714 
01715             if (option_debug)
01716                ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)");
01717          } else {
01718             /* Retrieve variable value */
01719             pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);
01720          }
01721          if (cp4) {
01722             cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);
01723 
01724             length = strlen(cp4);
01725             if (length > count)
01726                length = count;
01727             memcpy(cp2, cp4, length);
01728             count -= length;
01729             cp2 += length;
01730          }
01731       } else if (nextexp) {
01732          /* We have an expression.  Find the start and end, and determine
01733             if we are going to have to recursively call ourselves on the
01734             contents */
01735          vars = vare = nextexp + 2;
01736          brackets = 1;
01737          needsub = 0;
01738 
01739          /* Find the end of it */
01740          while(brackets && *vare) {
01741             if ((vare[0] == '$') && (vare[1] == '[')) {
01742                needsub++;
01743                brackets++;
01744                vare++;
01745             } else if (vare[0] == '[') {
01746                brackets++;
01747             } else if (vare[0] == ']') {
01748                brackets--;
01749             } else if ((vare[0] == '$') && (vare[1] == '{')) {
01750                needsub++;
01751                vare++;
01752             }
01753             vare++;
01754          }
01755          if (brackets)
01756             ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
01757          len = vare - vars - 1;
01758 
01759          /* Skip totally over expression */
01760          whereweare += (len + 3);
01761 
01762          if (!var)
01763             var = alloca(VAR_BUF_SIZE);
01764 
01765          /* Store variable name (and truncate) */
01766          ast_copy_string(var, vars, len + 1);
01767 
01768          /* Substitute if necessary */
01769          if (needsub) {
01770             if (!ltmp)
01771                ltmp = alloca(VAR_BUF_SIZE);
01772 
01773             memset(ltmp, 0, VAR_BUF_SIZE);
01774             pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1);
01775             vars = ltmp;
01776          } else {
01777             vars = var;
01778          }
01779 
01780          length = ast_expr(vars, cp2, count);
01781 
01782          if (length) {
01783             if (option_debug)
01784                ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2);
01785             count -= length;
01786             cp2 += length;
01787          }
01788       }
01789    }
01790 }

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

Definition at line 1797 of file pbx.c.

References pbx_substitute_variables_helper_full().

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

01798 {
01799    pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count);
01800 }

static void* pbx_thread ( void *  data  )  [static]

Definition at line 2649 of file pbx.c.

References __ast_pbx_run(), and decrease_call_count().

Referenced by ast_pbx_start().

02650 {
02651    /* Oh joyeous kernel, we're a new thread, with nothing to do but
02652       answer this channel and get it going.
02653    */
02654    /* NOTE:
02655       The launcher of this function _MUST_ increment 'countcalls'
02656       before invoking the function; it will be decremented when the
02657       PBX has finished running on the channel
02658     */
02659    struct ast_channel *c = data;
02660 
02661    __ast_pbx_run(c);
02662    decrease_call_count();
02663 
02664    pthread_exit(NULL);
02665 
02666    return NULL;
02667 }

static void print_ext ( struct ast_exten e,
char *  buf,
int  buflen 
) [static]

helper function to print an extension

Definition at line 3532 of file pbx.c.

References ast_get_extension_app(), ast_get_extension_app_data(), ast_get_extension_priority(), ast_strlen_zero(), and PRIORITY_HINT.

Referenced by show_dialplan_helper().

03533 {
03534    int prio = ast_get_extension_priority(e);
03535    if (prio == PRIORITY_HINT) {
03536       snprintf(buf, buflen, "hint: %s",
03537          ast_get_extension_app(e));
03538    } else {
03539       snprintf(buf, buflen, "%d. %s(%s)",
03540          prio, ast_get_extension_app(e),
03541          (!ast_strlen_zero(ast_get_extension_app_data(e)) ? (char *)ast_get_extension_app_data(e) : ""));
03542    }
03543 }

static void set_ext_pri ( struct ast_channel c,
const char *  exten,
int  pri 
) [static]

Definition at line 2346 of file pbx.c.

References ast_channel_lock, ast_channel_unlock, ast_channel::exten, and ast_channel::priority.

Referenced by __ast_pbx_run(), ast_pbx_outgoing_exten(), and pbx_builtin_waitexten().

02347 {
02348    ast_channel_lock(c);
02349    ast_copy_string(c->exten, exten, sizeof(c->exten));
02350    c->priority = pri;
02351    ast_channel_unlock(c);
02352 }

static int show_dialplan_helper ( int  fd,
const char *  context,
const char *  exten,
struct dialplan_counters dpc,
struct ast_include rinclude,
int  includecount,
const char *  includes[] 
) [static]

Definition at line 3546 of file pbx.c.

References ast_cli(), ast_extension_match(), ast_get_context_name(), ast_get_context_registrar(), ast_get_extension_label(), ast_get_extension_name(), ast_get_extension_registrar(), ast_get_ignorepat_name(), ast_get_ignorepat_registrar(), ast_get_include_name(), ast_get_include_registrar(), ast_get_switch_data(), ast_get_switch_name(), ast_get_switch_registrar(), ast_lock_context(), ast_log(), AST_MAX_EXTENSION, AST_PBX_MAX_STACK, ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), ast_walk_contexts(), ast_walk_extension_priorities(), dialplan_counters::context_existence, el, dialplan_counters::extension_existence, LOG_NOTICE, LOG_WARNING, print_ext(), dialplan_counters::total_context, dialplan_counters::total_exten, and dialplan_counters::total_prio.

Referenced by handle_show_dialplan().

03547 {
03548    struct ast_context *c = NULL;
03549    int res = 0, old_total_exten = dpc->total_exten;
03550 
03551    ast_rdlock_contexts();
03552 
03553    /* walk all contexts ... */
03554    while ( (c = ast_walk_contexts(c)) ) {
03555       struct ast_exten *e;
03556       struct ast_include *i;
03557       struct ast_ignorepat *ip;
03558       char buf[256], buf2[256];
03559       int context_info_printed = 0;
03560 
03561       if (context && strcmp(ast_get_context_name(c), context))
03562          continue;   /* skip this one, name doesn't match */
03563 
03564       dpc->context_existence = 1;
03565 
03566       ast_lock_context(c);
03567 
03568       /* are we looking for exten too? if yes, we print context
03569        * only if we find our extension.
03570        * Otherwise print context even if empty ?
03571        * XXX i am not sure how the rinclude is handled.
03572        * I think it ought to go inside.
03573        */
03574       if (!exten) {
03575          dpc->total_context++;
03576          ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
03577             ast_get_context_name(c), ast_get_context_registrar(c));
03578          context_info_printed = 1;
03579       }
03580 
03581       /* walk extensions ... */
03582       e = NULL;
03583       while ( (e = ast_walk_context_extensions(c, e)) ) {
03584          struct ast_exten *p;
03585 
03586          if (exten && !ast_extension_match(ast_get_extension_name(e), exten))
03587             continue;   /* skip, extension match failed */
03588 
03589          dpc->extension_existence = 1;
03590 
03591          /* may we print context info? */
03592          if (!context_info_printed) {
03593             dpc->total_context++;
03594             if (rinclude) { /* TODO Print more info about rinclude */
03595                ast_cli(fd, "[ Included context '%s' created by '%s' ]\n",
03596                   ast_get_context_name(c), ast_get_context_registrar(c));
03597             } else {
03598                ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
03599                   ast_get_context_name(c), ast_get_context_registrar(c));
03600             }
03601             context_info_printed = 1;
03602          }
03603          dpc->total_prio++;
03604 
03605          /* write extension name and first peer */
03606          snprintf(buf, sizeof(buf), "'%s' =>", ast_get_extension_name(e));
03607 
03608          print_ext(e, buf2, sizeof(buf2));
03609 
03610          ast_cli(fd, "  %-17s %-45s [%s]\n", buf, buf2,
03611             ast_get_extension_registrar(e));
03612 
03613          dpc->total_exten++;
03614          /* walk next extension peers */
03615          p = e;   /* skip the first one, we already got it */
03616          while ( (p = ast_walk_extension_priorities(e, p)) ) {
03617             const char *el = ast_get_extension_label(p);
03618             dpc->total_prio++;
03619             if (el)
03620                snprintf(buf, sizeof(buf), "   [%s]", el);
03621             else
03622                buf[0] = '\0';
03623             print_ext(p, buf2, sizeof(buf2));
03624 
03625             ast_cli(fd,"  %-17s %-45s [%s]\n", buf, buf2,
03626                ast_get_extension_registrar(p));
03627          }
03628       }
03629 
03630       /* walk included and write info ... */
03631       i = NULL;
03632       while ( (i = ast_walk_context_includes(c, i)) ) {
03633          snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i));
03634          if (exten) {
03635             /* Check all includes for the requested extension */
03636             if (includecount >= AST_PBX_MAX_STACK) {
03637                ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n");
03638             } else {
03639                int dupe=0;
03640                int x;
03641                for (x=0;x<includecount;x++) {
03642                   if (!strcasecmp(includes[x], ast_get_include_name(i))) {
03643                      dupe++;
03644                      break;
03645                   }
03646                }
03647                if (!dupe) {
03648                   includes[includecount] = ast_get_include_name(i);
03649                   show_dialplan_helper(fd, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes);
03650                } else {
03651                   ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context);
03652                }
03653             }
03654          } else {
03655             ast_cli(fd, "  Include =>        %-45s [%s]\n",
03656                buf, ast_get_include_registrar(i));
03657          }
03658       }
03659 
03660       /* walk ignore patterns and write info ... */
03661       ip = NULL;
03662       while ( (ip = ast_walk_context_ignorepats(c, ip)) ) {
03663          const char *ipname = ast_get_ignorepat_name(ip);
03664          char ignorepat[AST_MAX_EXTENSION];
03665          snprintf(buf, sizeof(buf), "'%s'", ipname);
03666          snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname);
03667          if (!exten || ast_extension_match(ignorepat, exten)) {
03668             ast_cli(fd, "  Ignore pattern => %-45s [%s]\n",
03669                buf, ast_get_ignorepat_registrar(ip));
03670          }
03671       }
03672       if (!rinclude) {
03673          struct ast_sw *sw = NULL;
03674          while ( (sw = ast_walk_context_switches(c, sw)) ) {
03675             snprintf(buf, sizeof(buf), "'%s/%s'",
03676                ast_get_switch_name(sw),
03677                ast_get_switch_data(sw));
03678             ast_cli(fd, "  Alt. Switch =>    %-45s [%s]\n",
03679                buf, ast_get_switch_registrar(sw));
03680          }
03681       }
03682 
03683       ast_unlock_context(c);
03684 
03685       /* if we print something in context, make an empty line */
03686       if (context_info_printed)
03687          ast_cli(fd, "\r\n");
03688    }
03689    ast_unlock_contexts();
03690 
03691    return (dpc->total_exten == old_total_exten) ? -1 : res;
03692 }

static char* substring ( const char *  value,
int  offset,
int  length,
char *  workspace,
size_t  workspace_len 
) [static]

takes a substring. It is ok to call with value == workspace.

offset < 0 means start from the end of the string and set the beginning to be that many characters back. length is the length of the substring. A value less than 0 means to leave that many off the end. Always return a copy in workspace.

Definition at line 1135 of file pbx.c.

Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().

01136 {
01137    char *ret = workspace;
01138    int lr;  /* length of the input string after the copy */
01139 
01140    ast_copy_string(workspace, value, workspace_len); /* always make a copy */
01141 
01142    lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
01143 
01144    /* Quick check if no need to do anything */
01145    if (offset == 0 && length >= lr) /* take the whole string */
01146       return ret;
01147 
01148    if (offset < 0)   {  /* translate negative offset into positive ones */
01149       offset = lr + offset;
01150       if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
01151          offset = 0;
01152    }
01153 
01154    /* too large offset result in empty string so we know what to return */
01155    if (offset >= lr)
01156       return ret + lr;  /* the final '\0' */
01157 
01158    ret += offset;    /* move to the start position */
01159    if (length >= 0 && length < lr - offset)  /* truncate if necessary */
01160       ret[length] = '\0';
01161    else if (length < 0) {
01162       if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */
01163          ret[lr + length - offset] = '\0';
01164       else
01165          ret[0] = '\0';
01166    }
01167 
01168    return ret;
01169 }

static void wait_for_hangup ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 5393 of file pbx.c.

References ast_frfree, ast_read(), ast_safe_sleep(), ast_strlen_zero(), ast_waitfor(), and f.

Referenced by pbx_builtin_busy(), and pbx_builtin_congestion().

05394 {
05395    int res;
05396    struct ast_frame *f;
05397    int waittime;
05398 
05399    if (ast_strlen_zero(data) || (sscanf(data, "%d", &waittime) != 1) || (waittime < 0))
05400       waittime = -1;
05401    if (waittime > -1) {
05402       ast_safe_sleep(chan, waittime * 1000);
05403    } else do {
05404       res = ast_waitfor(chan, -1);
05405       if (res < 0)
05406          return;
05407       f = ast_read(chan);
05408       if (f)
05409          ast_frfree(f);
05410    } while(f);
05411 }


Variable Documentation

int autofallthrough = 1 [static]

Definition at line 247 of file pbx.c.

Referenced by pbx_set_autofallthrough().

struct pbx_builtin builtins[] [static]

Declaration of builtin applications.

struct ast_cli_entry cli_set_global_deprecated [static]

Initial value:

 {
   { "set", "global", NULL },
   handle_set_global_deprecated, NULL,
        NULL }

Definition at line 3835 of file pbx.c.

struct ast_cli_entry cli_show_application_deprecated [static]

Initial value:

 {
   { "show", "application", NULL },
   handle_show_application_deprecated, NULL,
        NULL, complete_show_application }

Definition at line 3825 of file pbx.c.

struct ast_cli_entry cli_show_applications_deprecated [static]

Initial value:

 {
   { "show", "applications", NULL },
   handle_show_applications_deprecated, NULL,
   NULL, complete_show_applications_deprecated }

Definition at line 3795 of file pbx.c.

struct ast_cli_entry cli_show_dialplan_deprecated [static]

Initial value:

 {
   { "show", "dialplan", NULL },
   handle_show_dialplan, NULL,
        NULL, complete_show_dialplan_context }

Definition at line 3830 of file pbx.c.

struct ast_cli_entry cli_show_function_deprecated [static]

Initial value:

 {
   { "show" , "function", NULL },
   handle_show_function_deprecated, NULL,
        NULL, complete_show_function }

Definition at line 3820 of file pbx.c.

struct ast_cli_entry cli_show_functions_deprecated [static]

Initial value:

 {
   { "show", "functions", NULL },
   handle_show_functions_deprecated, NULL,
        NULL }

Definition at line 3800 of file pbx.c.

struct ast_cli_entry cli_show_globals_deprecated [static]

Initial value:

 {
   { "show", "globals", NULL },
   handle_show_globals, NULL,
        NULL }

Definition at line 3815 of file pbx.c.

struct ast_cli_entry cli_show_hints_deprecated [static]

Initial value:

 {
   { "show", "hints", NULL },
   handle_show_hints, NULL,
        NULL }

Definition at line 3810 of file pbx.c.

struct ast_cli_entry cli_show_switches_deprecated [static]

Initial value:

 {
   { "show", "switches", NULL },
   handle_show_switches, NULL,
        NULL }

Definition at line 3805 of file pbx.c.

struct ast_context* contexts [static]

Definition at line 517 of file pbx.c.

Referenced by __ast_context_create(), __ast_context_destroy(), ast_merge_contexts_and_delete(), and ast_walk_contexts().

int countcalls [static]

Definition at line 250 of file pbx.c.

Referenced by ast_active_calls(), decrease_call_count(), and increase_call_count().

char* days[] [static]

Definition at line 4239 of file pbx.c.

Referenced by ast_build_timing().

struct cfextension_states extension_states[] [static]

Referenced by ast_extension_state2str().

struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE [static]

Definition at line 245 of file pbx.c.

char* months[] [static]

Definition at line 4251 of file pbx.c.

Referenced by ast_build_timing().

struct ast_cli_entry pbx_cli[] [static]

Definition at line 3840 of file pbx.c.

Referenced by load_pbx().

char set_global_help[] [static]

Initial value:

"Usage: core set global <name> <value>\n"
"       Set global dialplan variable <name> to <value>\n"

Definition at line 3109 of file pbx.c.

char show_application_help[] [static]

Initial value:

"Usage: core show application <application> [<application> [<application> [...]]]\n"
"       Describes a particular application.\n"

Definition at line 3097 of file pbx.c.

char show_applications_help[] [static]

Initial value:

"Usage: core show applications [{like|describing} <text>]\n"
"       List applications which are currently available.\n"
"       If 'like', <text> will be a substring of the app name\n"
"       If 'describing', <text> will be a substring of the description\n"

Definition at line 3075 of file pbx.c.

char show_dialplan_help[] [static]

Initial value:

"Usage: dialplan show [exten@][context]\n"
"       Show dialplan\n"

Definition at line 3105 of file pbx.c.

char show_function_help[] [static]

Initial value:

"Usage: core show function <function>\n"
"       Describe a particular dialplan function.\n"

Definition at line 3101 of file pbx.c.

char show_functions_help[] [static]

Initial value:

"Usage: core show functions [like <text>]\n"
"       List builtin functions, optionally only those matching a given string\n"

Definition at line 3081 of file pbx.c.

char show_globals_help[] [static]

Initial value:

"Usage: core show globals\n"
"       List current global dialplan variables and their values\n"

Definition at line 3093 of file pbx.c.

char show_hints_help[] [static]

Initial value:

"Usage: core show hints\n"
"       List registered hints\n"

Definition at line 3089 of file pbx.c.

char show_switches_help[] [static]

Initial value:

"Usage: core show switches\n"
"       List registered switches\n"

Definition at line 3085 of file pbx.c.

struct ast_state_cb* statecbs

Definition at line 532 of file pbx.c.

Referenced by ast_extension_state_add(), ast_extension_state_del(), and ast_hint_state_changed().

int stateid = 1 [static]

Definition at line 524 of file pbx.c.


Generated on Tue Nov 4 13:20:41 2008 for Asterisk - the Open Source PBX by  doxygen 1.4.7