#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"
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) |
Main interface to add extensions to the list for out 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). | |
struct ast_context * | ast_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). | |
struct ast_context * | ast_context_find (const char *name) |
Find a context. | |
struct ast_context * | ast_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. | |
struct ast_custom_function * | ast_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) |
ast_extension_state: Check extension state for an extension by using hint | |
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) |
ast_extension_state2str: Return extension_state as string | |
int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
ast_extension_state_add: Add watcher for extension states | |
int | ast_extension_state_del (int id, ast_state_cb_type callback) |
ast_extension_state_del: Remove a watcher from the callback list | |
int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
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) |
struct ast_context * | ast_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) |
ast_get_hint: Get hint for channel | |
const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
const char * | ast_get_include_name (struct ast_include *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_exten * | ast_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, char *cid_num, char *cid_name) |
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) |
int | ast_pbx_outgoing_app2 (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, char *uniqueid) |
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) |
int | ast_pbx_outgoing_exten2 (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, int callingpres, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel, char *uniqueid) |
enum ast_pbx_result | ast_pbx_run (struct ast_channel *c) |
Execute the PBX in the current thread. | |
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) |
Dynamically register a new dial plan 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). | |
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. | |
struct ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *exten) |
struct ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
struct ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
struct ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
struct ast_context * | ast_walk_contexts (struct ast_context *con) |
struct ast_exten * | ast_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_context * | find_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_saydigits (struct ast_channel *, void *) |
static int | pbx_builtin_saynumber (struct ast_channel *, void *) |
static int | pbx_builtin_sayphonetic (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_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) |
struct ast_app * | pbx_findapp (const char *app) |
Find application handle in linked list. | |
static struct ast_switch * | pbx_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 [] |
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_context * | contexts |
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 [] |
struct ast_state_cb * | statecbs |
static int | stateid = 1 |
Definition in file pbx.c.
#define AST_PBX_MAX_STACK 128 |
Go no deeper than this through includes (not counting loops)
Definition at line 544 of file pbx.c.
Referenced by handle_show_dialplan(), pbx_find_extension(), and show_dialplan_helper().
#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 |
Definition at line 77 of file pbx.c.
Referenced by pbx_extension_helper(), and realtime_exec().
#define STATUS_NO_CONTEXT 1 |
Definition at line 906 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_EXTENSION 2 |
Definition at line 907 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_LABEL 4 |
Definition at line 909 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_PRIORITY 3 |
Definition at line 908 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_SUCCESS 5 |
#define SWITCH_DATA_LENGTH 256 |
Definition at line 80 of file pbx.c.
Referenced by ast_context_add_switch2(), and pbx_find_extension().
#define VAR_BUF_SIZE 4096 |
Definition at line 82 of file pbx.c.
Referenced by ast_add_extension2(), pbx_builtin_importvar(), and pbx_substitute_variables_helper_full().
#define WAITEXTEN_MOH (1 << 0) |
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.
Definition at line 749 of file pbx.c.
00749 { 00750 E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */ 00751 E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */ 00752 E_MATCH = 0x02, /* extension is an exact match */ 00753 E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */ 00754 E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */ 00755 E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */ 00756 };
static struct ast_context* __ast_context_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar, | |||
int | existsokay | |||
) | [static, read] |
Definition at line 3860 of file pbx.c.
References ast_calloc, ast_log(), ast_mutex_init(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_verbose(), ast_wrlock_contexts(), contexts, local_contexts, ast_context::lock, LOG_DEBUG, LOG_WARNING, ast_context::next, option_debug, option_verbose, ast_context::registrar, and VERBOSE_PREFIX_3.
Referenced by ast_context_create(), and ast_context_find_or_create().
03861 { 03862 struct ast_context *tmp, **local_contexts; 03863 int length = sizeof(struct ast_context) + strlen(name) + 1; 03864 03865 if (!extcontexts) { 03866 ast_rdlock_contexts(); 03867 local_contexts = &contexts; 03868 } else 03869 local_contexts = extcontexts; 03870 03871 for (tmp = *local_contexts; tmp; tmp = tmp->next) { 03872 if (!strcasecmp(tmp->name, name)) { 03873 if (!existsokay) { 03874 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 03875 tmp = NULL; 03876 } 03877 if (!extcontexts) 03878 ast_unlock_contexts(); 03879 return tmp; 03880 } 03881 } 03882 03883 if (!extcontexts) 03884 ast_unlock_contexts(); 03885 03886 if ((tmp = ast_calloc(1, length))) { 03887 ast_mutex_init(&tmp->lock); 03888 ast_mutex_init(&tmp->macrolock); 03889 strcpy(tmp->name, name); 03890 tmp->registrar = registrar; 03891 if (!extcontexts) 03892 ast_wrlock_contexts(); 03893 tmp->next = *local_contexts; 03894 *local_contexts = tmp; 03895 if (!extcontexts) 03896 ast_unlock_contexts(); 03897 if (option_debug) 03898 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 03899 if (option_verbose > 2) 03900 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 03901 } 03902 03903 return tmp; 03904 }
void __ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
Definition at line 5298 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, LOG_DEBUG, ast_exten::next, ast_ignorepat::next, ast_include::next, ast_context::next, option_debug, and ast_exten::peer.
Referenced by ast_context_destroy(), and ast_merge_contexts_and_delete().
05299 { 05300 struct ast_context *tmp, *tmpl=NULL; 05301 struct ast_include *tmpi; 05302 struct ast_sw *sw; 05303 struct ast_exten *e, *el, *en; 05304 struct ast_ignorepat *ipi; 05305 05306 for (tmp = contexts; tmp; ) { 05307 struct ast_context *next; /* next starting point */ 05308 for (; tmp; tmpl = tmp, tmp = tmp->next) { 05309 if (option_debug) 05310 ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar); 05311 if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) && 05312 (!con || !strcasecmp(tmp->name, con->name)) ) 05313 break; /* found it */ 05314 } 05315 if (!tmp) /* not found, we are done */ 05316 break; 05317 ast_mutex_lock(&tmp->lock); 05318 if (option_debug) 05319 ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar); 05320 next = tmp->next; 05321 if (tmpl) 05322 tmpl->next = next; 05323 else 05324 contexts = next; 05325 /* Okay, now we're safe to let it go -- in a sense, we were 05326 ready to let it go as soon as we locked it. */ 05327 ast_mutex_unlock(&tmp->lock); 05328 for (tmpi = tmp->includes; tmpi; ) { /* Free includes */ 05329 struct ast_include *tmpil = tmpi; 05330 tmpi = tmpi->next; 05331 free(tmpil); 05332 } 05333 for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */ 05334 struct ast_ignorepat *ipl = ipi; 05335 ipi = ipi->next; 05336 free(ipl); 05337 } 05338 while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list))) 05339 free(sw); 05340 for (e = tmp->root; e;) { 05341 for (en = e->peer; en;) { 05342 el = en; 05343 en = en->peer; 05344 destroy_exten(el); 05345 } 05346 el = e; 05347 e = e->next; 05348 destroy_exten(el); 05349 } 05350 ast_mutex_destroy(&tmp->lock); 05351 free(tmp); 05352 /* if we have a specific match, we are done, otherwise continue */ 05353 tmp = con ? NULL : next; 05354 } 05355 }
static int __ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
int | async | |||
) | [static] |
Definition at line 6336 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().
06337 { 06338 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06339 06340 if (!chan) 06341 return -2; 06342 06343 if (context == NULL) 06344 context = chan->context; 06345 if (exten == NULL) 06346 exten = chan->exten; 06347 06348 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06349 if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num)) 06350 return goto_func(chan, context, exten, priority); 06351 else 06352 return -3; 06353 }
static int __ast_pbx_run | ( | struct ast_channel * | c | ) | [static] |
Definition at line 2348 of file pbx.c.
References ast_channel::_softhangup, ast_channel::amaflags, ast_calloc, AST_CAUSE_NORMAL_CLEARING, ast_cdr_alloc(), ast_cdr_end(), ast_cdr_init(), ast_cdr_start(), ast_cdr_update(), ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, ast_hangup(), ast_log(), ast_opt_end_cdr_before_h_exten, AST_PBX_KEEPALIVE, ast_set2_flag, ast_set_flag, ast_softhangup(), AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_TIMEOUT, ast_spawn_extension(), ast_strlen_zero(), ast_test_flag, ast_verbose(), autofallthrough, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_num, collect_digits(), ast_channel::context, ast_pbx::dtimeout, error(), ast_channel::exten, free, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, ast_channel::pbx, pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_destroy(), ast_channel::priority, ast_pbx::rtimeout, set_ext_pri(), ast_cdr::start, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and ast_channel::whentohangup.
Referenced by ast_pbx_run(), and pbx_thread().
02349 { 02350 int found = 0; /* set if we find at least one match */ 02351 int res = 0; 02352 int autoloopflag; 02353 int error = 0; /* set an error conditions */ 02354 02355 /* A little initial setup here */ 02356 if (c->pbx) { 02357 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name); 02358 /* XXX and now what ? */ 02359 free(c->pbx); 02360 } 02361 if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx)))) 02362 return -1; 02363 if (c->amaflags) { 02364 if (!c->cdr) { 02365 c->cdr = ast_cdr_alloc(); 02366 if (!c->cdr) { 02367 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02368 free(c->pbx); 02369 return -1; 02370 } 02371 ast_cdr_init(c->cdr, c); 02372 } 02373 } 02374 /* Set reasonable defaults */ 02375 c->pbx->rtimeout = 10; 02376 c->pbx->dtimeout = 5; 02377 02378 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */ 02379 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP); 02380 02381 /* Start by trying whatever the channel is set to */ 02382 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02383 /* If not successful fall back to 's' */ 02384 if (option_verbose > 1) 02385 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); 02386 /* XXX the original code used the existing priority in the call to 02387 * ast_exists_extension(), and reset it to 1 afterwards. 02388 * I believe the correct thing is to set it to 1 immediately. 02389 */ 02390 set_ext_pri(c, "s", 1); 02391 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02392 /* JK02: And finally back to default if everything else failed */ 02393 if (option_verbose > 1) 02394 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); 02395 ast_copy_string(c->context, "default", sizeof(c->context)); 02396 } 02397 } 02398 if (c->cdr && ast_tvzero(c->cdr->start)) 02399 ast_cdr_start(c->cdr); 02400 for (;;) { 02401 char dst_exten[256]; /* buffer to accumulate digits */ 02402 int pos = 0; /* XXX should check bounds */ 02403 int digit = 0; 02404 02405 /* loop on priorities in this context/exten */ 02406 while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02407 found = 1; 02408 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02409 /* Something bad happened, or a hangup has been requested. */ 02410 if (strchr("0123456789ABCDEF*#", res)) { 02411 if (option_debug) 02412 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 02413 pos = 0; 02414 dst_exten[pos++] = digit = res; 02415 dst_exten[pos] = '\0'; 02416 break; 02417 } 02418 if (res == AST_PBX_KEEPALIVE) { 02419 if (option_debug) 02420 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02421 if (option_verbose > 1) 02422 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02423 error = 1; 02424 break; 02425 } 02426 if (option_debug) 02427 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02428 if (option_verbose > 1) 02429 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02430 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02431 c->_softhangup =0; 02432 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02433 /* atimeout, nothing bad */ 02434 } else { 02435 if (c->cdr) 02436 ast_cdr_update(c); 02437 error = 1; 02438 break; 02439 } 02440 } 02441 if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c,c->context,"T",1,c->cid.cid_num)) { 02442 set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */ 02443 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */ 02444 c->whentohangup = 0; 02445 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT; 02446 } else if (c->_softhangup) { 02447 if (option_debug) 02448 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", 02449 c->exten, c->priority); 02450 error = 1; 02451 break; 02452 } 02453 c->priority++; 02454 } /* end while - from here on we can use 'break' to go out */ 02455 if (error) 02456 break; 02457 02458 /* XXX we get here on non-existing extension or a keypress or hangup ? */ 02459 02460 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { 02461 /* If there is no match at priority 1, it is not a valid extension anymore. 02462 * Try to continue at "i", 1 or exit if the latter does not exist. 02463 */ 02464 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02465 if (option_verbose > 2) 02466 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name); 02467 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten); 02468 set_ext_pri(c, "i", 1); 02469 } else { 02470 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n", 02471 c->name, c->exten, c->context); 02472 error = 1; /* we know what to do with it */ 02473 break; 02474 } 02475 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02476 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */ 02477 c->_softhangup = 0; 02478 } else { /* keypress received, get more digits for a full extension */ 02479 int waittime = 0; 02480 if (digit) 02481 waittime = c->pbx->dtimeout; 02482 else if (!autofallthrough) 02483 waittime = c->pbx->rtimeout; 02484 if (!waittime) { 02485 const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 02486 if (!status) 02487 status = "UNKNOWN"; 02488 if (option_verbose > 2) 02489 ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status); 02490 if (!strcasecmp(status, "CONGESTION")) 02491 res = pbx_builtin_congestion(c, "10"); 02492 else if (!strcasecmp(status, "CHANUNAVAIL")) 02493 res = pbx_builtin_congestion(c, "10"); 02494 else if (!strcasecmp(status, "BUSY")) 02495 res = pbx_builtin_busy(c, "10"); 02496 error = 1; /* XXX disable message */ 02497 break; /* exit from the 'for' loop */ 02498 } 02499 02500 if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos)) 02501 break; 02502 if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */ 02503 set_ext_pri(c, dst_exten, 1); 02504 else { 02505 /* No such extension */ 02506 if (!ast_strlen_zero(dst_exten)) { 02507 /* An invalid extension */ 02508 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02509 if (option_verbose > 2) 02510 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name); 02511 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten); 02512 set_ext_pri(c, "i", 1); 02513 } else { 02514 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context); 02515 found = 1; /* XXX disable message */ 02516 break; 02517 } 02518 } else { 02519 /* A simple timeout */ 02520 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) { 02521 if (option_verbose > 2) 02522 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name); 02523 set_ext_pri(c, "t", 1); 02524 } else { 02525 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context); 02526 found = 1; /* XXX disable message */ 02527 break; 02528 } 02529 } 02530 } 02531 if (c->cdr) { 02532 if (option_verbose > 2) 02533 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name); 02534 ast_cdr_update(c); 02535 } 02536 } 02537 } 02538 if (!found && !error) 02539 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); 02540 if (res != AST_PBX_KEEPALIVE) 02541 ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING); 02542 if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) { 02543 if (c->cdr && ast_opt_end_cdr_before_h_exten) 02544 ast_cdr_end(c->cdr); 02545 set_ext_pri(c, "h", 1); 02546 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02547 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02548 /* Something bad happened, or a hangup has been requested. */ 02549 if (option_debug) 02550 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02551 if (option_verbose > 1) 02552 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02553 break; 02554 } 02555 c->priority++; 02556 } 02557 } 02558 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP); 02559 02560 pbx_destroy(c->pbx); 02561 c->pbx = NULL; 02562 if (res != AST_PBX_KEEPALIVE) 02563 ast_hangup(c); 02564 return 0; 02565 }
static int _extension_match_core | ( | const char * | pattern, | |
const char * | data, | |||
enum ext_match_t | mode | |||
) | [static] |
Definition at line 767 of file pbx.c.
References ast_log(), E_MATCH, E_MATCH_MASK, E_MATCHMORE, and LOG_WARNING.
Referenced by extension_match_core().
00768 { 00769 mode &= E_MATCH_MASK; /* only consider the relevant bits */ 00770 00771 if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */ 00772 return 1; 00773 00774 if (pattern[0] != '_') { /* not a pattern, try exact or partial match */ 00775 int ld = strlen(data), lp = strlen(pattern); 00776 00777 if (lp < ld) /* pattern too short, cannot match */ 00778 return 0; 00779 /* depending on the mode, accept full or partial match or both */ 00780 if (mode == E_MATCH) 00781 return !strcmp(pattern, data); /* 1 on match, 0 on fail */ 00782 if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */ 00783 return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */ 00784 else 00785 return 0; 00786 } 00787 pattern++; /* skip leading _ */ 00788 /* 00789 * XXX below we stop at '/' which is a separator for the CID info. However we should 00790 * not store '/' in the pattern at all. When we insure it, we can remove the checks. 00791 */ 00792 while (*data && *pattern && *pattern != '/') { 00793 const char *end; 00794 00795 if (*data == '-') { /* skip '-' in data (just a separator) */ 00796 data++; 00797 continue; 00798 } 00799 switch (toupper(*pattern)) { 00800 case '[': /* a range */ 00801 end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */ 00802 if (end == NULL) { 00803 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n"); 00804 return 0; /* unconditional failure */ 00805 } 00806 for (pattern++; pattern != end; pattern++) { 00807 if (pattern+2 < end && pattern[1] == '-') { /* this is a range */ 00808 if (*data >= pattern[0] && *data <= pattern[2]) 00809 break; /* match found */ 00810 else { 00811 pattern += 2; /* skip a total of 3 chars */ 00812 continue; 00813 } 00814 } else if (*data == pattern[0]) 00815 break; /* match found */ 00816 } 00817 if (pattern == end) 00818 return 0; 00819 pattern = end; /* skip and continue */ 00820 break; 00821 case 'N': 00822 if (*data < '2' || *data > '9') 00823 return 0; 00824 break; 00825 case 'X': 00826 if (*data < '0' || *data > '9') 00827 return 0; 00828 break; 00829 case 'Z': 00830 if (*data < '1' || *data > '9') 00831 return 0; 00832 break; 00833 case '.': /* Must match, even with more digits */ 00834 return 1; 00835 case '!': /* Early match */ 00836 return 2; 00837 case ' ': 00838 case '-': /* Ignore these in patterns */ 00839 data--; /* compensate the final data++ */ 00840 break; 00841 default: 00842 if (*data != *pattern) 00843 return 0; 00844 } 00845 data++; 00846 pattern++; 00847 } 00848 if (*data) /* data longer than pattern, no match */ 00849 return 0; 00850 /* 00851 * match so far, but ran off the end of the data. 00852 * Depending on what is next, determine match or not. 00853 */ 00854 if (*pattern == '\0' || *pattern == '/') /* exact match */ 00855 return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */ 00856 else if (*pattern == '!') /* early match */ 00857 return 2; 00858 else /* partial match */ 00859 return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */ 00860 }
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 4678 of file pbx.c.
References ast_add_hint(), ast_change_hint(), ast_log(), ast_exten::data, ast_exten::datad, 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().
04680 { 04681 struct ast_exten *ep; 04682 04683 for (ep = NULL; e ; ep = e, e = e->peer) { 04684 if (e->priority >= tmp->priority) 04685 break; 04686 } 04687 if (!e) { /* go at the end, and ep is surely set because the list is not empty */ 04688 ep->peer = tmp; 04689 return 0; /* success */ 04690 } 04691 if (e->priority == tmp->priority) { 04692 /* Can't have something exactly the same. Is this a 04693 replacement? If so, replace, otherwise, bonk. */ 04694 if (!replace) { 04695 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04696 if (tmp->datad) 04697 tmp->datad(tmp->data); 04698 free(tmp); 04699 return -1; 04700 } 04701 /* we are replacing e, so copy the link fields and then update 04702 * whoever pointed to e to point to us 04703 */ 04704 tmp->next = e->next; /* not meaningful if we are not first in the peer list */ 04705 tmp->peer = e->peer; /* always meaningful */ 04706 if (ep) /* We're in the peer list, just insert ourselves */ 04707 ep->peer = tmp; 04708 else if (el) /* We're the first extension. Take over e's functions */ 04709 el->next = tmp; 04710 else /* We're the very first extension. */ 04711 con->root = tmp; 04712 if (tmp->priority == PRIORITY_HINT) 04713 ast_change_hint(e,tmp); 04714 /* Destroy the old one */ 04715 if (e->datad) 04716 e->datad(e->data); 04717 free(e); 04718 } else { /* Slip ourselves in just before e */ 04719 tmp->peer = e; 04720 tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */ 04721 if (ep) /* Easy enough, we're just in the peer list */ 04722 ep->peer = tmp; 04723 else { /* we are the first in some peer list, so link in the ext list */ 04724 if (el) 04725 el->next = tmp; /* in the middle... */ 04726 else 04727 con->root = tmp; /* ... or at the head */ 04728 e->next = NULL; /* e is no more at the head, so e->next must be reset */ 04729 } 04730 /* And immediately return success. */ 04731 if (tmp->priority == PRIORITY_HINT) 04732 ast_add_hint(tmp); 04733 } 04734 return 0; 04735 }
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2670 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02671 { 02672 return countcalls; 02673 }
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.
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 |
0 | success | |
-1 | failure |
Definition at line 4554 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().
04557 { 04558 int ret = -1; 04559 struct ast_context *c = find_context_locked(context); 04560 04561 if (c) { 04562 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04563 application, data, datad, registrar); 04564 ast_unlock_contexts(); 04565 } 04566 return ret; 04567 }
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 | |||
) |
Main interface to add extensions to the list for out context.
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 4762 of file pbx.c.
References add_pri(), ast_exten::app, ast_add_hint(), ast_calloc, AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, errno, ext_cmp(), ext_strncpy(), ast_exten::exten, globals, ast_exten::label, ast_context::lock, LOG_DEBUG, ast_exten::matchcid, ast_exten::next, option_debug, 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(), ast_autoanswer_login(), autoanswer_reregister_extensions(), do_parking_thread(), load_config(), park_call_full(), pbx_load_config(), pbx_load_users(), sla_build_station(), and sla_build_trunk().
04766 { 04767 /* 04768 * Sort extensions (or patterns) according to the rules indicated above. 04769 * These are implemented by the function ext_cmp()). 04770 * All priorities for the same ext/pattern/cid are kept in a list, 04771 * using the 'peer' field as a link field.. 04772 */ 04773 struct ast_exten *tmp, *e, *el = NULL; 04774 int res; 04775 int length; 04776 char *p; 04777 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04778 04779 /* if we are adding a hint, and there are global variables, and the hint 04780 contains variable references, then expand them 04781 */ 04782 ast_mutex_lock(&globalslock); 04783 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04784 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04785 application = expand_buf; 04786 } 04787 ast_mutex_unlock(&globalslock); 04788 04789 length = sizeof(struct ast_exten); 04790 length += strlen(extension) + 1; 04791 length += strlen(application) + 1; 04792 if (label) 04793 length += strlen(label) + 1; 04794 if (callerid) 04795 length += strlen(callerid) + 1; 04796 else 04797 length ++; /* just the '\0' */ 04798 04799 /* Be optimistic: Build the extension structure first */ 04800 if (!(tmp = ast_calloc(1, length))) 04801 return -1; 04802 04803 /* use p as dst in assignments, as the fields are const char * */ 04804 p = tmp->stuff; 04805 if (label) { 04806 tmp->label = p; 04807 strcpy(p, label); 04808 p += strlen(label) + 1; 04809 } 04810 tmp->exten = p; 04811 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04812 tmp->priority = priority; 04813 tmp->cidmatch = p; /* but use p for assignments below */ 04814 if (callerid) { 04815 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04816 tmp->matchcid = 1; 04817 } else { 04818 *p++ = '\0'; 04819 tmp->matchcid = 0; 04820 } 04821 tmp->app = p; 04822 strcpy(p, application); 04823 tmp->parent = con; 04824 tmp->data = data; 04825 tmp->datad = datad; 04826 tmp->registrar = registrar; 04827 04828 ast_mutex_lock(&con->lock); 04829 res = 0; /* some compilers will think it is uninitialized otherwise */ 04830 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04831 res = ext_cmp(e->exten, extension); 04832 if (res == 0) { /* extension match, now look at cidmatch */ 04833 if (!e->matchcid && !tmp->matchcid) 04834 res = 0; 04835 else if (tmp->matchcid && !e->matchcid) 04836 res = 1; 04837 else if (e->matchcid && !tmp->matchcid) 04838 res = -1; 04839 else 04840 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04841 } 04842 if (res >= 0) 04843 break; 04844 } 04845 if (e && res == 0) { /* exact match, insert in the pri chain */ 04846 res = add_pri(con, tmp, el, e, replace); 04847 ast_mutex_unlock(&con->lock); 04848 if (res < 0) { 04849 errno = EEXIST; /* XXX do we care ? */ 04850 return 0; /* XXX should we return -1 maybe ? */ 04851 } 04852 } else { 04853 /* 04854 * not an exact match, this is the first entry with this pattern, 04855 * so insert in the main list right before 'e' (if any) 04856 */ 04857 tmp->next = e; 04858 if (el) 04859 el->next = tmp; 04860 else 04861 con->root = tmp; 04862 ast_mutex_unlock(&con->lock); 04863 if (tmp->priority == PRIORITY_HINT) 04864 ast_add_hint(tmp); 04865 } 04866 if (option_debug) { 04867 if (tmp->matchcid) { 04868 if (option_debug) 04869 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04870 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04871 } else { 04872 if (option_debug) 04873 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04874 tmp->exten, tmp->priority, con->name); 04875 } 04876 } 04877 if (option_verbose > 2) { 04878 if (tmp->matchcid) { 04879 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04880 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04881 } else { 04882 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04883 tmp->exten, tmp->priority, con->name); 04884 } 04885 } 04886 return 0; 04887 }
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 2170 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, ast_hint::laststate, LOG_DEBUG, and option_debug.
Referenced by add_pri(), and ast_add_extension2().
02171 { 02172 struct ast_hint *hint; 02173 02174 if (!e) 02175 return -1; 02176 02177 AST_LIST_LOCK(&hints); 02178 02179 /* Search if hint exists, do nothing */ 02180 AST_LIST_TRAVERSE(&hints, hint, list) { 02181 if (hint->exten == e) { 02182 AST_LIST_UNLOCK(&hints); 02183 if (option_debug > 1) 02184 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02185 return -1; 02186 } 02187 } 02188 02189 if (option_debug > 1) 02190 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02191 02192 if (!(hint = ast_calloc(1, sizeof(*hint)))) { 02193 AST_LIST_UNLOCK(&hints); 02194 return -1; 02195 } 02196 /* Initialize and insert new item at the top */ 02197 hint->exten = e; 02198 hint->laststate = ast_extension_state2(e); 02199 AST_LIST_INSERT_HEAD(&hints, hint, list); 02200 02201 AST_LIST_UNLOCK(&hints); 02202 return 0; 02203 }
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 4592 of file pbx.c.
References ast_channel::_state, ast_channel::amaflags, 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().
04593 { 04594 int res = 0; 04595 04596 ast_channel_lock(chan); 04597 04598 if (chan->pbx) { /* This channel is currently in the PBX */ 04599 ast_explicit_goto(chan, context, exten, priority); 04600 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04601 } else { 04602 /* In order to do it when the channel doesn't really exist within 04603 the PBX, we have to make a new channel, masquerade, and start the PBX 04604 at the new location */ 04605 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04606 if (chan->cdr) { 04607 tmpchan->cdr = ast_cdr_dup(chan->cdr); 04608 } 04609 if (!tmpchan) 04610 res = -1; 04611 else { 04612 /* Make formats okay */ 04613 tmpchan->readformat = chan->readformat; 04614 tmpchan->writeformat = chan->writeformat; 04615 /* Setup proper location */ 04616 ast_explicit_goto(tmpchan, 04617 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04618 04619 /* Masquerade into temp channel */ 04620 ast_channel_masquerade(tmpchan, chan); 04621 04622 /* Grab the locks and get going */ 04623 ast_channel_lock(tmpchan); 04624 ast_do_masquerade(tmpchan); 04625 ast_channel_unlock(tmpchan); 04626 /* Start the PBX going on our stolen channel */ 04627 if (ast_pbx_start(tmpchan)) { 04628 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04629 ast_hangup(tmpchan); 04630 res = -1; 04631 } 04632 } 04633 } 04634 ast_channel_unlock(chan); 04635 return res; 04636 }
int ast_async_goto_by_name | ( | const char * | channame, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4638 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04639 { 04640 struct ast_channel *chan; 04641 int res = -1; 04642 04643 chan = ast_get_channel_by_name_locked(channame); 04644 if (chan) { 04645 res = ast_async_goto(chan, context, exten, priority); 04646 ast_channel_unlock(chan); 04647 } 04648 return res; 04649 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6360 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06361 { 06362 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06363 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info_in | |||
) |
Definition at line 4230 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().
04231 { 04232 char info_save[256]; 04233 char *info; 04234 04235 /* Check for empty just in case */ 04236 if (ast_strlen_zero(info_in)) 04237 return 0; 04238 /* make a copy just in case we were passed a static string */ 04239 ast_copy_string(info_save, info_in, sizeof(info_save)); 04240 info = info_save; 04241 /* Assume everything except time */ 04242 i->monthmask = 0xfff; /* 12 bits */ 04243 i->daymask = 0x7fffffffU; /* 31 bits */ 04244 i->dowmask = 0x7f; /* 7 bits */ 04245 /* on each call, use strsep() to move info to the next argument */ 04246 get_timerange(i, strsep(&info, "|")); 04247 if (info) 04248 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04249 if (info) 04250 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04251 if (info) 04252 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04253 return 1; 04254 }
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.
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 |
Definition at line 2294 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().
02295 { 02296 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02297 }
ast_change_hint: Change hint for an extension
Definition at line 2206 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_hint::exten.
Referenced by add_pri().
02207 { 02208 struct ast_hint *hint; 02209 int res = -1; 02210 02211 AST_LIST_LOCK(&hints); 02212 AST_LIST_TRAVERSE(&hints, hint, list) { 02213 if (hint->exten == oe) { 02214 hint->exten = ne; 02215 res = 0; 02216 break; 02217 } 02218 } 02219 AST_LIST_UNLOCK(&hints); 02220 02221 return res; 02222 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4256 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().
04257 { 04258 struct tm tm; 04259 time_t t = time(NULL); 04260 04261 ast_localtime(&t, &tm, NULL); 04262 04263 /* If it's not the right month, return */ 04264 if (!(i->monthmask & (1 << tm.tm_mon))) 04265 return 0; 04266 04267 /* If it's not that time of the month.... */ 04268 /* Warning, tm_mday has range 1..31! */ 04269 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04270 return 0; 04271 04272 /* If it's not the right day of the week */ 04273 if (!(i->dowmask & (1 << tm.tm_wday))) 04274 return 0; 04275 04276 /* Sanity check the hour just to be safe */ 04277 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04278 ast_log(LOG_WARNING, "Insane time...\n"); 04279 return 0; 04280 } 04281 04282 /* Now the tough part, we calculate if it fits 04283 in the right time based on min/hour */ 04284 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04285 return 0; 04286 04287 /* If we got this far, then we're good */ 04288 return 1; 04289 }
int ast_context_add_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Add an ignorepat.
context | which context to add the ignorpattern to | |
ignorepat | ignorepattern to set up for the extension | |
registrar | registrar of the ignore pattern |
0 | on success | |
-1 | on failure |
Definition at line 4490 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().
04491 { 04492 int ret = -1; 04493 struct ast_context *c = find_context_locked(context); 04494 04495 if (c) { 04496 ret = ast_context_add_ignorepat2(c, value, registrar); 04497 ast_unlock_contexts(); 04498 } 04499 return ret; 04500 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | value, | |||
const char * | registrar | |||
) |
Definition at line 4502 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_compile_ael2(), ast_context_add_ignorepat(), and pbx_load_config().
04503 { 04504 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04505 int length; 04506 length = sizeof(struct ast_ignorepat); 04507 length += strlen(value) + 1; 04508 if (!(ignorepat = ast_calloc(1, length))) 04509 return -1; 04510 /* The cast to char * is because we need to write the initial value. 04511 * The field is not supposed to be modified otherwise 04512 */ 04513 strcpy((char *)ignorepat->pattern, value); 04514 ignorepat->next = NULL; 04515 ignorepat->registrar = registrar; 04516 ast_mutex_lock(&con->lock); 04517 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04518 ignorepatl = ignorepatc; 04519 if (!strcasecmp(ignorepatc->pattern, value)) { 04520 /* Already there */ 04521 ast_mutex_unlock(&con->lock); 04522 errno = EEXIST; 04523 return -1; 04524 } 04525 } 04526 if (ignorepatl) 04527 ignorepatl->next = ignorepat; 04528 else 04529 con->ignorepats = ignorepat; 04530 ast_mutex_unlock(&con->lock); 04531 return 0; 04532 04533 }
int ast_context_add_include | ( | const char * | context, | |
const char * | include, | |||
const char * | registrar | |||
) |
Add a context include.
context | context to add include to | |
include | new include to add | |
registrar | who's registering it |
0 | on success | |
-1 | on error |
Definition at line 4036 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().
04037 { 04038 int ret = -1; 04039 struct ast_context *c = find_context_locked(context); 04040 04041 if (c) { 04042 ret = ast_context_add_include2(c, include, registrar); 04043 ast_unlock_contexts(); 04044 } 04045 return ret; 04046 }
int ast_context_add_include2 | ( | struct ast_context * | con, | |
const char * | include, | |||
const char * | registrar | |||
) |
Add a context include.
con | context to add the include to | |
include | include to add | |
registrar | who registered the context |
0 | on success | |
-1 | on failure |
Definition at line 4298 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_compile_ael2(), ast_context_add_include(), and pbx_load_config().
04300 { 04301 struct ast_include *new_include; 04302 char *c; 04303 struct ast_include *i, *il = NULL; /* include, include_last */ 04304 int length; 04305 char *p; 04306 04307 length = sizeof(struct ast_include); 04308 length += 2 * (strlen(value) + 1); 04309 04310 /* allocate new include structure ... */ 04311 if (!(new_include = ast_calloc(1, length))) 04312 return -1; 04313 /* Fill in this structure. Use 'p' for assignments, as the fields 04314 * in the structure are 'const char *' 04315 */ 04316 p = new_include->stuff; 04317 new_include->name = p; 04318 strcpy(p, value); 04319 p += strlen(value) + 1; 04320 new_include->rname = p; 04321 strcpy(p, value); 04322 /* Strip off timing info, and process if it is there */ 04323 if ( (c = strchr(p, '|')) ) { 04324 *c++ = '\0'; 04325 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04326 } 04327 new_include->next = NULL; 04328 new_include->registrar = registrar; 04329 04330 ast_mutex_lock(&con->lock); 04331 04332 /* ... go to last include and check if context is already included too... */ 04333 for (i = con->includes; i; i = i->next) { 04334 if (!strcasecmp(i->name, new_include->name)) { 04335 free(new_include); 04336 ast_mutex_unlock(&con->lock); 04337 errno = EEXIST; 04338 return -1; 04339 } 04340 il = i; 04341 } 04342 04343 /* ... include new context into context list, unlock, return */ 04344 if (il) 04345 il->next = new_include; 04346 else 04347 con->includes = new_include; 04348 if (option_verbose > 2) 04349 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04350 ast_mutex_unlock(&con->lock); 04351 04352 return 0; 04353 }
int ast_context_add_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
int | eval, | |||
const char * | registrar | |||
) |
Add a switch.
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 |
0 | on success | |
-1 | on failure |
Definition at line 4360 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04361 { 04362 int ret = -1; 04363 struct ast_context *c = find_context_locked(context); 04364 04365 if (c) { /* found, add switch to this context */ 04366 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04367 ast_unlock_contexts(); 04368 } 04369 return ret; 04370 }
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).
Definition at line 4379 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, SWITCH_DATA_LENGTH, and VERBOSE_PREFIX_3.
Referenced by ast_compile_ael2(), ast_context_add_switch(), and pbx_load_config().
04381 { 04382 struct ast_sw *new_sw; 04383 struct ast_sw *i; 04384 int length; 04385 char *p; 04386 04387 length = sizeof(struct ast_sw); 04388 length += strlen(value) + 1; 04389 if (data) 04390 length += strlen(data); 04391 length++; 04392 if (eval) { 04393 /* Create buffer for evaluation of variables */ 04394 length += SWITCH_DATA_LENGTH; 04395 length++; 04396 } 04397 04398 /* allocate new sw structure ... */ 04399 if (!(new_sw = ast_calloc(1, length))) 04400 return -1; 04401 /* ... fill in this structure ... */ 04402 p = new_sw->stuff; 04403 new_sw->name = p; 04404 strcpy(new_sw->name, value); 04405 p += strlen(value) + 1; 04406 new_sw->data = p; 04407 if (data) { 04408 strcpy(new_sw->data, data); 04409 p += strlen(data) + 1; 04410 } else { 04411 strcpy(new_sw->data, ""); 04412 p++; 04413 } 04414 if (eval) 04415 new_sw->tmpdata = p; 04416 new_sw->eval = eval; 04417 new_sw->registrar = registrar; 04418 04419 /* ... try to lock this context ... */ 04420 ast_mutex_lock(&con->lock); 04421 04422 /* ... go to last sw and check if context is already swd too... */ 04423 AST_LIST_TRAVERSE(&con->alts, i, list) { 04424 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04425 free(new_sw); 04426 ast_mutex_unlock(&con->lock); 04427 errno = EEXIST; 04428 return -1; 04429 } 04430 } 04431 04432 /* ... sw new context into context list, unlock, return */ 04433 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04434 04435 if (option_verbose > 2) 04436 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04437 04438 ast_mutex_unlock(&con->lock); 04439 04440 return 0; 04441 }
struct ast_context* ast_context_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) | [read] |
Register a new context.
extcontexts | pointer to the ast_context structure pointer | |
name | name of the new context | |
registrar | registrar of the context |
Definition at line 3906 of file pbx.c.
References __ast_context_create().
Referenced by ast_autoanswer_login(), ast_compile_ael2(), autoanswer_reregister_extensions(), do_parking_thread(), load_config(), park_call_full(), reload_config(), and set_config().
03907 { 03908 return __ast_context_create(extcontexts, name, registrar, 0); 03909 }
void ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
Destroy a context (matches the specified context (or ANY context if NULL).
con | context to destroy | |
registrar | who registered it |
Definition at line 5357 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().
05358 { 05359 ast_wrlock_contexts(); 05360 __ast_context_destroy(con,registrar); 05361 ast_unlock_contexts(); 05362 }
struct ast_context* ast_context_find | ( | const char * | name | ) | [read] |
Find a context.
name | name of the context to find |
Definition at line 890 of file pbx.c.
References ast_rdlock_contexts(), ast_unlock_contexts(), and ast_walk_contexts().
Referenced by _macro_exec(), ast_autoanswer_login(), ast_context_verify_includes(), ast_ignore_pattern(), autoanswer_reregister_extensions(), cleanup_stale_contexts(), do_autoanswer_thread(), do_parking_thread(), load_config(), park_call_full(), park_exec(), register_peer_exten(), reload_config(), and set_config().
00891 { 00892 struct ast_context *tmp = NULL; 00893 00894 ast_rdlock_contexts(); 00895 00896 while ( (tmp = ast_walk_contexts(tmp)) ) { 00897 if (!name || !strcasecmp(name, tmp->name)) 00898 break; 00899 } 00900 00901 ast_unlock_contexts(); 00902 00903 return tmp; 00904 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) | [read] |
Definition at line 3911 of file pbx.c.
References __ast_context_create().
Referenced by ast_compile_ael2(), pbx_load_config(), pbx_load_users(), sla_build_station(), and sla_build_trunk().
03912 { 03913 return __ast_context_create(extcontexts, name, registrar, 1); 03914 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2907 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().
02908 { 02909 struct ast_context *c = NULL; 02910 int ret = -1; 02911 02912 ast_rdlock_contexts(); 02913 02914 while ((c = ast_walk_contexts(c))) { 02915 if (!strcmp(ast_get_context_name(c), context)) { 02916 ret = 0; 02917 break; 02918 } 02919 } 02920 02921 ast_unlock_contexts(); 02922 02923 /* if we found context, lock macrolock */ 02924 if (ret == 0) 02925 ret = ast_mutex_lock(&c->macrolock); 02926 02927 return ret; 02928 }
int ast_context_remove_extension | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | registrar | |||
) |
Simply remove extension from context.
context | context to remove extension from | |
extension | which extension to remove | |
priority | priority of extension to remove | |
registrar | registrar of the extension |
0 | on success | |
-1 | on failure |
Definition at line 2808 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().
02809 { 02810 int ret = -1; /* default error return */ 02811 struct ast_context *c = find_context_locked(context); 02812 02813 if (c) { /* ... remove extension ... */ 02814 ret = ast_context_remove_extension2(c, extension, priority, registrar); 02815 ast_unlock_contexts(); 02816 } 02817 return ret; 02818 }
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.
Definition at line 2830 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), destroy_exten(), ast_exten::exten, exten, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::registrar, and ast_context::root.
Referenced by ast_context_remove_extension(), do_autoanswer_thread(), do_parking_thread(), load_config(), and park_exec().
02831 { 02832 struct ast_exten *exten, *prev_exten = NULL; 02833 struct ast_exten *peer; 02834 02835 ast_mutex_lock(&con->lock); 02836 02837 /* scan the extension list to find matching extension-registrar */ 02838 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02839 if (!strcmp(exten->exten, extension) && 02840 (!registrar || !strcmp(exten->registrar, registrar))) 02841 break; 02842 } 02843 if (!exten) { 02844 /* we can't find right extension */ 02845 ast_mutex_unlock(&con->lock); 02846 return -1; 02847 } 02848 02849 /* should we free all peers in this extension? (priority == 0)? */ 02850 if (priority == 0) { 02851 /* remove this extension from context list */ 02852 if (prev_exten) 02853 prev_exten->next = exten->next; 02854 else 02855 con->root = exten->next; 02856 02857 /* fire out all peers */ 02858 while ( (peer = exten) ) { 02859 exten = peer->peer; /* prepare for next entry */ 02860 destroy_exten(peer); 02861 } 02862 } else { 02863 /* scan the priority list to remove extension with exten->priority == priority */ 02864 struct ast_exten *previous_peer = NULL; 02865 02866 for (peer = exten; peer; previous_peer = peer, peer = peer->peer) { 02867 if (peer->priority == priority && 02868 (!registrar || !strcmp(peer->registrar, registrar) )) 02869 break; /* found our priority */ 02870 } 02871 if (!peer) { /* not found */ 02872 ast_mutex_unlock(&con->lock); 02873 return -1; 02874 } 02875 /* we are first priority extension? */ 02876 if (!previous_peer) { 02877 /* 02878 * We are first in the priority chain, so must update the extension chain. 02879 * The next node is either the next priority or the next extension 02880 */ 02881 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02882 02883 if (!prev_exten) /* change the root... */ 02884 con->root = next_node; 02885 else 02886 prev_exten->next = next_node; /* unlink */ 02887 if (peer->peer) /* XXX update the new head of the pri list */ 02888 peer->peer->next = peer->next; 02889 } else { /* easy, we are not first priority in extension */ 02890 previous_peer->peer = peer->peer; 02891 } 02892 02893 /* now, free whole priority extension */ 02894 destroy_exten(peer); 02895 /* XXX should we return -1 ? */ 02896 } 02897 ast_mutex_unlock(&con->lock); 02898 return 0; 02899 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4447 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().
04448 { 04449 int ret = -1; 04450 struct ast_context *c = find_context_locked(context); 04451 04452 if (c) { 04453 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04454 ast_unlock_contexts(); 04455 } 04456 return ret; 04457 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4459 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().
04460 { 04461 struct ast_ignorepat *ip, *ipl = NULL; 04462 04463 ast_mutex_lock(&con->lock); 04464 04465 for (ip = con->ignorepats; ip; ip = ip->next) { 04466 if (!strcmp(ip->pattern, ignorepat) && 04467 (!registrar || (registrar == ip->registrar))) { 04468 if (ipl) { 04469 ipl->next = ip->next; 04470 free(ip); 04471 } else { 04472 con->ignorepats = ip->next; 04473 free(ip); 04474 } 04475 ast_mutex_unlock(&con->lock); 04476 return 0; 04477 } 04478 ipl = ip; 04479 } 04480 04481 ast_mutex_unlock(&con->lock); 04482 errno = EINVAL; 04483 return -1; 04484 }
int ast_context_remove_include | ( | const char * | context, | |
const char * | include, | |||
const char * | registrar | |||
) |
Remove a context include.
0 | on success | |
-1 | on failure |
Definition at line 2704 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().
02705 { 02706 int ret = -1; 02707 struct ast_context *c = find_context_locked(context); 02708 02709 if (c) { 02710 /* found, remove include from this context ... */ 02711 ret = ast_context_remove_include2(c, include, registrar); 02712 ast_unlock_contexts(); 02713 } 02714 return ret; 02715 }
int ast_context_remove_include2 | ( | struct ast_context * | con, | |
const char * | include, | |||
const char * | registrar | |||
) |
Removes an include by an ast_context structure.
0 | on success | |
-1 | on success |
Definition at line 2725 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().
02726 { 02727 struct ast_include *i, *pi = NULL; 02728 int ret = -1; 02729 02730 ast_mutex_lock(&con->lock); 02731 02732 /* find our include */ 02733 for (i = con->includes; i; pi = i, i = i->next) { 02734 if (!strcmp(i->name, include) && 02735 (!registrar || !strcmp(i->registrar, registrar))) { 02736 /* remove from list */ 02737 if (pi) 02738 pi->next = i->next; 02739 else 02740 con->includes = i->next; 02741 /* free include and return */ 02742 free(i); 02743 ret = 0; 02744 break; 02745 } 02746 } 02747 02748 ast_mutex_unlock(&con->lock); 02749 return ret; 02750 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2757 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02758 { 02759 int ret = -1; /* default error return */ 02760 struct ast_context *c = find_context_locked(context); 02761 02762 if (c) { 02763 /* remove switch from this context ... */ 02764 ret = ast_context_remove_switch2(c, sw, data, registrar); 02765 ast_unlock_contexts(); 02766 } 02767 return ret; 02768 }
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.
Definition at line 2778 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().
02779 { 02780 struct ast_sw *i; 02781 int ret = -1; 02782 02783 ast_mutex_lock(&con->lock); 02784 02785 /* walk switches */ 02786 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02787 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02788 (!registrar || !strcmp(i->registrar, registrar))) { 02789 /* found, remove from list */ 02790 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02791 free(i); /* free switch and return */ 02792 ret = 0; 02793 break; 02794 } 02795 } 02796 AST_LIST_TRAVERSE_SAFE_END 02797 02798 ast_mutex_unlock(&con->lock); 02799 02800 return ret; 02801 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2935 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().
02936 { 02937 struct ast_context *c = NULL; 02938 int ret = -1; 02939 02940 ast_rdlock_contexts(); 02941 02942 while ((c = ast_walk_contexts(c))) { 02943 if (!strcmp(ast_get_context_name(c), context)) { 02944 ret = 0; 02945 break; 02946 } 02947 } 02948 02949 ast_unlock_contexts(); 02950 02951 /* if we found context, unlock macrolock */ 02952 if (ret == 0) 02953 ret = ast_mutex_unlock(&c->macrolock); 02954 02955 return ret; 02956 }
int ast_context_verify_includes | ( | struct ast_context * | con | ) |
Verifies includes in an ast_contect structure.
con | context in which to verify the includes |
0 | if no problems found | |
-1 | if there were any missing context |
Definition at line 6321 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().
06322 { 06323 struct ast_include *inc = NULL; 06324 int res = 0; 06325 06326 while ( (inc = ast_walk_context_includes(con, inc)) ) 06327 if (!ast_context_find(inc->rname)) { 06328 res = -1; 06329 ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n", 06330 ast_get_context_name(con), inc->rname); 06331 } 06332 return res; 06333 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) | [read] |
Definition at line 1443 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().
01444 { 01445 struct ast_custom_function *acf = NULL; 01446 01447 AST_LIST_LOCK(&acf_root); 01448 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01449 if (!strcmp(name, acf->name)) 01450 break; 01451 } 01452 AST_LIST_UNLOCK(&acf_root); 01453 01454 return acf; 01455 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1479 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().
01480 { 01481 struct ast_custom_function *cur; 01482 01483 if (!acf) 01484 return -1; 01485 01486 AST_LIST_LOCK(&acf_root); 01487 01488 if (ast_custom_function_find(acf->name)) { 01489 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01490 AST_LIST_UNLOCK(&acf_root); 01491 return -1; 01492 } 01493 01494 /* Store in alphabetical order */ 01495 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01496 if (strcasecmp(acf->name, cur->name) < 0) { 01497 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01498 break; 01499 } 01500 } 01501 AST_LIST_TRAVERSE_SAFE_END 01502 if (!cur) 01503 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01504 01505 AST_LIST_UNLOCK(&acf_root); 01506 01507 if (option_verbose > 1) 01508 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01509 01510 return 0; 01511 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1457 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().
01458 { 01459 struct ast_custom_function *cur; 01460 01461 if (!acf) 01462 return -1; 01463 01464 AST_LIST_LOCK(&acf_root); 01465 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01466 if (cur == acf) { 01467 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01468 if (option_verbose > 1) 01469 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01470 break; 01471 } 01472 } 01473 AST_LIST_TRAVERSE_SAFE_END 01474 AST_LIST_UNLOCK(&acf_root); 01475 01476 return acf ? 0 : -1; 01477 }
int ast_exists_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) |
Determine whether an extension exists.
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 |
Definition at line 2279 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_exten2(), builtin_atxfer(), builtin_blindtransfer(), cb_events(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), disa_exec(), 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(), rpt_exec(), skinny_ss(), socket_process(), ss_thread(), waitstream_core(), and zt_handle_dtmfup().
02280 { 02281 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02282 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4569 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(), builtin_atxfer(), disa_exec(), and handle_setpriority().
04570 { 04571 if (!chan) 04572 return -1; 04573 04574 ast_channel_lock(chan); 04575 04576 if (!ast_strlen_zero(context)) 04577 ast_copy_string(chan->context, context, sizeof(chan->context)); 04578 if (!ast_strlen_zero(exten)) 04579 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04580 if (priority > -1) { 04581 chan->priority = priority; 04582 /* see flag description in channel.h for explanation */ 04583 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04584 chan->priority--; 04585 } 04586 04587 ast_channel_unlock(chan); 04588 04589 return 0; 04590 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 883 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00884 { 00885 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00886 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00887 return extension_match_core(pattern, data, needmore); 00888 }
int ast_extension_match | ( | const char * | pattern, | |
const char * | extension | |||
) |
Determine if a given extension matches a given pattern (in NXX format).
pattern | pattern to match | |
extension | extension to check against the pattern. |
1 | on match | |
0 | on failure |
Definition at line 878 of file pbx.c.
References E_MATCH, and extension_match_core().
Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), loopback_canmatch(), loopback_exec(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), and show_dialplan_helper().
00879 { 00880 return extension_match_core(pattern, data, E_MATCH); 00881 }
int ast_extension_state | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten | |||
) |
ast_extension_state: Check extension state for an extension by using hint
Uses hint and devicestate callback to get the state of an extension.
Definition at line 2003 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
02004 { 02005 struct ast_exten *e; 02006 02007 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 02008 if (!e) 02009 return -1; /* No hint, return -1 */ 02010 02011 return ast_extension_state2(e); /* Check all devices in the hint */ 02012 }
static int ast_extension_state2 | ( | struct ast_exten * | e | ) | [static] |
ast_extensions_state2: Check state of extension by using hints
Definition at line 1906 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().
01907 { 01908 char hint[AST_MAX_EXTENSION]; 01909 char *cur, *rest; 01910 int allunavailable = 1, allbusy = 1, allfree = 1, allonhold = 1; 01911 int busy = 0, inuse = 0, ring = 0; 01912 01913 if (!e) 01914 return -1; 01915 01916 ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint)); 01917 01918 rest = hint; /* One or more devices separated with a & character */ 01919 while ( (cur = strsep(&rest, "&")) ) { 01920 int res = ast_device_state(cur); 01921 switch (res) { 01922 case AST_DEVICE_NOT_INUSE: 01923 allunavailable = 0; 01924 allbusy = 0; 01925 allonhold = 0; 01926 break; 01927 case AST_DEVICE_INUSE: 01928 inuse = 1; 01929 allunavailable = 0; 01930 allfree = 0; 01931 allonhold = 0; 01932 break; 01933 case AST_DEVICE_RINGING: 01934 ring = 1; 01935 allunavailable = 0; 01936 allfree = 0; 01937 allonhold = 0; 01938 break; 01939 case AST_DEVICE_RINGINUSE: 01940 inuse = 1; 01941 ring = 1; 01942 allunavailable = 0; 01943 allfree = 0; 01944 allonhold = 0; 01945 break; 01946 case AST_DEVICE_ONHOLD: 01947 allunavailable = 0; 01948 allfree = 0; 01949 break; 01950 case AST_DEVICE_BUSY: 01951 allunavailable = 0; 01952 allfree = 0; 01953 allonhold = 0; 01954 busy = 1; 01955 break; 01956 case AST_DEVICE_UNAVAILABLE: 01957 case AST_DEVICE_INVALID: 01958 allbusy = 0; 01959 allfree = 0; 01960 allonhold = 0; 01961 break; 01962 default: 01963 allunavailable = 0; 01964 allbusy = 0; 01965 allfree = 0; 01966 allonhold = 0; 01967 } 01968 } 01969 01970 if (!inuse && ring) 01971 return AST_EXTENSION_RINGING; 01972 if (inuse && ring) 01973 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 01974 if (inuse) 01975 return AST_EXTENSION_INUSE; 01976 if (allfree) 01977 return AST_EXTENSION_NOT_INUSE; 01978 if (allonhold) 01979 return AST_EXTENSION_ONHOLD; 01980 if (allbusy) 01981 return AST_EXTENSION_BUSY; 01982 if (allunavailable) 01983 return AST_EXTENSION_UNAVAILABLE; 01984 if (busy) 01985 return AST_EXTENSION_INUSE; 01986 01987 return AST_EXTENSION_NOT_INUSE; 01988 }
const char* ast_extension_state2str | ( | int | extension_state | ) |
ast_extension_state2str: Return extension_state as string
Return string representation of the state of an extension.
Definition at line 1991 of file pbx.c.
References extension_states, and cfextension_states::text.
Referenced by __sip_show_channels(), cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
01992 { 01993 int i; 01994 01995 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01996 if (extension_states[i].extension_state == extension_state) 01997 return extension_states[i].text; 01998 } 01999 return "Unknown"; 02000 }
int ast_extension_state_add | ( | const char * | context, | |
const char * | exten, | |||
ast_state_cb_type | callback, | |||
void * | data | |||
) |
ast_extension_state_add: Add watcher for extension states
Registers a state change callback.
Definition at line 2058 of file pbx.c.
References ast_calloc, ast_hint_extension(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_state_cb::id, ast_state_cb::next, statecbs, and stateid.
Referenced by handle_request_subscribe(), init_manager(), and load_module().
02060 { 02061 struct ast_hint *hint; 02062 struct ast_state_cb *cblist; 02063 struct ast_exten *e; 02064 02065 /* If there's no context and extension: add callback to statecbs list */ 02066 if (!context && !exten) { 02067 AST_LIST_LOCK(&hints); 02068 02069 for (cblist = statecbs; cblist; cblist = cblist->next) { 02070 if (cblist->callback == callback) { 02071 cblist->data = data; 02072 AST_LIST_UNLOCK(&hints); 02073 return 0; 02074 } 02075 } 02076 02077 /* Now insert the callback */ 02078 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02079 AST_LIST_UNLOCK(&hints); 02080 return -1; 02081 } 02082 cblist->id = 0; 02083 cblist->callback = callback; 02084 cblist->data = data; 02085 02086 cblist->next = statecbs; 02087 statecbs = cblist; 02088 02089 AST_LIST_UNLOCK(&hints); 02090 return 0; 02091 } 02092 02093 if (!context || !exten) 02094 return -1; 02095 02096 /* This callback type is for only one hint, so get the hint */ 02097 e = ast_hint_extension(NULL, context, exten); 02098 if (!e) { 02099 return -1; 02100 } 02101 02102 /* Find the hint in the list of hints */ 02103 AST_LIST_LOCK(&hints); 02104 02105 AST_LIST_TRAVERSE(&hints, hint, list) { 02106 if (hint->exten == e) 02107 break; 02108 } 02109 02110 if (!hint) { 02111 /* We have no hint, sorry */ 02112 AST_LIST_UNLOCK(&hints); 02113 return -1; 02114 } 02115 02116 /* Now insert the callback in the callback list */ 02117 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02118 AST_LIST_UNLOCK(&hints); 02119 return -1; 02120 } 02121 cblist->id = stateid++; /* Unique ID for this callback */ 02122 cblist->callback = callback; /* Pointer to callback routine */ 02123 cblist->data = data; /* Data for the callback */ 02124 02125 cblist->next = hint->callbacks; 02126 hint->callbacks = cblist; 02127 02128 AST_LIST_UNLOCK(&hints); 02129 return cblist->id; 02130 }
int ast_extension_state_del | ( | int | id, | |
ast_state_cb_type | callback | |||
) |
ast_extension_state_del: Remove a watcher from the callback list
Deletes a registered state change callback by ID.
Definition at line 2133 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().
02134 { 02135 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02136 int ret = -1; 02137 02138 if (!id && !callback) 02139 return -1; 02140 02141 AST_LIST_LOCK(&hints); 02142 02143 if (!id) { /* id == 0 is a callback without extension */ 02144 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02145 if ((*p_cur)->callback == callback) 02146 break; 02147 } 02148 } else { /* callback with extension, find the callback based on ID */ 02149 struct ast_hint *hint; 02150 AST_LIST_TRAVERSE(&hints, hint, list) { 02151 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02152 if ((*p_cur)->id == id) 02153 break; 02154 } 02155 if (*p_cur) /* found in the inner loop */ 02156 break; 02157 } 02158 } 02159 if (p_cur && *p_cur) { 02160 struct ast_state_cb *cur = *p_cur; 02161 *p_cur = cur->next; 02162 free(cur); 02163 ret = 0; 02164 } 02165 AST_LIST_UNLOCK(&hints); 02166 return ret; 02167 }
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.
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 |
Definition at line 2284 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().
02285 { 02286 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02287 }
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.
Definition at line 2289 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02290 { 02291 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02292 }
int ast_func_read | ( | struct ast_channel * | chan, | |
char * | function, | |||
char * | workspace, | |||
size_t | len | |||
) |
executes a read operation on a function
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 |
Definition at line 1533 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().
01534 { 01535 char *args = func_args(function); 01536 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01537 01538 if (acfptr == NULL) 01539 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01540 else if (!acfptr->read) 01541 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01542 else 01543 return acfptr->read(chan, function, args, workspace, len); 01544 return -1; 01545 }
int ast_func_write | ( | struct ast_channel * | chan, | |
char * | function, | |||
const char * | value | |||
) |
executes a write operation on a function
chan | Channel to execute on | |
function | Data containing the function call string (will be modified) | |
value | A value parameter to pass for writing |
Definition at line 1547 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().
01548 { 01549 char *args = func_args(function); 01550 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01551 01552 if (acfptr == NULL) 01553 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01554 else if (!acfptr->write) 01555 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01556 else 01557 return acfptr->write(chan, function, args, value); 01558 01559 return -1; 01560 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6178 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().
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6216 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06217 { 06218 return c ? c->registrar : NULL; 06219 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6246 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().
06247 { 06248 return e ? e->app : NULL; 06249 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6251 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06252 { 06253 return e ? e->data : NULL; 06254 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6241 of file pbx.c.
References ast_exten::cidmatch.
Referenced by find_matching_priority(), and handle_save_dialplan().
06242 { 06243 return e ? e->cidmatch : NULL; 06244 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) | [read] |
Definition at line 6183 of file pbx.c.
References ast_exten::parent.
Referenced by handle_show_hints().
06184 { 06185 return exten ? exten->parent : NULL; 06186 }
const char* ast_get_extension_label | ( | struct ast_exten * | exten | ) |
Definition at line 6193 of file pbx.c.
References ast_exten::label.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06194 { 06195 return exten ? exten->label : NULL; 06196 }
int ast_get_extension_matchcid | ( | struct ast_exten * | e | ) |
Definition at line 6236 of file pbx.c.
References ast_exten::matchcid.
Referenced by find_matching_priority(), and handle_save_dialplan().
06237 { 06238 return e ? e->matchcid : 0; 06239 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6188 of file pbx.c.
References ast_exten::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().
06189 { 06190 return exten ? exten->exten : NULL; 06191 }
int ast_get_extension_priority | ( | struct ast_exten * | exten | ) |
Definition at line 6208 of file pbx.c.
References ast_exten::priority.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), and print_ext().
06209 { 06210 return exten ? exten->priority : -1; 06211 }
const char* ast_get_extension_registrar | ( | struct ast_exten * | e | ) |
Definition at line 6221 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06222 { 06223 return e ? e->registrar : NULL; 06224 }
int ast_get_hint | ( | char * | hint, | |
int | hintsize, | |||
char * | name, | |||
int | namesize, | |||
struct ast_channel * | c, | |||
const char * | context, | |||
const char * | exten | |||
) |
ast_get_hint: Get hint for channel
If an extension exists, return non-zero.
Definition at line 2262 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(), manager_state_cb(), pbx_retrieve_variable(), and transmit_state_notify().
02263 { 02264 struct ast_exten *e = ast_hint_extension(c, context, exten); 02265 02266 if (e) { 02267 if (hint) 02268 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02269 if (name) { 02270 const char *tmp = ast_get_extension_app_data(e); 02271 if (tmp) 02272 ast_copy_string(name, tmp, namesize); 02273 } 02274 return -1; 02275 } 02276 return 0; 02277 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6203 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().
06204 { 06205 return ip ? ip->pattern : NULL; 06206 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6231 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06232 { 06233 return ip ? ip->registrar : NULL; 06234 }
const char* ast_get_include_name | ( | struct ast_include * | inc | ) |
Definition at line 6198 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().
06199 { 06200 return inc ? inc->name : NULL; 06201 }
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6226 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06227 { 06228 return i ? i->registrar : NULL; 06229 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6261 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06262 { 06263 return sw ? sw->data : NULL; 06264 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6256 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06257 { 06258 return sw ? sw->name : NULL; 06259 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6266 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06267 { 06268 return sw ? sw->registrar : NULL; 06269 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6355 of file pbx.c.
References __ast_goto_if_exists().
Referenced by aqm_exec(), auth_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().
06356 { 06357 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06358 }
static struct ast_exten* ast_hint_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten | |||
) | [static, read] |
ast_hint_extension: Find hint for given extension in context
Definition at line 1893 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(), ast_extension_state_add(), and ast_get_hint().
01894 { 01895 struct ast_exten *e; 01896 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */ 01897 01898 ast_rdlock_contexts(); 01899 e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH); 01900 ast_unlock_contexts(); 01901 01902 return e; 01903 }
void ast_hint_state_changed | ( | const char * | device, | |
char * | cid_num, | |||
char * | cid_name | |||
) |
Definition at line 2014 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_exten::exten, ast_hint::exten, ast_hint::laststate, ast_state_cb::next, ast_exten::parent, parse(), statecbs, and strsep().
Referenced by do_state_change().
02015 { 02016 struct ast_hint *hint; 02017 02018 AST_LIST_LOCK(&hints); 02019 02020 AST_LIST_TRAVERSE(&hints, hint, list) { 02021 struct ast_state_cb *cblist; 02022 char buf[AST_MAX_EXTENSION]; 02023 char *parse = buf; 02024 char *cur; 02025 int state; 02026 02027 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02028 while ( (cur = strsep(&parse, "&")) ) { 02029 if (!strcasecmp(cur, device)) 02030 break; 02031 } 02032 if (!cur) 02033 continue; 02034 02035 /* Get device state for this hint */ 02036 state = ast_extension_state2(hint->exten); 02037 02038 if ((state == -1) || (state == hint->laststate)) 02039 continue; 02040 02041 /* Device state changed since last check - notify the watchers */ 02042 02043 /* For general callbacks */ 02044 for (cblist = statecbs; cblist; cblist = cblist->next) 02045 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data, cid_num, cid_name); 02046 02047 /* For extension callbacks */ 02048 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02049 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data, cid_num, cid_name); 02050 02051 hint->laststate = state; /* record we saw the change */ 02052 } 02053 02054 AST_LIST_UNLOCK(&hints); 02055 }
int ast_ignore_pattern | ( | const char * | context, | |
const char * | pattern | |||
) |
Checks to see if a number should be ignored.
context | context to search within | |
pattern | to check whether it should be ignored or not |
0 | if the pattern should not be ignored | |
non-zero | if the pattern should be ignored |
Definition at line 4535 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().
04536 { 04537 struct ast_context *con = ast_context_find(context); 04538 if (con) { 04539 struct ast_ignorepat *pat; 04540 for (pat = con->ignorepats; pat; pat = pat->next) { 04541 if (ast_extension_match(pat->pattern, pattern)) 04542 return 1; 04543 } 04544 } 04545 04546 return 0; 04547 }
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.
con | context to lock |
0 | on success | |
-1 | on failure |
Definition at line 6165 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().
06166 { 06167 return ast_mutex_lock(&con->lock); 06168 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6142 of file pbx.c.
References ast_rwlock_wrlock().
Referenced by _macro_exec(), 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(), dundi_precache_full(), find_matching_endwhile(), and handle_save_dialplan().
06143 { 06144 return ast_rwlock_wrlock(&conlock); 06145 }
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).
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 |
Definition at line 2299 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().
02300 { 02301 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02302 }
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.
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 3929 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, context, contexts, ast_state_cb::data, E_MATCH, ast_exten::exten, ast_hint::exten, exten, free, ast_hint::laststate, LOG_DEBUG, LOG_WARNING, ast_state_cb::next, ast_context::next, option_debug, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.
Referenced by pbx_load_module().
03930 { 03931 struct ast_context *tmp, *lasttmp = NULL; 03932 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03933 struct store_hint *this; 03934 struct ast_hint *hint; 03935 struct ast_exten *exten; 03936 int length; 03937 struct ast_state_cb *thiscb, *prevcb; 03938 03939 /* it is very important that this function hold the hint list lock _and_ the conlock 03940 during its operation; not only do we need to ensure that the list of contexts 03941 and extensions does not change, but also that no hint callbacks (watchers) are 03942 added or removed during the merge/delete process 03943 03944 in addition, the locks _must_ be taken in this order, because there are already 03945 other code paths that use this order 03946 */ 03947 ast_wrlock_contexts(); 03948 AST_LIST_LOCK(&hints); 03949 03950 /* preserve all watchers for hints associated with this registrar */ 03951 AST_LIST_TRAVERSE(&hints, hint, list) { 03952 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03953 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03954 if (!(this = ast_calloc(1, length))) 03955 continue; 03956 this->callbacks = hint->callbacks; 03957 hint->callbacks = NULL; 03958 this->laststate = hint->laststate; 03959 this->context = this->data; 03960 strcpy(this->data, hint->exten->parent->name); 03961 this->exten = this->data + strlen(this->context) + 1; 03962 strcpy(this->exten, hint->exten->exten); 03963 AST_LIST_INSERT_HEAD(&store, this, list); 03964 } 03965 } 03966 03967 tmp = *extcontexts; 03968 if (registrar) { 03969 /* XXX remove previous contexts from same registrar */ 03970 if (option_debug) 03971 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 03972 __ast_context_destroy(NULL,registrar); 03973 while (tmp) { 03974 lasttmp = tmp; 03975 tmp = tmp->next; 03976 } 03977 } else { 03978 /* XXX remove contexts with the same name */ 03979 while (tmp) { 03980 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 03981 __ast_context_destroy(tmp,tmp->registrar); 03982 lasttmp = tmp; 03983 tmp = tmp->next; 03984 } 03985 } 03986 if (lasttmp) { 03987 lasttmp->next = contexts; 03988 contexts = *extcontexts; 03989 *extcontexts = NULL; 03990 } else 03991 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 03992 03993 /* restore the watchers for hints that can be found; notify those that 03994 cannot be restored 03995 */ 03996 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 03997 struct pbx_find_info q = { .stacklen = 0 }; 03998 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 03999 /* Find the hint in the list of hints */ 04000 AST_LIST_TRAVERSE(&hints, hint, list) { 04001 if (hint->exten == exten) 04002 break; 04003 } 04004 if (!exten || !hint) { 04005 /* this hint has been removed, notify the watchers */ 04006 prevcb = NULL; 04007 thiscb = this->callbacks; 04008 while (thiscb) { 04009 prevcb = thiscb; 04010 thiscb = thiscb->next; 04011 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data, NULL, NULL); 04012 free(prevcb); 04013 } 04014 } else { 04015 thiscb = this->callbacks; 04016 while (thiscb->next) 04017 thiscb = thiscb->next; 04018 thiscb->next = hint->callbacks; 04019 hint->callbacks = this->callbacks; 04020 hint->laststate = this->laststate; 04021 } 04022 free(this); 04023 } 04024 04025 AST_LIST_UNLOCK(&hints); 04026 ast_unlock_contexts(); 04027 04028 return; 04029 }
AST_MUTEX_DEFINE_STATIC | ( | maxcalllock | ) |
AST_MUTEX_DEFINE_STATIC | ( | globalslock | ) |
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6365 of file pbx.c.
References ast_cdr_update(), ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, exten, LOG_WARNING, ast_channel::priority, 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().
06366 { 06367 char *exten, *pri, *context; 06368 char *stringp; 06369 int ipri; 06370 int mode = 0; 06371 06372 if (ast_strlen_zero(goto_string)) { 06373 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06374 return -1; 06375 } 06376 stringp = ast_strdupa(goto_string); 06377 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06378 exten = strsep(&stringp, "|"); 06379 pri = strsep(&stringp, "|"); 06380 if (!exten) { /* Only a priority in this one */ 06381 pri = context; 06382 exten = NULL; 06383 context = NULL; 06384 } else if (!pri) { /* Only an extension and priority in this one */ 06385 pri = exten; 06386 exten = context; 06387 context = NULL; 06388 } 06389 if (*pri == '+') { 06390 mode = 1; 06391 pri++; 06392 } else if (*pri == '-') { 06393 mode = -1; 06394 pri++; 06395 } 06396 if (sscanf(pri, "%d", &ipri) != 1) { 06397 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06398 pri, chan->cid.cid_num)) < 1) { 06399 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06400 return -1; 06401 } else 06402 mode = 0; 06403 } 06404 /* At this point we have a priority and maybe an extension and a context */ 06405 06406 if (mode) 06407 ipri = chan->priority + (ipri * mode); 06408 06409 ast_explicit_goto(chan, context, exten, ipri); 06410 ast_cdr_update(chan); 06411 return 0; 06412 06413 }
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 5294 of file pbx.c.
References ast_pbx_outgoing_app2().
Referenced by attempt_thread(), and orig_app().
05295 { 05296 return ast_pbx_outgoing_app2(type, format, data, timeout, app, appdata, reason, sync, 0, cid_num, cid_name, vars, account, locked_channel, NULL); 05297 }
int ast_pbx_outgoing_app2 | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
const char * | app, | |||
const char * | appdata, | |||
int * | reason, | |||
int | sync, | |||
int | callingpres, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
struct ast_variable * | vars, | |||
const char * | account, | |||
struct ast_channel ** | locked_channel, | |||
char * | uniqueid | |||
) |
Synchronously or asynchronously make an outbound call and send it to a particular application with given extension (extended version with callinpres and uniqueid)
Definition at line 5151 of file pbx.c.
References __ast_request_and_dial(), ast_channel::_state, outgoing_helper::account, async_stat::app, app_tmp::app, async_stat::appdata, 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, app_tmp::chan, app_tmp::data, errno, free, ast_channel::hangupcause, LOG_WARNING, option_verbose, async_stat::p, ast_channel::pbx, app_tmp::t, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), ast_pbx_outgoing_app(), and fast_originate().
05152 { 05153 struct ast_channel *chan; 05154 struct app_tmp *tmp; 05155 int res = -1, cdr_res = -1; 05156 struct outgoing_helper oh; 05157 pthread_attr_t attr; 05158 05159 memset(&oh, 0, sizeof(oh)); 05160 oh.vars = vars; 05161 oh.account = account; 05162 05163 if (locked_channel) 05164 *locked_channel = NULL; 05165 if (ast_strlen_zero(app)) { 05166 res = -1; 05167 goto outgoing_app_cleanup; 05168 } 05169 if (sync) { 05170 chan = __ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid); 05171 if (chan) { 05172 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05173 ast_log(LOG_WARNING, "%s already has a call detail record??\n", chan->name); 05174 } else { 05175 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05176 if(!chan->cdr) { 05177 /* allocation of the cdr failed */ 05178 free(chan->pbx); 05179 res = -1; 05180 goto outgoing_app_cleanup; 05181 } 05182 /* allocation of the cdr was successful */ 05183 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05184 ast_cdr_start(chan->cdr); 05185 } 05186 ast_set_variables(chan, vars); 05187 if (account) 05188 ast_cdr_setaccount(chan, account); 05189 if (chan->_state == AST_STATE_UP) { 05190 res = 0; 05191 if (option_verbose > 3) 05192 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05193 tmp = ast_calloc(1, sizeof(*tmp)); 05194 if (!tmp) 05195 res = -1; 05196 else { 05197 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05198 if (appdata) 05199 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05200 tmp->chan = chan; 05201 if (sync > 1) { 05202 if (locked_channel) 05203 ast_channel_unlock(chan); 05204 ast_pbx_run_app(tmp); 05205 } else { 05206 pthread_attr_init(&attr); 05207 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05208 if (locked_channel) 05209 ast_channel_lock(chan); 05210 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05211 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05212 free(tmp); 05213 if (locked_channel) 05214 ast_channel_unlock(chan); 05215 ast_hangup(chan); 05216 res = -1; 05217 } else { 05218 if (locked_channel) 05219 *locked_channel = chan; 05220 } 05221 pthread_attr_destroy(&attr); 05222 } 05223 } 05224 } else { 05225 if (option_verbose > 3) 05226 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05227 if (chan->cdr) { /* update the cdr */ 05228 /* here we update the status of the call, which sould be busy. 05229 * if that fails then we set the status to failed */ 05230 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05231 ast_cdr_failed(chan->cdr); 05232 } 05233 ast_hangup(chan); 05234 } 05235 } 05236 05237 if (res < 0) { /* the call failed for some reason */ 05238 if (*reason == 0) { /* if the call failed (not busy or no answer) 05239 * update the cdr with the failed message */ 05240 cdr_res = ast_pbx_outgoing_cdr_failed(); 05241 if (cdr_res != 0) { 05242 res = cdr_res; 05243 goto outgoing_app_cleanup; 05244 } 05245 } 05246 } 05247 05248 } else { 05249 struct async_stat *as; 05250 if (!(as = ast_calloc(1, sizeof(*as)))) { 05251 res = -1; 05252 goto outgoing_app_cleanup; 05253 } 05254 chan = __ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid); 05255 if (!chan) { 05256 free(as); 05257 res = -1; 05258 goto outgoing_app_cleanup; 05259 } 05260 as->chan = chan; 05261 ast_copy_string(as->app, app, sizeof(as->app)); 05262 if (appdata) 05263 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05264 as->timeout = timeout; 05265 ast_set_variables(chan, vars); 05266 if (account) 05267 ast_cdr_setaccount(chan, account); 05268 /* Start a new thread, and get something handling this channel. */ 05269 pthread_attr_init(&attr); 05270 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05271 if (locked_channel) 05272 ast_channel_lock(chan); 05273 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05274 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05275 free(as); 05276 if (locked_channel) 05277 ast_channel_unlock(chan); 05278 ast_hangup(chan); 05279 res = -1; 05280 pthread_attr_destroy(&attr); 05281 goto outgoing_app_cleanup; 05282 } else { 05283 if (locked_channel) 05284 *locked_channel = chan; 05285 } 05286 pthread_attr_destroy(&attr); 05287 res = 0; 05288 } 05289 outgoing_app_cleanup: 05290 ast_variables_destroy(vars); 05291 return res; 05292 }
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 4963 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_app2(), and ast_pbx_outgoing_exten2().
04964 { 04965 /* allocate a channel */ 04966 struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0); 04967 04968 if (!chan) 04969 return -1; /* failure */ 04970 04971 if (!chan->cdr) { 04972 /* allocation of the cdr failed */ 04973 ast_channel_free(chan); /* free the channel */ 04974 return -1; /* return failure */ 04975 } 04976 04977 /* allocation of the cdr was successful */ 04978 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 04979 ast_cdr_start(chan->cdr); /* record the start and stop time */ 04980 ast_cdr_end(chan->cdr); 04981 ast_cdr_failed(chan->cdr); /* set the status to failed */ 04982 ast_cdr_detach(chan->cdr); /* post and free the record */ 04983 ast_channel_free(chan); /* free the channel */ 04984 04985 return 0; /* success */ 04986 }
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 5123 of file pbx.c.
References ast_pbx_outgoing_exten2().
Referenced by attempt_thread(), and orig_exten().
05124 { 05125 return ast_pbx_outgoing_exten2(type, format, data, timeout, context, exten, priority, reason, sync, 0, cid_num, cid_name, vars, account, channel, NULL); 05126 }
int ast_pbx_outgoing_exten2 | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
int * | reason, | |||
int | sync, | |||
int | callingpres, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
struct ast_variable * | vars, | |||
const char * | account, | |||
struct ast_channel ** | locked_channel, | |||
char * | uniqueid | |||
) |
Synchronously or asynchronously make an outbound call and send it to a particular extension (extended version with callinpres and uniqueid)
Definition at line 4988 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, async_stat::chan, async_stat::context, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, option_verbose, async_stat::p, pbx_builtin_setvar_helper(), set_ext_pri(), async_stat::timeout, and VERBOSE_PREFIX_4.
Referenced by action_originate(), ast_pbx_outgoing_exten(), and fast_originate().
04989 { 04990 struct ast_channel *chan; 04991 struct async_stat *as; 04992 int res = -1, cdr_res = -1; 04993 struct outgoing_helper oh; 04994 pthread_attr_t attr; 04995 04996 if (sync) { 04997 LOAD_OH(oh); 04998 chan = __ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, &oh, uniqueid); 04999 if (channel) { 05000 *channel = chan; 05001 if (chan) 05002 ast_channel_lock(chan); 05003 } 05004 if (chan) { 05005 if (chan->_state == AST_STATE_UP) { 05006 res = 0; 05007 if (option_verbose > 3) 05008 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05009 05010 if (sync > 1) { 05011 if (channel) 05012 ast_channel_unlock(chan); 05013 if (ast_pbx_run(chan)) { 05014 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05015 if (channel) 05016 *channel = NULL; 05017 ast_hangup(chan); 05018 res = -1; 05019 } 05020 } else { 05021 if (ast_pbx_start(chan)) { 05022 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05023 if (channel) { 05024 *channel = NULL; 05025 ast_channel_unlock(chan); 05026 } 05027 ast_hangup(chan); 05028 res = -1; 05029 } 05030 } 05031 } else { 05032 if (option_verbose > 3) 05033 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05034 05035 if (chan->cdr) { /* update the cdr */ 05036 /* here we update the status of the call, which sould be busy. 05037 * if that fails then we set the status to failed */ 05038 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05039 ast_cdr_failed(chan->cdr); 05040 } 05041 05042 if (channel) { 05043 *channel = NULL; 05044 ast_channel_unlock(chan); 05045 } 05046 ast_hangup(chan); 05047 } 05048 } 05049 05050 if (res < 0) { /* the call failed for some reason */ 05051 if (*reason == 0) { /* if the call failed (not busy or no answer) 05052 * update the cdr with the failed message */ 05053 cdr_res = ast_pbx_outgoing_cdr_failed(); 05054 if (cdr_res != 0) { 05055 res = cdr_res; 05056 goto outgoing_exten_cleanup; 05057 } 05058 } 05059 05060 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05061 /* check if "failed" exists */ 05062 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05063 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05064 if (chan) { 05065 char failed_reason[4] = ""; 05066 if (!ast_strlen_zero(context)) 05067 ast_copy_string(chan->context, context, sizeof(chan->context)); 05068 set_ext_pri(chan, "failed", 1); 05069 ast_set_variables(chan, vars); 05070 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05071 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05072 if (account) 05073 ast_cdr_setaccount(chan, account); 05074 ast_pbx_run(chan); 05075 } 05076 } 05077 } 05078 } else { 05079 if (!(as = ast_calloc(1, sizeof(*as)))) { 05080 res = -1; 05081 goto outgoing_exten_cleanup; 05082 } 05083 chan = ast_request_and_dial(type, format, data, timeout, reason, callingpres, cid_num, cid_name, uniqueid); 05084 if (channel) { 05085 *channel = chan; 05086 if (chan) 05087 ast_channel_lock(chan); 05088 } 05089 if (!chan) { 05090 free(as); 05091 res = -1; 05092 goto outgoing_exten_cleanup; 05093 } 05094 as->chan = chan; 05095 ast_copy_string(as->context, context, sizeof(as->context)); 05096 set_ext_pri(as->chan, exten, priority); 05097 as->timeout = timeout; 05098 ast_set_variables(chan, vars); 05099 if (account) 05100 ast_cdr_setaccount(chan, account); 05101 pthread_attr_init(&attr); 05102 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05103 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05104 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05105 free(as); 05106 if (channel) { 05107 *channel = NULL; 05108 ast_channel_unlock(chan); 05109 } 05110 ast_hangup(chan); 05111 res = -1; 05112 pthread_attr_destroy(&attr); 05113 goto outgoing_exten_cleanup; 05114 } 05115 pthread_attr_destroy(&attr); 05116 res = 0; 05117 } 05118 outgoing_exten_cleanup: 05119 ast_variables_destroy(vars); 05120 return res; 05121 }
enum ast_pbx_result ast_pbx_run | ( | struct ast_channel * | c | ) |
Execute the PBX in the current thread.
c | channel to run the pbx on |
Definition at line 2657 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_exten2(), async_wait(), mgcp_ss(), skinny_newcall(), and ss_thread().
02658 { 02659 enum ast_pbx_result res = AST_PBX_SUCCESS; 02660 02661 if (increase_call_count(c)) 02662 return AST_PBX_CALL_LIMIT; 02663 02664 res = __ast_pbx_run(c); 02665 decrease_call_count(); 02666 02667 return res; 02668 }
void* ast_pbx_run_app | ( | void * | data | ) |
run the application and free the descriptor once done
Definition at line 5135 of file pbx.c.
References app_tmp::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_app2().
05136 { 05137 struct app_tmp *tmp = data; 05138 struct ast_app *app; 05139 app = pbx_findapp(tmp->app); 05140 if (app) { 05141 if (option_verbose > 3) 05142 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05143 pbx_exec(tmp->chan, app, tmp->data); 05144 } else 05145 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05146 ast_hangup(tmp->chan); 05147 free(tmp); 05148 return NULL; 05149 }
enum ast_pbx_result ast_pbx_start | ( | struct ast_channel * | c | ) |
Create a new thread and start the PBX.
c | channel to start the pbx on |
Definition at line 2631 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_exten2(), 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().
02632 { 02633 pthread_t t; 02634 pthread_attr_t attr; 02635 02636 if (!c) { 02637 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02638 return AST_PBX_FAILED; 02639 } 02640 02641 if (increase_call_count(c)) 02642 return AST_PBX_CALL_LIMIT; 02643 02644 /* Start a new thread, and get something handling this channel. */ 02645 pthread_attr_init(&attr); 02646 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02647 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02648 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02649 pthread_attr_destroy(&attr); 02650 return AST_PBX_FAILED; 02651 } 02652 pthread_attr_destroy(&attr); 02653 02654 return AST_PBX_SUCCESS; 02655 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6147 of file pbx.c.
References ast_rwlock_rdlock().
Referenced by __ast_context_create(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), complete_show_dialplan_context(), find_context_locked(), pbx_extension_helper(), and show_dialplan_helper().
06148 { 06149 return ast_rwlock_rdlock(&conlock); 06150 }
int ast_register_application | ( | const char * | app, | |
int(*)(struct ast_channel *, void *) | execute, | |||
const char * | synopsis, | |||
const char * | description | |||
) |
Dynamically register a new dial plan application.
Register an application.
Definition at line 2959 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().
02960 { 02961 struct ast_app *tmp, *cur = NULL; 02962 char tmps[80]; 02963 int length; 02964 02965 AST_LIST_LOCK(&apps); 02966 AST_LIST_TRAVERSE(&apps, tmp, list) { 02967 if (!strcasecmp(app, tmp->name)) { 02968 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02969 AST_LIST_UNLOCK(&apps); 02970 return -1; 02971 } 02972 } 02973 02974 length = sizeof(*tmp) + strlen(app) + 1; 02975 02976 if (!(tmp = ast_calloc(1, length))) { 02977 AST_LIST_UNLOCK(&apps); 02978 return -1; 02979 } 02980 02981 strcpy(tmp->name, app); 02982 tmp->execute = execute; 02983 tmp->synopsis = synopsis; 02984 tmp->description = description; 02985 02986 /* Store in alphabetical order */ 02987 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 02988 if (strcasecmp(tmp->name, cur->name) < 0) { 02989 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 02990 break; 02991 } 02992 } 02993 AST_LIST_TRAVERSE_SAFE_END 02994 if (!cur) 02995 AST_LIST_INSERT_TAIL(&apps, tmp, list); 02996 02997 if (option_verbose > 1) 02998 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02999 03000 AST_LIST_UNLOCK(&apps); 03001 03002 return 0; 03003 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3009 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().
03010 { 03011 struct ast_switch *tmp; 03012 03013 AST_LIST_LOCK(&switches); 03014 AST_LIST_TRAVERSE(&switches, tmp, list) { 03015 if (!strcasecmp(tmp->name, sw->name)) { 03016 AST_LIST_UNLOCK(&switches); 03017 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03018 return -1; 03019 } 03020 } 03021 AST_LIST_INSERT_TAIL(&switches, sw, list); 03022 AST_LIST_UNLOCK(&switches); 03023 03024 return 0; 03025 }
static int ast_remove_hint | ( | struct ast_exten * | e | ) | [static] |
ast_remove_hint: Remove hint from extension
Definition at line 2225 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().
02226 { 02227 /* Cleanup the Notifys if hint is removed */ 02228 struct ast_hint *hint; 02229 struct ast_state_cb *cblist, *cbprev; 02230 int res = -1; 02231 02232 if (!e) 02233 return -1; 02234 02235 AST_LIST_LOCK(&hints); 02236 AST_LIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) { 02237 if (hint->exten == e) { 02238 cbprev = NULL; 02239 cblist = hint->callbacks; 02240 while (cblist) { 02241 /* Notify with -1 and remove all callbacks */ 02242 cbprev = cblist; 02243 cblist = cblist->next; 02244 cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data, NULL, NULL); 02245 free(cbprev); 02246 } 02247 hint->callbacks = NULL; 02248 AST_LIST_REMOVE_CURRENT(&hints, list); 02249 free(hint); 02250 res = 0; 02251 break; 02252 } 02253 } 02254 AST_LIST_TRAVERSE_SAFE_END 02255 AST_LIST_UNLOCK(&hints); 02256 02257 return res; 02258 }
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).
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 |
0 | on success | |
-1 | on failure. |
Definition at line 2304 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), and loopback_exec().
02305 { 02306 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02307 }
int ast_unlock_context | ( | struct ast_context * | con | ) |
Unlocks | the given context |
con | context to unlock |
0 | on success | |
-1 | on failure |
Definition at line 6170 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().
06171 { 06172 return ast_mutex_unlock(&con->lock); 06173 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6157 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().
06158 { 06159 return ast_rwlock_unlock(&conlock); 06160 }
int ast_unregister_application | ( | const char * | app | ) |
Unregister an application.
app | name of the application (does not have to be the same string as the one that was registered) |
0 | success | |
-1 | failure |
Definition at line 3840 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().
03841 { 03842 struct ast_app *tmp; 03843 03844 AST_LIST_LOCK(&apps); 03845 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03846 if (!strcasecmp(app, tmp->name)) { 03847 AST_LIST_REMOVE_CURRENT(&apps, list); 03848 if (option_verbose > 1) 03849 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03850 free(tmp); 03851 break; 03852 } 03853 } 03854 AST_LIST_TRAVERSE_SAFE_END 03855 AST_LIST_UNLOCK(&apps); 03856 03857 return tmp ? 0 : -1; 03858 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3027 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, and AST_LIST_UNLOCK.
Referenced by __unload_module(), and unload_module().
03028 { 03029 AST_LIST_LOCK(&switches); 03030 AST_LIST_REMOVE(&switches, sw, list); 03031 AST_LIST_UNLOCK(&switches); 03032 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | exten | |||
) | [read] |
Definition at line 6279 of file pbx.c.
References ast_exten::next, 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().
06281 { 06282 if (!exten) 06283 return con ? con->root : NULL; 06284 else 06285 return exten->next; 06286 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) | [read] |
Definition at line 6312 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().
06314 { 06315 if (!ip) 06316 return con ? con->ignorepats : NULL; 06317 else 06318 return ip->next; 06319 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) | [read] |
Definition at line 6303 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().
06305 { 06306 if (!inc) 06307 return con ? con->includes : NULL; 06308 else 06309 return inc->next; 06310 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) | [read] |
Definition at line 6288 of file pbx.c.
References AST_LIST_FIRST, and AST_LIST_NEXT.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06290 { 06291 if (!sw) 06292 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06293 else 06294 return AST_LIST_NEXT(sw, list); 06295 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) | [read] |
Definition at line 6274 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().
struct ast_exten* ast_walk_extension_priorities | ( | struct ast_exten * | exten, | |
struct ast_exten * | priority | |||
) | [read] |
Definition at line 6297 of file pbx.c.
References ast_exten::peer.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().
06299 { 06300 return priority ? priority->peer : exten; 06301 }
int ast_wrlock_contexts | ( | void | ) |
Definition at line 6152 of file pbx.c.
References ast_rwlock_wrlock().
Referenced by __ast_context_create(), ast_context_destroy(), and ast_merge_contexts_and_delete().
06153 { 06154 return ast_rwlock_wrlock(&conlock); 06155 }
static void* async_wait | ( | void * | data | ) | [static] |
Definition at line 4900 of file pbx.c.
References ast_channel::_state, 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, ast_frame::frametype, free, LOG_ERROR, LOG_WARNING, option_verbose, pbx_exec(), pbx_findapp(), ast_channel::priority, async_stat::priority, ast_frame::subclass, async_stat::timeout, and VERBOSE_PREFIX_3.
Referenced by ast_pbx_outgoing_app2(), and ast_pbx_outgoing_exten2().
04901 { 04902 struct async_stat *as = data; 04903 struct ast_channel *chan = as->chan; 04904 int timeout = as->timeout; 04905 int res; 04906 struct ast_frame *f; 04907 struct ast_app *app; 04908 04909 while (timeout && (chan->_state != AST_STATE_UP)) { 04910 res = ast_waitfor(chan, timeout); 04911 if (res < 1) 04912 break; 04913 if (timeout > -1) 04914 timeout = res; 04915 f = ast_read(chan); 04916 if (!f) 04917 break; 04918 if (f->frametype == AST_FRAME_CONTROL) { 04919 if ((f->subclass == AST_CONTROL_BUSY) || 04920 (f->subclass == AST_CONTROL_CONGESTION) ) { 04921 ast_frfree(f); 04922 break; 04923 } 04924 } 04925 ast_frfree(f); 04926 } 04927 if (chan->_state == AST_STATE_UP) { 04928 if (!ast_strlen_zero(as->app)) { 04929 app = pbx_findapp(as->app); 04930 if (app) { 04931 if (option_verbose > 2) 04932 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 04933 pbx_exec(chan, app, as->appdata); 04934 } else 04935 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 04936 } else { 04937 if (!ast_strlen_zero(as->context)) 04938 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 04939 if (!ast_strlen_zero(as->exten)) 04940 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 04941 if (as->priority > 0) 04942 chan->priority = as->priority; 04943 /* Run the PBX */ 04944 if (ast_pbx_run(chan)) { 04945 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 04946 } else { 04947 /* PBX will have taken care of this */ 04948 chan = NULL; 04949 } 04950 } 04951 } 04952 free(as); 04953 if (chan) 04954 ast_hangup(chan); 04955 return NULL; 04956 }
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 2322 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.
Referenced by __ast_pbx_run().
02323 { 02324 int digit; 02325 02326 buf[pos] = '\0'; /* make sure it is properly terminated */ 02327 while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) { 02328 /* As long as we're willing to wait, and as long as it's not defined, 02329 keep reading digits until we can't possibly get a right answer anymore. */ 02330 digit = ast_waitfordigit(c, waittime * 1000); 02331 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02332 c->_softhangup = 0; 02333 } else { 02334 if (!digit) /* No entry */ 02335 break; 02336 if (digit < 0) /* Error, maybe a hangup */ 02337 return -1; 02338 if (pos < buflen - 1) { /* XXX maybe error otherwise ? */ 02339 buf[pos++] = digit; 02340 buf[pos] = '\0'; 02341 } 02342 waittime = c->pbx->dtimeout; 02343 } 02344 } 02345 return 0; 02346 }
static char* complete_show_application | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3085 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and strdup.
03086 { 03087 struct ast_app *a; 03088 char *ret = NULL; 03089 int which = 0; 03090 int wordlen = strlen(word); 03091 03092 /* return the n-th [partial] matching entry */ 03093 AST_LIST_LOCK(&apps); 03094 AST_LIST_TRAVERSE(&apps, a, list) { 03095 if (!strncasecmp(word, a->name, wordlen) && ++which > state) { 03096 ret = strdup(a->name); 03097 break; 03098 } 03099 } 03100 AST_LIST_UNLOCK(&apps); 03101 03102 return ret; 03103 }
static char* complete_show_applications | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3446 of file pbx.c.
References ast_cli_complete().
03447 { 03448 static char* choices[] = { "like", "describing", NULL }; 03449 03450 return (pos != 3) ? NULL : ast_cli_complete(word, choices, state); 03451 }
static char* complete_show_applications_deprecated | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3439 of file pbx.c.
References ast_cli_complete().
03440 { 03441 static char* choices[] = { "like", "describing", NULL }; 03442 03443 return (pos != 2) ? NULL : ast_cli_complete(word, choices, state); 03444 }
static char* complete_show_dialplan_context | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3456 of file pbx.c.
References ast_get_context_name(), ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), and ast_walk_contexts().
03458 { 03459 struct ast_context *c = NULL; 03460 char *ret = NULL; 03461 int which = 0; 03462 int wordlen; 03463 03464 /* we are do completion of [exten@]context on second position only */ 03465 if (pos != 2) 03466 return NULL; 03467 03468 ast_rdlock_contexts(); 03469 03470 wordlen = strlen(word); 03471 03472 /* walk through all contexts and return the n-th match */ 03473 while ( (c = ast_walk_contexts(c)) ) { 03474 if (!strncasecmp(word, ast_get_context_name(c), wordlen) && ++which > state) { 03475 ret = ast_strdup(ast_get_context_name(c)); 03476 break; 03477 } 03478 } 03479 03480 ast_unlock_contexts(); 03481 03482 return ret; 03483 }
static char* complete_show_function | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1423 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_custom_function::name, and strdup.
01424 { 01425 struct ast_custom_function *acf; 01426 char *ret = NULL; 01427 int which = 0; 01428 int wordlen = strlen(word); 01429 01430 /* case-insensitive for convenience in this 'complete' function */ 01431 AST_LIST_LOCK(&acf_root); 01432 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01433 if (!strncasecmp(word, acf->name, wordlen) && ++which > state) { 01434 ret = strdup(acf->name); 01435 break; 01436 } 01437 } 01438 AST_LIST_UNLOCK(&acf_root); 01439 01440 return ret; 01441 }
static void decrease_call_count | ( | void | ) | [static] |
Definition at line 2593 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), and countcalls.
Referenced by ast_pbx_run(), and pbx_thread().
02594 { 02595 ast_mutex_lock(&maxcalllock); 02596 if (countcalls > 0) 02597 countcalls--; 02598 ast_mutex_unlock(&maxcalllock); 02599 }
static void destroy_exten | ( | struct ast_exten * | e | ) | [static] |
Definition at line 2601 of file pbx.c.
References ast_remove_hint(), ast_exten::data, ast_exten::datad, free, ast_exten::priority, and PRIORITY_HINT.
Referenced by __ast_context_destroy(), and ast_context_remove_extension2().
02602 { 02603 if (e->priority == PRIORITY_HINT) 02604 ast_remove_hint(e); 02605 02606 if (e->datad) 02607 e->datad(e->data); 02608 free(e); 02609 }
static int ext_cmp | ( | const char * | a, | |
const char * | b | |||
) | [static] |
the full routine to compare extensions in rules.
Definition at line 717 of file pbx.c.
References ext_cmp1().
Referenced by ast_add_extension2().
00718 { 00719 /* make sure non-patterns come first. 00720 * If a is not a pattern, it either comes first or 00721 * we use strcmp to compare the strings. 00722 */ 00723 int ret = 0; 00724 00725 if (a[0] != '_') 00726 return (b[0] == '_') ? -1 : strcmp(a, b); 00727 00728 /* Now we know a is a pattern; if b is not, a comes first */ 00729 if (b[0] != '_') 00730 return 1; 00731 #if 0 /* old mode for ext matching */ 00732 return strcmp(a, b); 00733 #endif 00734 /* ok we need full pattern sorting routine */ 00735 while (!ret && a && b) 00736 ret = ext_cmp1(&a) - ext_cmp1(&b); 00737 if (ret == 0) 00738 return 0; 00739 else 00740 return (ret > 0) ? 1 : -1; 00741 }
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 645 of file pbx.c.
References ast_log(), and LOG_WARNING.
Referenced by ext_cmp().
00646 { 00647 uint32_t chars[8]; 00648 int c, cmin = 0xff, count = 0; 00649 const char *end; 00650 00651 /* load, sign extend and advance pointer until we find 00652 * a valid character. 00653 */ 00654 while ( (c = *(*p)++) && (c == ' ' || c == '-') ) 00655 ; /* ignore some characters */ 00656 00657 /* always return unless we have a set of chars */ 00658 switch (c) { 00659 default: /* ordinary character */ 00660 return 0x0000 | (c & 0xff); 00661 00662 case 'N': /* 2..9 */ 00663 return 0x0700 | '2' ; 00664 00665 case 'X': /* 0..9 */ 00666 return 0x0900 | '0'; 00667 00668 case 'Z': /* 1..9 */ 00669 return 0x0800 | '1'; 00670 00671 case '.': /* wildcard */ 00672 return 0x10000; 00673 00674 case '!': /* earlymatch */ 00675 return 0x20000; /* less specific than NULL */ 00676 00677 case '\0': /* empty string */ 00678 *p = NULL; 00679 return 0x30000; 00680 00681 case '[': /* pattern */ 00682 break; 00683 } 00684 /* locate end of set */ 00685 end = strchr(*p, ']'); 00686 00687 if (end == NULL) { 00688 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n"); 00689 return 0x40000; /* XXX make this entry go last... */ 00690 } 00691 00692 bzero(chars, sizeof(chars)); /* clear all chars in the set */ 00693 for (; *p < end ; (*p)++) { 00694 unsigned char c1, c2; /* first-last char in range */ 00695 c1 = (unsigned char)((*p)[0]); 00696 if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */ 00697 c2 = (unsigned char)((*p)[2]); 00698 *p += 2; /* skip a total of 3 chars */ 00699 } else /* individual character */ 00700 c2 = c1; 00701 if (c1 < cmin) 00702 cmin = c1; 00703 for (; c1 <= c2; c1++) { 00704 uint32_t mask = 1 << (c1 % 32); 00705 if ( (chars[ c1 / 32 ] & mask) == 0) 00706 count += 0x100; 00707 chars[ c1 / 32 ] |= mask; 00708 } 00709 } 00710 (*p)++; 00711 return count == 0 ? 0x30000 : (count | cmin); 00712 }
static int ext_strncpy | ( | char * | dst, | |
const char * | src, | |||
int | len | |||
) | [static] |
copy a string skipping whitespace
Definition at line 4652 of file pbx.c.
Referenced by ast_add_extension2().
04653 { 04654 int count=0; 04655 04656 while (*src && (count < len - 1)) { 04657 switch(*src) { 04658 case ' ': 04659 /* otherwise exten => [a-b],1,... doesn't work */ 04660 /* case '-': */ 04661 /* Ignore */ 04662 break; 04663 default: 04664 *dst = *src; 04665 dst++; 04666 } 04667 src++; 04668 count++; 04669 } 04670 *dst = '\0'; 04671 04672 return count; 04673 }
static int extension_match_core | ( | const char * | pattern, | |
const char * | data, | |||
enum ext_match_t | mode | |||
) | [static] |
Definition at line 866 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().
00867 { 00868 int i; 00869 static int prof_id = -2; /* marker for 'unallocated' id */ 00870 if (prof_id == -2) 00871 prof_id = ast_add_profile("ext_match", 0); 00872 ast_mark(prof_id, 1); 00873 i = _extension_match_core(pattern, data, mode); 00874 ast_mark(prof_id, 0); 00875 return i; 00876 }
static struct ast_context* find_context_locked | ( | const char * | context | ) | [static, read] |
Definition at line 2685 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().
02686 { 02687 struct ast_context *c = NULL; 02688 02689 ast_rdlock_contexts(); 02690 while ( (c = ast_walk_contexts(c)) ) { 02691 if (!strcmp(ast_get_context_name(c), context)) 02692 return c; 02693 } 02694 ast_unlock_contexts(); 02695 02696 return NULL; 02697 }
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 1516 of file pbx.c.
References ast_log(), and LOG_WARNING.
Referenced by ast_func_read(), and ast_func_write().
01517 { 01518 char *args = strchr(function, '('); 01519 01520 if (!args) 01521 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01522 else { 01523 char *p; 01524 *args++ = '\0'; 01525 if ((p = strrchr(args, ')')) ) 01526 *p = '\0'; 01527 else 01528 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01529 } 01530 return args; 01531 }
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 4070 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, lookup_name(), and s.
Referenced by ast_build_timing().
04071 { 04072 int s, e; /* start and ending position */ 04073 unsigned int mask = 0; 04074 04075 /* Check for whole range */ 04076 if (ast_strlen_zero(src) || !strcmp(src, "*")) { 04077 s = 0; 04078 e = max - 1; 04079 } else { 04080 /* Get start and ending position */ 04081 char *c = strchr(src, '-'); 04082 if (c) 04083 *c++ = '\0'; 04084 /* Find the start */ 04085 s = lookup_name(src, names, max); 04086 if (!s) { 04087 ast_log(LOG_WARNING, "Invalid %s '%s', assuming none\n", msg, src); 04088 return 0; 04089 } 04090 s--; 04091 if (c) { /* find end of range */ 04092 e = lookup_name(c, names, max); 04093 if (!e) { 04094 ast_log(LOG_WARNING, "Invalid end %s '%s', assuming none\n", msg, c); 04095 return 0; 04096 } 04097 e--; 04098 } else 04099 e = s; 04100 } 04101 /* Fill the mask. Remember that ranges are cyclic */ 04102 mask = 1 << e; /* initialize with last element */ 04103 while (s != e) { 04104 if (s >= max) { 04105 s = 0; 04106 mask |= (1 << s); 04107 } else { 04108 mask |= (1 << s); 04109 s++; 04110 } 04111 } 04112 return mask; 04113 }
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 4116 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask.
Referenced by ast_build_timing().
04117 { 04118 char *e; 04119 int x; 04120 int s1, s2; 04121 int e1, e2; 04122 /* int cth, ctm; */ 04123 04124 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 04125 memset(i->minmask, 0, sizeof(i->minmask)); 04126 04127 /* 2-minutes per bit, since the mask has only 32 bits :( */ 04128 /* Star is all times */ 04129 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 04130 for (x=0; x<24; x++) 04131 i->minmask[x] = 0x3fffffff; /* 30 bits */ 04132 return; 04133 } 04134 /* Otherwise expect a range */ 04135 e = strchr(times, '-'); 04136 if (!e) { 04137 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n"); 04138 return; 04139 } 04140 *e++ = '\0'; 04141 /* XXX why skip non digits ? */ 04142 while (*e && !isdigit(*e)) 04143 e++; 04144 if (!*e) { 04145 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n"); 04146 return; 04147 } 04148 if (sscanf(times, "%d:%d", &s1, &s2) != 2) { 04149 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times); 04150 return; 04151 } 04152 if (sscanf(e, "%d:%d", &e1, &e2) != 2) { 04153 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e); 04154 return; 04155 } 04156 /* XXX this needs to be optimized */ 04157 #if 1 04158 s1 = s1 * 30 + s2/2; 04159 if ((s1 < 0) || (s1 >= 24*30)) { 04160 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times); 04161 return; 04162 } 04163 e1 = e1 * 30 + e2/2; 04164 if ((e1 < 0) || (e1 >= 24*30)) { 04165 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e); 04166 return; 04167 } 04168 /* Go through the time and enable each appropriate bit */ 04169 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) { 04170 i->minmask[x/30] |= (1 << (x % 30)); 04171 } 04172 /* Do the last one */ 04173 i->minmask[x/30] |= (1 << (x % 30)); 04174 #else 04175 for (cth=0; cth<24; cth++) { 04176 /* Initialize masks to blank */ 04177 i->minmask[cth] = 0; 04178 for (ctm=0; ctm<30; ctm++) { 04179 if ( 04180 /* First hour with more than one hour */ 04181 (((cth == s1) && (ctm >= s2)) && 04182 ((cth < e1))) 04183 /* Only one hour */ 04184 || (((cth == s1) && (ctm >= s2)) && 04185 ((cth == e1) && (ctm <= e2))) 04186 /* In between first and last hours (more than 2 hours) */ 04187 || ((cth > s1) && 04188 (cth < e1)) 04189 /* Last hour with more than one hour */ 04190 || ((cth > s1) && 04191 ((cth == e1) && (ctm <= e2))) 04192 ) 04193 i->minmask[cth] |= (1 << (ctm / 2)); 04194 } 04195 } 04196 #endif 04197 /* All done */ 04198 return; 04199 }
static int handle_set_global | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3741 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03742 { 03743 if (argc != 5) 03744 return RESULT_SHOWUSAGE; 03745 03746 pbx_builtin_setvar_helper(NULL, argv[3], argv[4]); 03747 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[3], argv[4]); 03748 03749 return RESULT_SUCCESS; 03750 }
static int handle_set_global_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI support for setting global variables.
Definition at line 3729 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03730 { 03731 if (argc != 4) 03732 return RESULT_SHOWUSAGE; 03733 03734 pbx_builtin_setvar_helper(NULL, argv[2], argv[3]); 03735 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[2], argv[3]); 03736 03737 return RESULT_SUCCESS; 03738 }
static int handle_show_application | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3175 of file pbx.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_APP, COLOR_CYAN, COLOR_MAGENTA, ast_app::description, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_app::synopsis, and term_color().
03176 { 03177 struct ast_app *a; 03178 int app, no_registered_app = 1; 03179 03180 if (argc < 4) 03181 return RESULT_SHOWUSAGE; 03182 03183 /* ... go through all applications ... */ 03184 AST_LIST_LOCK(&apps); 03185 AST_LIST_TRAVERSE(&apps, a, list) { 03186 /* ... compare this application name with all arguments given 03187 * to 'show application' command ... */ 03188 for (app = 3; app < argc; app++) { 03189 if (!strcasecmp(a->name, argv[app])) { 03190 /* Maximum number of characters added by terminal coloring is 22 */ 03191 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03192 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03193 int synopsis_size, description_size; 03194 03195 no_registered_app = 0; 03196 03197 if (a->synopsis) 03198 synopsis_size = strlen(a->synopsis) + 23; 03199 else 03200 synopsis_size = strlen("Not available") + 23; 03201 synopsis = alloca(synopsis_size); 03202 03203 if (a->description) 03204 description_size = strlen(a->description) + 23; 03205 else 03206 description_size = strlen("Not available") + 23; 03207 description = alloca(description_size); 03208 03209 if (synopsis && description) { 03210 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03211 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03212 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03213 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03214 term_color(synopsis, 03215 a->synopsis ? a->synopsis : "Not available", 03216 COLOR_CYAN, 0, synopsis_size); 03217 term_color(description, 03218 a->description ? a->description : "Not available", 03219 COLOR_CYAN, 0, description_size); 03220 03221 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03222 } else { 03223 /* ... one of our applications, show info ...*/ 03224 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03225 "[Synopsis]\n %s\n\n" 03226 "[Description]\n%s\n", 03227 a->name, 03228 a->synopsis ? a->synopsis : "Not available", 03229 a->description ? a->description : "Not available"); 03230 } 03231 } 03232 } 03233 } 03234 AST_LIST_UNLOCK(&apps); 03235 03236 /* we found at least one app? no? */ 03237 if (no_registered_app) { 03238 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03239 return RESULT_FAILURE; 03240 } 03241 03242 return RESULT_SUCCESS; 03243 }
static int handle_show_application_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3105 of file pbx.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_APP, COLOR_CYAN, COLOR_MAGENTA, ast_app::description, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_app::synopsis, and term_color().
03106 { 03107 struct ast_app *a; 03108 int app, no_registered_app = 1; 03109 03110 if (argc < 3) 03111 return RESULT_SHOWUSAGE; 03112 03113 /* ... go through all applications ... */ 03114 AST_LIST_LOCK(&apps); 03115 AST_LIST_TRAVERSE(&apps, a, list) { 03116 /* ... compare this application name with all arguments given 03117 * to 'show application' command ... */ 03118 for (app = 2; app < argc; app++) { 03119 if (!strcasecmp(a->name, argv[app])) { 03120 /* Maximum number of characters added by terminal coloring is 22 */ 03121 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03122 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03123 int synopsis_size, description_size; 03124 03125 no_registered_app = 0; 03126 03127 if (a->synopsis) 03128 synopsis_size = strlen(a->synopsis) + 23; 03129 else 03130 synopsis_size = strlen("Not available") + 23; 03131 synopsis = alloca(synopsis_size); 03132 03133 if (a->description) 03134 description_size = strlen(a->description) + 23; 03135 else 03136 description_size = strlen("Not available") + 23; 03137 description = alloca(description_size); 03138 03139 if (synopsis && description) { 03140 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03141 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03142 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03143 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03144 term_color(synopsis, 03145 a->synopsis ? a->synopsis : "Not available", 03146 COLOR_CYAN, 0, synopsis_size); 03147 term_color(description, 03148 a->description ? a->description : "Not available", 03149 COLOR_CYAN, 0, description_size); 03150 03151 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03152 } else { 03153 /* ... one of our applications, show info ...*/ 03154 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03155 "[Synopsis]\n %s\n\n" 03156 "[Description]\n%s\n", 03157 a->name, 03158 a->synopsis ? a->synopsis : "Not available", 03159 a->description ? a->description : "Not available"); 03160 } 03161 } 03162 } 03163 } 03164 AST_LIST_UNLOCK(&apps); 03165 03166 /* we found at least one app? no? */ 03167 if (no_registered_app) { 03168 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03169 return RESULT_FAILURE; 03170 } 03171 03172 return RESULT_SUCCESS; 03173 }
static int handle_show_applications | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3370 of file pbx.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::description, RESULT_SUCCESS, strcasestr(), and ast_app::synopsis.
03371 { 03372 struct ast_app *a; 03373 int like = 0, describing = 0; 03374 int total_match = 0; /* Number of matches in like clause */ 03375 int total_apps = 0; /* Number of apps registered */ 03376 03377 AST_LIST_LOCK(&apps); 03378 03379 if (AST_LIST_EMPTY(&apps)) { 03380 ast_cli(fd, "There are no registered applications\n"); 03381 AST_LIST_UNLOCK(&apps); 03382 return -1; 03383 } 03384 03385 /* core list applications like <keyword> */ 03386 if ((argc == 5) && (!strcmp(argv[3], "like"))) { 03387 like = 1; 03388 } else if ((argc > 4) && (!strcmp(argv[3], "describing"))) { 03389 describing = 1; 03390 } 03391 03392 /* core list applications describing <keyword1> [<keyword2>] [...] */ 03393 if ((!like) && (!describing)) { 03394 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03395 } else { 03396 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03397 } 03398 03399 AST_LIST_TRAVERSE(&apps, a, list) { 03400 int printapp = 0; 03401 total_apps++; 03402 if (like) { 03403 if (strcasestr(a->name, argv[4])) { 03404 printapp = 1; 03405 total_match++; 03406 } 03407 } else if (describing) { 03408 if (a->description) { 03409 /* Match all words on command line */ 03410 int i; 03411 printapp = 1; 03412 for (i = 4; i < argc; i++) { 03413 if (!strcasestr(a->description, argv[i])) { 03414 printapp = 0; 03415 } else { 03416 total_match++; 03417 } 03418 } 03419 } 03420 } else { 03421 printapp = 1; 03422 } 03423 03424 if (printapp) { 03425 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03426 } 03427 } 03428 if ((!like) && (!describing)) { 03429 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03430 } else { 03431 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03432 } 03433 03434 AST_LIST_UNLOCK(&apps); 03435 03436 return RESULT_SUCCESS; 03437 }
static int handle_show_applications_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3302 of file pbx.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::description, RESULT_SUCCESS, strcasestr(), and ast_app::synopsis.
03303 { 03304 struct ast_app *a; 03305 int like = 0, describing = 0; 03306 int total_match = 0; /* Number of matches in like clause */ 03307 int total_apps = 0; /* Number of apps registered */ 03308 03309 AST_LIST_LOCK(&apps); 03310 03311 if (AST_LIST_EMPTY(&apps)) { 03312 ast_cli(fd, "There are no registered applications\n"); 03313 AST_LIST_UNLOCK(&apps); 03314 return -1; 03315 } 03316 03317 /* show applications like <keyword> */ 03318 if ((argc == 4) && (!strcmp(argv[2], "like"))) { 03319 like = 1; 03320 } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { 03321 describing = 1; 03322 } 03323 03324 /* show applications describing <keyword1> [<keyword2>] [...] */ 03325 if ((!like) && (!describing)) { 03326 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03327 } else { 03328 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03329 } 03330 03331 AST_LIST_TRAVERSE(&apps, a, list) { 03332 int printapp = 0; 03333 total_apps++; 03334 if (like) { 03335 if (strcasestr(a->name, argv[3])) { 03336 printapp = 1; 03337 total_match++; 03338 } 03339 } else if (describing) { 03340 if (a->description) { 03341 /* Match all words on command line */ 03342 int i; 03343 printapp = 1; 03344 for (i = 3; i < argc; i++) { 03345 if (!strcasestr(a->description, argv[i])) { 03346 printapp = 0; 03347 } else { 03348 total_match++; 03349 } 03350 } 03351 } 03352 } else { 03353 printapp = 1; 03354 } 03355 03356 if (printapp) { 03357 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03358 } 03359 } 03360 if ((!like) && (!describing)) { 03361 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03362 } else { 03363 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03364 } 03365 03366 AST_LIST_UNLOCK(&apps); 03367 03368 return RESULT_SUCCESS; 03369 }
static int handle_show_dialplan | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3656 of file pbx.c.
References ast_cli(), AST_PBX_MAX_STACK, ast_strdupa, ast_strlen_zero(), context, dialplan_counters::context_existence, exten, dialplan_counters::extension_existence, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, show_dialplan_helper(), strsep(), dialplan_counters::total_context, dialplan_counters::total_exten, and dialplan_counters::total_prio.
03657 { 03658 char *exten = NULL, *context = NULL; 03659 /* Variables used for different counters */ 03660 struct dialplan_counters counters; 03661 03662 const char *incstack[AST_PBX_MAX_STACK]; 03663 memset(&counters, 0, sizeof(counters)); 03664 03665 if (argc != 2 && argc != 3) 03666 return RESULT_SHOWUSAGE; 03667 03668 /* we obtain [exten@]context? if yes, split them ... */ 03669 if (argc == 3) { 03670 if (strchr(argv[2], '@')) { /* split into exten & context */ 03671 context = ast_strdupa(argv[2]); 03672 exten = strsep(&context, "@"); 03673 /* change empty strings to NULL */ 03674 if (ast_strlen_zero(exten)) 03675 exten = NULL; 03676 } else { /* no '@' char, only context given */ 03677 context = argv[2]; 03678 } 03679 if (ast_strlen_zero(context)) 03680 context = NULL; 03681 } 03682 /* else Show complete dial plan, context and exten are NULL */ 03683 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03684 03685 /* check for input failure and throw some error messages */ 03686 if (context && !counters.context_existence) { 03687 ast_cli(fd, "There is no existence of '%s' context\n", context); 03688 return RESULT_FAILURE; 03689 } 03690 03691 if (exten && !counters.extension_existence) { 03692 if (context) 03693 ast_cli(fd, "There is no existence of %s@%s extension\n", 03694 exten, context); 03695 else 03696 ast_cli(fd, 03697 "There is no existence of '%s' extension in all contexts\n", 03698 exten); 03699 return RESULT_FAILURE; 03700 } 03701 03702 ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", 03703 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions", 03704 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities", 03705 counters.total_context, counters.total_context == 1 ? "context" : "contexts"); 03706 03707 /* everything ok */ 03708 return RESULT_SUCCESS; 03709 }
static int handle_show_function | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1367 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().
01368 { 01369 struct ast_custom_function *acf; 01370 /* Maximum number of characters added by terminal coloring is 22 */ 01371 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01372 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01373 char stxtitle[40], *syntax = NULL; 01374 int synopsis_size, description_size, syntax_size; 01375 01376 if (argc < 4) 01377 return RESULT_SHOWUSAGE; 01378 01379 if (!(acf = ast_custom_function_find(argv[3]))) { 01380 ast_cli(fd, "No function by that name registered.\n"); 01381 return RESULT_FAILURE; 01382 01383 } 01384 01385 if (acf->synopsis) 01386 synopsis_size = strlen(acf->synopsis) + 23; 01387 else 01388 synopsis_size = strlen("Not available") + 23; 01389 synopsis = alloca(synopsis_size); 01390 01391 if (acf->desc) 01392 description_size = strlen(acf->desc) + 23; 01393 else 01394 description_size = strlen("Not available") + 23; 01395 description = alloca(description_size); 01396 01397 if (acf->syntax) 01398 syntax_size = strlen(acf->syntax) + 23; 01399 else 01400 syntax_size = strlen("Not available") + 23; 01401 syntax = alloca(syntax_size); 01402 01403 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01404 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01405 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01406 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01407 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01408 term_color(syntax, 01409 acf->syntax ? acf->syntax : "Not available", 01410 COLOR_CYAN, 0, syntax_size); 01411 term_color(synopsis, 01412 acf->synopsis ? acf->synopsis : "Not available", 01413 COLOR_CYAN, 0, synopsis_size); 01414 term_color(description, 01415 acf->desc ? acf->desc : "Not available", 01416 COLOR_CYAN, 0, description_size); 01417 01418 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01419 01420 return RESULT_SUCCESS; 01421 }
static int handle_show_function_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1311 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().
01312 { 01313 struct ast_custom_function *acf; 01314 /* Maximum number of characters added by terminal coloring is 22 */ 01315 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01316 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01317 char stxtitle[40], *syntax = NULL; 01318 int synopsis_size, description_size, syntax_size; 01319 01320 if (argc < 3) 01321 return RESULT_SHOWUSAGE; 01322 01323 if (!(acf = ast_custom_function_find(argv[2]))) { 01324 ast_cli(fd, "No function by that name registered.\n"); 01325 return RESULT_FAILURE; 01326 01327 } 01328 01329 if (acf->synopsis) 01330 synopsis_size = strlen(acf->synopsis) + 23; 01331 else 01332 synopsis_size = strlen("Not available") + 23; 01333 synopsis = alloca(synopsis_size); 01334 01335 if (acf->desc) 01336 description_size = strlen(acf->desc) + 23; 01337 else 01338 description_size = strlen("Not available") + 23; 01339 description = alloca(description_size); 01340 01341 if (acf->syntax) 01342 syntax_size = strlen(acf->syntax) + 23; 01343 else 01344 syntax_size = strlen("Not available") + 23; 01345 syntax = alloca(syntax_size); 01346 01347 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01348 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01349 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01350 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01351 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01352 term_color(syntax, 01353 acf->syntax ? acf->syntax : "Not available", 01354 COLOR_CYAN, 0, syntax_size); 01355 term_color(synopsis, 01356 acf->synopsis ? acf->synopsis : "Not available", 01357 COLOR_CYAN, 0, synopsis_size); 01358 term_color(description, 01359 acf->desc ? acf->desc : "Not available", 01360 COLOR_CYAN, 0, description_size); 01361 01362 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01363 01364 return RESULT_SUCCESS; 01365 }
static int handle_show_functions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1283 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.
01284 { 01285 struct ast_custom_function *acf; 01286 int count_acf = 0; 01287 int like = 0; 01288 01289 if (argc == 5 && (!strcmp(argv[3], "like")) ) { 01290 like = 1; 01291 } else if (argc != 3) { 01292 return RESULT_SHOWUSAGE; 01293 } 01294 01295 ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed"); 01296 01297 AST_LIST_LOCK(&acf_root); 01298 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01299 if (!like || strstr(acf->name, argv[4])) { 01300 count_acf++; 01301 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01302 } 01303 } 01304 AST_LIST_UNLOCK(&acf_root); 01305 01306 ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : ""); 01307 01308 return RESULT_SUCCESS; 01309 }
static int handle_show_functions_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1256 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.
01257 { 01258 struct ast_custom_function *acf; 01259 int count_acf = 0; 01260 int like = 0; 01261 01262 if (argc == 4 && (!strcmp(argv[2], "like")) ) { 01263 like = 1; 01264 } else if (argc != 2) { 01265 return RESULT_SHOWUSAGE; 01266 } 01267 01268 ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed"); 01269 01270 AST_LIST_LOCK(&acf_root); 01271 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01272 if (!like || strstr(acf->name, argv[3])) { 01273 count_acf++; 01274 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01275 } 01276 } 01277 AST_LIST_UNLOCK(&acf_root); 01278 01279 ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : ""); 01280 01281 return RESULT_SUCCESS; 01282 }
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 3712 of file pbx.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), globals, and RESULT_SUCCESS.
03713 { 03714 int i = 0; 03715 struct ast_var_t *newvariable; 03716 03717 ast_mutex_lock(&globalslock); 03718 AST_LIST_TRAVERSE (&globals, newvariable, entries) { 03719 i++; 03720 ast_cli(fd, " %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable)); 03721 } 03722 ast_mutex_unlock(&globalslock); 03723 ast_cli(fd, "\n -- %d variables\n", i); 03724 03725 return RESULT_SUCCESS; 03726 }
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 3246 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.
03247 { 03248 struct ast_hint *hint; 03249 int num = 0; 03250 int watchers; 03251 struct ast_state_cb *watcher; 03252 03253 if (AST_LIST_EMPTY(&hints)) { 03254 ast_cli(fd, "There are no registered dialplan hints\n"); 03255 return RESULT_SUCCESS; 03256 } 03257 /* ... we have hints ... */ 03258 ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); 03259 AST_LIST_LOCK(&hints); 03260 AST_LIST_TRAVERSE(&hints, hint, list) { 03261 watchers = 0; 03262 for (watcher = hint->callbacks; watcher; watcher = watcher->next) 03263 watchers++; 03264 ast_cli(fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", 03265 ast_get_extension_name(hint->exten), 03266 ast_get_context_name(ast_get_extension_context(hint->exten)), 03267 ast_get_extension_app(hint->exten), 03268 ast_extension_state2str(hint->laststate), watchers); 03269 num++; 03270 } 03271 ast_cli(fd, "----------------\n"); 03272 ast_cli(fd, "- %d hints registered\n", num); 03273 AST_LIST_UNLOCK(&hints); 03274 return RESULT_SUCCESS; 03275 }
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 3278 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.
03279 { 03280 struct ast_switch *sw; 03281 03282 AST_LIST_LOCK(&switches); 03283 03284 if (AST_LIST_EMPTY(&switches)) { 03285 AST_LIST_UNLOCK(&switches); 03286 ast_cli(fd, "There are no registered alternative switches\n"); 03287 return RESULT_SUCCESS; 03288 } 03289 03290 ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); 03291 AST_LIST_TRAVERSE(&switches, sw, list) 03292 ast_cli(fd, "%s: %s\n", sw->name, sw->description); 03293 03294 AST_LIST_UNLOCK(&switches); 03295 03296 return RESULT_SUCCESS; 03297 }
static int include_valid | ( | struct ast_include * | i | ) | [inline, static] |
Definition at line 576 of file pbx.c.
References ast_check_timing(), ast_include::hastime, and ast_include::timing.
Referenced by pbx_find_extension().
00577 { 00578 if (!i->hastime) 00579 return 1; 00580 00581 return ast_check_timing(&(i->timing)); 00582 }
static int increase_call_count | ( | const struct ast_channel * | c | ) | [static] |
Definition at line 2568 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().
02569 { 02570 int failed = 0; 02571 double curloadavg; 02572 ast_mutex_lock(&maxcalllock); 02573 if (option_maxcalls) { 02574 if (countcalls >= option_maxcalls) { 02575 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name); 02576 failed = -1; 02577 } 02578 } 02579 if (option_maxload) { 02580 getloadavg(&curloadavg, 1); 02581 if (curloadavg >= option_maxload) { 02582 ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg); 02583 failed = -1; 02584 } 02585 } 02586 if (!failed) 02587 countcalls++; 02588 ast_mutex_unlock(&maxcalllock); 02589 02590 return failed; 02591 }
int load_pbx | ( | void | ) |
Provided by pbx.c
Definition at line 6116 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().
06117 { 06118 int x; 06119 06120 /* Initialize the PBX */ 06121 if (option_verbose) { 06122 ast_verbose( "Asterisk PBX Core Initializing\n"); 06123 ast_verbose( "Registering builtin applications:\n"); 06124 } 06125 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(struct ast_cli_entry)); 06126 06127 /* Register builtin applications */ 06128 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06129 if (option_verbose) 06130 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06131 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06132 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06133 return -1; 06134 } 06135 } 06136 return 0; 06137 }
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 4052 of file pbx.c.
Referenced by get_range().
04053 { 04054 int i; 04055 04056 if (names) { 04057 for (i = 0; names[i]; i++) { 04058 if (!strcasecmp(s, names[i])) 04059 return i+1; 04060 } 04061 } else if (sscanf(s, "%d", &i) == 1 && i >= 1 && i <= max) { 04062 return i; 04063 } 04064 return 0; /* error return */ 04065 }
static int matchcid | ( | const char * | cidpattern, | |
const char * | callerid | |||
) | [static] |
Definition at line 912 of file pbx.c.
References ast_extension_match(), and ast_strlen_zero().
Referenced by pbx_find_extension().
00913 { 00914 /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so 00915 failing to get a number should count as a match, otherwise not */ 00916 00917 if (ast_strlen_zero(callerid)) 00918 return ast_strlen_zero(cidpattern) ? 1 : 0; 00919 00920 return ast_extension_match(cidpattern, callerid); 00921 }
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 1072 of file pbx.c.
Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
01073 { 01074 int parens=0; 01075 01076 *offset = 0; 01077 *length = INT_MAX; 01078 *isfunc = 0; 01079 for (; *var; var++) { 01080 if (*var == '(') { 01081 (*isfunc)++; 01082 parens++; 01083 } else if (*var == ')') { 01084 parens--; 01085 } else if (*var == ':' && parens == 0) { 01086 *var++ = '\0'; 01087 sscanf(var, "%d:%d", offset, length); 01088 return 1; /* offset:length valid */ 01089 } 01090 } 01091 return 0; 01092 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6003 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), ast_var_delete(), and globals.
Referenced by handle_reload_extensions(), and reload().
06004 { 06005 struct ast_var_t *vardata; 06006 06007 ast_mutex_lock(&globalslock); 06008 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06009 ast_var_delete(vardata); 06010 ast_mutex_unlock(&globalslock); 06011 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5780 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), globals, and ast_channel::varshead.
Referenced by __ast_pbx_run(), __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(), 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().
05781 { 05782 struct ast_var_t *variables; 05783 const char *ret = NULL; 05784 int i; 05785 struct varshead *places[2] = { NULL, &globals }; 05786 05787 if (!name) 05788 return NULL; 05789 05790 if (chan) { 05791 ast_channel_lock(chan); 05792 places[0] = &chan->varshead; 05793 } 05794 05795 for (i = 0; i < 2; i++) { 05796 if (!places[i]) 05797 continue; 05798 if (places[i] == &globals) 05799 ast_mutex_lock(&globalslock); 05800 AST_LIST_TRAVERSE(places[i], variables, entries) { 05801 if (!strcmp(name, ast_var_name(variables))) { 05802 ret = ast_var_value(variables); 05803 break; 05804 } 05805 } 05806 if (places[i] == &globals) 05807 ast_mutex_unlock(&globalslock); 05808 if (ret) 05809 break; 05810 } 05811 05812 if (chan) 05813 ast_channel_unlock(chan); 05814 05815 return ret; 05816 }
static int pbx_builtin_gotoif | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 6023 of file pbx.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_DEBUG, LOG_WARNING, option_debug, pbx_builtin_goto(), pbx_checkcondition(), and strsep().
06024 { 06025 char *condition, *branch1, *branch2, *branch; 06026 int rc; 06027 char *stringp; 06028 06029 if (ast_strlen_zero(data)) { 06030 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06031 return 0; 06032 } 06033 06034 stringp = ast_strdupa(data); 06035 condition = strsep(&stringp,"?"); 06036 branch1 = strsep(&stringp,":"); 06037 branch2 = strsep(&stringp,""); 06038 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06039 06040 if (ast_strlen_zero(branch)) { 06041 if (option_debug) 06042 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06043 return 0; 06044 } 06045 06046 rc = pbx_builtin_goto(chan, branch); 06047 06048 return rc; 06049 }
int pbx_builtin_importvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5942 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.
05943 { 05944 char *name; 05945 char *value; 05946 char *channel; 05947 char tmp[VAR_BUF_SIZE]=""; 05948 05949 if (ast_strlen_zero(data)) { 05950 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 05951 return 0; 05952 } 05953 05954 value = ast_strdupa(data); 05955 name = strsep(&value,"="); 05956 channel = strsep(&value,"|"); 05957 if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */ 05958 struct ast_channel *chan2 = ast_get_channel_by_name_locked(channel); 05959 if (chan2) { 05960 char *s = alloca(strlen(value) + 4); 05961 if (s) { 05962 sprintf(s, "${%s}", value); 05963 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 05964 } 05965 ast_channel_unlock(chan2); 05966 } 05967 pbx_builtin_setvar_helper(chan, name, tmp); 05968 } 05969 05970 return(0); 05971 }
static int pbx_builtin_noop | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
void pbx_builtin_pushvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5818 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_verbose(), globals, LOG_WARNING, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.
Referenced by acf_odbc_read(), acf_odbc_write(), and gosub_exec().
05819 { 05820 struct ast_var_t *newvariable; 05821 struct varshead *headp; 05822 05823 if (name[strlen(name)-1] == ')') { 05824 char *function = ast_strdupa(name); 05825 05826 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05827 ast_func_write(chan, function, value); 05828 return; 05829 } 05830 05831 if (chan) { 05832 ast_channel_lock(chan); 05833 headp = &chan->varshead; 05834 } else { 05835 ast_mutex_lock(&globalslock); 05836 headp = &globals; 05837 } 05838 05839 if (value) { 05840 if ((option_verbose > 1) && (headp == &globals)) 05841 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05842 newvariable = ast_var_assign(name, value); 05843 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05844 } 05845 05846 if (chan) 05847 ast_channel_unlock(chan); 05848 else 05849 ast_mutex_unlock(&globalslock); 05850 }
static int pbx_builtin_saycharacters | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 6090 of file pbx.c.
References ast_channel::_state, ast_answer(), ast_say_character_str(), and AST_STATE_UP.
06091 { 06092 int res = 0; 06093 06094 if (data) { 06095 if (chan->_state != AST_STATE_UP) { 06096 ast_answer(chan); 06097 } 06098 res = ast_say_character_str(chan, data, "", chan->language); 06099 } 06100 return res; 06101 }
static int pbx_builtin_saydigits | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 6077 of file pbx.c.
References ast_channel::_state, ast_answer(), ast_say_digit_str(), and AST_STATE_UP.
06078 { 06079 int res = 0; 06080 06081 if (data) { 06082 if (chan->_state != AST_STATE_UP) { 06083 ast_answer(chan); 06084 } 06085 res = ast_say_digit_str(chan, data, "", chan->language); 06086 } 06087 return res; 06088 }
static int pbx_builtin_saynumber | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 6051 of file pbx.c.
References ast_channel::_state, ast_answer(), ast_log(), ast_say_number(), AST_STATE_UP, ast_strlen_zero(), LOG_WARNING, and strsep().
06052 { 06053 char tmp[256]; 06054 char *number = tmp; 06055 char *options; 06056 06057 if (ast_strlen_zero(data)) { 06058 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06059 return -1; 06060 } 06061 ast_copy_string(tmp, data, sizeof(tmp)); 06062 strsep(&number, "|"); 06063 options = strsep(&number, "|"); 06064 if (options) { 06065 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06066 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06067 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06068 return -1; 06069 } 06070 } 06071 if (chan->_state != AST_STATE_UP) { 06072 ast_answer(chan); 06073 } 06074 return ast_say_number(chan, atoi(tmp), "", chan->language, options); 06075 }
static int pbx_builtin_sayphonetic | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 6103 of file pbx.c.
References ast_channel::_state, ast_answer(), ast_say_phonetic_str(), and AST_STATE_UP.
06104 { 06105 int res = 0; 06106 06107 if (data) { 06108 if (chan->_state != AST_STATE_UP) { 06109 ast_answer(chan); 06110 } 06111 res = ast_say_phonetic_str(chan, data, "", chan->language); 06112 } 06113 return res; 06114 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5749 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().
05750 { 05751 struct ast_var_t *variables; 05752 const char *var, *val; 05753 int total = 0; 05754 05755 if (!chan) 05756 return 0; 05757 05758 memset(buf, 0, size); 05759 05760 ast_channel_lock(chan); 05761 05762 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05763 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05764 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05765 ) { 05766 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05767 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05768 break; 05769 } else 05770 total++; 05771 } else 05772 break; 05773 } 05774 05775 ast_channel_unlock(chan); 05776 05777 return total; 05778 }
static int pbx_builtin_setglobalvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5974 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, pbx_builtin_setvar_helper(), and strsep().
05975 { 05976 char *name; 05977 char *stringp = data; 05978 static int dep_warning = 0; 05979 05980 if (ast_strlen_zero(data)) { 05981 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 05982 return 0; 05983 } 05984 05985 name = strsep(&stringp, "="); 05986 05987 if (!dep_warning) { 05988 dep_warning = 1; 05989 ast_log(LOG_WARNING, "SetGlobalVar is deprecated. Please use Set(GLOBAL(%s)=%s) instead.\n", name, stringp); 05990 } 05991 05992 /*! \todo XXX watch out, leading whitespace ? */ 05993 pbx_builtin_setvar_helper(NULL, name, stringp); 05994 05995 return(0); 05996 }
int pbx_builtin_setvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) |
Definition at line 5902 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().
05903 { 05904 char *name, *value, *mydata; 05905 int argc; 05906 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 05907 int global = 0; 05908 int x; 05909 05910 if (ast_strlen_zero(data)) { 05911 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 05912 return 0; 05913 } 05914 05915 mydata = ast_strdupa(data); 05916 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 05917 05918 /* check for a trailing flags argument */ 05919 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 05920 argc--; 05921 if (strchr(argv[argc], 'g')) { 05922 ast_log(LOG_WARNING, "The use of the 'g' flag is deprecated. Please use Set(GLOBAL(foo)=bar) instead\n"); 05923 global = 1; 05924 } 05925 } 05926 05927 if (argc > 1) 05928 ast_log(LOG_WARNING, "Setting multiple variables at once within Set is deprecated. Please separate each name/value pair into its own line.\n"); 05929 05930 for (x = 0; x < argc; x++) { 05931 name = argv[x]; 05932 if ((value = strchr(name, '='))) { 05933 *value++ = '\0'; 05934 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 05935 } else 05936 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 05937 } 05938 05939 return(0); 05940 }
void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5852 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), globals, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2.
Referenced by __ast_pbx_run(), __login_exec(), __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_exten2(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), conf_run(), 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_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().
05853 { 05854 struct ast_var_t *newvariable; 05855 struct varshead *headp; 05856 const char *nametail = name; 05857 05858 if (name[strlen(name)-1] == ')') { 05859 char *function = ast_strdupa(name); 05860 05861 ast_func_write(chan, function, value); 05862 return; 05863 } 05864 05865 if (chan) { 05866 ast_channel_lock(chan); 05867 headp = &chan->varshead; 05868 } else { 05869 ast_mutex_lock(&globalslock); 05870 headp = &globals; 05871 } 05872 05873 /* For comparison purposes, we have to strip leading underscores */ 05874 if (*nametail == '_') { 05875 nametail++; 05876 if (*nametail == '_') 05877 nametail++; 05878 } 05879 05880 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05881 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05882 /* there is already such a variable, delete it */ 05883 AST_LIST_REMOVE(headp, newvariable, entries); 05884 ast_var_delete(newvariable); 05885 break; 05886 } 05887 } 05888 05889 if (value) { 05890 if ((option_verbose > 1) && (headp == &globals)) 05891 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05892 newvariable = ast_var_assign(name, value); 05893 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05894 } 05895 05896 if (chan) 05897 ast_channel_unlock(chan); 05898 else 05899 ast_mutex_unlock(&globalslock); 05900 }
int pbx_checkcondition | ( | const char * | condition | ) |
Evaluate a condition.
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 6013 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().
06014 { 06015 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06016 return 0; 06017 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06018 return atoi(condition); 06019 else /* Strings are true */ 06020 return 1; 06021 }
static void pbx_destroy | ( | struct ast_pbx * | p | ) | [static] |
Definition at line 584 of file pbx.c.
References free.
Referenced by __ast_pbx_run().
00585 { 00586 free(p); 00587 }
int pbx_exec | ( | struct ast_channel * | c, | |
struct ast_app * | app, | |||
void * | data | |||
) |
Execute an application.
c | channel to execute on | |
app | which app to execute | |
data | the data passed into the app |
c | Channel |
app | Application |
data | Data for execution |
Definition at line 510 of file pbx.c.
References ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, ast_channel::data, and ast_app::execute.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00513 { 00514 int res; 00515 00516 const char *saved_c_appl; 00517 const char *saved_c_data; 00518 00519 if (c->cdr && !ast_check_hangup(c)) 00520 ast_cdr_setapp(c->cdr, app->name, data); 00521 00522 /* save channel values */ 00523 saved_c_appl= c->appl; 00524 saved_c_data= c->data; 00525 00526 c->appl = app->name; 00527 c->data = data; 00528 /* XXX remember what to to when we have linked apps to modules */ 00529 if (app->module) { 00530 /* XXX LOCAL_USER_ADD(app->module) */ 00531 } 00532 res = app->execute(c, data); 00533 if (app->module) { 00534 /* XXX LOCAL_USER_REMOVE(app->module) */ 00535 } 00536 /* restore channel values */ 00537 c->appl = saved_c_appl; 00538 c->data = saved_c_data; 00539 return res; 00540 }
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.
Definition at line 1795 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().
01798 { 01799 struct ast_exten *e; 01800 struct ast_app *app; 01801 int res; 01802 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */ 01803 char passdata[EXT_DATA_SIZE]; 01804 01805 int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE); 01806 01807 ast_rdlock_contexts(); 01808 e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action); 01809 if (e) { 01810 if (matching_action) { 01811 ast_unlock_contexts(); 01812 return -1; /* success, we found it */ 01813 } else if (action == E_FINDLABEL) { /* map the label to a priority */ 01814 res = e->priority; 01815 ast_unlock_contexts(); 01816 return res; /* the priority we were looking for */ 01817 } else { /* spawn */ 01818 app = pbx_findapp(e->app); 01819 ast_unlock_contexts(); 01820 if (!app) { 01821 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority); 01822 return -1; 01823 } 01824 if (c->context != context) 01825 ast_copy_string(c->context, context, sizeof(c->context)); 01826 if (c->exten != exten) 01827 ast_copy_string(c->exten, exten, sizeof(c->exten)); 01828 c->priority = priority; 01829 pbx_substitute_variables(passdata, sizeof(passdata), c, e); 01830 if (option_debug) { 01831 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name); 01832 } 01833 if (option_verbose > 2) { 01834 char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE]; 01835 ast_verbose( VERBOSE_PREFIX_3 "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n", 01836 exten, context, priority, 01837 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)), 01838 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 01839 term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)), 01840 "in new stack"); 01841 } 01842 manager_event(EVENT_FLAG_CALL, "Newexten", 01843 "Channel: %s\r\n" 01844 "Context: %s\r\n" 01845 "Extension: %s\r\n" 01846 "Priority: %d\r\n" 01847 "Application: %s\r\n" 01848 "AppData: %s\r\n" 01849 "Uniqueid: %s\r\n", 01850 c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid); 01851 return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */ 01852 } 01853 } else if (q.swo) { /* not found here, but in another switch */ 01854 ast_unlock_contexts(); 01855 if (matching_action) { 01856 return -1; 01857 } else { 01858 if (!q.swo->exec) { 01859 ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name); 01860 res = -1; 01861 } 01862 return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data); 01863 } 01864 } else { /* not found anywhere, see what happened */ 01865 ast_unlock_contexts(); 01866 switch (q.status) { 01867 case STATUS_NO_CONTEXT: 01868 if (!matching_action) 01869 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context); 01870 break; 01871 case STATUS_NO_EXTENSION: 01872 if (!matching_action) 01873 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context); 01874 break; 01875 case STATUS_NO_PRIORITY: 01876 if (!matching_action) 01877 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context); 01878 break; 01879 case STATUS_NO_LABEL: 01880 if (context) 01881 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context); 01882 break; 01883 default: 01884 if (option_debug) 01885 ast_log(LOG_DEBUG, "Shouldn't happen!\n"); 01886 } 01887 01888 return (matching_action) ? 0 : -1; 01889 } 01890 }
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, read] |
Definition at line 939 of file pbx.c.
References ast_autoservice_start(), ast_autoservice_stop(), AST_LIST_TRAVERSE, ast_log(), AST_PBX_MAX_STACK, ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), ast_switch::canmatch, ast_exten::cidmatch, ast_sw::data, pbx_find_info::data, E_CANMATCH, E_FINDLABEL, E_MATCHMORE, ast_sw::eval, ast_switch::exists, ast_exten::exten, extension_match_core(), pbx_find_info::foundcontext, include_valid(), ast_context::includes, pbx_find_info::incstack, ast_exten::label, LOG_WARNING, match(), matchcid(), ast_exten::matchcid, ast_switch::matchmore, ast_sw::name, ast_include::next, pbx_findswitch(), pbx_substitute_variables_helper(), ast_exten::priority, ast_include::rname, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, STATUS_SUCCESS, SWITCH_DATA_LENGTH, and pbx_find_info::swo.
Referenced by ast_hint_extension(), ast_merge_contexts_and_delete(), and pbx_extension_helper().
00943 { 00944 int x, res; 00945 struct ast_context *tmp; 00946 struct ast_exten *e, *eroot; 00947 struct ast_include *i; 00948 struct ast_sw *sw; 00949 00950 /* Initialize status if appropriate */ 00951 if (q->stacklen == 0) { 00952 q->status = STATUS_NO_CONTEXT; 00953 q->swo = NULL; 00954 q->data = NULL; 00955 q->foundcontext = NULL; 00956 } 00957 /* Check for stack overflow */ 00958 if (q->stacklen >= AST_PBX_MAX_STACK) { 00959 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n"); 00960 return NULL; 00961 } 00962 /* Check first to see if we've already been checked */ 00963 for (x = 0; x < q->stacklen; x++) { 00964 if (!strcasecmp(q->incstack[x], context)) 00965 return NULL; 00966 } 00967 if (bypass) /* bypass means we only look there */ 00968 tmp = bypass; 00969 else { /* look in contexts */ 00970 tmp = NULL; 00971 while ((tmp = ast_walk_contexts(tmp)) ) { 00972 if (!strcmp(tmp->name, context)) 00973 break; 00974 } 00975 if (!tmp) 00976 return NULL; 00977 } 00978 if (q->status < STATUS_NO_EXTENSION) 00979 q->status = STATUS_NO_EXTENSION; 00980 00981 /* scan the list trying to match extension and CID */ 00982 eroot = NULL; 00983 while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) { 00984 int match = extension_match_core(eroot->exten, exten, action); 00985 /* 0 on fail, 1 on match, 2 on earlymatch */ 00986 00987 if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid))) 00988 continue; /* keep trying */ 00989 if (match == 2 && action == E_MATCHMORE) { 00990 /* We match an extension ending in '!'. 00991 * The decision in this case is final and is NULL (no match). 00992 */ 00993 return NULL; 00994 } 00995 /* found entry, now look for the right priority */ 00996 if (q->status < STATUS_NO_PRIORITY) 00997 q->status = STATUS_NO_PRIORITY; 00998 e = NULL; 00999 while ( (e = ast_walk_extension_priorities(eroot, e)) ) { 01000 /* Match label or priority */ 01001 if (action == E_FINDLABEL) { 01002 if (q->status < STATUS_NO_LABEL) 01003 q->status = STATUS_NO_LABEL; 01004 if (label && e->label && !strcmp(label, e->label)) 01005 break; /* found it */ 01006 } else if (e->priority == priority) { 01007 break; /* found it */ 01008 } /* else keep searching */ 01009 } 01010 if (e) { /* found a valid match */ 01011 q->status = STATUS_SUCCESS; 01012 q->foundcontext = context; 01013 return e; 01014 } 01015 } 01016 /* Check alternative switches */ 01017 AST_LIST_TRAVERSE(&tmp->alts, sw, list) { 01018 struct ast_switch *asw = pbx_findswitch(sw->name); 01019 ast_switch_f *aswf = NULL; 01020 char *datap; 01021 01022 if (!asw) { 01023 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); 01024 continue; 01025 } 01026 /* Substitute variables now */ 01027 if (sw->eval) 01028 pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1); 01029 01030 /* equivalent of extension_match_core() at the switch level */ 01031 if (action == E_CANMATCH) 01032 aswf = asw->canmatch; 01033 else if (action == E_MATCHMORE) 01034 aswf = asw->matchmore; 01035 else /* action == E_MATCH */ 01036 aswf = asw->exists; 01037 datap = sw->eval ? sw->tmpdata : sw->data; 01038 if (!aswf) 01039 res = 0; 01040 else { 01041 if (chan) 01042 ast_autoservice_start(chan); 01043 res = aswf(chan, context, exten, priority, callerid, datap); 01044 if (chan) 01045 ast_autoservice_stop(chan); 01046 } 01047 if (res) { /* Got a match */ 01048 q->swo = asw; 01049 q->data = datap; 01050 q->foundcontext = context; 01051 /* XXX keep status = STATUS_NO_CONTEXT ? */ 01052 return NULL; 01053 } 01054 } 01055 q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */ 01056 /* Now try any includes we have in this context */ 01057 for (i = tmp->includes; i; i = i->next) { 01058 if (include_valid(i)) { 01059 if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) 01060 return e; 01061 if (q->swo) 01062 return NULL; 01063 } 01064 } 01065 return NULL; 01066 }
struct ast_app* pbx_findapp | ( | const char * | app | ) | [read] |
Find application handle in linked list.
Look up an application.
Definition at line 548 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(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00549 { 00550 struct ast_app *tmp; 00551 00552 AST_LIST_LOCK(&apps); 00553 AST_LIST_TRAVERSE(&apps, tmp, list) { 00554 if (!strcasecmp(tmp->name, app)) 00555 break; 00556 } 00557 AST_LIST_UNLOCK(&apps); 00558 00559 return tmp; 00560 }
static struct ast_switch* pbx_findswitch | ( | const char * | sw | ) | [static, read] |
Definition at line 562 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_switch::name.
Referenced by pbx_find_extension().
00563 { 00564 struct ast_switch *asw; 00565 00566 AST_LIST_LOCK(&switches); 00567 AST_LIST_TRAVERSE(&switches, asw, list) { 00568 if (!strcasecmp(asw->name, sw)) 00569 break; 00570 } 00571 AST_LIST_UNLOCK(&switches); 00572 00573 return asw; 00574 }
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 ---
Definition at line 1140 of file pbx.c.
References 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, globals, ast_channel::hangupcause, offset, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::varshead.
Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full().
01141 { 01142 const char not_found = '\0'; 01143 char *tmpvar; 01144 const char *s; /* the result */ 01145 int offset, length; 01146 int i, need_substring; 01147 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 01148 01149 if (c) { 01150 ast_channel_lock(c); 01151 places[0] = &c->varshead; 01152 } 01153 /* 01154 * Make a copy of var because parse_variable_name() modifies the string. 01155 * Then if called directly, we might need to run substring() on the result; 01156 * remember this for later in 'need_substring', 'offset' and 'length' 01157 */ 01158 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 01159 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 01160 01161 /* 01162 * Look first into predefined variables, then into variable lists. 01163 * Variable 's' points to the result, according to the following rules: 01164 * s == ¬_found (set at the beginning) means that we did not find a 01165 * matching variable and need to look into more places. 01166 * If s != ¬_found, s is a valid result string as follows: 01167 * s = NULL if the variable does not have a value; 01168 * you typically do this when looking for an unset predefined variable. 01169 * s = workspace if the result has been assembled there; 01170 * typically done when the result is built e.g. with an snprintf(), 01171 * so we don't need to do an additional copy. 01172 * s != workspace in case we have a string, that needs to be copied 01173 * (the ast_copy_string is done once for all at the end). 01174 * Typically done when the result is already available in some string. 01175 */ 01176 s = ¬_found; /* default value */ 01177 if (c) { /* This group requires a valid channel */ 01178 /* Names with common parts are looked up a piece at a time using strncmp. */ 01179 if (!strncmp(var, "CALL", 4)) { 01180 if (!strncmp(var + 4, "ING", 3)) { 01181 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 01182 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01183 s = workspace; 01184 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 01185 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01186 s = workspace; 01187 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 01188 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01189 s = workspace; 01190 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 01191 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01192 s = workspace; 01193 } 01194 } 01195 } else if (!strcmp(var, "HINT")) { 01196 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 01197 } else if (!strcmp(var, "HINTNAME")) { 01198 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 01199 } else if (!strcmp(var, "EXTEN")) { 01200 s = c->exten; 01201 } else if (!strcmp(var, "CONTEXT")) { 01202 s = c->context; 01203 } else if (!strcmp(var, "PRIORITY")) { 01204 snprintf(workspace, workspacelen, "%d", c->priority); 01205 s = workspace; 01206 } else if (!strcmp(var, "CHANNEL")) { 01207 s = c->name; 01208 } else if (!strcmp(var, "UNIQUEID")) { 01209 s = c->uniqueid; 01210 } else if (!strcmp(var, "HANGUPCAUSE")) { 01211 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01212 s = workspace; 01213 } 01214 } 01215 if (s == ¬_found) { /* look for more */ 01216 if (!strcmp(var, "EPOCH")) { 01217 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01218 s = workspace; 01219 } else if (!strcmp(var, "SYSTEMNAME")) { 01220 s = ast_config_AST_SYSTEM_NAME; 01221 } 01222 } 01223 /* if not found, look into chanvars or global vars */ 01224 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) { 01225 struct ast_var_t *variables; 01226 if (!places[i]) 01227 continue; 01228 if (places[i] == &globals) 01229 ast_mutex_lock(&globalslock); 01230 AST_LIST_TRAVERSE(places[i], variables, entries) { 01231 if (strcasecmp(ast_var_name(variables), var)==0) { 01232 s = ast_var_value(variables); 01233 break; 01234 } 01235 } 01236 if (places[i] == &globals) 01237 ast_mutex_unlock(&globalslock); 01238 } 01239 if (s == ¬_found || s == NULL) 01240 *ret = NULL; 01241 else { 01242 if (s != workspace) 01243 ast_copy_string(workspace, s, workspacelen); 01244 *ret = workspace; 01245 if (need_substring) 01246 *ret = substring(*ret, offset, length, workspace, workspacelen); 01247 } 01248 01249 if (c) 01250 ast_channel_unlock(c); 01251 }
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 2675 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02676 { 02677 int oldval = autofallthrough; 02678 autofallthrough = newval; 02679 return oldval; 02680 }
static void pbx_substitute_variables | ( | char * | passdata, | |
int | datalen, | |||
struct ast_channel * | c, | |||
struct ast_exten * | e | |||
) | [static] |
Definition at line 1766 of file pbx.c.
References ast_exten::data, and pbx_substitute_variables_helper().
Referenced by pbx_extension_helper().
01767 { 01768 memset(passdata, 0, datalen); 01769 01770 /* No variables or expressions in e->data, so why scan it? */ 01771 if (e->data && !strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) { 01772 ast_copy_string(passdata, e->data, datalen); 01773 return; 01774 } 01775 01776 pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1); 01777 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1756 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_find_extension(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), rpt_exec(), sendpage(), try_calling(), and tryexec_exec().
01757 { 01758 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01759 }
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 1562 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().
01563 { 01564 /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be 01565 zero-filled */ 01566 char *cp4; 01567 const char *tmp, *whereweare; 01568 int length, offset, offset2, isfunction; 01569 char *workspace = NULL; 01570 char *ltmp = NULL, *var = NULL; 01571 char *nextvar, *nextexp, *nextthing; 01572 char *vars, *vare; 01573 int pos, brackets, needsub, len; 01574 01575 whereweare=tmp=cp1; 01576 while (!ast_strlen_zero(whereweare) && count) { 01577 /* Assume we're copying the whole remaining string */ 01578 pos = strlen(whereweare); 01579 nextvar = NULL; 01580 nextexp = NULL; 01581 nextthing = strchr(whereweare, '$'); 01582 if (nextthing) { 01583 switch(nextthing[1]) { 01584 case '{': 01585 nextvar = nextthing; 01586 pos = nextvar - whereweare; 01587 break; 01588 case '[': 01589 nextexp = nextthing; 01590 pos = nextexp - whereweare; 01591 break; 01592 default: 01593 pos = 1; 01594 } 01595 } 01596 01597 if (pos) { 01598 /* Can't copy more than 'count' bytes */ 01599 if (pos > count) 01600 pos = count; 01601 01602 /* Copy that many bytes */ 01603 memcpy(cp2, whereweare, pos); 01604 01605 count -= pos; 01606 cp2 += pos; 01607 whereweare += pos; 01608 } 01609 01610 if (nextvar) { 01611 /* We have a variable. Find the start and end, and determine 01612 if we are going to have to recursively call ourselves on the 01613 contents */ 01614 vars = vare = nextvar + 2; 01615 brackets = 1; 01616 needsub = 0; 01617 01618 /* Find the end of it */ 01619 while (brackets && *vare) { 01620 if ((vare[0] == '$') && (vare[1] == '{')) { 01621 needsub++; 01622 } else if (vare[0] == '{') { 01623 brackets++; 01624 } else if (vare[0] == '}') { 01625 brackets--; 01626 } else if ((vare[0] == '$') && (vare[1] == '[')) 01627 needsub++; 01628 vare++; 01629 } 01630 if (brackets) 01631 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n"); 01632 len = vare - vars - 1; 01633 01634 /* Skip totally over variable string */ 01635 whereweare += (len + 3); 01636 01637 if (!var) 01638 var = alloca(VAR_BUF_SIZE); 01639 01640 /* Store variable name (and truncate) */ 01641 ast_copy_string(var, vars, len + 1); 01642 01643 /* Substitute if necessary */ 01644 if (needsub) { 01645 if (!ltmp) 01646 ltmp = alloca(VAR_BUF_SIZE); 01647 01648 memset(ltmp, 0, VAR_BUF_SIZE); 01649 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01650 vars = ltmp; 01651 } else { 01652 vars = var; 01653 } 01654 01655 if (!workspace) 01656 workspace = alloca(VAR_BUF_SIZE); 01657 01658 workspace[0] = '\0'; 01659 01660 parse_variable_name(vars, &offset, &offset2, &isfunction); 01661 if (isfunction) { 01662 /* Evaluate function */ 01663 if (c || !headp) 01664 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace; 01665 else { 01666 struct varshead old; 01667 struct ast_channel *c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/%p", vars); 01668 if (c) { 01669 memcpy(&old, &c->varshead, sizeof(old)); 01670 memcpy(&c->varshead, headp, sizeof(c->varshead)); 01671 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace; 01672 /* Don't deallocate the varshead that was passed in */ 01673 memcpy(&c->varshead, &old, sizeof(c->varshead)); 01674 ast_channel_free(c); 01675 } else 01676 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 01677 } 01678 01679 if (option_debug) 01680 ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)"); 01681 } else { 01682 /* Retrieve variable value */ 01683 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp); 01684 } 01685 if (cp4) { 01686 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE); 01687 01688 length = strlen(cp4); 01689 if (length > count) 01690 length = count; 01691 memcpy(cp2, cp4, length); 01692 count -= length; 01693 cp2 += length; 01694 } 01695 } else if (nextexp) { 01696 /* We have an expression. Find the start and end, and determine 01697 if we are going to have to recursively call ourselves on the 01698 contents */ 01699 vars = vare = nextexp + 2; 01700 brackets = 1; 01701 needsub = 0; 01702 01703 /* Find the end of it */ 01704 while(brackets && *vare) { 01705 if ((vare[0] == '$') && (vare[1] == '[')) { 01706 needsub++; 01707 brackets++; 01708 vare++; 01709 } else if (vare[0] == '[') { 01710 brackets++; 01711 } else if (vare[0] == ']') { 01712 brackets--; 01713 } else if ((vare[0] == '$') && (vare[1] == '{')) { 01714 needsub++; 01715 vare++; 01716 } 01717 vare++; 01718 } 01719 if (brackets) 01720 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n"); 01721 len = vare - vars - 1; 01722 01723 /* Skip totally over expression */ 01724 whereweare += (len + 3); 01725 01726 if (!var) 01727 var = alloca(VAR_BUF_SIZE); 01728 01729 /* Store variable name (and truncate) */ 01730 ast_copy_string(var, vars, len + 1); 01731 01732 /* Substitute if necessary */ 01733 if (needsub) { 01734 if (!ltmp) 01735 ltmp = alloca(VAR_BUF_SIZE); 01736 01737 memset(ltmp, 0, VAR_BUF_SIZE); 01738 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01739 vars = ltmp; 01740 } else { 01741 vars = var; 01742 } 01743 01744 length = ast_expr(vars, cp2, count); 01745 01746 if (length) { 01747 if (option_debug) 01748 ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2); 01749 count -= length; 01750 cp2 += length; 01751 } 01752 } 01753 } 01754 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1761 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), do_say(), dundi_lookup_local(), and loopback_helper().
01762 { 01763 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01764 }
static void* pbx_thread | ( | void * | data | ) | [static] |
Definition at line 2611 of file pbx.c.
References __ast_pbx_run(), and decrease_call_count().
Referenced by ast_pbx_start().
02612 { 02613 /* Oh joyeous kernel, we're a new thread, with nothing to do but 02614 answer this channel and get it going. 02615 */ 02616 /* NOTE: 02617 The launcher of this function _MUST_ increment 'countcalls' 02618 before invoking the function; it will be decremented when the 02619 PBX has finished running on the channel 02620 */ 02621 struct ast_channel *c = data; 02622 02623 __ast_pbx_run(c); 02624 decrease_call_count(); 02625 02626 pthread_exit(NULL); 02627 02628 return NULL; 02629 }
static void print_ext | ( | struct ast_exten * | e, | |
char * | buf, | |||
int | buflen | |||
) | [static] |
helper function to print an extension
Definition at line 3494 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().
03495 { 03496 int prio = ast_get_extension_priority(e); 03497 if (prio == PRIORITY_HINT) { 03498 snprintf(buf, buflen, "hint: %s", 03499 ast_get_extension_app(e)); 03500 } else { 03501 snprintf(buf, buflen, "%d. %s(%s)", 03502 prio, ast_get_extension_app(e), 03503 (!ast_strlen_zero(ast_get_extension_app_data(e)) ? (char *)ast_get_extension_app_data(e) : "")); 03504 } 03505 }
static void set_ext_pri | ( | struct ast_channel * | c, | |
const char * | exten, | |||
int | pri | |||
) | [static] |
Definition at line 2310 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_exten2(), and pbx_builtin_waitexten().
02311 { 02312 ast_channel_lock(c); 02313 ast_copy_string(c->exten, exten, sizeof(c->exten)); 02314 c->priority = pri; 02315 ast_channel_unlock(c); 02316 }
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 3508 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().
03509 { 03510 struct ast_context *c = NULL; 03511 int res = 0, old_total_exten = dpc->total_exten; 03512 03513 ast_rdlock_contexts(); 03514 03515 /* walk all contexts ... */ 03516 while ( (c = ast_walk_contexts(c)) ) { 03517 struct ast_exten *e; 03518 struct ast_include *i; 03519 struct ast_ignorepat *ip; 03520 char buf[256], buf2[256]; 03521 int context_info_printed = 0; 03522 03523 if (context && strcmp(ast_get_context_name(c), context)) 03524 continue; /* skip this one, name doesn't match */ 03525 03526 dpc->context_existence = 1; 03527 03528 ast_lock_context(c); 03529 03530 /* are we looking for exten too? if yes, we print context 03531 * only if we find our extension. 03532 * Otherwise print context even if empty ? 03533 * XXX i am not sure how the rinclude is handled. 03534 * I think it ought to go inside. 03535 */ 03536 if (!exten) { 03537 dpc->total_context++; 03538 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03539 ast_get_context_name(c), ast_get_context_registrar(c)); 03540 context_info_printed = 1; 03541 } 03542 03543 /* walk extensions ... */ 03544 e = NULL; 03545 while ( (e = ast_walk_context_extensions(c, e)) ) { 03546 struct ast_exten *p; 03547 03548 if (exten && !ast_extension_match(ast_get_extension_name(e), exten)) 03549 continue; /* skip, extension match failed */ 03550 03551 dpc->extension_existence = 1; 03552 03553 /* may we print context info? */ 03554 if (!context_info_printed) { 03555 dpc->total_context++; 03556 if (rinclude) { /* TODO Print more info about rinclude */ 03557 ast_cli(fd, "[ Included context '%s' created by '%s' ]\n", 03558 ast_get_context_name(c), ast_get_context_registrar(c)); 03559 } else { 03560 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03561 ast_get_context_name(c), ast_get_context_registrar(c)); 03562 } 03563 context_info_printed = 1; 03564 } 03565 dpc->total_prio++; 03566 03567 /* write extension name and first peer */ 03568 snprintf(buf, sizeof(buf), "'%s' =>", ast_get_extension_name(e)); 03569 03570 print_ext(e, buf2, sizeof(buf2)); 03571 03572 ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2, 03573 ast_get_extension_registrar(e)); 03574 03575 dpc->total_exten++; 03576 /* walk next extension peers */ 03577 p = e; /* skip the first one, we already got it */ 03578 while ( (p = ast_walk_extension_priorities(e, p)) ) { 03579 const char *el = ast_get_extension_label(p); 03580 dpc->total_prio++; 03581 if (el) 03582 snprintf(buf, sizeof(buf), " [%s]", el); 03583 else 03584 buf[0] = '\0'; 03585 print_ext(p, buf2, sizeof(buf2)); 03586 03587 ast_cli(fd," %-17s %-45s [%s]\n", buf, buf2, 03588 ast_get_extension_registrar(p)); 03589 } 03590 } 03591 03592 /* walk included and write info ... */ 03593 i = NULL; 03594 while ( (i = ast_walk_context_includes(c, i)) ) { 03595 snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i)); 03596 if (exten) { 03597 /* Check all includes for the requested extension */ 03598 if (includecount >= AST_PBX_MAX_STACK) { 03599 ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n"); 03600 } else { 03601 int dupe=0; 03602 int x; 03603 for (x=0;x<includecount;x++) { 03604 if (!strcasecmp(includes[x], ast_get_include_name(i))) { 03605 dupe++; 03606 break; 03607 } 03608 } 03609 if (!dupe) { 03610 includes[includecount] = ast_get_include_name(i); 03611 show_dialplan_helper(fd, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes); 03612 } else { 03613 ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context); 03614 } 03615 } 03616 } else { 03617 ast_cli(fd, " Include => %-45s [%s]\n", 03618 buf, ast_get_include_registrar(i)); 03619 } 03620 } 03621 03622 /* walk ignore patterns and write info ... */ 03623 ip = NULL; 03624 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) { 03625 const char *ipname = ast_get_ignorepat_name(ip); 03626 char ignorepat[AST_MAX_EXTENSION]; 03627 snprintf(buf, sizeof(buf), "'%s'", ipname); 03628 snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname); 03629 if (!exten || ast_extension_match(ignorepat, exten)) { 03630 ast_cli(fd, " Ignore pattern => %-45s [%s]\n", 03631 buf, ast_get_ignorepat_registrar(ip)); 03632 } 03633 } 03634 if (!rinclude) { 03635 struct ast_sw *sw = NULL; 03636 while ( (sw = ast_walk_context_switches(c, sw)) ) { 03637 snprintf(buf, sizeof(buf), "'%s/%s'", 03638 ast_get_switch_name(sw), 03639 ast_get_switch_data(sw)); 03640 ast_cli(fd, " Alt. Switch => %-45s [%s]\n", 03641 buf, ast_get_switch_registrar(sw)); 03642 } 03643 } 03644 03645 ast_unlock_context(c); 03646 03647 /* if we print something in context, make an empty line */ 03648 if (context_info_printed) 03649 ast_cli(fd, "\r\n"); 03650 } 03651 ast_unlock_contexts(); 03652 03653 return (dpc->total_exten == old_total_exten) ? -1 : res; 03654 }
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 1102 of file pbx.c.
Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
01103 { 01104 char *ret = workspace; 01105 int lr; /* length of the input string after the copy */ 01106 01107 ast_copy_string(workspace, value, workspace_len); /* always make a copy */ 01108 01109 lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */ 01110 01111 /* Quick check if no need to do anything */ 01112 if (offset == 0 && length >= lr) /* take the whole string */ 01113 return ret; 01114 01115 if (offset < 0) { /* translate negative offset into positive ones */ 01116 offset = lr + offset; 01117 if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */ 01118 offset = 0; 01119 } 01120 01121 /* too large offset result in empty string so we know what to return */ 01122 if (offset >= lr) 01123 return ret + lr; /* the final '\0' */ 01124 01125 ret += offset; /* move to the start position */ 01126 if (length >= 0 && length < lr - offset) /* truncate if necessary */ 01127 ret[length] = '\0'; 01128 else if (length < 0) { 01129 if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */ 01130 ret[lr + length - offset] = '\0'; 01131 else 01132 ret[0] = '\0'; 01133 } 01134 01135 return ret; 01136 }
static void wait_for_hangup | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5364 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().
05365 { 05366 int res; 05367 struct ast_frame *f; 05368 int waittime; 05369 05370 if (ast_strlen_zero(data) || (sscanf(data, "%d", &waittime) != 1) || (waittime < 0)) 05371 waittime = -1; 05372 if (waittime > -1) { 05373 ast_safe_sleep(chan, waittime * 1000); 05374 } else do { 05375 res = ast_waitfor(chan, -1); 05376 if (res < 0) 05377 return; 05378 f = ast_read(chan); 05379 if (f) 05380 ast_frfree(f); 05381 } while(f); 05382 }
int autofallthrough = 1 [static] |
struct pbx_builtin builtins[] [static] |
struct ast_cli_entry cli_set_global_deprecated [static] |
Initial value:
{ { "set", "global", NULL }, handle_set_global_deprecated, NULL, NULL }
struct ast_cli_entry cli_show_application_deprecated [static] |
Initial value:
{ { "show", "application", NULL }, handle_show_application_deprecated, NULL, NULL, complete_show_application }
struct ast_cli_entry cli_show_applications_deprecated [static] |
Initial value:
{ { "show", "applications", NULL }, handle_show_applications_deprecated, NULL, NULL, complete_show_applications_deprecated }
struct ast_cli_entry cli_show_dialplan_deprecated [static] |
Initial value:
{ { "show", "dialplan", NULL }, handle_show_dialplan, NULL, NULL, complete_show_dialplan_context }
struct ast_cli_entry cli_show_function_deprecated [static] |
Initial value:
{ { "show" , "function", NULL }, handle_show_function_deprecated, NULL, NULL, complete_show_function }
struct ast_cli_entry cli_show_functions_deprecated [static] |
Initial value:
{ { "show", "functions", NULL }, handle_show_functions_deprecated, NULL, NULL }
struct ast_cli_entry cli_show_globals_deprecated [static] |
Initial value:
{ { "show", "globals", NULL }, handle_show_globals, NULL, NULL }
struct ast_cli_entry cli_show_hints_deprecated [static] |
Initial value:
{ { "show", "hints", NULL }, handle_show_hints, NULL, NULL }
struct ast_cli_entry cli_show_switches_deprecated [static] |
Initial value:
{ { "show", "switches", NULL }, handle_show_switches, NULL, NULL }
struct ast_context* contexts [static] |
Definition at line 490 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 246 of file pbx.c.
Referenced by ast_active_calls(), decrease_call_count(), and increase_call_count().
char* days[] [static] |
struct cfextension_states extension_states[] [static] |
Referenced by ast_extension_state2str().
struct varshead globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE [static] |
Definition at line 241 of file pbx.c.
Referenced by ast_add_extension2(), handle_show_globals(), pbx_builtin_clear_globals(), pbx_builtin_getvar_helper(), pbx_builtin_pushvar_helper(), pbx_builtin_setvar_helper(), and pbx_retrieve_variable().
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[] [static] |
struct ast_state_cb* statecbs |
Definition at line 505 of file pbx.c.
Referenced by ast_extension_state_add(), ast_extension_state_del(), and ast_hint_state_changed().
int stateid = 1 [static] |