#include "asterisk.h"
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include <limits.h>
#include "asterisk/lock.h"
#include "asterisk/cli.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/options.h"
#include "asterisk/logger.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/cdr.h"
#include "asterisk/config.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/ast_expr.h"
#include "asterisk/linkedlists.h"
#include "asterisk/say.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/musiconhold.h"
#include "asterisk/app.h"
#include "asterisk/devicestate.h"
#include "asterisk/stringfields.h"
#include "asterisk/threadstorage.h"
Go to the source code of this file.
Data Structures | |
struct | acf_root |
struct | app_tmp |
struct | apps |
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 | hints |
struct | pbx_builtin |
Declaration of builtin applications. More... | |
struct | pbx_find_info |
struct | store_hint |
struct | store_hints |
struct | switches |
Defines | |
#define | AST_PBX_MAX_STACK 128 |
#define | BACKGROUND_MATCHEXTEN (1 << 2) |
#define | BACKGROUND_NOANSWER (1 << 1) |
#define | BACKGROUND_PLAYBACK (1 << 3) |
#define | BACKGROUND_SKIP (1 << 0) |
#define | EXT_DATA_SIZE 8192 |
#define | SAY_STUBS |
#define | STATUS_NO_CONTEXT 1 |
#define | STATUS_NO_EXTENSION 2 |
#define | STATUS_NO_LABEL 4 |
#define | STATUS_NO_PRIORITY 3 |
#define | STATUS_SUCCESS 5 |
#define | SWITCH_DATA_LENGTH 256 |
#define | VAR_BUF_SIZE 4096 |
#define | VAR_HARDTRAN 3 |
#define | VAR_NORMAL 1 |
#define | VAR_SOFTTRAN 2 |
#define | WAITEXTEN_MOH (1 << 0) |
Enumerations | |
enum | ext_match_t { E_MATCHMORE = 0x00, E_CANMATCH = 0x01, E_MATCH = 0x02, E_MATCH_MASK = 0x03, E_SPAWN = 0x12, E_FINDLABEL = 0x22 } |
Functions | |
static struct ast_context * | __ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar, int existsokay) |
void | __ast_context_destroy (struct ast_context *con, const char *registrar) |
static int | __ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, int async) |
static int | __ast_pbx_run (struct ast_channel *c) |
static int | _extension_match_core (const char *pattern, const char *data, enum ext_match_t mode) |
static int | add_pri (struct ast_context *con, struct ast_exten *tmp, struct ast_exten *el, struct ast_exten *e, int replace) |
add the extension in the priority chain. returns 0 on success, -1 on failure | |
int | ast_active_calls (void) |
Retrieve the number of active calls. | |
int | ast_add_extension (const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
Add and extension to an extension context. | |
int | ast_add_extension2 (struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar) |
Add an extension to an extension context, this time with an ast_context *. | |
static int | ast_add_hint (struct ast_exten *e) |
ast_add_hint: Add hint to hint list, check initial extension state | |
int | ast_async_goto (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_async_goto_by_name (const char *channame, const char *context, const char *exten, int priority) |
int | ast_async_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
int | ast_build_timing (struct ast_timing *i, const char *info_in) |
int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Looks for a valid matching extension. | |
static int | ast_change_hint (struct ast_exten *oe, struct ast_exten *ne) |
ast_change_hint: Change hint for an extension | |
int | ast_check_timing (const struct ast_timing *i) |
int | ast_context_add_ignorepat (const char *context, const char *value, const char *registrar) |
Add an ignorepat. | |
int | ast_context_add_ignorepat2 (struct ast_context *con, const char *value, const char *registrar) |
int | ast_context_add_include (const char *context, const char *include, const char *registrar) |
Add a context include. | |
int | ast_context_add_include2 (struct ast_context *con, const char *value, const char *registrar) |
Add a context include. | |
int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
Add a switch. | |
int | ast_context_add_switch2 (struct ast_context *con, const char *value, const char *data, int eval, const char *registrar) |
Adds a switch (first param is a ast_context). | |
ast_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). | |
ast_context * | ast_context_find (const char *name) |
Find a context. | |
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_extension_callerid (const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar) |
int | ast_context_remove_extension_callerid2 (struct ast_context *con, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar) |
int | ast_context_remove_ignorepat (const char *context, const char *ignorepat, const char *registrar) |
int | ast_context_remove_ignorepat2 (struct ast_context *con, const char *ignorepat, const char *registrar) |
int | ast_context_remove_include (const char *context, const char *include, const char *registrar) |
Remove a context include. | |
int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
Removes an include by an ast_context structure. | |
int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
Remove a switch. | |
int | ast_context_remove_switch2 (struct ast_context *con, const char *sw, const char *data, const char *registrar) |
This function locks given context, removes switch, unlock context and return. | |
int | ast_context_unlockmacro (const char *context) |
Unlocks the macrolock in the given context. | |
int | ast_context_verify_includes (struct ast_context *con) |
Verifies includes in an ast_contect structure. | |
ast_custom_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) |
Uses hint and devicestate callback to get the state of an extension. | |
static int | ast_extension_state2 (struct ast_exten *e) |
ast_extensions_state2: Check state of extension by using hints | |
const char * | ast_extension_state2str (int extension_state) |
Return string representation of the state of an extension. | |
int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
Registers a state change callback. | |
int | ast_extension_state_del (int id, ast_state_cb_type callback) |
Deletes a registered state change callback by ID. | |
int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
Find the priority of an extension that has the specified label. | |
int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
Find the priority of an extension that has the specified label. | |
int | ast_func_read (struct ast_channel *chan, char *function, char *workspace, size_t len) |
executes a read operation on a function | |
int | ast_func_write (struct ast_channel *chan, char *function, const char *value) |
executes a write operation on a function | |
const char * | ast_get_context_name (struct ast_context *con) |
const char * | ast_get_context_registrar (struct ast_context *c) |
const char * | ast_get_extension_app (struct ast_exten *e) |
void * | ast_get_extension_app_data (struct ast_exten *e) |
const char * | ast_get_extension_cidmatch (struct ast_exten *e) |
ast_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) |
If an extension exists, return non-zero. | |
const char * | ast_get_ignorepat_name (struct ast_ignorepat *ip) |
const char * | ast_get_ignorepat_registrar (struct ast_ignorepat *ip) |
const char * | ast_get_include_name (struct ast_include *inc) |
const char * | ast_get_include_registrar (struct ast_include *i) |
const char * | ast_get_switch_data (struct ast_sw *sw) |
const char * | ast_get_switch_name (struct ast_sw *sw) |
const char * | ast_get_switch_registrar (struct ast_sw *sw) |
int | ast_goto_if_exists (struct ast_channel *chan, const char *context, const char *exten, int priority) |
static struct ast_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) |
int | ast_ignore_pattern (const char *context, const char *pattern) |
Checks to see if a number should be ignored. | |
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. | |
int | ast_parseable_goto (struct ast_channel *chan, const char *goto_string) |
int | ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
static int | ast_pbx_outgoing_cdr_failed (void) |
int | ast_pbx_outgoing_exten (const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel) |
enum ast_pbx_result | ast_pbx_run (struct ast_channel *c) |
Execute the PBX in the current thread. | |
static void * | ast_pbx_run_app (void *data) |
run the application and free the descriptor once done | |
enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
Create a new thread and start the PBX. | |
int | ast_rdlock_contexts (void) |
int | ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description) |
Register an application. | |
int | ast_register_switch (struct ast_switch *sw) |
Register an alternative dialplan switch. | |
static int | ast_remove_hint (struct ast_exten *e) |
ast_remove_hint: Remove hint from extension | |
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. | |
ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *exten) |
ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
ast_context * | ast_walk_contexts (struct ast_context *con) |
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 registered dial plan hints | |
static int | handle_show_switches (int fd, int argc, char *argv[]) |
handle_show_switches: CLI support for listing registered dial plan switches | |
static int | include_valid (struct ast_include *i) |
static int | increase_call_count (const struct ast_channel *c) |
int | load_pbx (void) |
static int | lookup_name (const char *s, char *const names[], int max) |
Helper for get_range. return the index of the matching entry, starting from 1. If names is not supplied, try numeric values. | |
static int | matchcid (const char *cidpattern, const char *callerid) |
static int | parse_variable_name (char *var, int *offset, int *length, int *isfunc) |
extract offset:length from variable name. Returns 1 if there is a offset:length part, which is trimmed off (values go into variables) | |
static int | pbx_builtin_answer (struct ast_channel *, void *) |
static int | pbx_builtin_background (struct ast_channel *, void *) |
static int | pbx_builtin_busy (struct ast_channel *, void *) |
void | pbx_builtin_clear_globals (void) |
static int | pbx_builtin_congestion (struct ast_channel *, void *) |
static int | pbx_builtin_execiftime (struct ast_channel *, void *) |
const char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
static int | pbx_builtin_goto (struct ast_channel *, void *) |
static int | pbx_builtin_gotoif (struct ast_channel *, void *) |
static int | pbx_builtin_gotoiftime (struct ast_channel *, void *) |
static int | pbx_builtin_hangup (struct ast_channel *, void *) |
static int | pbx_builtin_importvar (struct ast_channel *, void *) |
static int | pbx_builtin_noop (struct ast_channel *, void *) |
static int | pbx_builtin_progress (struct ast_channel *, void *) |
void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
static int | pbx_builtin_resetcdr (struct ast_channel *, void *) |
static int | pbx_builtin_ringing (struct ast_channel *, void *) |
static int | pbx_builtin_saycharacters (struct ast_channel *, void *) |
static int | pbx_builtin_saydate (struct ast_channel *, void *) |
static int | pbx_builtin_saydigits (struct ast_channel *, void *) |
static int | pbx_builtin_saynumber (struct ast_channel *, void *) |
static int | pbx_builtin_sayphonetic (struct ast_channel *, void *) |
static int | pbx_builtin_saytime (struct ast_channel *, void *) |
int | pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
static int | pbx_builtin_setamaflags (struct ast_channel *, void *) |
static int | pbx_builtin_setglobalvar (struct ast_channel *, void *) |
int | pbx_builtin_setvar (struct ast_channel *, void *) |
void | pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value) |
static int | pbx_builtin_wait (struct ast_channel *, void *) |
static int | pbx_builtin_waitexten (struct ast_channel *, void *) |
int | pbx_checkcondition (const char *condition) |
Evaluate a condition. | |
static void | pbx_destroy (struct ast_pbx *p) |
int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data) |
Execute an application. | |
static int | pbx_extension_helper (struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action) |
The return value depends on the action:. | |
static struct ast_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) |
ast_app * | pbx_findapp (const char *app) |
Look up an application. | |
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 | switch_data_init (void) |
static void | wait_for_hangup (struct ast_channel *chan, void *data) |
Variables | |
static int | autofallthrough = 1 |
static struct ast_app_option | background_opts [128] = { [ 's' ] = { .flag = (1 << 0) }, [ 'n' ] = { .flag = (1 << 1) }, [ 'm' ] = { .flag = (1 << 2) }, [ 'p' ] = { .flag = (1 << 3) },} |
static struct pbx_builtin | builtins [] |
Declaration of builtin applications. | |
static struct ast_cli_entry | cli_set_global_deprecated |
static struct ast_cli_entry | cli_show_application_deprecated |
static struct ast_cli_entry | cli_show_applications_deprecated |
static struct ast_cli_entry | cli_show_dialplan_deprecated |
static struct ast_cli_entry | cli_show_function_deprecated |
static struct ast_cli_entry | cli_show_functions_deprecated |
static struct ast_cli_entry | cli_show_globals_deprecated |
static struct ast_cli_entry | cli_show_hints_deprecated |
static struct ast_cli_entry | cli_show_switches_deprecated |
static ast_rwlock_t | conlock = PTHREAD_RWLOCK_INITIALIZER |
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 ast_mutex_t | globalslock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static ast_mutex_t | maxcalllock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static char * | months [] |
static struct ast_cli_entry | pbx_cli [] |
static struct ast_app_option | resetcdr_opts [128] = { [ 'w' ] = { .flag = (1 << 1) }, [ 'a' ] = { .flag = (1 << 2) }, [ 'v' ] = { .flag = (1 << 0) },} |
static char | set_global_help [] |
static char | show_application_help [] |
static char | show_applications_help [] |
static char | show_dialplan_help [] |
static char | show_function_help [] |
static char | show_functions_help [] |
static char | show_globals_help [] |
static char | show_hints_help [] |
static char | show_switches_help [] |
ast_state_cb * | statecbs |
static int | stateid = 1 |
static struct ast_threadstorage | switch_data = { .once = PTHREAD_ONCE_INIT, .key_init = switch_data_init , } |
static struct ast_app_option | waitexten_opts [128] = { [ 'm' ] = { .flag = (1 << 0) , .arg_index = 0 + 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 571 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 78 of file pbx.c.
Referenced by pbx_extension_helper(), and realtime_exec().
#define STATUS_NO_CONTEXT 1 |
Definition at line 934 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_EXTENSION 2 |
Definition at line 935 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_LABEL 4 |
Definition at line 937 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_PRIORITY 3 |
Definition at line 936 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_SUCCESS 5 |
#define VAR_BUF_SIZE 4096 |
Definition at line 83 of file pbx.c.
Referenced by ast_add_extension2(), pbx_builtin_importvar(), and pbx_substitute_variables_helper_full().
#define 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 777 of file pbx.c.
00777 { 00778 E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */ 00779 E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */ 00780 E_MATCH = 0x02, /* extension is an exact match */ 00781 E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */ 00782 E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */ 00783 E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */ 00784 };
static struct ast_context* __ast_context_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar, | |||
int | existsokay | |||
) | [static] |
Definition at line 3899 of file pbx.c.
References ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), contexts, local_contexts, LOG_WARNING, ast_context::name, name, and ast_context::next.
Referenced by ast_context_create(), and ast_context_find_or_create().
03900 { 03901 struct ast_context *tmp, **local_contexts; 03902 int length = sizeof(struct ast_context) + strlen(name) + 1; 03903 03904 if (!extcontexts) { 03905 ast_rdlock_contexts(); 03906 local_contexts = &contexts; 03907 } else 03908 local_contexts = extcontexts; 03909 03910 for (tmp = *local_contexts; tmp; tmp = tmp->next) { 03911 if (!strcasecmp(tmp->name, name)) { 03912 if (!existsokay) { 03913 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 03914 tmp = NULL; 03915 } 03916 if (!extcontexts) 03917 ast_unlock_contexts(); 03918 return tmp; 03919 } 03920 } 03921 03922 if (!extcontexts) 03923 ast_unlock_contexts(); 03924 03925 if ((tmp = ast_calloc(1, length))) { 03926 ast_mutex_init(&tmp->lock); 03927 ast_mutex_init(&tmp->macrolock); 03928 strcpy(tmp->name, name); 03929 tmp->registrar = registrar; 03930 if (!extcontexts) 03931 ast_wrlock_contexts(); 03932 tmp->next = *local_contexts; 03933 *local_contexts = tmp; 03934 if (!extcontexts) 03935 ast_unlock_contexts(); 03936 if (option_debug) 03937 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 03938 if (option_verbose > 2) 03939 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 03940 } 03941 03942 return tmp; 03943 }
void __ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
Definition at line 5328 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), contexts, destroy_exten(), el, free, ast_context::name, ast_exten::next, ast_include::next, ast_context::next, ast_ignorepat::next, and ast_exten::peer.
Referenced by ast_context_destroy(), and ast_merge_contexts_and_delete().
05329 { 05330 struct ast_context *tmp, *tmpl=NULL; 05331 struct ast_include *tmpi; 05332 struct ast_sw *sw; 05333 struct ast_exten *e, *el, *en; 05334 struct ast_ignorepat *ipi; 05335 05336 for (tmp = contexts; tmp; ) { 05337 struct ast_context *next; /* next starting point */ 05338 for (; tmp; tmpl = tmp, tmp = tmp->next) { 05339 if (option_debug) 05340 ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar); 05341 if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) && 05342 (!con || !strcasecmp(tmp->name, con->name)) ) 05343 break; /* found it */ 05344 } 05345 if (!tmp) /* not found, we are done */ 05346 break; 05347 ast_mutex_lock(&tmp->lock); 05348 if (option_debug) 05349 ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar); 05350 next = tmp->next; 05351 if (tmpl) 05352 tmpl->next = next; 05353 else 05354 contexts = next; 05355 /* Okay, now we're safe to let it go -- in a sense, we were 05356 ready to let it go as soon as we locked it. */ 05357 ast_mutex_unlock(&tmp->lock); 05358 for (tmpi = tmp->includes; tmpi; ) { /* Free includes */ 05359 struct ast_include *tmpil = tmpi; 05360 tmpi = tmpi->next; 05361 free(tmpil); 05362 } 05363 for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */ 05364 struct ast_ignorepat *ipl = ipi; 05365 ipi = ipi->next; 05366 free(ipl); 05367 } 05368 while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list))) 05369 free(sw); 05370 for (e = tmp->root; e;) { 05371 for (en = e->peer; en;) { 05372 el = en; 05373 en = en->peer; 05374 destroy_exten(el); 05375 } 05376 el = e; 05377 e = e->next; 05378 destroy_exten(el); 05379 } 05380 ast_mutex_destroy(&tmp->lock); 05381 free(tmp); 05382 /* if we have a specific match, we are done, otherwise continue */ 05383 tmp = con ? NULL : next; 05384 } 05385 }
static int __ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
int | async | |||
) | [static] |
Definition at line 6459 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().
06460 { 06461 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06462 06463 if (!chan) 06464 return -2; 06465 06466 if (context == NULL) 06467 context = chan->context; 06468 if (exten == NULL) 06469 exten = chan->exten; 06470 06471 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06472 if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num)) 06473 return goto_func(chan, context, exten, priority); 06474 else 06475 return -3; 06476 }
static int __ast_pbx_run | ( | struct ast_channel * | c | ) | [static] |
Definition at line 2387 of file pbx.c.
References ast_channel::_softhangup, ast_calloc, ast_copy_string(), ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, ast_log(), AST_PBX_KEEPALIVE, ast_set_flag, AST_SOFTHANGUP_ASYNCGOTO, AST_SOFTHANGUP_TIMEOUT, ast_spawn_extension(), ast_test_flag, ast_verbose(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_pbx::dtimeout, ast_channel::exten, free, LOG_DEBUG, LOG_WARNING, ast_channel::name, option_debug, option_verbose, ast_channel::pbx, ast_channel::priority, ast_pbx::rtimeout, set_ext_pri(), and VERBOSE_PREFIX_2.
Referenced by ast_pbx_run(), and pbx_thread().
02388 { 02389 int found = 0; /* set if we find at least one match */ 02390 int res = 0; 02391 int autoloopflag; 02392 int error = 0; /* set an error conditions */ 02393 const char *emc; 02394 02395 /* A little initial setup here */ 02396 if (c->pbx) { 02397 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name); 02398 /* XXX and now what ? */ 02399 free(c->pbx); 02400 } 02401 if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx)))) 02402 return -1; 02403 /* Set reasonable defaults */ 02404 c->pbx->rtimeout = 10; 02405 c->pbx->dtimeout = 5; 02406 02407 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */ 02408 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP); 02409 02410 /* Start by trying whatever the channel is set to */ 02411 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02412 /* If not successful fall back to 's' */ 02413 if (option_verbose > 1) 02414 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); 02415 /* XXX the original code used the existing priority in the call to 02416 * ast_exists_extension(), and reset it to 1 afterwards. 02417 * I believe the correct thing is to set it to 1 immediately. 02418 */ 02419 set_ext_pri(c, "s", 1); 02420 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02421 /* JK02: And finally back to default if everything else failed */ 02422 if (option_verbose > 1) 02423 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); 02424 ast_copy_string(c->context, "default", sizeof(c->context)); 02425 } 02426 } 02427 for (;;) { 02428 char dst_exten[256]; /* buffer to accumulate digits */ 02429 int pos = 0; /* XXX should check bounds */ 02430 int digit = 0; 02431 02432 /* loop on priorities in this context/exten */ 02433 while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02434 found = 1; 02435 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02436 /* Something bad happened, or a hangup has been requested. */ 02437 if (strchr("0123456789ABCDEF*#", res)) { 02438 if (option_debug) 02439 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 02440 pos = 0; 02441 dst_exten[pos++] = digit = res; 02442 dst_exten[pos] = '\0'; 02443 break; 02444 } 02445 if (res == AST_PBX_KEEPALIVE) { 02446 if (option_debug) 02447 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02448 if (option_verbose > 1) 02449 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02450 error = 1; 02451 break; 02452 } 02453 if (option_debug) 02454 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02455 if (option_verbose > 1) 02456 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02457 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02458 c->_softhangup = 0; 02459 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02460 /* atimeout, nothing bad */ 02461 } else { 02462 if (c->cdr) 02463 ast_cdr_update(c); 02464 error = 1; 02465 break; 02466 } 02467 } 02468 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02469 c->_softhangup = 0; 02470 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c,c->context,"T",1,c->cid.cid_num)) { 02471 set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */ 02472 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */ 02473 c->whentohangup = 0; 02474 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT; 02475 } else if (c->_softhangup) { 02476 if (option_debug) 02477 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", 02478 c->exten, c->priority); 02479 error = 1; 02480 break; 02481 } 02482 c->priority++; 02483 } /* end while - from here on we can use 'break' to go out */ 02484 if (error) 02485 break; 02486 02487 /* XXX we get here on non-existing extension or a keypress or hangup ? */ 02488 02489 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { 02490 /* If there is no match at priority 1, it is not a valid extension anymore. 02491 * Try to continue at "i", 1 or exit if the latter does not exist. 02492 */ 02493 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02494 if (option_verbose > 2) 02495 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name); 02496 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten); 02497 set_ext_pri(c, "i", 1); 02498 } else { 02499 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n", 02500 c->name, c->exten, c->context); 02501 error = 1; /* we know what to do with it */ 02502 break; 02503 } 02504 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02505 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */ 02506 c->_softhangup = 0; 02507 } else { /* keypress received, get more digits for a full extension */ 02508 int waittime = 0; 02509 if (digit) 02510 waittime = c->pbx->dtimeout; 02511 else if (!autofallthrough) 02512 waittime = c->pbx->rtimeout; 02513 if (!waittime) { 02514 const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 02515 if (!status) 02516 status = "UNKNOWN"; 02517 if (option_verbose > 2) 02518 ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status); 02519 if (!strcasecmp(status, "CONGESTION")) 02520 res = pbx_builtin_congestion(c, "10"); 02521 else if (!strcasecmp(status, "CHANUNAVAIL")) 02522 res = pbx_builtin_congestion(c, "10"); 02523 else if (!strcasecmp(status, "BUSY")) 02524 res = pbx_builtin_busy(c, "10"); 02525 error = 1; /* XXX disable message */ 02526 break; /* exit from the 'for' loop */ 02527 } 02528 02529 if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos)) 02530 break; 02531 if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */ 02532 set_ext_pri(c, dst_exten, 1); 02533 else { 02534 /* No such extension */ 02535 if (!ast_strlen_zero(dst_exten)) { 02536 /* An invalid extension */ 02537 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02538 if (option_verbose > 2) 02539 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name); 02540 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten); 02541 set_ext_pri(c, "i", 1); 02542 } else { 02543 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context); 02544 found = 1; /* XXX disable message */ 02545 break; 02546 } 02547 } else { 02548 /* A simple timeout */ 02549 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) { 02550 if (option_verbose > 2) 02551 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name); 02552 set_ext_pri(c, "t", 1); 02553 } else { 02554 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context); 02555 found = 1; /* XXX disable message */ 02556 break; 02557 } 02558 } 02559 } 02560 if (c->cdr) { 02561 if (option_verbose > 2) 02562 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name); 02563 ast_cdr_update(c); 02564 } 02565 } 02566 } 02567 if (!found && !error) 02568 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); 02569 if (res != AST_PBX_KEEPALIVE) 02570 ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING); 02571 ast_channel_lock(c); 02572 if ((emc = pbx_builtin_getvar_helper(c, "EXIT_MACRO_CONTEXT"))) { 02573 emc = ast_strdupa(emc); 02574 } 02575 ast_channel_unlock(c); 02576 if ((res != AST_PBX_KEEPALIVE) && !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) && 02577 ((emc && ast_exists_extension(c, emc, "h", 1, c->cid.cid_num)) || 02578 (ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num) && (emc = c->context)))) { 02579 ast_copy_string(c->context, emc, sizeof(c->context)); 02580 set_ext_pri(c, "h", 1); 02581 if (c->cdr && ast_opt_end_cdr_before_h_exten) { 02582 ast_cdr_end(c->cdr); 02583 } 02584 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02585 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02586 /* Something bad happened, or a hangup has been requested. */ 02587 if (option_debug) 02588 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02589 if (option_verbose > 1) 02590 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02591 break; 02592 } 02593 c->priority++; 02594 } 02595 } 02596 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP); 02597 ast_clear_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */ 02598 pbx_destroy(c->pbx); 02599 c->pbx = NULL; 02600 if (res != AST_PBX_KEEPALIVE) 02601 ast_hangup(c); 02602 return 0; 02603 }
static int _extension_match_core | ( | const char * | pattern, | |
const char * | data, | |||
enum ext_match_t | mode | |||
) | [static] |
Definition at line 795 of file pbx.c.
References ast_log(), E_MATCH, E_MATCH_MASK, E_MATCHMORE, and LOG_WARNING.
Referenced by extension_match_core().
00796 { 00797 mode &= E_MATCH_MASK; /* only consider the relevant bits */ 00798 00799 if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */ 00800 return 1; 00801 00802 if (pattern[0] != '_') { /* not a pattern, try exact or partial match */ 00803 int ld = strlen(data), lp = strlen(pattern); 00804 00805 if (lp < ld) /* pattern too short, cannot match */ 00806 return 0; 00807 /* depending on the mode, accept full or partial match or both */ 00808 if (mode == E_MATCH) 00809 return !strcmp(pattern, data); /* 1 on match, 0 on fail */ 00810 if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */ 00811 return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */ 00812 else 00813 return 0; 00814 } 00815 pattern++; /* skip leading _ */ 00816 /* 00817 * XXX below we stop at '/' which is a separator for the CID info. However we should 00818 * not store '/' in the pattern at all. When we insure it, we can remove the checks. 00819 */ 00820 while (*data && *pattern && *pattern != '/') { 00821 const char *end; 00822 00823 if (*data == '-') { /* skip '-' in data (just a separator) */ 00824 data++; 00825 continue; 00826 } 00827 switch (toupper(*pattern)) { 00828 case '[': /* a range */ 00829 end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */ 00830 if (end == NULL) { 00831 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n"); 00832 return 0; /* unconditional failure */ 00833 } 00834 for (pattern++; pattern != end; pattern++) { 00835 if (pattern+2 < end && pattern[1] == '-') { /* this is a range */ 00836 if (*data >= pattern[0] && *data <= pattern[2]) 00837 break; /* match found */ 00838 else { 00839 pattern += 2; /* skip a total of 3 chars */ 00840 continue; 00841 } 00842 } else if (*data == pattern[0]) 00843 break; /* match found */ 00844 } 00845 if (pattern == end) 00846 return 0; 00847 pattern = end; /* skip and continue */ 00848 break; 00849 case 'N': 00850 if (*data < '2' || *data > '9') 00851 return 0; 00852 break; 00853 case 'X': 00854 if (*data < '0' || *data > '9') 00855 return 0; 00856 break; 00857 case 'Z': 00858 if (*data < '1' || *data > '9') 00859 return 0; 00860 break; 00861 case '.': /* Must match, even with more digits */ 00862 return 1; 00863 case '!': /* Early match */ 00864 return 2; 00865 case ' ': 00866 case '-': /* Ignore these in patterns */ 00867 data--; /* compensate the final data++ */ 00868 break; 00869 default: 00870 if (*data != *pattern) 00871 return 0; 00872 } 00873 data++; 00874 pattern++; 00875 } 00876 if (*data) /* data longer than pattern, no match */ 00877 return 0; 00878 /* 00879 * match so far, but ran off the end of the data. 00880 * Depending on what is next, determine match or not. 00881 */ 00882 if (*pattern == '\0' || *pattern == '/') /* exact match */ 00883 return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */ 00884 else if (*pattern == '!') /* early match */ 00885 return 2; 00886 else /* partial match */ 00887 return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */ 00888 }
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 4722 of file pbx.c.
References ast_change_hint(), ast_log(), ast_exten::data, ast_exten::datad, el, ast_exten::exten, free, LOG_WARNING, ast_context::name, ast_exten::next, ast_exten::peer, ast_exten::priority, PRIORITY_HINT, and ast_context::root.
Referenced by ast_add_extension2().
04724 { 04725 struct ast_exten *ep; 04726 04727 for (ep = NULL; e ; ep = e, e = e->peer) { 04728 if (e->priority >= tmp->priority) 04729 break; 04730 } 04731 if (!e) { /* go at the end, and ep is surely set because the list is not empty */ 04732 ep->peer = tmp; 04733 return 0; /* success */ 04734 } 04735 if (e->priority == tmp->priority) { 04736 /* Can't have something exactly the same. Is this a 04737 replacement? If so, replace, otherwise, bonk. */ 04738 if (!replace) { 04739 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04740 if (tmp->datad) 04741 tmp->datad(tmp->data); 04742 free(tmp); 04743 return -1; 04744 } 04745 /* we are replacing e, so copy the link fields and then update 04746 * whoever pointed to e to point to us 04747 */ 04748 tmp->next = e->next; /* not meaningful if we are not first in the peer list */ 04749 tmp->peer = e->peer; /* always meaningful */ 04750 if (ep) /* We're in the peer list, just insert ourselves */ 04751 ep->peer = tmp; 04752 else if (el) /* We're the first extension. Take over e's functions */ 04753 el->next = tmp; 04754 else /* We're the very first extension. */ 04755 con->root = tmp; 04756 if (tmp->priority == PRIORITY_HINT) 04757 ast_change_hint(e,tmp); 04758 /* Destroy the old one */ 04759 if (e->datad) 04760 e->datad(e->data); 04761 free(e); 04762 } else { /* Slip ourselves in just before e */ 04763 tmp->peer = e; 04764 tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */ 04765 if (ep) /* Easy enough, we're just in the peer list */ 04766 ep->peer = tmp; 04767 else { /* we are the first in some peer list, so link in the ext list */ 04768 if (el) 04769 el->next = tmp; /* in the middle... */ 04770 else 04771 con->root = tmp; /* ... or at the head */ 04772 e->next = NULL; /* e is no more at the head, so e->next must be reset */ 04773 } 04774 /* And immediately return success. */ 04775 if (tmp->priority == PRIORITY_HINT) 04776 ast_add_hint(tmp); 04777 } 04778 return 0; 04779 }
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2709 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02710 { 02711 return countcalls; 02712 }
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 4591 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().
04594 { 04595 int ret = -1; 04596 struct ast_context *c = find_context_locked(context); 04597 04598 if (c) { 04599 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04600 application, data, datad, registrar); 04601 ast_unlock_contexts(); 04602 } 04603 return ret; 04604 }
int ast_add_extension2 | ( | struct ast_context * | con, | |
int | replace, | |||
const char * | extension, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
const char * | application, | |||
void * | data, | |||
void(*)(void *) | datad, | |||
const char * | registrar | |||
) |
Add an extension to an extension context, this time with an ast_context *.
We sort extensions in order of matching preference, so that we can stop the search as soon as we find a suitable match. This ordering also takes care of wildcards such as '.' (meaning "one or more of any character") and '!' (which is 'earlymatch', meaning "zero or more of any character" but also impacts the return value from CANMATCH and EARLYMATCH.
The extension match rules defined in the devmeeting 2006.05.05 are quite simple: WE SELECT THE LONGEST MATCH. In detail, "longest" means the number of matched characters in the extension. In case of ties (e.g. _XXX and 333) in the length of a pattern, we give priority to entries with the smallest cardinality (e.g, [5-9] comes before [2-8] before the former has only 5 elements, while the latter has 7, etc. In case of same cardinality, the first element in the range counts. If we still have a tie, any final '!' will make this as a possibly less specific pattern.
EBUSY - can't lock EEXIST - extension with the same priority exist and no replace is set
Definition at line 4806 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, globalslock, ast_exten::label, ast_context::lock, ast_exten::matchcid, ast_context::name, ast_exten::next, option_verbose, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, ast_context::root, ast_exten::stuff, VAR_BUF_SIZE, and VERBOSE_PREFIX_3.
Referenced by add_extensions(), ast_add_extension(), do_parking_thread(), park_call_full(), pbx_load_config(), and pbx_load_users().
04810 { 04811 /* 04812 * Sort extensions (or patterns) according to the rules indicated above. 04813 * These are implemented by the function ext_cmp()). 04814 * All priorities for the same ext/pattern/cid are kept in a list, 04815 * using the 'peer' field as a link field.. 04816 */ 04817 struct ast_exten *tmp, *e, *el = NULL; 04818 int res; 04819 int length; 04820 char *p; 04821 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04822 04823 /* if we are adding a hint, and there are global variables, and the hint 04824 contains variable references, then expand them 04825 */ 04826 ast_mutex_lock(&globalslock); 04827 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04828 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04829 application = expand_buf; 04830 } 04831 ast_mutex_unlock(&globalslock); 04832 04833 length = sizeof(struct ast_exten); 04834 length += strlen(extension) + 1; 04835 length += strlen(application) + 1; 04836 if (label) 04837 length += strlen(label) + 1; 04838 if (callerid) 04839 length += strlen(callerid) + 1; 04840 else 04841 length ++; /* just the '\0' */ 04842 04843 /* Be optimistic: Build the extension structure first */ 04844 if (!(tmp = ast_calloc(1, length))) 04845 return -1; 04846 04847 /* use p as dst in assignments, as the fields are const char * */ 04848 p = tmp->stuff; 04849 if (label) { 04850 tmp->label = p; 04851 strcpy(p, label); 04852 p += strlen(label) + 1; 04853 } 04854 tmp->exten = p; 04855 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04856 tmp->priority = priority; 04857 tmp->cidmatch = p; /* but use p for assignments below */ 04858 if (callerid) { 04859 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04860 tmp->matchcid = 1; 04861 } else { 04862 *p++ = '\0'; 04863 tmp->matchcid = 0; 04864 } 04865 tmp->app = p; 04866 strcpy(p, application); 04867 tmp->parent = con; 04868 tmp->data = data; 04869 tmp->datad = datad; 04870 tmp->registrar = registrar; 04871 04872 ast_mutex_lock(&con->lock); 04873 res = 0; /* some compilers will think it is uninitialized otherwise */ 04874 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04875 res = ext_cmp(e->exten, tmp->exten); 04876 if (res == 0) { /* extension match, now look at cidmatch */ 04877 if (!e->matchcid && !tmp->matchcid) 04878 res = 0; 04879 else if (tmp->matchcid && !e->matchcid) 04880 res = 1; 04881 else if (e->matchcid && !tmp->matchcid) 04882 res = -1; 04883 else 04884 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04885 } 04886 if (res >= 0) 04887 break; 04888 } 04889 if (e && res == 0) { /* exact match, insert in the pri chain */ 04890 res = add_pri(con, tmp, el, e, replace); 04891 ast_mutex_unlock(&con->lock); 04892 if (res < 0) { 04893 errno = EEXIST; /* XXX do we care ? */ 04894 return 0; /* XXX should we return -1 maybe ? */ 04895 } 04896 } else { 04897 /* 04898 * not an exact match, this is the first entry with this pattern, 04899 * so insert in the main list right before 'e' (if any) 04900 */ 04901 tmp->next = e; 04902 if (el) 04903 el->next = tmp; 04904 else 04905 con->root = tmp; 04906 ast_mutex_unlock(&con->lock); 04907 if (tmp->priority == PRIORITY_HINT) 04908 ast_add_hint(tmp); 04909 } 04910 if (option_debug) { 04911 if (tmp->matchcid) { 04912 if (option_debug) 04913 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04914 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04915 } else { 04916 if (option_debug) 04917 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04918 tmp->exten, tmp->priority, con->name); 04919 } 04920 } 04921 if (option_verbose > 2) { 04922 if (tmp->matchcid) { 04923 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04924 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04925 } else { 04926 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04927 tmp->exten, tmp->priority, con->name); 04928 } 04929 } 04930 return 0; 04931 }
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 2209 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_sw::list, LOG_DEBUG, and option_debug.
Referenced by ast_add_extension2().
02210 { 02211 struct ast_hint *hint; 02212 02213 if (!e) 02214 return -1; 02215 02216 AST_LIST_LOCK(&hints); 02217 02218 /* Search if hint exists, do nothing */ 02219 AST_LIST_TRAVERSE(&hints, hint, list) { 02220 if (hint->exten == e) { 02221 AST_LIST_UNLOCK(&hints); 02222 if (option_debug > 1) 02223 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02224 return -1; 02225 } 02226 } 02227 02228 if (option_debug > 1) 02229 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02230 02231 if (!(hint = ast_calloc(1, sizeof(*hint)))) { 02232 AST_LIST_UNLOCK(&hints); 02233 return -1; 02234 } 02235 /* Initialize and insert new item at the top */ 02236 hint->exten = e; 02237 hint->laststate = ast_extension_state2(e); 02238 AST_LIST_INSERT_HEAD(&hints, hint, list); 02239 02240 AST_LIST_UNLOCK(&hints); 02241 return 0; 02242 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4629 of file pbx.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::amaflags, ast_cdr_discard(), ast_cdr_dup(), ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_pbx_start(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_channel::cdr, ast_channel::context, ast_channel::exten, LOG_WARNING, ast_channel::name, 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(), dahdi_handle_dtmfup(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), and socket_process().
04630 { 04631 int res = 0; 04632 04633 ast_channel_lock(chan); 04634 04635 if (chan->pbx) { /* This channel is currently in the PBX */ 04636 ast_explicit_goto(chan, context, exten, priority); 04637 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04638 } else { 04639 /* In order to do it when the channel doesn't really exist within 04640 the PBX, we have to make a new channel, masquerade, and start the PBX 04641 at the new location */ 04642 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04643 if (!tmpchan) { 04644 res = -1; 04645 } else { 04646 if (chan->cdr) { 04647 ast_cdr_discard(tmpchan->cdr); 04648 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04649 } 04650 /* Make formats okay */ 04651 tmpchan->readformat = chan->readformat; 04652 tmpchan->writeformat = chan->writeformat; 04653 /* Setup proper location */ 04654 ast_explicit_goto(tmpchan, 04655 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04656 04657 /* Masquerade into temp channel */ 04658 if (ast_channel_masquerade(tmpchan, chan)) { 04659 /* Failed to set up the masquerade. It's probably chan_local 04660 * in the middle of optimizing itself out. Sad. :( */ 04661 ast_hangup(tmpchan); 04662 tmpchan = NULL; 04663 res = -1; 04664 } else { 04665 /* Grab the locks and get going */ 04666 ast_channel_lock(tmpchan); 04667 ast_do_masquerade(tmpchan); 04668 ast_channel_unlock(tmpchan); 04669 /* Start the PBX going on our stolen channel */ 04670 if (ast_pbx_start(tmpchan)) { 04671 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04672 ast_hangup(tmpchan); 04673 res = -1; 04674 } 04675 } 04676 } 04677 } 04678 ast_channel_unlock(chan); 04679 return res; 04680 }
int ast_async_goto_by_name | ( | const char * | channame, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4682 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04683 { 04684 struct ast_channel *chan; 04685 int res = -1; 04686 04687 chan = ast_get_channel_by_name_locked(channame); 04688 if (chan) { 04689 res = ast_async_goto(chan, context, exten, priority); 04690 ast_channel_unlock(chan); 04691 } 04692 return res; 04693 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6483 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06484 { 06485 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06486 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info_in | |||
) |
Definition at line 4269 of file pbx.c.
References ast_copy_string(), ast_strlen_zero(), ast_timing::daymask, days, ast_timing::dowmask, get_range(), get_timerange(), ast_timing::monthmask, and months.
Referenced by ast_context_add_include2(), iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime().
04270 { 04271 char info_save[256]; 04272 char *info; 04273 04274 /* Check for empty just in case */ 04275 if (ast_strlen_zero(info_in)) 04276 return 0; 04277 /* make a copy just in case we were passed a static string */ 04278 ast_copy_string(info_save, info_in, sizeof(info_save)); 04279 info = info_save; 04280 /* Assume everything except time */ 04281 i->monthmask = 0xfff; /* 12 bits */ 04282 i->daymask = 0x7fffffffU; /* 31 bits */ 04283 i->dowmask = 0x7f; /* 7 bits */ 04284 /* on each call, use strsep() to move info to the next argument */ 04285 get_timerange(i, strsep(&info, "|")); 04286 if (info) 04287 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04288 if (info) 04289 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04290 if (info) 04291 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04292 return 1; 04293 }
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 2333 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().
02334 { 02335 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02336 }
ast_change_hint: Change hint for an extension
Definition at line 2245 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::exten, and ast_sw::list.
Referenced by add_pri().
02246 { 02247 struct ast_hint *hint; 02248 int res = -1; 02249 02250 AST_LIST_LOCK(&hints); 02251 AST_LIST_TRAVERSE(&hints, hint, list) { 02252 if (hint->exten == oe) { 02253 hint->exten = ne; 02254 res = 0; 02255 break; 02256 } 02257 } 02258 AST_LIST_UNLOCK(&hints); 02259 02260 return res; 02261 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4295 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().
04296 { 04297 struct tm tm; 04298 time_t t = time(NULL); 04299 04300 ast_localtime(&t, &tm, NULL); 04301 04302 /* If it's not the right month, return */ 04303 if (!(i->monthmask & (1 << tm.tm_mon))) 04304 return 0; 04305 04306 /* If it's not that time of the month.... */ 04307 /* Warning, tm_mday has range 1..31! */ 04308 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04309 return 0; 04310 04311 /* If it's not the right day of the week */ 04312 if (!(i->dowmask & (1 << tm.tm_wday))) 04313 return 0; 04314 04315 /* Sanity check the hour just to be safe */ 04316 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04317 ast_log(LOG_WARNING, "Insane time...\n"); 04318 return 0; 04319 } 04320 04321 /* Now the tough part, we calculate if it fits 04322 in the right time based on min/hour */ 04323 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04324 return 0; 04325 04326 /* If we got this far, then we're good */ 04327 return 1; 04328 }
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 4522 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().
04523 { 04524 int ret = -1; 04525 struct ast_context *c = find_context_locked(context); 04526 04527 if (c) { 04528 ret = ast_context_add_ignorepat2(c, value, registrar); 04529 ast_unlock_contexts(); 04530 } 04531 return ret; 04532 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | value, | |||
const char * | registrar | |||
) |
Definition at line 4534 of file pbx.c.
References ast_calloc, ast_mutex_lock(), ast_mutex_unlock(), errno, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar.
Referenced by ast_context_add_ignorepat(), and pbx_load_config().
04535 { 04536 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04537 int length; 04538 char *pattern; 04539 length = sizeof(struct ast_ignorepat); 04540 length += strlen(value) + 1; 04541 if (!(ignorepat = ast_calloc(1, length))) 04542 return -1; 04543 /* The cast to char * is because we need to write the initial value. 04544 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04545 * sees the cast as dereferencing a type-punned pointer and warns about 04546 * it. This is the workaround (we're telling gcc, yes, that's really 04547 * what we wanted to do). 04548 */ 04549 pattern = (char *) ignorepat->pattern; 04550 strcpy(pattern, value); 04551 ignorepat->next = NULL; 04552 ignorepat->registrar = registrar; 04553 ast_mutex_lock(&con->lock); 04554 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04555 ignorepatl = ignorepatc; 04556 if (!strcasecmp(ignorepatc->pattern, value)) { 04557 /* Already there */ 04558 ast_mutex_unlock(&con->lock); 04559 errno = EEXIST; 04560 return -1; 04561 } 04562 } 04563 if (ignorepatl) 04564 ignorepatl->next = ignorepat; 04565 else 04566 con->ignorepats = ignorepat; 04567 ast_mutex_unlock(&con->lock); 04568 return 0; 04569 04570 }
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 4075 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().
04076 { 04077 int ret = -1; 04078 struct ast_context *c = find_context_locked(context); 04079 04080 if (c) { 04081 ret = ast_context_add_include2(c, include, registrar); 04082 ast_unlock_contexts(); 04083 } 04084 return ret; 04085 }
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 4337 of file pbx.c.
References ast_build_timing(), ast_calloc, ast_get_context_name(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), errno, free, ast_include::hastime, ast_context::includes, ast_context::lock, ast_include::name, ast_include::next, option_verbose, ast_include::registrar, ast_include::rname, ast_include::stuff, ast_include::timing, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_include(), and pbx_load_config().
04339 { 04340 struct ast_include *new_include; 04341 char *c; 04342 struct ast_include *i, *il = NULL; /* include, include_last */ 04343 int length; 04344 char *p; 04345 04346 length = sizeof(struct ast_include); 04347 length += 2 * (strlen(value) + 1); 04348 04349 /* allocate new include structure ... */ 04350 if (!(new_include = ast_calloc(1, length))) 04351 return -1; 04352 /* Fill in this structure. Use 'p' for assignments, as the fields 04353 * in the structure are 'const char *' 04354 */ 04355 p = new_include->stuff; 04356 new_include->name = p; 04357 strcpy(p, value); 04358 p += strlen(value) + 1; 04359 new_include->rname = p; 04360 strcpy(p, value); 04361 /* Strip off timing info, and process if it is there */ 04362 if ( (c = strchr(p, '|')) ) { 04363 *c++ = '\0'; 04364 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04365 } 04366 new_include->next = NULL; 04367 new_include->registrar = registrar; 04368 04369 ast_mutex_lock(&con->lock); 04370 04371 /* ... go to last include and check if context is already included too... */ 04372 for (i = con->includes; i; i = i->next) { 04373 if (!strcasecmp(i->name, new_include->name)) { 04374 free(new_include); 04375 ast_mutex_unlock(&con->lock); 04376 errno = EEXIST; 04377 return -1; 04378 } 04379 il = i; 04380 } 04381 04382 /* ... include new context into context list, unlock, return */ 04383 if (il) 04384 il->next = new_include; 04385 else 04386 con->includes = new_include; 04387 if (option_verbose > 2) 04388 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04389 ast_mutex_unlock(&con->lock); 04390 04391 return 0; 04392 }
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 4399 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04400 { 04401 int ret = -1; 04402 struct ast_context *c = find_context_locked(context); 04403 04404 if (c) { /* found, add switch to this context */ 04405 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04406 ast_unlock_contexts(); 04407 } 04408 return ret; 04409 }
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 4418 of file pbx.c.
References ast_context::alts, 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, store_hint::list, ast_context::lock, ast_sw::name, option_verbose, ast_sw::registrar, ast_sw::stuff, and VERBOSE_PREFIX_3.
Referenced by ast_context_add_switch(), and pbx_load_config().
04420 { 04421 struct ast_sw *new_sw; 04422 struct ast_sw *i; 04423 int length; 04424 char *p; 04425 04426 length = sizeof(struct ast_sw); 04427 length += strlen(value) + 1; 04428 if (data) 04429 length += strlen(data); 04430 length++; 04431 04432 /* allocate new sw structure ... */ 04433 if (!(new_sw = ast_calloc(1, length))) 04434 return -1; 04435 /* ... fill in this structure ... */ 04436 p = new_sw->stuff; 04437 new_sw->name = p; 04438 strcpy(new_sw->name, value); 04439 p += strlen(value) + 1; 04440 new_sw->data = p; 04441 if (data) { 04442 strcpy(new_sw->data, data); 04443 p += strlen(data) + 1; 04444 } else { 04445 strcpy(new_sw->data, ""); 04446 p++; 04447 } 04448 new_sw->eval = eval; 04449 new_sw->registrar = registrar; 04450 04451 /* ... try to lock this context ... */ 04452 ast_mutex_lock(&con->lock); 04453 04454 /* ... go to last sw and check if context is already swd too... */ 04455 AST_LIST_TRAVERSE(&con->alts, i, list) { 04456 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04457 free(new_sw); 04458 ast_mutex_unlock(&con->lock); 04459 errno = EEXIST; 04460 return -1; 04461 } 04462 } 04463 04464 /* ... sw new context into context list, unlock, return */ 04465 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04466 04467 if (option_verbose > 2) 04468 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04469 04470 ast_mutex_unlock(&con->lock); 04471 04472 return 0; 04473 }
struct ast_context* ast_context_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
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 3945 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03946 { 03947 return __ast_context_create(extcontexts, name, registrar, 0); 03948 }
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 5387 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().
05388 { 05389 ast_wrlock_contexts(); 05390 __ast_context_destroy(con,registrar); 05391 ast_unlock_contexts(); 05392 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 918 of file pbx.c.
References ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::name.
Referenced by _macro_exec(), ast_context_verify_includes(), ast_ignore_pattern(), cleanup_stale_contexts(), do_parking_thread(), park_call_full(), park_exec(), register_peer_exten(), and set_config().
00919 { 00920 struct ast_context *tmp = NULL; 00921 00922 ast_rdlock_contexts(); 00923 00924 while ( (tmp = ast_walk_contexts(tmp)) ) { 00925 if (!name || !strcasecmp(name, tmp->name)) 00926 break; 00927 } 00928 00929 ast_unlock_contexts(); 00930 00931 return tmp; 00932 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
Definition at line 3950 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03951 { 03952 return __ast_context_create(extcontexts, name, registrar, 1); 03953 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2946 of file pbx.c.
References ast_get_context_name(), ast_mutex_lock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.
Referenced by _macro_exec().
02947 { 02948 struct ast_context *c = NULL; 02949 int ret = -1; 02950 02951 ast_rdlock_contexts(); 02952 02953 while ((c = ast_walk_contexts(c))) { 02954 if (!strcmp(ast_get_context_name(c), context)) { 02955 ret = 0; 02956 break; 02957 } 02958 } 02959 02960 ast_unlock_contexts(); 02961 02962 /* if we found context, lock macrolock */ 02963 if (ret == 0) 02964 ret = ast_mutex_lock(&c->macrolock); 02965 02966 return ret; 02967 }
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 (0 to remove all) | |
callerid | NULL to remove all; non-NULL to match a single record per priority | |
matchcid | non-zero to match callerid element (if non-NULL); 0 to match default case | |
registrar | registrar of the extension |
0 | on success | |
-1 | on failure |
Definition at line 2847 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02848 { 02849 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02850 }
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 2874 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02875 { 02876 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02877 }
int ast_context_remove_extension_callerid | ( | const char * | context, | |
const char * | extension, | |||
int | priority, | |||
const char * | callerid, | |||
int | matchcid, | |||
const char * | registrar | |||
) |
Definition at line 2852 of file pbx.c.
References ast_context_remove_extension_callerid2(), ast_unlock_contexts(), and find_context_locked().
Referenced by ast_context_remove_extension(), handle_context_remove_extension(), and handle_context_remove_extension_deprecated().
02853 { 02854 int ret = -1; /* default error return */ 02855 struct ast_context *c = find_context_locked(context); 02856 02857 if (c) { /* ... remove extension ... */ 02858 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02859 ast_unlock_contexts(); 02860 } 02861 return ret; 02862 }
int ast_context_remove_extension_callerid2 | ( | struct ast_context * | con, | |
const char * | extension, | |||
int | priority, | |||
const char * | callerid, | |||
int | matchcid, | |||
const char * | registrar | |||
) |
Definition at line 2879 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_exten::cidmatch, destroy_exten(), exten, ast_exten::exten, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::priority, ast_exten::registrar, and ast_context::root.
Referenced by ast_context_remove_extension2(), and ast_context_remove_extension_callerid().
02880 { 02881 struct ast_exten *exten, *prev_exten = NULL; 02882 struct ast_exten *peer; 02883 struct ast_exten *previous_peer = NULL; 02884 struct ast_exten *next_peer = NULL; 02885 int found = 0; 02886 02887 ast_mutex_lock(&con->lock); 02888 02889 /* scan the extension list to find first matching extension-registrar */ 02890 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02891 if (!strcmp(exten->exten, extension) && 02892 (!registrar || !strcmp(exten->registrar, registrar))) 02893 break; 02894 } 02895 if (!exten) { 02896 /* we can't find right extension */ 02897 ast_mutex_unlock(&con->lock); 02898 return -1; 02899 } 02900 02901 /* scan the priority list to remove extension with exten->priority == priority */ 02902 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02903 peer && !strcmp(peer->exten, extension); 02904 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02905 if ((priority == 0 || peer->priority == priority) && 02906 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02907 (!registrar || !strcmp(peer->registrar, registrar) )) { 02908 found = 1; 02909 02910 /* we are first priority extension? */ 02911 if (!previous_peer) { 02912 /* 02913 * We are first in the priority chain, so must update the extension chain. 02914 * The next node is either the next priority or the next extension 02915 */ 02916 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02917 02918 if (!prev_exten) { /* change the root... */ 02919 con->root = next_node; 02920 } else { 02921 prev_exten->next = next_node; /* unlink */ 02922 } 02923 if (peer->peer) { /* update the new head of the pri list */ 02924 peer->peer->next = peer->next; 02925 } 02926 } else { /* easy, we are not first priority in extension */ 02927 previous_peer->peer = peer->peer; 02928 } 02929 02930 /* now, free whole priority extension */ 02931 destroy_exten(peer); 02932 } else { 02933 previous_peer = peer; 02934 } 02935 } 02936 ast_mutex_unlock(&con->lock); 02937 return found ? 0 : -1; 02938 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4479 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().
04480 { 04481 int ret = -1; 04482 struct ast_context *c = find_context_locked(context); 04483 04484 if (c) { 04485 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04486 ast_unlock_contexts(); 04487 } 04488 return ret; 04489 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4491 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().
04492 { 04493 struct ast_ignorepat *ip, *ipl = NULL; 04494 04495 ast_mutex_lock(&con->lock); 04496 04497 for (ip = con->ignorepats; ip; ip = ip->next) { 04498 if (!strcmp(ip->pattern, ignorepat) && 04499 (!registrar || (registrar == ip->registrar))) { 04500 if (ipl) { 04501 ipl->next = ip->next; 04502 free(ip); 04503 } else { 04504 con->ignorepats = ip->next; 04505 free(ip); 04506 } 04507 ast_mutex_unlock(&con->lock); 04508 return 0; 04509 } 04510 ipl = ip; 04511 } 04512 04513 ast_mutex_unlock(&con->lock); 04514 errno = EINVAL; 04515 return -1; 04516 }
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 2743 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().
02744 { 02745 int ret = -1; 02746 struct ast_context *c = find_context_locked(context); 02747 02748 if (c) { 02749 /* found, remove include from this context ... */ 02750 ret = ast_context_remove_include2(c, include, registrar); 02751 ast_unlock_contexts(); 02752 } 02753 return ret; 02754 }
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 2764 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().
02765 { 02766 struct ast_include *i, *pi = NULL; 02767 int ret = -1; 02768 02769 ast_mutex_lock(&con->lock); 02770 02771 /* find our include */ 02772 for (i = con->includes; i; pi = i, i = i->next) { 02773 if (!strcmp(i->name, include) && 02774 (!registrar || !strcmp(i->registrar, registrar))) { 02775 /* remove from list */ 02776 if (pi) 02777 pi->next = i->next; 02778 else 02779 con->includes = i->next; 02780 /* free include and return */ 02781 free(i); 02782 ret = 0; 02783 break; 02784 } 02785 } 02786 02787 ast_mutex_unlock(&con->lock); 02788 return ret; 02789 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2796 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02797 { 02798 int ret = -1; /* default error return */ 02799 struct ast_context *c = find_context_locked(context); 02800 02801 if (c) { 02802 /* remove switch from this context ... */ 02803 ret = ast_context_remove_switch2(c, sw, data, registrar); 02804 ast_unlock_contexts(); 02805 } 02806 return ret; 02807 }
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 2817 of file pbx.c.
References ast_context::alts, 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_sw::list, ast_context::lock, ast_sw::name, and ast_sw::registrar.
Referenced by ast_context_remove_switch().
02818 { 02819 struct ast_sw *i; 02820 int ret = -1; 02821 02822 ast_mutex_lock(&con->lock); 02823 02824 /* walk switches */ 02825 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02826 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02827 (!registrar || !strcmp(i->registrar, registrar))) { 02828 /* found, remove from list */ 02829 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02830 free(i); /* free switch and return */ 02831 ret = 0; 02832 break; 02833 } 02834 } 02835 AST_LIST_TRAVERSE_SAFE_END 02836 02837 ast_mutex_unlock(&con->lock); 02838 02839 return ret; 02840 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2974 of file pbx.c.
References ast_get_context_name(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), and ast_context::macrolock.
Referenced by _macro_exec().
02975 { 02976 struct ast_context *c = NULL; 02977 int ret = -1; 02978 02979 ast_rdlock_contexts(); 02980 02981 while ((c = ast_walk_contexts(c))) { 02982 if (!strcmp(ast_get_context_name(c), context)) { 02983 ret = 0; 02984 break; 02985 } 02986 } 02987 02988 ast_unlock_contexts(); 02989 02990 /* if we found context, unlock macrolock */ 02991 if (ret == 0) 02992 ret = ast_mutex_unlock(&c->macrolock); 02993 02994 return ret; 02995 }
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 6440 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().
06441 { 06442 struct ast_include *inc = NULL; 06443 int res = 0; 06444 06445 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06446 if (ast_context_find(inc->rname)) 06447 continue; 06448 06449 res = -1; 06450 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06451 ast_get_context_name(con), inc->rname); 06452 break; 06453 } 06454 06455 return res; 06456 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 1480 of file pbx.c.
References ast_custom_function::acflist, 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().
01481 { 01482 struct ast_custom_function *acf = NULL; 01483 01484 AST_LIST_LOCK(&acf_root); 01485 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01486 if (!strcmp(name, acf->name)) 01487 break; 01488 } 01489 AST_LIST_UNLOCK(&acf_root); 01490 01491 return acf; 01492 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1516 of file pbx.c.
References ast_custom_function::acflist, 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().
01517 { 01518 struct ast_custom_function *cur; 01519 01520 if (!acf) 01521 return -1; 01522 01523 AST_LIST_LOCK(&acf_root); 01524 01525 if (ast_custom_function_find(acf->name)) { 01526 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01527 AST_LIST_UNLOCK(&acf_root); 01528 return -1; 01529 } 01530 01531 /* Store in alphabetical order */ 01532 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01533 if (strcasecmp(acf->name, cur->name) < 0) { 01534 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01535 break; 01536 } 01537 } 01538 AST_LIST_TRAVERSE_SAFE_END 01539 if (!cur) 01540 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01541 01542 AST_LIST_UNLOCK(&acf_root); 01543 01544 if (option_verbose > 1) 01545 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01546 01547 return 0; 01548 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1494 of file pbx.c.
References ast_custom_function::acflist, 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().
01495 { 01496 struct ast_custom_function *cur; 01497 01498 if (!acf) 01499 return -1; 01500 01501 AST_LIST_LOCK(&acf_root); 01502 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01503 if (cur == acf) { 01504 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01505 if (option_verbose > 1) 01506 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01507 break; 01508 } 01509 } 01510 AST_LIST_TRAVERSE_SAFE_END 01511 AST_LIST_UNLOCK(&acf_root); 01512 01513 return acf ? 0 : -1; 01514 }
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 2318 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_bridge_call(), ast_pbx_outgoing_exten(), builtin_blindtransfer(), cb_events(), conf_run(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), disa_exec(), do_atxfer(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), process_ast_dsp(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().
02319 { 02320 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02321 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4606 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_FLAG_IN_AUTOLOOP, ast_strlen_zero(), ast_test_flag, ast_channel::context, ast_channel::exten, and ast_channel::priority.
Referenced by __ast_goto_if_exists(), ast_async_goto(), ast_parseable_goto(), disa_exec(), do_atxfer(), and handle_setpriority().
04607 { 04608 if (!chan) 04609 return -1; 04610 04611 ast_channel_lock(chan); 04612 04613 if (!ast_strlen_zero(context)) 04614 ast_copy_string(chan->context, context, sizeof(chan->context)); 04615 if (!ast_strlen_zero(exten)) 04616 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04617 if (priority > -1) { 04618 chan->priority = priority; 04619 /* see flag description in channel.h for explanation */ 04620 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04621 chan->priority--; 04622 } 04623 04624 ast_channel_unlock(chan); 04625 04626 return 0; 04627 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 911 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00912 { 00913 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00914 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00915 return extension_match_core(pattern, data, needmore); 00916 }
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 906 of file pbx.c.
References E_MATCH, and extension_match_core().
Referenced by ast_ignore_pattern(), do_say(), find_matching_priority(), loopback_canmatch(), loopback_exists(), loopback_matchmore(), matchcid(), misdn_cfg_is_msn_valid(), realtime_switch_common(), and show_dialplan_helper().
00907 { 00908 return extension_match_core(pattern, data, E_MATCH); 00909 }
int ast_extension_state | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten | |||
) |
Uses hint and devicestate callback to get the state of an extension.
c | this is not important | |
context | which context to look in | |
exten | which extension to get state |
Definition at line 2040 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
02041 { 02042 struct ast_exten *e; 02043 02044 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 02045 if (!e) 02046 return -1; /* No hint, return -1 */ 02047 02048 return ast_extension_state2(e); /* Check all devices in the hint */ 02049 }
static int ast_extension_state2 | ( | struct ast_exten * | e | ) | [static] |
ast_extensions_state2: Check state of extension by using hints
Definition at line 1943 of file pbx.c.
References ast_copy_string(), 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, and ring().
Referenced by ast_add_hint(), ast_extension_state(), and ast_hint_state_changed().
01944 { 01945 char hint[AST_MAX_EXTENSION]; 01946 char *cur, *rest; 01947 int allunavailable = 1, allbusy = 1, allfree = 1, allonhold = 1; 01948 int busy = 0, inuse = 0, ring = 0; 01949 01950 if (!e) 01951 return -1; 01952 01953 ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint)); 01954 01955 rest = hint; /* One or more devices separated with a & character */ 01956 while ( (cur = strsep(&rest, "&")) ) { 01957 int res = ast_device_state(cur); 01958 switch (res) { 01959 case AST_DEVICE_NOT_INUSE: 01960 allunavailable = 0; 01961 allbusy = 0; 01962 allonhold = 0; 01963 break; 01964 case AST_DEVICE_INUSE: 01965 inuse = 1; 01966 allunavailable = 0; 01967 allfree = 0; 01968 allonhold = 0; 01969 break; 01970 case AST_DEVICE_RINGING: 01971 ring = 1; 01972 allunavailable = 0; 01973 allfree = 0; 01974 allonhold = 0; 01975 break; 01976 case AST_DEVICE_RINGINUSE: 01977 inuse = 1; 01978 ring = 1; 01979 allunavailable = 0; 01980 allfree = 0; 01981 allonhold = 0; 01982 break; 01983 case AST_DEVICE_ONHOLD: 01984 allunavailable = 0; 01985 allfree = 0; 01986 break; 01987 case AST_DEVICE_BUSY: 01988 allunavailable = 0; 01989 allfree = 0; 01990 allonhold = 0; 01991 busy = 1; 01992 break; 01993 case AST_DEVICE_UNAVAILABLE: 01994 case AST_DEVICE_INVALID: 01995 allbusy = 0; 01996 allfree = 0; 01997 allonhold = 0; 01998 break; 01999 default: 02000 allunavailable = 0; 02001 allbusy = 0; 02002 allfree = 0; 02003 allonhold = 0; 02004 } 02005 } 02006 02007 if (!inuse && ring) 02008 return AST_EXTENSION_RINGING; 02009 if (inuse && ring) 02010 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 02011 if (inuse) 02012 return AST_EXTENSION_INUSE; 02013 if (allfree) 02014 return AST_EXTENSION_NOT_INUSE; 02015 if (allonhold) 02016 return AST_EXTENSION_ONHOLD; 02017 if (allbusy) 02018 return AST_EXTENSION_BUSY; 02019 if (allunavailable) 02020 return AST_EXTENSION_UNAVAILABLE; 02021 if (busy) 02022 return AST_EXTENSION_INUSE; 02023 02024 return AST_EXTENSION_NOT_INUSE; 02025 }
const char* ast_extension_state2str | ( | int | extension_state | ) |
Return string representation of the state of an extension.
extension_state | is the numerical state delivered by ast_extension_state |
Definition at line 2028 of file pbx.c.
References extension_states.
Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
02029 { 02030 int i; 02031 02032 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 02033 if (extension_states[i].extension_state == extension_state) 02034 return extension_states[i].text; 02035 } 02036 return "Unknown"; 02037 }
int ast_extension_state_add | ( | const char * | context, | |
const char * | exten, | |||
ast_state_cb_type | callback, | |||
void * | data | |||
) |
Registers a state change callback.
context | which context to look in | |
exten | which extension to get state | |
callback | callback to call if state changed | |
data | to pass to callback |
-1 | on failure | |
ID | on success |
Definition at line 2097 of file pbx.c.
References ast_calloc, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_state_cb::callback, ast_state_cb::data, ast_state_cb::next, and statecbs.
Referenced by handle_request_subscribe(), and init_manager().
02099 { 02100 struct ast_hint *hint; 02101 struct ast_state_cb *cblist; 02102 struct ast_exten *e; 02103 02104 /* If there's no context and extension: add callback to statecbs list */ 02105 if (!context && !exten) { 02106 AST_LIST_LOCK(&hints); 02107 02108 for (cblist = statecbs; cblist; cblist = cblist->next) { 02109 if (cblist->callback == callback) { 02110 cblist->data = data; 02111 AST_LIST_UNLOCK(&hints); 02112 return 0; 02113 } 02114 } 02115 02116 /* Now insert the callback */ 02117 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02118 AST_LIST_UNLOCK(&hints); 02119 return -1; 02120 } 02121 cblist->id = 0; 02122 cblist->callback = callback; 02123 cblist->data = data; 02124 02125 cblist->next = statecbs; 02126 statecbs = cblist; 02127 02128 AST_LIST_UNLOCK(&hints); 02129 return 0; 02130 } 02131 02132 if (!context || !exten) 02133 return -1; 02134 02135 /* This callback type is for only one hint, so get the hint */ 02136 e = ast_hint_extension(NULL, context, exten); 02137 if (!e) { 02138 return -1; 02139 } 02140 02141 /* Find the hint in the list of hints */ 02142 AST_LIST_LOCK(&hints); 02143 02144 AST_LIST_TRAVERSE(&hints, hint, list) { 02145 if (hint->exten == e) 02146 break; 02147 } 02148 02149 if (!hint) { 02150 /* We have no hint, sorry */ 02151 AST_LIST_UNLOCK(&hints); 02152 return -1; 02153 } 02154 02155 /* Now insert the callback in the callback list */ 02156 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02157 AST_LIST_UNLOCK(&hints); 02158 return -1; 02159 } 02160 cblist->id = stateid++; /* Unique ID for this callback */ 02161 cblist->callback = callback; /* Pointer to callback routine */ 02162 cblist->data = data; /* Data for the callback */ 02163 02164 cblist->next = hint->callbacks; 02165 hint->callbacks = cblist; 02166 02167 AST_LIST_UNLOCK(&hints); 02168 return cblist->id; 02169 }
int ast_extension_state_del | ( | int | id, | |
ast_state_cb_type | callback | |||
) |
Deletes a registered state change callback by ID.
id | of the callback to delete | |
callback | callback |
0 | success | |
-1 | failure |
Definition at line 2172 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_hint::callbacks, free, ast_sw::list, ast_state_cb::next, and statecbs.
Referenced by __sip_destroy(), and handle_request_subscribe().
02173 { 02174 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02175 int ret = -1; 02176 02177 if (!id && !callback) 02178 return -1; 02179 02180 AST_LIST_LOCK(&hints); 02181 02182 if (!id) { /* id == 0 is a callback without extension */ 02183 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02184 if ((*p_cur)->callback == callback) 02185 break; 02186 } 02187 } else { /* callback with extension, find the callback based on ID */ 02188 struct ast_hint *hint; 02189 AST_LIST_TRAVERSE(&hints, hint, list) { 02190 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02191 if ((*p_cur)->id == id) 02192 break; 02193 } 02194 if (*p_cur) /* found in the inner loop */ 02195 break; 02196 } 02197 } 02198 if (p_cur && *p_cur) { 02199 struct ast_state_cb *cur = *p_cur; 02200 *p_cur = cur->next; 02201 free(cur); 02202 ret = 0; 02203 } 02204 AST_LIST_UNLOCK(&hints); 02205 return ret; 02206 }
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 2323 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().
02324 { 02325 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02326 }
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.
This function is the same as ast_findlabel_extension, except that it accepts a pointer to an ast_context structure to specify the context instead of the name of the context. Otherwise, the functions behave the same.
Definition at line 2328 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02329 { 02330 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02331 }
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 1570 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().
01571 { 01572 char *args = func_args(function); 01573 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01574 01575 if (acfptr == NULL) 01576 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01577 else if (!acfptr->read) 01578 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01579 else 01580 return acfptr->read(chan, function, args, workspace, len); 01581 return -1; 01582 }
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 1584 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().
01585 { 01586 char *args = func_args(function); 01587 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01588 01589 if (acfptr == NULL) 01590 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01591 else if (!acfptr->write) 01592 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01593 else 01594 return acfptr->write(chan, function, args, value); 01595 01596 return -1; 01597 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6297 of file pbx.c.
References ast_context::name.
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().
06298 { 06299 return con ? con->name : NULL; 06300 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6335 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06336 { 06337 return c ? c->registrar : NULL; 06338 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6365 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().
06366 { 06367 return e ? e->app : NULL; 06368 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6370 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06371 { 06372 return e ? e->data : NULL; 06373 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6360 of file pbx.c.
References ast_exten::cidmatch.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), and handle_save_dialplan().
06361 { 06362 return e ? e->cidmatch : NULL; 06363 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | exten | ) |
Definition at line 6312 of file pbx.c.
References exten.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
int ast_get_extension_matchcid | ( | struct ast_exten * | e | ) |
Definition at line 6355 of file pbx.c.
References ast_exten::matchcid.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), and handle_save_dialplan().
06356 { 06357 return e ? e->matchcid : 0; 06358 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6307 of file pbx.c.
References exten.
Referenced by ast_add_hint(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().
int ast_get_extension_priority | ( | struct ast_exten * | exten | ) |
Definition at line 6327 of file pbx.c.
References exten.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), and print_ext().
const char* ast_get_extension_registrar | ( | struct ast_exten * | e | ) |
Definition at line 6340 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06341 { 06342 return e ? e->registrar : NULL; 06343 }
int ast_get_hint | ( | char * | hint, | |
int | maxlen, | |||
char * | name, | |||
int | maxnamelen, | |||
struct ast_channel * | c, | |||
const char * | context, | |||
const char * | exten | |||
) |
If an extension exists, return non-zero.
hint | buffer for hint | |
maxlen | size of hint buffer | |
name | buffer for name portion of hint | |
maxnamelen | size of name buffer | |
c | this is not important | |
context | which context to look in | |
exten | which extension to search for |
Definition at line 2301 of file pbx.c.
References ast_copy_string(), ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension().
Referenced by action_extensionstate(), get_cid_name(), get_destination(), pbx_retrieve_variable(), and transmit_state_notify().
02302 { 02303 struct ast_exten *e = ast_hint_extension(c, context, exten); 02304 02305 if (e) { 02306 if (hint) 02307 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02308 if (name) { 02309 const char *tmp = ast_get_extension_app_data(e); 02310 if (tmp) 02311 ast_copy_string(name, tmp, namesize); 02312 } 02313 return -1; 02314 } 02315 return 0; 02316 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6322 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().
06323 { 06324 return ip ? ip->pattern : NULL; 06325 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6350 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06351 { 06352 return ip ? ip->registrar : NULL; 06353 }
const char* ast_get_include_name | ( | struct ast_include * | inc | ) |
Definition at line 6317 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().
06318 { 06319 return inc ? inc->name : NULL; 06320 }
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6345 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06346 { 06347 return i ? i->registrar : NULL; 06348 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6380 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06381 { 06382 return sw ? sw->data : NULL; 06383 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6375 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06376 { 06377 return sw ? sw->name : NULL; 06378 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6385 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06386 { 06387 return sw ? sw->registrar : NULL; 06388 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6478 of file pbx.c.
References __ast_goto_if_exists().
Referenced by aqm_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), do_directory(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), onedigit_goto(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), system_exec_helper(), transfer_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer().
06479 { 06480 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06481 }
static struct ast_exten* ast_hint_extension | ( | struct ast_channel * | c, | |
const char * | context, | |||
const char * | exten | |||
) | [static] |
ast_hint_extension: Find hint for given extension in context
Definition at line 1930 of file pbx.c.
References ast_rdlock_contexts(), ast_unlock_contexts(), E_MATCH, pbx_find_extension(), PRIORITY_HINT, and pbx_find_info::stacklen.
Referenced by ast_extension_state(), and ast_get_hint().
01931 { 01932 struct ast_exten *e; 01933 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */ 01934 01935 ast_rdlock_contexts(); 01936 e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH); 01937 ast_unlock_contexts(); 01938 01939 return e; 01940 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 2051 of file pbx.c.
References ast_copy_string(), ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_rdlock_contexts(), ast_unlock_contexts(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_exten::exten, ast_hint::laststate, ast_sw::list, ast_context::name, ast_state_cb::next, ast_exten::parent, parse(), and statecbs.
Referenced by do_state_change().
02052 { 02053 struct ast_hint *hint; 02054 02055 ast_rdlock_contexts(); 02056 AST_LIST_LOCK(&hints); 02057 02058 AST_LIST_TRAVERSE(&hints, hint, list) { 02059 struct ast_state_cb *cblist; 02060 char buf[AST_MAX_EXTENSION]; 02061 char *parse = buf; 02062 char *cur; 02063 int state; 02064 02065 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02066 while ( (cur = strsep(&parse, "&")) ) { 02067 if (!strcasecmp(cur, device)) 02068 break; 02069 } 02070 if (!cur) 02071 continue; 02072 02073 /* Get device state for this hint */ 02074 state = ast_extension_state2(hint->exten); 02075 02076 if ((state == -1) || (state == hint->laststate)) 02077 continue; 02078 02079 /* Device state changed since last check - notify the watchers */ 02080 02081 /* For general callbacks */ 02082 for (cblist = statecbs; cblist; cblist = cblist->next) 02083 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02084 02085 /* For extension callbacks */ 02086 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02087 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02088 02089 hint->laststate = state; /* record we saw the change */ 02090 } 02091 02092 AST_LIST_UNLOCK(&hints); 02093 ast_unlock_contexts(); 02094 }
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 4572 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().
04573 { 04574 struct ast_context *con = ast_context_find(context); 04575 if (con) { 04576 struct ast_ignorepat *pat; 04577 for (pat = con->ignorepats; pat; pat = pat->next) { 04578 if (ast_extension_match(pat->pattern, pattern)) 04579 return 1; 04580 } 04581 } 04582 04583 return 0; 04584 }
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 6284 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().
06285 { 06286 return ast_mutex_lock(&con->lock); 06287 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6261 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by find_matching_endwhile().
06262 { 06263 return ast_rwlock_wrlock(&conlock); 06264 }
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 2338 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().
02339 { 02340 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02341 }
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 3968 of file pbx.c.
References __ast_context_destroy(), ast_calloc, AST_EXTENSION_REMOVED, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_unlock_contexts(), ast_wrlock_contexts(), ast_state_cb::callback, ast_hint::callbacks, store_hint::callbacks, store_hint::context, contexts, ast_state_cb::data, E_MATCH, store_hint::exten, ast_hint::exten, ast_exten::exten, free, store_hint::laststate, ast_hint::laststate, store_hint::list, LOG_WARNING, ast_context::name, ast_context::next, ast_state_cb::next, ast_exten::parent, pbx_find_extension(), PRIORITY_HINT, ast_context::registrar, and pbx_find_info::stacklen.
Referenced by pbx_load_module().
03969 { 03970 struct ast_context *tmp, *lasttmp = NULL; 03971 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03972 struct store_hint *this; 03973 struct ast_hint *hint; 03974 struct ast_exten *exten; 03975 int length; 03976 struct ast_state_cb *thiscb, *prevcb; 03977 03978 /* it is very important that this function hold the hint list lock _and_ the conlock 03979 during its operation; not only do we need to ensure that the list of contexts 03980 and extensions does not change, but also that no hint callbacks (watchers) are 03981 added or removed during the merge/delete process 03982 03983 in addition, the locks _must_ be taken in this order, because there are already 03984 other code paths that use this order 03985 */ 03986 ast_wrlock_contexts(); 03987 AST_LIST_LOCK(&hints); 03988 03989 /* preserve all watchers for hints associated with this registrar */ 03990 AST_LIST_TRAVERSE(&hints, hint, list) { 03991 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03992 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03993 if (!(this = ast_calloc(1, length))) 03994 continue; 03995 this->callbacks = hint->callbacks; 03996 hint->callbacks = NULL; 03997 this->laststate = hint->laststate; 03998 this->context = this->data; 03999 strcpy(this->data, hint->exten->parent->name); 04000 this->exten = this->data + strlen(this->context) + 1; 04001 strcpy(this->exten, hint->exten->exten); 04002 AST_LIST_INSERT_HEAD(&store, this, list); 04003 } 04004 } 04005 04006 tmp = *extcontexts; 04007 if (registrar) { 04008 /* XXX remove previous contexts from same registrar */ 04009 if (option_debug) 04010 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 04011 __ast_context_destroy(NULL,registrar); 04012 while (tmp) { 04013 lasttmp = tmp; 04014 tmp = tmp->next; 04015 } 04016 } else { 04017 /* XXX remove contexts with the same name */ 04018 while (tmp) { 04019 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04020 __ast_context_destroy(tmp,tmp->registrar); 04021 lasttmp = tmp; 04022 tmp = tmp->next; 04023 } 04024 } 04025 if (lasttmp) { 04026 lasttmp->next = contexts; 04027 contexts = *extcontexts; 04028 *extcontexts = NULL; 04029 } else 04030 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04031 04032 /* restore the watchers for hints that can be found; notify those that 04033 cannot be restored 04034 */ 04035 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04036 struct pbx_find_info q = { .stacklen = 0 }; 04037 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04038 /* Find the hint in the list of hints */ 04039 AST_LIST_TRAVERSE(&hints, hint, list) { 04040 if (hint->exten == exten) 04041 break; 04042 } 04043 if (!exten || !hint) { 04044 /* this hint has been removed, notify the watchers */ 04045 prevcb = NULL; 04046 thiscb = this->callbacks; 04047 while (thiscb) { 04048 prevcb = thiscb; 04049 thiscb = thiscb->next; 04050 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04051 free(prevcb); 04052 } 04053 } else { 04054 thiscb = this->callbacks; 04055 while (thiscb->next) 04056 thiscb = thiscb->next; 04057 thiscb->next = hint->callbacks; 04058 hint->callbacks = this->callbacks; 04059 hint->laststate = this->laststate; 04060 } 04061 free(this); 04062 } 04063 04064 AST_LIST_UNLOCK(&hints); 04065 ast_unlock_contexts(); 04066 04067 return; 04068 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6488 of file pbx.c.
References ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, exten, ast_channel::exten, LOG_WARNING, and ast_channel::priority.
Referenced by _while_exec(), check_goto_on_transfer(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), return_exec(), and while_continue_exec().
06489 { 06490 char *exten, *pri, *context; 06491 char *stringp; 06492 int ipri; 06493 int mode = 0; 06494 06495 if (ast_strlen_zero(goto_string)) { 06496 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06497 return -1; 06498 } 06499 stringp = ast_strdupa(goto_string); 06500 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06501 exten = strsep(&stringp, "|"); 06502 pri = strsep(&stringp, "|"); 06503 if (!exten) { /* Only a priority in this one */ 06504 pri = context; 06505 exten = NULL; 06506 context = NULL; 06507 } else if (!pri) { /* Only an extension and priority in this one */ 06508 pri = exten; 06509 exten = context; 06510 context = NULL; 06511 } 06512 if (*pri == '+') { 06513 mode = 1; 06514 pri++; 06515 } else if (*pri == '-') { 06516 mode = -1; 06517 pri++; 06518 } 06519 if (sscanf(pri, "%d", &ipri) != 1) { 06520 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06521 pri, chan->cid.cid_num)) < 1) { 06522 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06523 return -1; 06524 } else 06525 mode = 0; 06526 } 06527 /* At this point we have a priority and maybe an extension and a context */ 06528 06529 if (mode) 06530 ipri = chan->priority + (ipri * mode); 06531 06532 ast_explicit_goto(chan, context, exten, ipri); 06533 return 0; 06534 06535 }
int ast_pbx_outgoing_app | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int | timeout, | |||
const char * | app, | |||
const char * | appdata, | |||
int * | reason, | |||
int | sync, | |||
const char * | cid_num, | |||
const char * | cid_name, | |||
struct ast_variable * | vars, | |||
const char * | account, | |||
struct ast_channel ** | locked_channel | |||
) |
Synchronously or asynchronously make an outbound call and send it to a particular application with given extension
Definition at line 5199 of file pbx.c.
References __ast_request_and_dial(), ast_calloc, ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_setaccount(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), 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(), async_stat::chan, errno, free, LOG_WARNING, option_verbose, outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_app().
05200 { 05201 struct ast_channel *chan; 05202 struct app_tmp *tmp; 05203 int res = -1, cdr_res = -1; 05204 struct outgoing_helper oh; 05205 pthread_attr_t attr; 05206 05207 memset(&oh, 0, sizeof(oh)); 05208 oh.vars = vars; 05209 oh.account = account; 05210 05211 if (locked_channel) 05212 *locked_channel = NULL; 05213 if (ast_strlen_zero(app)) { 05214 res = -1; 05215 goto outgoing_app_cleanup; 05216 } 05217 if (sync) { 05218 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05219 if (chan) { 05220 ast_set_variables(chan, vars); 05221 if (account) 05222 ast_cdr_setaccount(chan, account); 05223 if (chan->_state == AST_STATE_UP) { 05224 res = 0; 05225 if (option_verbose > 3) 05226 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05227 tmp = ast_calloc(1, sizeof(*tmp)); 05228 if (!tmp) 05229 res = -1; 05230 else { 05231 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05232 if (appdata) 05233 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05234 tmp->chan = chan; 05235 if (sync > 1) { 05236 if (locked_channel) 05237 ast_channel_unlock(chan); 05238 ast_pbx_run_app(tmp); 05239 } else { 05240 pthread_attr_init(&attr); 05241 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05242 if (locked_channel) 05243 ast_channel_lock(chan); 05244 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05245 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05246 free(tmp); 05247 if (locked_channel) 05248 ast_channel_unlock(chan); 05249 ast_hangup(chan); 05250 res = -1; 05251 } else { 05252 if (locked_channel) 05253 *locked_channel = chan; 05254 } 05255 pthread_attr_destroy(&attr); 05256 } 05257 } 05258 } else { 05259 if (option_verbose > 3) 05260 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05261 if (chan->cdr) { /* update the cdr */ 05262 /* here we update the status of the call, which sould be busy. 05263 * if that fails then we set the status to failed */ 05264 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05265 ast_cdr_failed(chan->cdr); 05266 } 05267 ast_hangup(chan); 05268 } 05269 } 05270 05271 if (res < 0) { /* the call failed for some reason */ 05272 if (*reason == 0) { /* if the call failed (not busy or no answer) 05273 * update the cdr with the failed message */ 05274 cdr_res = ast_pbx_outgoing_cdr_failed(); 05275 if (cdr_res != 0) { 05276 res = cdr_res; 05277 goto outgoing_app_cleanup; 05278 } 05279 } 05280 } 05281 05282 } else { 05283 struct async_stat *as; 05284 if (!(as = ast_calloc(1, sizeof(*as)))) { 05285 res = -1; 05286 goto outgoing_app_cleanup; 05287 } 05288 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05289 if (!chan) { 05290 free(as); 05291 res = -1; 05292 goto outgoing_app_cleanup; 05293 } 05294 as->chan = chan; 05295 ast_copy_string(as->app, app, sizeof(as->app)); 05296 if (appdata) 05297 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05298 as->timeout = timeout; 05299 ast_set_variables(chan, vars); 05300 if (account) 05301 ast_cdr_setaccount(chan, account); 05302 /* Start a new thread, and get something handling this channel. */ 05303 pthread_attr_init(&attr); 05304 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05305 if (locked_channel) 05306 ast_channel_lock(chan); 05307 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05308 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05309 free(as); 05310 if (locked_channel) 05311 ast_channel_unlock(chan); 05312 ast_hangup(chan); 05313 res = -1; 05314 pthread_attr_destroy(&attr); 05315 goto outgoing_app_cleanup; 05316 } else { 05317 if (locked_channel) 05318 *locked_channel = chan; 05319 } 05320 pthread_attr_destroy(&attr); 05321 res = 0; 05322 } 05323 outgoing_app_cleanup: 05324 ast_variables_destroy(vars); 05325 return res; 05326 }
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 5007 of file pbx.c.
References ast_cdr_detach(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_start(), ast_channel_alloc(), ast_channel_free(), AST_STATE_DOWN, and ast_channel::cdr.
Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
05008 { 05009 /* allocate a channel */ 05010 struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", ""); 05011 05012 if (!chan) 05013 return -1; /* failure */ 05014 05015 if (!chan->cdr) { 05016 /* allocation of the cdr failed */ 05017 ast_channel_free(chan); /* free the channel */ 05018 return -1; /* return failure */ 05019 } 05020 05021 /* allocation of the cdr was successful */ 05022 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05023 ast_cdr_start(chan->cdr); /* record the start and stop time */ 05024 ast_cdr_end(chan->cdr); 05025 ast_cdr_failed(chan->cdr); /* set the status to failed */ 05026 ast_cdr_detach(chan->cdr); /* post and free the record */ 05027 chan->cdr = NULL; 05028 ast_channel_free(chan); /* free the channel */ 05029 05030 return 0; /* success */ 05031 }
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 5033 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_copy_string(), ast_exists_extension(), ast_hangup(), ast_log(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_DOWN, AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, ast_channel::context, free, ast_channel::hangupcause, LOAD_OH, LOG_ERROR, LOG_WARNING, ast_channel::name, option_verbose, pbx_builtin_setvar_helper(), set_ext_pri(), outgoing_helper::vars, and VERBOSE_PREFIX_4.
Referenced by action_originate(), attempt_thread(), fast_originate(), and orig_exten().
05034 { 05035 struct ast_channel *chan; 05036 struct async_stat *as; 05037 int res = -1, cdr_res = -1; 05038 struct outgoing_helper oh; 05039 pthread_attr_t attr; 05040 05041 if (sync) { 05042 LOAD_OH(oh); 05043 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05044 if (channel) { 05045 *channel = chan; 05046 if (chan) 05047 ast_channel_lock(chan); 05048 } 05049 if (chan) { 05050 if (chan->_state == AST_STATE_UP) { 05051 res = 0; 05052 if (option_verbose > 3) 05053 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05054 05055 if (sync > 1) { 05056 if (channel) 05057 ast_channel_unlock(chan); 05058 if (ast_pbx_run(chan)) { 05059 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05060 if (channel) 05061 *channel = NULL; 05062 ast_hangup(chan); 05063 chan = NULL; 05064 res = -1; 05065 } 05066 } else { 05067 if (ast_pbx_start(chan)) { 05068 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05069 if (channel) { 05070 *channel = NULL; 05071 ast_channel_unlock(chan); 05072 } 05073 ast_hangup(chan); 05074 res = -1; 05075 } 05076 chan = NULL; 05077 } 05078 } else { 05079 if (option_verbose > 3) 05080 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05081 05082 if (chan->cdr) { /* update the cdr */ 05083 /* here we update the status of the call, which sould be busy. 05084 * if that fails then we set the status to failed */ 05085 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05086 ast_cdr_failed(chan->cdr); 05087 } 05088 05089 if (channel) { 05090 *channel = NULL; 05091 ast_channel_unlock(chan); 05092 } 05093 ast_hangup(chan); 05094 chan = NULL; 05095 } 05096 } 05097 05098 if (res < 0) { /* the call failed for some reason */ 05099 if (*reason == 0) { /* if the call failed (not busy or no answer) 05100 * update the cdr with the failed message */ 05101 cdr_res = ast_pbx_outgoing_cdr_failed(); 05102 if (cdr_res != 0) { 05103 res = cdr_res; 05104 goto outgoing_exten_cleanup; 05105 } 05106 } 05107 05108 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05109 /* check if "failed" exists */ 05110 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05111 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05112 if (chan) { 05113 char failed_reason[4] = ""; 05114 if (!ast_strlen_zero(context)) 05115 ast_copy_string(chan->context, context, sizeof(chan->context)); 05116 set_ext_pri(chan, "failed", 1); 05117 ast_set_variables(chan, vars); 05118 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05119 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05120 if (account) 05121 ast_cdr_setaccount(chan, account); 05122 if (ast_pbx_run(chan)) { 05123 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05124 ast_hangup(chan); 05125 } 05126 chan = NULL; 05127 } 05128 } 05129 } 05130 } else { 05131 if (!(as = ast_calloc(1, sizeof(*as)))) { 05132 res = -1; 05133 goto outgoing_exten_cleanup; 05134 } 05135 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05136 if (channel) { 05137 *channel = chan; 05138 if (chan) 05139 ast_channel_lock(chan); 05140 } 05141 if (!chan) { 05142 free(as); 05143 res = -1; 05144 goto outgoing_exten_cleanup; 05145 } 05146 as->chan = chan; 05147 ast_copy_string(as->context, context, sizeof(as->context)); 05148 set_ext_pri(as->chan, exten, priority); 05149 as->timeout = timeout; 05150 ast_set_variables(chan, vars); 05151 if (account) 05152 ast_cdr_setaccount(chan, account); 05153 pthread_attr_init(&attr); 05154 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05155 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05156 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05157 free(as); 05158 if (channel) { 05159 *channel = NULL; 05160 ast_channel_unlock(chan); 05161 } 05162 ast_hangup(chan); 05163 res = -1; 05164 pthread_attr_destroy(&attr); 05165 goto outgoing_exten_cleanup; 05166 } 05167 pthread_attr_destroy(&attr); 05168 res = 0; 05169 } 05170 outgoing_exten_cleanup: 05171 ast_variables_destroy(vars); 05172 return res; 05173 }
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 2696 of file pbx.c.
References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().
Referenced by ast_pbx_outgoing_exten(), async_wait(), do_idle_thread(), mgcp_ss(), skinny_newcall(), and ss_thread().
02697 { 02698 enum ast_pbx_result res = AST_PBX_SUCCESS; 02699 02700 if (increase_call_count(c)) 02701 return AST_PBX_CALL_LIMIT; 02702 02703 res = __ast_pbx_run(c); 02704 decrease_call_count(); 02705 02706 return res; 02707 }
static void* ast_pbx_run_app | ( | void * | data | ) | [static] |
run the application and free the descriptor once done
Definition at line 5183 of file pbx.c.
References app_tmp::app, app, ast_hangup(), ast_log(), ast_verbose(), app_tmp::chan, app_tmp::data, free, LOG_WARNING, ast_channel::name, option_verbose, pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_4.
Referenced by ast_pbx_outgoing_app().
05184 { 05185 struct app_tmp *tmp = data; 05186 struct ast_app *app; 05187 app = pbx_findapp(tmp->app); 05188 if (app) { 05189 if (option_verbose > 3) 05190 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05191 pbx_exec(tmp->chan, app, tmp->data); 05192 } else 05193 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05194 ast_hangup(tmp->chan); 05195 free(tmp); 05196 return NULL; 05197 }
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 2669 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, decrease_call_count(), increase_call_count(), LOG_WARNING, pbx_thread(), and t.
Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), dahdi_new(), 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(), and skinny_new().
02670 { 02671 pthread_t t; 02672 pthread_attr_t attr; 02673 02674 if (!c) { 02675 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02676 return AST_PBX_FAILED; 02677 } 02678 02679 if (increase_call_count(c)) 02680 return AST_PBX_CALL_LIMIT; 02681 02682 /* Start a new thread, and get something handling this channel. */ 02683 pthread_attr_init(&attr); 02684 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02685 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02686 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02687 pthread_attr_destroy(&attr); 02688 decrease_call_count(); 02689 return AST_PBX_FAILED; 02690 } 02691 pthread_attr_destroy(&attr); 02692 02693 return AST_PBX_SUCCESS; 02694 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6266 of file pbx.c.
References ast_rwlock_rdlock(), and conlock.
Referenced by __ast_context_create(), _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().
06267 { 06268 return ast_rwlock_rdlock(&conlock); 06269 }
int ast_register_application | ( | const char * | app, | |
int(*)(struct ast_channel *, void *) | execute, | |||
const char * | synopsis, | |||
const char * | description | |||
) |
Register an application.
app | Short name of the application | |
execute | a function callback to execute the application. It should return non-zero if the channel needs to be hung up. | |
synopsis | a short description (one line synopsis) of the application | |
description | long description with all of the details about the use of the application |
0 | success | |
-1 | failure. |
Definition at line 2998 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, ast_app::list, LOG_WARNING, ast_app::name, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2.
Referenced by load_module(), and load_pbx().
02999 { 03000 struct ast_app *tmp, *cur = NULL; 03001 char tmps[80]; 03002 int length; 03003 03004 AST_LIST_LOCK(&apps); 03005 AST_LIST_TRAVERSE(&apps, tmp, list) { 03006 if (!strcasecmp(app, tmp->name)) { 03007 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 03008 AST_LIST_UNLOCK(&apps); 03009 return -1; 03010 } 03011 } 03012 03013 length = sizeof(*tmp) + strlen(app) + 1; 03014 03015 if (!(tmp = ast_calloc(1, length))) { 03016 AST_LIST_UNLOCK(&apps); 03017 return -1; 03018 } 03019 03020 strcpy(tmp->name, app); 03021 tmp->execute = execute; 03022 tmp->synopsis = synopsis; 03023 tmp->description = description; 03024 03025 /* Store in alphabetical order */ 03026 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 03027 if (strcasecmp(tmp->name, cur->name) < 0) { 03028 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03029 break; 03030 } 03031 } 03032 AST_LIST_TRAVERSE_SAFE_END 03033 if (!cur) 03034 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03035 03036 if (option_verbose > 1) 03037 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03038 03039 AST_LIST_UNLOCK(&apps); 03040 03041 return 0; 03042 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3048 of file pbx.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_switch::list, LOG_WARNING, and ast_switch::name.
Referenced by load_module().
03049 { 03050 struct ast_switch *tmp; 03051 03052 AST_LIST_LOCK(&switches); 03053 AST_LIST_TRAVERSE(&switches, tmp, list) { 03054 if (!strcasecmp(tmp->name, sw->name)) { 03055 AST_LIST_UNLOCK(&switches); 03056 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03057 return -1; 03058 } 03059 } 03060 AST_LIST_INSERT_TAIL(&switches, sw, list); 03061 AST_LIST_UNLOCK(&switches); 03062 03063 return 0; 03064 }
static int ast_remove_hint | ( | struct ast_exten * | e | ) | [static] |
ast_remove_hint: Remove hint from extension
Definition at line 2264 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_sw::list, ast_context::name, ast_state_cb::next, and ast_exten::parent.
Referenced by destroy_exten().
02265 { 02266 /* Cleanup the Notifys if hint is removed */ 02267 struct ast_hint *hint; 02268 struct ast_state_cb *cblist, *cbprev; 02269 int res = -1; 02270 02271 if (!e) 02272 return -1; 02273 02274 AST_LIST_LOCK(&hints); 02275 AST_LIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) { 02276 if (hint->exten == e) { 02277 cbprev = NULL; 02278 cblist = hint->callbacks; 02279 while (cblist) { 02280 /* Notify with -1 and remove all callbacks */ 02281 cbprev = cblist; 02282 cblist = cblist->next; 02283 cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data); 02284 free(cbprev); 02285 } 02286 hint->callbacks = NULL; 02287 AST_LIST_REMOVE_CURRENT(&hints, list); 02288 free(hint); 02289 res = 0; 02290 break; 02291 } 02292 } 02293 AST_LIST_TRAVERSE_SAFE_END 02294 AST_LIST_UNLOCK(&hints); 02295 02296 return res; 02297 }
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 2343 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), and loopback_exec().
02344 { 02345 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02346 }
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 6289 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().
06290 { 06291 return ast_mutex_unlock(&con->lock); 06292 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6276 of file pbx.c.
References ast_rwlock_unlock(), and conlock.
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_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), 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().
06277 { 06278 return ast_rwlock_unlock(&conlock); 06279 }
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 3879 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, ast_app::list, ast_app::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __unload_module(), and unload_module().
03880 { 03881 struct ast_app *tmp; 03882 03883 AST_LIST_LOCK(&apps); 03884 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03885 if (!strcasecmp(app, tmp->name)) { 03886 AST_LIST_REMOVE_CURRENT(&apps, list); 03887 if (option_verbose > 1) 03888 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03889 free(tmp); 03890 break; 03891 } 03892 } 03893 AST_LIST_TRAVERSE_SAFE_END 03894 AST_LIST_UNLOCK(&apps); 03895 03896 return tmp ? 0 : -1; 03897 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3066 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and ast_switch::list.
Referenced by __unload_module(), and unload_module().
03067 { 03068 AST_LIST_LOCK(&switches); 03069 AST_LIST_REMOVE(&switches, sw, list); 03070 AST_LIST_UNLOCK(&switches); 03071 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | exten | |||
) |
Definition at line 6398 of file pbx.c.
References exten, and ast_context::root.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().
06400 { 06401 if (!exten) 06402 return con ? con->root : NULL; 06403 else 06404 return exten->next; 06405 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6431 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().
06433 { 06434 if (!ip) 06435 return con ? con->ignorepats : NULL; 06436 else 06437 return ip->next; 06438 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6422 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().
06424 { 06425 if (!inc) 06426 return con ? con->includes : NULL; 06427 else 06428 return inc->next; 06429 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6407 of file pbx.c.
References ast_context::alts, AST_LIST_FIRST, AST_LIST_NEXT, and ast_sw::list.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06409 { 06410 if (!sw) 06411 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06412 else 06413 return AST_LIST_NEXT(sw, list); 06414 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6393 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 | |||
) |
Definition at line 6416 of file pbx.c.
References exten, and ast_exten::priority.
Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), find_matching_priority(), handle_save_dialplan(), pbx_find_extension(), and show_dialplan_helper().
int ast_wrlock_contexts | ( | void | ) |
Definition at line 6271 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by ast_context_destroy(), ast_merge_contexts_and_delete(), and complete_context_dont_include_deprecated().
06272 { 06273 return ast_rwlock_wrlock(&conlock); 06274 }
static void* async_wait | ( | void * | data | ) | [static] |
Definition at line 4944 of file pbx.c.
References ast_channel::_state, app, async_stat::app, async_stat::appdata, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, ast_copy_string(), AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_pbx_run(), ast_read(), AST_STATE_UP, ast_strlen_zero(), ast_verbose(), ast_waitfor(), async_stat::chan, ast_channel::context, async_stat::context, ast_channel::exten, async_stat::exten, f, free, LOG_ERROR, LOG_WARNING, ast_channel::name, option_verbose, pbx_exec(), pbx_findapp(), ast_channel::priority, async_stat::priority, async_stat::timeout, and VERBOSE_PREFIX_3.
Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().
04945 { 04946 struct async_stat *as = data; 04947 struct ast_channel *chan = as->chan; 04948 int timeout = as->timeout; 04949 int res; 04950 struct ast_frame *f; 04951 struct ast_app *app; 04952 04953 while (timeout && (chan->_state != AST_STATE_UP)) { 04954 res = ast_waitfor(chan, timeout); 04955 if (res < 1) 04956 break; 04957 if (timeout > -1) 04958 timeout = res; 04959 f = ast_read(chan); 04960 if (!f) 04961 break; 04962 if (f->frametype == AST_FRAME_CONTROL) { 04963 if ((f->subclass == AST_CONTROL_BUSY) || 04964 (f->subclass == AST_CONTROL_CONGESTION) ) { 04965 ast_frfree(f); 04966 break; 04967 } 04968 } 04969 ast_frfree(f); 04970 } 04971 if (chan->_state == AST_STATE_UP) { 04972 if (!ast_strlen_zero(as->app)) { 04973 app = pbx_findapp(as->app); 04974 if (app) { 04975 if (option_verbose > 2) 04976 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 04977 pbx_exec(chan, app, as->appdata); 04978 } else 04979 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 04980 } else { 04981 if (!ast_strlen_zero(as->context)) 04982 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 04983 if (!ast_strlen_zero(as->exten)) 04984 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 04985 if (as->priority > 0) 04986 chan->priority = as->priority; 04987 /* Run the PBX */ 04988 if (ast_pbx_run(chan)) { 04989 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 04990 } else { 04991 /* PBX will have taken care of this */ 04992 chan = NULL; 04993 } 04994 } 04995 } 04996 free(as); 04997 if (chan) 04998 ast_hangup(chan); 04999 return NULL; 05000 }
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 2361 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.
02362 { 02363 int digit; 02364 02365 buf[pos] = '\0'; /* make sure it is properly terminated */ 02366 while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) { 02367 /* As long as we're willing to wait, and as long as it's not defined, 02368 keep reading digits until we can't possibly get a right answer anymore. */ 02369 digit = ast_waitfordigit(c, waittime * 1000); 02370 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02371 c->_softhangup = 0; 02372 } else { 02373 if (!digit) /* No entry */ 02374 break; 02375 if (digit < 0) /* Error, maybe a hangup */ 02376 return -1; 02377 if (pos < buflen - 1) { /* XXX maybe error otherwise ? */ 02378 buf[pos++] = digit; 02379 buf[pos] = '\0'; 02380 } 02381 waittime = c->pbx->dtimeout; 02382 } 02383 } 02384 return 0; 02385 }
static char* complete_show_application | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3124 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::list, ast_app::name, and strdup.
03125 { 03126 struct ast_app *a; 03127 char *ret = NULL; 03128 int which = 0; 03129 int wordlen = strlen(word); 03130 03131 /* return the n-th [partial] matching entry */ 03132 AST_LIST_LOCK(&apps); 03133 AST_LIST_TRAVERSE(&apps, a, list) { 03134 if (!strncasecmp(word, a->name, wordlen) && ++which > state) { 03135 ret = strdup(a->name); 03136 break; 03137 } 03138 } 03139 AST_LIST_UNLOCK(&apps); 03140 03141 return ret; 03142 }
static char* complete_show_applications | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3485 of file pbx.c.
References ast_cli_complete().
03486 { 03487 static char* choices[] = { "like", "describing", NULL }; 03488 03489 return (pos != 3) ? NULL : ast_cli_complete(word, choices, state); 03490 }
static char* complete_show_applications_deprecated | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3478 of file pbx.c.
References ast_cli_complete().
03479 { 03480 static char* choices[] = { "like", "describing", NULL }; 03481 03482 return (pos != 2) ? NULL : ast_cli_complete(word, choices, state); 03483 }
static char* complete_show_dialplan_context | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3495 of file pbx.c.
References ast_get_context_name(), ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), and ast_walk_contexts().
03497 { 03498 struct ast_context *c = NULL; 03499 char *ret = NULL; 03500 int which = 0; 03501 int wordlen; 03502 03503 /* we are do completion of [exten@]context on second position only */ 03504 if (pos != 2) 03505 return NULL; 03506 03507 ast_rdlock_contexts(); 03508 03509 wordlen = strlen(word); 03510 03511 /* walk through all contexts and return the n-th match */ 03512 while ( (c = ast_walk_contexts(c)) ) { 03513 if (!strncasecmp(word, ast_get_context_name(c), wordlen) && ++which > state) { 03514 ret = ast_strdup(ast_get_context_name(c)); 03515 break; 03516 } 03517 } 03518 03519 ast_unlock_contexts(); 03520 03521 return ret; 03522 }
static char* complete_show_function | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1460 of file pbx.c.
References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_custom_function::name, and strdup.
01461 { 01462 struct ast_custom_function *acf; 01463 char *ret = NULL; 01464 int which = 0; 01465 int wordlen = strlen(word); 01466 01467 /* case-insensitive for convenience in this 'complete' function */ 01468 AST_LIST_LOCK(&acf_root); 01469 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01470 if (!strncasecmp(word, acf->name, wordlen) && ++which > state) { 01471 ret = strdup(acf->name); 01472 break; 01473 } 01474 } 01475 AST_LIST_UNLOCK(&acf_root); 01476 01477 return ret; 01478 }
static void decrease_call_count | ( | void | ) | [static] |
Definition at line 2631 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), countcalls, and maxcalllock.
Referenced by ast_pbx_run(), ast_pbx_start(), and pbx_thread().
02632 { 02633 ast_mutex_lock(&maxcalllock); 02634 if (countcalls > 0) 02635 countcalls--; 02636 ast_mutex_unlock(&maxcalllock); 02637 }
static void destroy_exten | ( | struct ast_exten * | e | ) | [static] |
Definition at line 2639 of file pbx.c.
References ast_remove_hint(), free, ast_exten::priority, and PRIORITY_HINT.
Referenced by __ast_context_destroy(), and ast_context_remove_extension_callerid2().
02640 { 02641 if (e->priority == PRIORITY_HINT) 02642 ast_remove_hint(e); 02643 02644 if (e->datad) 02645 e->datad(e->data); 02646 free(e); 02647 }
static int ext_cmp | ( | const char * | a, | |
const char * | b | |||
) | [static] |
the full routine to compare extensions in rules.
Definition at line 745 of file pbx.c.
References ext_cmp1().
Referenced by ast_add_extension2().
00746 { 00747 /* make sure non-patterns come first. 00748 * If a is not a pattern, it either comes first or 00749 * we use strcmp to compare the strings. 00750 */ 00751 int ret = 0; 00752 00753 if (a[0] != '_') 00754 return (b[0] == '_') ? -1 : strcmp(a, b); 00755 00756 /* Now we know a is a pattern; if b is not, a comes first */ 00757 if (b[0] != '_') 00758 return 1; 00759 #if 0 /* old mode for ext matching */ 00760 return strcmp(a, b); 00761 #endif 00762 /* ok we need full pattern sorting routine */ 00763 while (!ret && a && b) 00764 ret = ext_cmp1(&a) - ext_cmp1(&b); 00765 if (ret == 0) 00766 return 0; 00767 else 00768 return (ret > 0) ? 1 : -1; 00769 }
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 673 of file pbx.c.
References ast_log(), and LOG_WARNING.
Referenced by ext_cmp().
00674 { 00675 uint32_t chars[8]; 00676 int c, cmin = 0xff, count = 0; 00677 const char *end; 00678 00679 /* load, sign extend and advance pointer until we find 00680 * a valid character. 00681 */ 00682 while ( (c = *(*p)++) && (c == ' ' || c == '-') ) 00683 ; /* ignore some characters */ 00684 00685 /* always return unless we have a set of chars */ 00686 switch (c) { 00687 default: /* ordinary character */ 00688 return 0x0000 | (c & 0xff); 00689 00690 case 'N': /* 2..9 */ 00691 return 0x0800 | '2' ; 00692 00693 case 'X': /* 0..9 */ 00694 return 0x0A00 | '0'; 00695 00696 case 'Z': /* 1..9 */ 00697 return 0x0900 | '1'; 00698 00699 case '.': /* wildcard */ 00700 return 0x10000; 00701 00702 case '!': /* earlymatch */ 00703 return 0x20000; /* less specific than NULL */ 00704 00705 case '\0': /* empty string */ 00706 *p = NULL; 00707 return 0x30000; 00708 00709 case '[': /* pattern */ 00710 break; 00711 } 00712 /* locate end of set */ 00713 end = strchr(*p, ']'); 00714 00715 if (end == NULL) { 00716 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n"); 00717 return 0x40000; /* XXX make this entry go last... */ 00718 } 00719 00720 bzero(chars, sizeof(chars)); /* clear all chars in the set */ 00721 for (; *p < end ; (*p)++) { 00722 unsigned char c1, c2; /* first-last char in range */ 00723 c1 = (unsigned char)((*p)[0]); 00724 if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */ 00725 c2 = (unsigned char)((*p)[2]); 00726 *p += 2; /* skip a total of 3 chars */ 00727 } else /* individual character */ 00728 c2 = c1; 00729 if (c1 < cmin) 00730 cmin = c1; 00731 for (; c1 <= c2; c1++) { 00732 uint32_t mask = 1 << (c1 % 32); 00733 if ( (chars[ c1 / 32 ] & mask) == 0) 00734 count += 0x100; 00735 chars[ c1 / 32 ] |= mask; 00736 } 00737 } 00738 (*p)++; 00739 return count == 0 ? 0x30000 : (count | cmin); 00740 }
static int ext_strncpy | ( | char * | dst, | |
const char * | src, | |||
int | len | |||
) | [static] |
copy a string skipping whitespace
Definition at line 4696 of file pbx.c.
Referenced by ast_add_extension2().
04697 { 04698 int count=0; 04699 04700 while (*src && (count < len - 1)) { 04701 switch(*src) { 04702 case ' ': 04703 /* otherwise exten => [a-b],1,... doesn't work */ 04704 /* case '-': */ 04705 /* Ignore */ 04706 break; 04707 default: 04708 *dst = *src; 04709 dst++; 04710 } 04711 src++; 04712 count++; 04713 } 04714 *dst = '\0'; 04715 04716 return count; 04717 }
static int extension_match_core | ( | const char * | pattern, | |
const char * | data, | |||
enum ext_match_t | mode | |||
) | [static] |
Definition at line 894 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().
00895 { 00896 int i; 00897 static int prof_id = -2; /* marker for 'unallocated' id */ 00898 if (prof_id == -2) 00899 prof_id = ast_add_profile("ext_match", 0); 00900 ast_mark(prof_id, 1); 00901 i = _extension_match_core(pattern, data, mode); 00902 ast_mark(prof_id, 0); 00903 return i; 00904 }
static struct ast_context* find_context_locked | ( | const char * | context | ) | [static] |
Definition at line 2724 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_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), and ast_context_remove_switch().
02725 { 02726 struct ast_context *c = NULL; 02727 02728 ast_rdlock_contexts(); 02729 while ( (c = ast_walk_contexts(c)) ) { 02730 if (!strcmp(ast_get_context_name(c), context)) 02731 return c; 02732 } 02733 ast_unlock_contexts(); 02734 02735 return NULL; 02736 }
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 1553 of file pbx.c.
References ast_log(), and LOG_WARNING.
Referenced by ast_func_read(), and ast_func_write().
01554 { 01555 char *args = strchr(function, '('); 01556 01557 if (!args) 01558 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01559 else { 01560 char *p; 01561 *args++ = '\0'; 01562 if ((p = strrchr(args, ')')) ) 01563 *p = '\0'; 01564 else 01565 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01566 } 01567 return args; 01568 }
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 4109 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, lookup_name(), and s.
Referenced by ast_build_timing().
04110 { 04111 int s, e; /* start and ending position */ 04112 unsigned int mask = 0; 04113 04114 /* Check for whole range */ 04115 if (ast_strlen_zero(src) || !strcmp(src, "*")) { 04116 s = 0; 04117 e = max - 1; 04118 } else { 04119 /* Get start and ending position */ 04120 char *c = strchr(src, '-'); 04121 if (c) 04122 *c++ = '\0'; 04123 /* Find the start */ 04124 s = lookup_name(src, names, max); 04125 if (!s) { 04126 ast_log(LOG_WARNING, "Invalid %s '%s', assuming none\n", msg, src); 04127 return 0; 04128 } 04129 s--; 04130 if (c) { /* find end of range */ 04131 e = lookup_name(c, names, max); 04132 if (!e) { 04133 ast_log(LOG_WARNING, "Invalid end %s '%s', assuming none\n", msg, c); 04134 return 0; 04135 } 04136 e--; 04137 } else 04138 e = s; 04139 } 04140 /* Fill the mask. Remember that ranges are cyclic */ 04141 mask = 1 << e; /* initialize with last element */ 04142 while (s != e) { 04143 if (s >= max) { 04144 s = 0; 04145 mask |= (1 << s); 04146 } else { 04147 mask |= (1 << s); 04148 s++; 04149 } 04150 } 04151 return mask; 04152 }
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 4155 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask.
Referenced by ast_build_timing().
04156 { 04157 char *e; 04158 int x; 04159 int s1, s2; 04160 int e1, e2; 04161 /* int cth, ctm; */ 04162 04163 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 04164 memset(i->minmask, 0, sizeof(i->minmask)); 04165 04166 /* 2-minutes per bit, since the mask has only 32 bits :( */ 04167 /* Star is all times */ 04168 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 04169 for (x=0; x<24; x++) 04170 i->minmask[x] = 0x3fffffff; /* 30 bits */ 04171 return; 04172 } 04173 /* Otherwise expect a range */ 04174 e = strchr(times, '-'); 04175 if (!e) { 04176 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n"); 04177 return; 04178 } 04179 *e++ = '\0'; 04180 /* XXX why skip non digits ? */ 04181 while (*e && !isdigit(*e)) 04182 e++; 04183 if (!*e) { 04184 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n"); 04185 return; 04186 } 04187 if (sscanf(times, "%d:%d", &s1, &s2) != 2) { 04188 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times); 04189 return; 04190 } 04191 if (sscanf(e, "%d:%d", &e1, &e2) != 2) { 04192 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e); 04193 return; 04194 } 04195 /* XXX this needs to be optimized */ 04196 #if 1 04197 s1 = s1 * 30 + s2/2; 04198 if ((s1 < 0) || (s1 >= 24*30)) { 04199 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times); 04200 return; 04201 } 04202 e1 = e1 * 30 + e2/2; 04203 if ((e1 < 0) || (e1 >= 24*30)) { 04204 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e); 04205 return; 04206 } 04207 /* Go through the time and enable each appropriate bit */ 04208 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) { 04209 i->minmask[x/30] |= (1 << (x % 30)); 04210 } 04211 /* Do the last one */ 04212 i->minmask[x/30] |= (1 << (x % 30)); 04213 #else 04214 for (cth=0; cth<24; cth++) { 04215 /* Initialize masks to blank */ 04216 i->minmask[cth] = 0; 04217 for (ctm=0; ctm<30; ctm++) { 04218 if ( 04219 /* First hour with more than one hour */ 04220 (((cth == s1) && (ctm >= s2)) && 04221 ((cth < e1))) 04222 /* Only one hour */ 04223 || (((cth == s1) && (ctm >= s2)) && 04224 ((cth == e1) && (ctm <= e2))) 04225 /* In between first and last hours (more than 2 hours) */ 04226 || ((cth > s1) && 04227 (cth < e1)) 04228 /* Last hour with more than one hour */ 04229 || ((cth > s1) && 04230 ((cth == e1) && (ctm <= e2))) 04231 ) 04232 i->minmask[cth] |= (1 << (ctm / 2)); 04233 } 04234 } 04235 #endif 04236 /* All done */ 04237 return; 04238 }
static int handle_set_global | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3780 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03781 { 03782 if (argc != 5) 03783 return RESULT_SHOWUSAGE; 03784 03785 pbx_builtin_setvar_helper(NULL, argv[3], argv[4]); 03786 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[3], argv[4]); 03787 03788 return RESULT_SUCCESS; 03789 }
static int handle_set_global_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI support for setting global variables.
Definition at line 3768 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03769 { 03770 if (argc != 4) 03771 return RESULT_SHOWUSAGE; 03772 03773 pbx_builtin_setvar_helper(NULL, argv[2], argv[3]); 03774 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[2], argv[3]); 03775 03776 return RESULT_SUCCESS; 03777 }
static int handle_show_application | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3214 of file pbx.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_MAX_APP, COLOR_CYAN, COLOR_MAGENTA, ast_app::description, ast_app::list, ast_app::name, RESULT_SHOWUSAGE, ast_app::synopsis, and term_color().
03215 { 03216 struct ast_app *a; 03217 int app, no_registered_app = 1; 03218 03219 if (argc < 4) 03220 return RESULT_SHOWUSAGE; 03221 03222 /* ... go through all applications ... */ 03223 AST_LIST_LOCK(&apps); 03224 AST_LIST_TRAVERSE(&apps, a, list) { 03225 /* ... compare this application name with all arguments given 03226 * to 'show application' command ... */ 03227 for (app = 3; app < argc; app++) { 03228 if (!strcasecmp(a->name, argv[app])) { 03229 /* Maximum number of characters added by terminal coloring is 22 */ 03230 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03231 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03232 int synopsis_size, description_size; 03233 03234 no_registered_app = 0; 03235 03236 if (a->synopsis) 03237 synopsis_size = strlen(a->synopsis) + 23; 03238 else 03239 synopsis_size = strlen("Not available") + 23; 03240 synopsis = alloca(synopsis_size); 03241 03242 if (a->description) 03243 description_size = strlen(a->description) + 23; 03244 else 03245 description_size = strlen("Not available") + 23; 03246 description = alloca(description_size); 03247 03248 if (synopsis && description) { 03249 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03250 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03251 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03252 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03253 term_color(synopsis, 03254 a->synopsis ? a->synopsis : "Not available", 03255 COLOR_CYAN, 0, synopsis_size); 03256 term_color(description, 03257 a->description ? a->description : "Not available", 03258 COLOR_CYAN, 0, description_size); 03259 03260 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03261 } else { 03262 /* ... one of our applications, show info ...*/ 03263 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03264 "[Synopsis]\n %s\n\n" 03265 "[Description]\n%s\n", 03266 a->name, 03267 a->synopsis ? a->synopsis : "Not available", 03268 a->description ? a->description : "Not available"); 03269 } 03270 } 03271 } 03272 } 03273 AST_LIST_UNLOCK(&apps); 03274 03275 /* we found at least one app? no? */ 03276 if (no_registered_app) { 03277 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03278 return RESULT_FAILURE; 03279 } 03280 03281 return RESULT_SUCCESS; 03282 }
static int handle_show_application_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3144 of file pbx.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_MAX_APP, COLOR_CYAN, COLOR_MAGENTA, ast_app::description, ast_app::list, ast_app::name, RESULT_SHOWUSAGE, ast_app::synopsis, and term_color().
03145 { 03146 struct ast_app *a; 03147 int app, no_registered_app = 1; 03148 03149 if (argc < 3) 03150 return RESULT_SHOWUSAGE; 03151 03152 /* ... go through all applications ... */ 03153 AST_LIST_LOCK(&apps); 03154 AST_LIST_TRAVERSE(&apps, a, list) { 03155 /* ... compare this application name with all arguments given 03156 * to 'show application' command ... */ 03157 for (app = 2; app < argc; app++) { 03158 if (!strcasecmp(a->name, argv[app])) { 03159 /* Maximum number of characters added by terminal coloring is 22 */ 03160 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03161 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03162 int synopsis_size, description_size; 03163 03164 no_registered_app = 0; 03165 03166 if (a->synopsis) 03167 synopsis_size = strlen(a->synopsis) + 23; 03168 else 03169 synopsis_size = strlen("Not available") + 23; 03170 synopsis = alloca(synopsis_size); 03171 03172 if (a->description) 03173 description_size = strlen(a->description) + 23; 03174 else 03175 description_size = strlen("Not available") + 23; 03176 description = alloca(description_size); 03177 03178 if (synopsis && description) { 03179 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03180 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03181 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03182 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03183 term_color(synopsis, 03184 a->synopsis ? a->synopsis : "Not available", 03185 COLOR_CYAN, 0, synopsis_size); 03186 term_color(description, 03187 a->description ? a->description : "Not available", 03188 COLOR_CYAN, 0, description_size); 03189 03190 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03191 } else { 03192 /* ... one of our applications, show info ...*/ 03193 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03194 "[Synopsis]\n %s\n\n" 03195 "[Description]\n%s\n", 03196 a->name, 03197 a->synopsis ? a->synopsis : "Not available", 03198 a->description ? a->description : "Not available"); 03199 } 03200 } 03201 } 03202 } 03203 AST_LIST_UNLOCK(&apps); 03204 03205 /* we found at least one app? no? */ 03206 if (no_registered_app) { 03207 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03208 return RESULT_FAILURE; 03209 } 03210 03211 return RESULT_SUCCESS; 03212 }
static int handle_show_applications | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3409 of file pbx.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::description, ast_app::list, ast_app::name, and ast_app::synopsis.
03410 { 03411 struct ast_app *a; 03412 int like = 0, describing = 0; 03413 int total_match = 0; /* Number of matches in like clause */ 03414 int total_apps = 0; /* Number of apps registered */ 03415 03416 AST_LIST_LOCK(&apps); 03417 03418 if (AST_LIST_EMPTY(&apps)) { 03419 ast_cli(fd, "There are no registered applications\n"); 03420 AST_LIST_UNLOCK(&apps); 03421 return -1; 03422 } 03423 03424 /* core list applications like <keyword> */ 03425 if ((argc == 5) && (!strcmp(argv[3], "like"))) { 03426 like = 1; 03427 } else if ((argc > 4) && (!strcmp(argv[3], "describing"))) { 03428 describing = 1; 03429 } 03430 03431 /* core list applications describing <keyword1> [<keyword2>] [...] */ 03432 if ((!like) && (!describing)) { 03433 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03434 } else { 03435 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03436 } 03437 03438 AST_LIST_TRAVERSE(&apps, a, list) { 03439 int printapp = 0; 03440 total_apps++; 03441 if (like) { 03442 if (strcasestr(a->name, argv[4])) { 03443 printapp = 1; 03444 total_match++; 03445 } 03446 } else if (describing) { 03447 if (a->description) { 03448 /* Match all words on command line */ 03449 int i; 03450 printapp = 1; 03451 for (i = 4; i < argc; i++) { 03452 if (!strcasestr(a->description, argv[i])) { 03453 printapp = 0; 03454 } else { 03455 total_match++; 03456 } 03457 } 03458 } 03459 } else { 03460 printapp = 1; 03461 } 03462 03463 if (printapp) { 03464 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03465 } 03466 } 03467 if ((!like) && (!describing)) { 03468 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03469 } else { 03470 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03471 } 03472 03473 AST_LIST_UNLOCK(&apps); 03474 03475 return RESULT_SUCCESS; 03476 }
static int handle_show_applications_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3341 of file pbx.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::description, ast_app::list, ast_app::name, and ast_app::synopsis.
03342 { 03343 struct ast_app *a; 03344 int like = 0, describing = 0; 03345 int total_match = 0; /* Number of matches in like clause */ 03346 int total_apps = 0; /* Number of apps registered */ 03347 03348 AST_LIST_LOCK(&apps); 03349 03350 if (AST_LIST_EMPTY(&apps)) { 03351 ast_cli(fd, "There are no registered applications\n"); 03352 AST_LIST_UNLOCK(&apps); 03353 return -1; 03354 } 03355 03356 /* show applications like <keyword> */ 03357 if ((argc == 4) && (!strcmp(argv[2], "like"))) { 03358 like = 1; 03359 } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { 03360 describing = 1; 03361 } 03362 03363 /* show applications describing <keyword1> [<keyword2>] [...] */ 03364 if ((!like) && (!describing)) { 03365 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03366 } else { 03367 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03368 } 03369 03370 AST_LIST_TRAVERSE(&apps, a, list) { 03371 int printapp = 0; 03372 total_apps++; 03373 if (like) { 03374 if (strcasestr(a->name, argv[3])) { 03375 printapp = 1; 03376 total_match++; 03377 } 03378 } else if (describing) { 03379 if (a->description) { 03380 /* Match all words on command line */ 03381 int i; 03382 printapp = 1; 03383 for (i = 3; i < argc; i++) { 03384 if (!strcasestr(a->description, argv[i])) { 03385 printapp = 0; 03386 } else { 03387 total_match++; 03388 } 03389 } 03390 } 03391 } else { 03392 printapp = 1; 03393 } 03394 03395 if (printapp) { 03396 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03397 } 03398 } 03399 if ((!like) && (!describing)) { 03400 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03401 } else { 03402 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03403 } 03404 03405 AST_LIST_UNLOCK(&apps); 03406 03407 return RESULT_SUCCESS; 03408 }
static int handle_show_dialplan | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3695 of file pbx.c.
References ast_cli(), AST_PBX_MAX_STACK, ast_strdupa, ast_strlen_zero(), context, exten, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and show_dialplan_helper().
03696 { 03697 char *exten = NULL, *context = NULL; 03698 /* Variables used for different counters */ 03699 struct dialplan_counters counters; 03700 03701 const char *incstack[AST_PBX_MAX_STACK]; 03702 memset(&counters, 0, sizeof(counters)); 03703 03704 if (argc != 2 && argc != 3) 03705 return RESULT_SHOWUSAGE; 03706 03707 /* we obtain [exten@]context? if yes, split them ... */ 03708 if (argc == 3) { 03709 if (strchr(argv[2], '@')) { /* split into exten & context */ 03710 context = ast_strdupa(argv[2]); 03711 exten = strsep(&context, "@"); 03712 /* change empty strings to NULL */ 03713 if (ast_strlen_zero(exten)) 03714 exten = NULL; 03715 } else { /* no '@' char, only context given */ 03716 context = argv[2]; 03717 } 03718 if (ast_strlen_zero(context)) 03719 context = NULL; 03720 } 03721 /* else Show complete dial plan, context and exten are NULL */ 03722 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03723 03724 /* check for input failure and throw some error messages */ 03725 if (context && !counters.context_existence) { 03726 ast_cli(fd, "There is no existence of '%s' context\n", context); 03727 return RESULT_FAILURE; 03728 } 03729 03730 if (exten && !counters.extension_existence) { 03731 if (context) 03732 ast_cli(fd, "There is no existence of %s@%s extension\n", 03733 exten, context); 03734 else 03735 ast_cli(fd, 03736 "There is no existence of '%s' extension in all contexts\n", 03737 exten); 03738 return RESULT_FAILURE; 03739 } 03740 03741 ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", 03742 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions", 03743 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities", 03744 counters.total_context, counters.total_context == 1 ? "context" : "contexts"); 03745 03746 /* everything ok */ 03747 return RESULT_SUCCESS; 03748 }
static int handle_show_function | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1404 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().
01405 { 01406 struct ast_custom_function *acf; 01407 /* Maximum number of characters added by terminal coloring is 22 */ 01408 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01409 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01410 char stxtitle[40], *syntax = NULL; 01411 int synopsis_size, description_size, syntax_size; 01412 01413 if (argc < 4) 01414 return RESULT_SHOWUSAGE; 01415 01416 if (!(acf = ast_custom_function_find(argv[3]))) { 01417 ast_cli(fd, "No function by that name registered.\n"); 01418 return RESULT_FAILURE; 01419 01420 } 01421 01422 if (acf->synopsis) 01423 synopsis_size = strlen(acf->synopsis) + 23; 01424 else 01425 synopsis_size = strlen("Not available") + 23; 01426 synopsis = alloca(synopsis_size); 01427 01428 if (acf->desc) 01429 description_size = strlen(acf->desc) + 23; 01430 else 01431 description_size = strlen("Not available") + 23; 01432 description = alloca(description_size); 01433 01434 if (acf->syntax) 01435 syntax_size = strlen(acf->syntax) + 23; 01436 else 01437 syntax_size = strlen("Not available") + 23; 01438 syntax = alloca(syntax_size); 01439 01440 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01441 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01442 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01443 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01444 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01445 term_color(syntax, 01446 acf->syntax ? acf->syntax : "Not available", 01447 COLOR_CYAN, 0, syntax_size); 01448 term_color(synopsis, 01449 acf->synopsis ? acf->synopsis : "Not available", 01450 COLOR_CYAN, 0, synopsis_size); 01451 term_color(description, 01452 acf->desc ? acf->desc : "Not available", 01453 COLOR_CYAN, 0, description_size); 01454 01455 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01456 01457 return RESULT_SUCCESS; 01458 }
static int handle_show_function_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1348 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().
01349 { 01350 struct ast_custom_function *acf; 01351 /* Maximum number of characters added by terminal coloring is 22 */ 01352 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01353 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01354 char stxtitle[40], *syntax = NULL; 01355 int synopsis_size, description_size, syntax_size; 01356 01357 if (argc < 3) 01358 return RESULT_SHOWUSAGE; 01359 01360 if (!(acf = ast_custom_function_find(argv[2]))) { 01361 ast_cli(fd, "No function by that name registered.\n"); 01362 return RESULT_FAILURE; 01363 01364 } 01365 01366 if (acf->synopsis) 01367 synopsis_size = strlen(acf->synopsis) + 23; 01368 else 01369 synopsis_size = strlen("Not available") + 23; 01370 synopsis = alloca(synopsis_size); 01371 01372 if (acf->desc) 01373 description_size = strlen(acf->desc) + 23; 01374 else 01375 description_size = strlen("Not available") + 23; 01376 description = alloca(description_size); 01377 01378 if (acf->syntax) 01379 syntax_size = strlen(acf->syntax) + 23; 01380 else 01381 syntax_size = strlen("Not available") + 23; 01382 syntax = alloca(syntax_size); 01383 01384 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01385 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01386 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01387 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01388 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01389 term_color(syntax, 01390 acf->syntax ? acf->syntax : "Not available", 01391 COLOR_CYAN, 0, syntax_size); 01392 term_color(synopsis, 01393 acf->synopsis ? acf->synopsis : "Not available", 01394 COLOR_CYAN, 0, synopsis_size); 01395 term_color(description, 01396 acf->desc ? acf->desc : "Not available", 01397 COLOR_CYAN, 0, description_size); 01398 01399 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01400 01401 return RESULT_SUCCESS; 01402 }
static int handle_show_functions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1320 of file pbx.c.
References ast_custom_function::acflist, 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.
01321 { 01322 struct ast_custom_function *acf; 01323 int count_acf = 0; 01324 int like = 0; 01325 01326 if (argc == 5 && (!strcmp(argv[3], "like")) ) { 01327 like = 1; 01328 } else if (argc != 3) { 01329 return RESULT_SHOWUSAGE; 01330 } 01331 01332 ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed"); 01333 01334 AST_LIST_LOCK(&acf_root); 01335 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01336 if (!like || strstr(acf->name, argv[4])) { 01337 count_acf++; 01338 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01339 } 01340 } 01341 AST_LIST_UNLOCK(&acf_root); 01342 01343 ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : ""); 01344 01345 return RESULT_SUCCESS; 01346 }
static int handle_show_functions_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1293 of file pbx.c.
References ast_custom_function::acflist, 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.
01294 { 01295 struct ast_custom_function *acf; 01296 int count_acf = 0; 01297 int like = 0; 01298 01299 if (argc == 4 && (!strcmp(argv[2], "like")) ) { 01300 like = 1; 01301 } else if (argc != 2) { 01302 return RESULT_SHOWUSAGE; 01303 } 01304 01305 ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed"); 01306 01307 AST_LIST_LOCK(&acf_root); 01308 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01309 if (!like || strstr(acf->name, argv[3])) { 01310 count_acf++; 01311 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01312 } 01313 } 01314 AST_LIST_UNLOCK(&acf_root); 01315 01316 ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : ""); 01317 01318 return RESULT_SUCCESS; 01319 }
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 3751 of file pbx.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), ast_var_t::entries, globals, globalslock, and RESULT_SUCCESS.
03752 { 03753 int i = 0; 03754 struct ast_var_t *newvariable; 03755 03756 ast_mutex_lock(&globalslock); 03757 AST_LIST_TRAVERSE (&globals, newvariable, entries) { 03758 i++; 03759 ast_cli(fd, " %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable)); 03760 } 03761 ast_mutex_unlock(&globalslock); 03762 ast_cli(fd, "\n -- %d variables\n", i); 03763 03764 return RESULT_SUCCESS; 03765 }
static int handle_show_hints | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
handle_show_hints: CLI support for listing registered dial plan hints
Definition at line 3285 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.
03286 { 03287 struct ast_hint *hint; 03288 int num = 0; 03289 int watchers; 03290 struct ast_state_cb *watcher; 03291 03292 if (AST_LIST_EMPTY(&hints)) { 03293 ast_cli(fd, "There are no registered dialplan hints\n"); 03294 return RESULT_SUCCESS; 03295 } 03296 /* ... we have hints ... */ 03297 ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); 03298 AST_LIST_LOCK(&hints); 03299 AST_LIST_TRAVERSE(&hints, hint, list) { 03300 watchers = 0; 03301 for (watcher = hint->callbacks; watcher; watcher = watcher->next) 03302 watchers++; 03303 ast_cli(fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", 03304 ast_get_extension_name(hint->exten), 03305 ast_get_context_name(ast_get_extension_context(hint->exten)), 03306 ast_get_extension_app(hint->exten), 03307 ast_extension_state2str(hint->laststate), watchers); 03308 num++; 03309 } 03310 ast_cli(fd, "----------------\n"); 03311 ast_cli(fd, "- %d hints registered\n", num); 03312 AST_LIST_UNLOCK(&hints); 03313 return RESULT_SUCCESS; 03314 }
static int handle_show_switches | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
handle_show_switches: CLI support for listing registered dial plan switches
Definition at line 3317 of file pbx.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_switch::description, ast_switch::list, ast_switch::name, and RESULT_SUCCESS.
03318 { 03319 struct ast_switch *sw; 03320 03321 AST_LIST_LOCK(&switches); 03322 03323 if (AST_LIST_EMPTY(&switches)) { 03324 AST_LIST_UNLOCK(&switches); 03325 ast_cli(fd, "There are no registered alternative switches\n"); 03326 return RESULT_SUCCESS; 03327 } 03328 03329 ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); 03330 AST_LIST_TRAVERSE(&switches, sw, list) 03331 ast_cli(fd, "%s: %s\n", sw->name, sw->description); 03332 03333 AST_LIST_UNLOCK(&switches); 03334 03335 return RESULT_SUCCESS; 03336 }
static int include_valid | ( | struct ast_include * | i | ) | [inline, static] |
Definition at line 603 of file pbx.c.
References ast_check_timing(), ast_include::hastime, and ast_include::timing.
00604 { 00605 if (!i->hastime) 00606 return 1; 00607 00608 return ast_check_timing(&(i->timing)); 00609 }
static int increase_call_count | ( | const struct ast_channel * | c | ) | [static] |
Definition at line 2606 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), countcalls, LOG_NOTICE, maxcalllock, ast_channel::name, option_maxcalls, and option_maxload.
Referenced by ast_pbx_run(), and ast_pbx_start().
02607 { 02608 int failed = 0; 02609 double curloadavg; 02610 ast_mutex_lock(&maxcalllock); 02611 if (option_maxcalls) { 02612 if (countcalls >= option_maxcalls) { 02613 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name); 02614 failed = -1; 02615 } 02616 } 02617 if (option_maxload) { 02618 getloadavg(&curloadavg, 1); 02619 if (curloadavg >= option_maxload) { 02620 ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg); 02621 failed = -1; 02622 } 02623 } 02624 if (!failed) 02625 countcalls++; 02626 ast_mutex_unlock(&maxcalllock); 02627 02628 return failed; 02629 }
int load_pbx | ( | void | ) |
Provided by pbx.c
Definition at line 6235 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().
06236 { 06237 int x; 06238 06239 /* Initialize the PBX */ 06240 if (option_verbose) { 06241 ast_verbose( "Asterisk PBX Core Initializing\n"); 06242 ast_verbose( "Registering builtin applications:\n"); 06243 } 06244 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(struct ast_cli_entry)); 06245 06246 /* Register builtin applications */ 06247 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06248 if (option_verbose) 06249 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06250 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06251 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06252 return -1; 06253 } 06254 } 06255 return 0; 06256 }
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 4091 of file pbx.c.
Referenced by get_range().
04092 { 04093 int i; 04094 04095 if (names) { 04096 for (i = 0; names[i]; i++) { 04097 if (!strcasecmp(s, names[i])) 04098 return i+1; 04099 } 04100 } else if (sscanf(s, "%d", &i) == 1 && i >= 1 && i <= max) { 04101 return i; 04102 } 04103 return 0; /* error return */ 04104 }
static int matchcid | ( | const char * | cidpattern, | |
const char * | callerid | |||
) | [static] |
Definition at line 940 of file pbx.c.
References ast_extension_match(), and ast_strlen_zero().
Referenced by pbx_find_extension().
00941 { 00942 /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so 00943 failing to get a number should count as a match, otherwise not */ 00944 00945 if (ast_strlen_zero(callerid)) 00946 return ast_strlen_zero(cidpattern) ? 1 : 0; 00947 00948 return ast_extension_match(cidpattern, callerid); 00949 }
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 1106 of file pbx.c.
Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
01107 { 01108 int parens=0; 01109 01110 *offset = 0; 01111 *length = INT_MAX; 01112 *isfunc = 0; 01113 for (; *var; var++) { 01114 if (*var == '(') { 01115 (*isfunc)++; 01116 parens++; 01117 } else if (*var == ')') { 01118 parens--; 01119 } else if (*var == ':' && parens == 0) { 01120 *var++ = '\0'; 01121 sscanf(var, "%d:%d", offset, length); 01122 return 1; /* offset:length valid */ 01123 } 01124 } 01125 return 0; 01126 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6037 of file pbx.c.
References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), ast_var_delete(), ast_var_t::entries, globals, and globalslock.
Referenced by handle_reload_extensions(), and reload().
06038 { 06039 struct ast_var_t *vardata; 06040 06041 ast_mutex_lock(&globalslock); 06042 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06043 ast_var_delete(vardata); 06044 ast_mutex_unlock(&globalslock); 06045 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5814 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 globalslock.
Referenced by __login_exec(), _macro_exec(), _while_exec(), agent_hangup(), agent_read(), agentmonitoroutgoing_exec(), ast_bridge_call(), ast_channel_bridge(), ast_feature_interpret(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dundi_exec(), dundi_helper(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), macro_fixup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), park_space_reserve(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), ring_entry(), run_agi(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_calling(), try_suggested_sip_codec(), and wait_for_answer().
05815 { 05816 struct ast_var_t *variables; 05817 const char *ret = NULL; 05818 int i; 05819 struct varshead *places[2] = { NULL, &globals }; 05820 05821 if (!name) 05822 return NULL; 05823 05824 if (chan) { 05825 ast_channel_lock(chan); 05826 places[0] = &chan->varshead; 05827 } 05828 05829 for (i = 0; i < 2; i++) { 05830 if (!places[i]) 05831 continue; 05832 if (places[i] == &globals) 05833 ast_mutex_lock(&globalslock); 05834 AST_LIST_TRAVERSE(places[i], variables, entries) { 05835 if (!strcmp(name, ast_var_name(variables))) { 05836 ret = ast_var_value(variables); 05837 break; 05838 } 05839 } 05840 if (places[i] == &globals) 05841 ast_mutex_unlock(&globalslock); 05842 if (ret) 05843 break; 05844 } 05845 05846 if (chan) 05847 ast_channel_unlock(chan); 05848 05849 return ret; 05850 }
static int pbx_builtin_gotoif | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6057 of file pbx.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_goto(), and pbx_checkcondition().
06058 { 06059 char *condition, *branch1, *branch2, *branch; 06060 int rc; 06061 char *stringp; 06062 06063 if (ast_strlen_zero(data)) { 06064 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06065 return 0; 06066 } 06067 06068 stringp = ast_strdupa(data); 06069 condition = strsep(&stringp,"?"); 06070 branch1 = strsep(&stringp,":"); 06071 branch2 = strsep(&stringp,""); 06072 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06073 06074 if (ast_strlen_zero(branch)) { 06075 if (option_debug) 06076 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06077 return 0; 06078 } 06079 06080 rc = pbx_builtin_goto(chan, branch); 06081 06082 return rc; 06083 }
int pbx_builtin_importvar | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 5976 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, and VAR_BUF_SIZE.
05977 { 05978 char *name; 05979 char *value; 05980 char *channel; 05981 char tmp[VAR_BUF_SIZE]=""; 05982 05983 if (ast_strlen_zero(data)) { 05984 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 05985 return 0; 05986 } 05987 05988 value = ast_strdupa(data); 05989 name = strsep(&value,"="); 05990 channel = strsep(&value,"|"); 05991 if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */ 05992 struct ast_channel *chan2 = ast_get_channel_by_name_locked(channel); 05993 if (chan2) { 05994 char *s = alloca(strlen(value) + 4); 05995 if (s) { 05996 sprintf(s, "${%s}", value); 05997 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 05998 } 05999 ast_channel_unlock(chan2); 06000 } 06001 pbx_builtin_setvar_helper(chan, name, tmp); 06002 } 06003 06004 return(0); 06005 }
static int pbx_builtin_noop | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
void pbx_builtin_pushvar_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_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_var_assign(), ast_verbose(), globals, globalslock, LOG_WARNING, option_verbose, and VERBOSE_PREFIX_2.
Referenced by acf_odbc_read(), acf_odbc_write(), and gosub_exec().
05853 { 05854 struct ast_var_t *newvariable; 05855 struct varshead *headp; 05856 05857 if (name[strlen(name)-1] == ')') { 05858 char *function = ast_strdupa(name); 05859 05860 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 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 if (value) { 05874 if ((option_verbose > 1) && (headp == &globals)) 05875 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05876 newvariable = ast_var_assign(name, value); 05877 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05878 } 05879 05880 if (chan) 05881 ast_channel_unlock(chan); 05882 else 05883 ast_mutex_unlock(&globalslock); 05884 }
static int pbx_builtin_saycharacters | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6122 of file pbx.c.
References ast_say_character_str(), and ast_channel::language.
06123 { 06124 int res = 0; 06125 06126 if (data) 06127 res = ast_say_character_str(chan, data, "", chan->language); 06128 return res; 06129 }
static int pbx_builtin_saydate | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6140 of file pbx.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_say_date, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::language, LOG_WARNING, parse(), and pbx_builtin_setvar_helper().
06141 { 06142 int res = 0; 06143 char *parse; 06144 int unixdate = 0; 06145 char charascii[2]; 06146 06147 AST_DECLARE_APP_ARGS(args, 06148 AST_APP_ARG(datestr); 06149 AST_APP_ARG(digits); 06150 ); 06151 06152 06153 if (ast_strlen_zero(data)) { 06154 ast_log(LOG_WARNING, "SayDate requires an argument (date)\n"); 06155 return -1; 06156 } 06157 06158 if (!(parse = ast_strdupa(data))) { 06159 ast_log(LOG_WARNING, "Memory Error!\n"); 06160 return -1; 06161 } 06162 06163 AST_STANDARD_APP_ARGS(args, parse); 06164 06165 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06166 ast_log(LOG_WARNING, "SayDate escape digits must be a subset from '0123456789*#'\n"); 06167 args.digits = ""; 06168 } 06169 06170 if (sscanf(args.datestr, "%d", &unixdate) != 1) { 06171 ast_log(LOG_WARNING, "Firt argument to SayDate must be numeric (date)\n"); 06172 return -1; 06173 } 06174 06175 res = ast_say_date(chan, (time_t)unixdate, args.digits, chan->language); 06176 if (res > 0) { 06177 if (isdigit(res) || (res == '*') || (res == '#')) { 06178 snprintf(charascii, 2, "%c", res); 06179 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06180 res = 0; 06181 } else { 06182 ast_log(LOG_WARNING, "SayDate: invalid return value (%d) detected\n", res); 06183 } 06184 } 06185 return res; 06186 }
static int pbx_builtin_saydigits | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6113 of file pbx.c.
References ast_say_digit_str(), and ast_channel::language.
06114 { 06115 int res = 0; 06116 06117 if (data) 06118 res = ast_say_digit_str(chan, data, "", chan->language); 06119 return res; 06120 }
static int pbx_builtin_saynumber | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6085 of file pbx.c.
References ast_copy_string(), ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, and LOG_WARNING.
06086 { 06087 char tmp[256]; 06088 char *number = tmp; 06089 char *options; 06090 06091 if (ast_strlen_zero(data)) { 06092 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06093 return -1; 06094 } 06095 ast_copy_string(tmp, data, sizeof(tmp)); 06096 strsep(&number, "|"); 06097 options = strsep(&number, "|"); 06098 if (options) { 06099 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06100 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06101 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06102 return -1; 06103 } 06104 } 06105 06106 if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) { 06107 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp); 06108 } 06109 06110 return 0; 06111 }
static int pbx_builtin_sayphonetic | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6131 of file pbx.c.
References ast_say_phonetic_str(), and ast_channel::language.
06132 { 06133 int res = 0; 06134 06135 if (data) 06136 res = ast_say_phonetic_str(chan, data, "", chan->language); 06137 return res; 06138 }
static int pbx_builtin_saytime | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6188 of file pbx.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_say_time, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::language, LOG_WARNING, parse(), and pbx_builtin_setvar_helper().
06189 { 06190 int res = 0; 06191 char *parse; 06192 int secs = 0; 06193 char charascii[2]; 06194 06195 AST_DECLARE_APP_ARGS(args, 06196 AST_APP_ARG(timestr); 06197 AST_APP_ARG(digits); 06198 ); 06199 06200 if (ast_strlen_zero(data)) { 06201 ast_log(LOG_WARNING, "SayTime requires an argument (time in seconds)\n"); 06202 return -1; 06203 } 06204 06205 if (!(parse = ast_strdupa(data))) { 06206 ast_log(LOG_WARNING, "Memory Error!\n"); 06207 return -1; 06208 } 06209 06210 AST_STANDARD_APP_ARGS(args, parse); 06211 06212 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06213 ast_log(LOG_WARNING, "SayTime escape digits must be a subset from '0123456789*#'\n"); 06214 args.digits = ""; 06215 } 06216 06217 if (sscanf(args.timestr, "%d", &secs) != 1) { 06218 ast_log(LOG_WARNING, "Firt argument to SayTime must be numeric (time in seconds)\n"); 06219 return -1; 06220 } 06221 06222 res = ast_say_time(chan, (time_t)secs, args.digits, chan->language); 06223 if (res > 0) { 06224 if (isdigit(res) || (res == '*') || (res == '#')) { 06225 snprintf(charascii, 2, "%c", res); 06226 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06227 res = 0; 06228 } else { 06229 ast_log(LOG_WARNING, "SayTime: invalid return value (%d) detected\n", res); 06230 } 06231 } 06232 return res; 06233 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5783 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(), ast_var_t::entries, LOG_ERROR, total, var, and ast_channel::varshead.
Referenced by dumpchan_exec(), handle_showchan(), handle_showchan_deprecated(), and vars2manager().
05784 { 05785 struct ast_var_t *variables; 05786 const char *var, *val; 05787 int total = 0; 05788 05789 if (!chan) 05790 return 0; 05791 05792 memset(buf, 0, size); 05793 05794 ast_channel_lock(chan); 05795 05796 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05797 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05798 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05799 ) { 05800 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05801 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05802 break; 05803 } else 05804 total++; 05805 } else 05806 break; 05807 } 05808 05809 ast_channel_unlock(chan); 05810 05811 return total; 05812 }
static int pbx_builtin_setglobalvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 6008 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and pbx_builtin_setvar_helper().
06009 { 06010 char *name; 06011 char *stringp = data; 06012 static int dep_warning = 0; 06013 06014 if (ast_strlen_zero(data)) { 06015 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06016 return 0; 06017 } 06018 06019 name = strsep(&stringp, "="); 06020 06021 if (!dep_warning) { 06022 dep_warning = 1; 06023 ast_log(LOG_WARNING, "SetGlobalVar is deprecated. Please use Set(GLOBAL(%s)=%s) instead.\n", name, stringp); 06024 } 06025 06026 /*! \todo XXX watch out, leading whitespace ? */ 06027 pbx_builtin_setvar_helper(NULL, name, stringp); 06028 06029 return(0); 06030 }
int pbx_builtin_setvar | ( | struct ast_channel * | , | |
void * | ||||
) |
Definition at line 5936 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().
05937 { 05938 char *name, *value, *mydata; 05939 int argc; 05940 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 05941 int global = 0; 05942 int x; 05943 05944 if (ast_strlen_zero(data)) { 05945 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 05946 return 0; 05947 } 05948 05949 mydata = ast_strdupa(data); 05950 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 05951 05952 /* check for a trailing flags argument */ 05953 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 05954 argc--; 05955 if (strchr(argv[argc], 'g')) { 05956 ast_log(LOG_WARNING, "The use of the 'g' flag is deprecated. Please use Set(GLOBAL(foo)=bar) instead\n"); 05957 global = 1; 05958 } 05959 } 05960 05961 if (argc > 1) 05962 ast_log(LOG_WARNING, "Setting multiple variables at once within Set is deprecated. Please separate each name/value pair into its own line.\n"); 05963 05964 for (x = 0; x < argc; x++) { 05965 name = argv[x]; 05966 if ((value = strchr(name, '='))) { 05967 *value++ = '\0'; 05968 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 05969 } else 05970 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 05971 } 05972 05973 return(0); 05974 }
void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5886 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, globalslock, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __oh323_new(), _macro_exec(), _while_exec(), acf_odbc_read(), acf_odbc_write(), action_setvar(), agi_exec_full(), aji_status_exec(), aqm_exec(), array(), ast_bridge_call(), ast_channel_bridge(), ast_feature_request_and_dial(), ast_iax2_new(), ast_monitor_start(), ast_pbx_outgoing_exten(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), dahdi_handle_dtmfup(), dahdi_new(), disa_exec(), do_waiting(), end_bridge_callback(), 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(), macro_fixup(), misdn_call(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), park_exec(), parse_moved_contact(), pbx_builtin_importvar(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_load_config(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_exec(), realtime_update_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_hangup(), sip_new(), sla_calc_trunk_timeouts(), sla_station_exec(), sla_trunk_exec(), socket_process(), speech_create(), ss_thread(), start_monitor_exec(), system_exec_helper(), transfer_exec(), try_calling(), tryexec_exec(), upqm_exec(), vm_box_exists(), vm_exec(), and vmauthenticate().
05887 { 05888 struct ast_var_t *newvariable; 05889 struct varshead *headp; 05890 const char *nametail = name; 05891 05892 if (name[strlen(name)-1] == ')') { 05893 char *function = ast_strdupa(name); 05894 05895 ast_func_write(chan, function, value); 05896 return; 05897 } 05898 05899 if (chan) { 05900 ast_channel_lock(chan); 05901 headp = &chan->varshead; 05902 } else { 05903 ast_mutex_lock(&globalslock); 05904 headp = &globals; 05905 } 05906 05907 /* For comparison purposes, we have to strip leading underscores */ 05908 if (*nametail == '_') { 05909 nametail++; 05910 if (*nametail == '_') 05911 nametail++; 05912 } 05913 05914 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05915 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05916 /* there is already such a variable, delete it */ 05917 AST_LIST_REMOVE(headp, newvariable, entries); 05918 ast_var_delete(newvariable); 05919 break; 05920 } 05921 } 05922 05923 if (value) { 05924 if ((option_verbose > 1) && (headp == &globals)) 05925 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05926 newvariable = ast_var_assign(name, value); 05927 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05928 } 05929 05930 if (chan) 05931 ast_channel_unlock(chan); 05932 else 05933 ast_mutex_unlock(&globalslock); 05934 }
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 6047 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().
06048 { 06049 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06050 return 0; 06051 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06052 return atoi(condition); 06053 else /* Strings are true */ 06054 return 1; 06055 }
static void pbx_destroy | ( | struct ast_pbx * | p | ) | [static] |
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 537 of file pbx.c.
References app, ast_channel::appl, ast_cdr_setapp(), ast_check_hangup(), ast_channel::cdr, ast_channel::data, and S_OR.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00540 { 00541 int res; 00542 00543 const char *saved_c_appl; 00544 const char *saved_c_data; 00545 00546 if (c->cdr && !ast_check_hangup(c)) 00547 ast_cdr_setapp(c->cdr, app->name, data); 00548 00549 /* save channel values */ 00550 saved_c_appl= c->appl; 00551 saved_c_data= c->data; 00552 00553 c->appl = app->name; 00554 c->data = data; 00555 /* XXX remember what to to when we have linked apps to modules */ 00556 if (app->module) { 00557 /* XXX LOCAL_USER_ADD(app->module) */ 00558 } 00559 res = app->execute(c, S_OR(data, "")); 00560 if (app->module) { 00561 /* XXX LOCAL_USER_REMOVE(app->module) */ 00562 } 00563 /* restore channel values */ 00564 c->appl = saved_c_appl; 00565 c->data = saved_c_data; 00566 return res; 00567 }
static int pbx_extension_helper | ( | struct ast_channel * | c, | |
struct ast_context * | con, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
enum ext_match_t | action | |||
) | [static] |
The return value depends on the action:.
E_MATCH, E_CANMATCH, E_MATCHMORE require a real match, and return 0 on failure, -1 on match; E_FINDLABEL maps the label to a priority, and returns the priority on success, ... XXX E_SPAWN, spawn an application, and return 0 on success, -1 on failure.
Definition at line 1832 of file pbx.c.
References ast_exten::app, app, ast_copy_string(), 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, ast_channel::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(), ast_channel::uniqueid, 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().
01835 { 01836 struct ast_exten *e; 01837 struct ast_app *app; 01838 int res; 01839 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */ 01840 char passdata[EXT_DATA_SIZE]; 01841 01842 int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE); 01843 01844 ast_rdlock_contexts(); 01845 e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action); 01846 if (e) { 01847 if (matching_action) { 01848 ast_unlock_contexts(); 01849 return -1; /* success, we found it */ 01850 } else if (action == E_FINDLABEL) { /* map the label to a priority */ 01851 res = e->priority; 01852 ast_unlock_contexts(); 01853 return res; /* the priority we were looking for */ 01854 } else { /* spawn */ 01855 app = pbx_findapp(e->app); 01856 ast_unlock_contexts(); 01857 if (!app) { 01858 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority); 01859 return -1; 01860 } 01861 if (c->context != context) 01862 ast_copy_string(c->context, context, sizeof(c->context)); 01863 if (c->exten != exten) 01864 ast_copy_string(c->exten, exten, sizeof(c->exten)); 01865 c->priority = priority; 01866 pbx_substitute_variables(passdata, sizeof(passdata), c, e); 01867 if (option_debug) { 01868 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name); 01869 } 01870 if (option_verbose > 2) { 01871 char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE]; 01872 ast_verbose( VERBOSE_PREFIX_3 "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n", 01873 exten, context, priority, 01874 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)), 01875 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 01876 term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)), 01877 "in new stack"); 01878 } 01879 manager_event(EVENT_FLAG_CALL, "Newexten", 01880 "Channel: %s\r\n" 01881 "Context: %s\r\n" 01882 "Extension: %s\r\n" 01883 "Priority: %d\r\n" 01884 "Application: %s\r\n" 01885 "AppData: %s\r\n" 01886 "Uniqueid: %s\r\n", 01887 c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid); 01888 return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */ 01889 } 01890 } else if (q.swo) { /* not found here, but in another switch */ 01891 ast_unlock_contexts(); 01892 if (matching_action) { 01893 return -1; 01894 } else { 01895 if (!q.swo->exec) { 01896 ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name); 01897 res = -1; 01898 } 01899 return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data); 01900 } 01901 } else { /* not found anywhere, see what happened */ 01902 ast_unlock_contexts(); 01903 switch (q.status) { 01904 case STATUS_NO_CONTEXT: 01905 if (!matching_action) 01906 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context); 01907 break; 01908 case STATUS_NO_EXTENSION: 01909 if (!matching_action) 01910 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context); 01911 break; 01912 case STATUS_NO_PRIORITY: 01913 if (!matching_action) 01914 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context); 01915 break; 01916 case STATUS_NO_LABEL: 01917 if (context) 01918 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context); 01919 break; 01920 default: 01921 if (option_debug) 01922 ast_log(LOG_DEBUG, "Shouldn't happen!\n"); 01923 } 01924 01925 return (matching_action) ? 0 : -1; 01926 } 01927 }
static struct ast_exten* pbx_find_extension | ( | struct ast_channel * | chan, | |
struct ast_context * | bypass, | |||
struct pbx_find_info * | q, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
enum ext_match_t | action | |||
) | [static] |
Definition at line 967 of file pbx.c.
References ast_log(), AST_PBX_MAX_STACK, ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), ast_exten::cidmatch, pbx_find_info::data, E_FINDLABEL, E_MATCHMORE, ast_exten::exten, extension_match_core(), pbx_find_info::foundcontext, pbx_find_info::incstack, ast_exten::label, LOG_WARNING, match(), matchcid(), ast_exten::matchcid, ast_context::name, ast_exten::priority, pbx_find_info::stacklen, pbx_find_info::status, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, STATUS_SUCCESS, and pbx_find_info::swo.
Referenced by ast_hint_extension(), ast_merge_contexts_and_delete(), and pbx_extension_helper().
00971 { 00972 int x, res; 00973 struct ast_context *tmp; 00974 struct ast_exten *e, *eroot; 00975 struct ast_include *i; 00976 struct ast_sw *sw; 00977 char *tmpdata = NULL; 00978 00979 /* Initialize status if appropriate */ 00980 if (q->stacklen == 0) { 00981 q->status = STATUS_NO_CONTEXT; 00982 q->swo = NULL; 00983 q->data = NULL; 00984 q->foundcontext = NULL; 00985 } 00986 /* Check for stack overflow */ 00987 if (q->stacklen >= AST_PBX_MAX_STACK) { 00988 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n"); 00989 return NULL; 00990 } 00991 /* Check first to see if we've already been checked */ 00992 for (x = 0; x < q->stacklen; x++) { 00993 if (!strcasecmp(q->incstack[x], context)) 00994 return NULL; 00995 } 00996 if (bypass) /* bypass means we only look there */ 00997 tmp = bypass; 00998 else { /* look in contexts */ 00999 tmp = NULL; 01000 while ((tmp = ast_walk_contexts(tmp)) ) { 01001 if (!strcmp(tmp->name, context)) 01002 break; 01003 } 01004 if (!tmp) 01005 return NULL; 01006 } 01007 if (q->status < STATUS_NO_EXTENSION) 01008 q->status = STATUS_NO_EXTENSION; 01009 01010 /* scan the list trying to match extension and CID */ 01011 eroot = NULL; 01012 while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) { 01013 int match = extension_match_core(eroot->exten, exten, action); 01014 /* 0 on fail, 1 on match, 2 on earlymatch */ 01015 01016 if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid))) 01017 continue; /* keep trying */ 01018 if (match == 2 && action == E_MATCHMORE) { 01019 /* We match an extension ending in '!'. 01020 * The decision in this case is final and is NULL (no match). 01021 */ 01022 return NULL; 01023 } 01024 /* found entry, now look for the right priority */ 01025 if (q->status < STATUS_NO_PRIORITY) 01026 q->status = STATUS_NO_PRIORITY; 01027 e = NULL; 01028 while ( (e = ast_walk_extension_priorities(eroot, e)) ) { 01029 /* Match label or priority */ 01030 if (action == E_FINDLABEL) { 01031 if (q->status < STATUS_NO_LABEL) 01032 q->status = STATUS_NO_LABEL; 01033 if (label && e->label && !strcmp(label, e->label)) 01034 break; /* found it */ 01035 } else if (e->priority == priority) { 01036 break; /* found it */ 01037 } /* else keep searching */ 01038 } 01039 if (e) { /* found a valid match */ 01040 q->status = STATUS_SUCCESS; 01041 q->foundcontext = context; 01042 return e; 01043 } 01044 } 01045 /* Check alternative switches */ 01046 AST_LIST_TRAVERSE(&tmp->alts, sw, list) { 01047 struct ast_switch *asw = pbx_findswitch(sw->name); 01048 ast_switch_f *aswf = NULL; 01049 char *datap; 01050 01051 if (!asw) { 01052 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); 01053 continue; 01054 } 01055 /* Substitute variables now */ 01056 if (sw->eval) { 01057 if (!(tmpdata = ast_threadstorage_get(&switch_data, 512))) { 01058 ast_log(LOG_WARNING, "Can't evaluate switch?!"); 01059 continue; 01060 } 01061 pbx_substitute_variables_helper(chan, sw->data, tmpdata, 512); 01062 } 01063 01064 /* equivalent of extension_match_core() at the switch level */ 01065 if (action == E_CANMATCH) 01066 aswf = asw->canmatch; 01067 else if (action == E_MATCHMORE) 01068 aswf = asw->matchmore; 01069 else /* action == E_MATCH */ 01070 aswf = asw->exists; 01071 datap = sw->eval ? tmpdata : sw->data; 01072 if (!aswf) 01073 res = 0; 01074 else { 01075 if (chan) 01076 ast_autoservice_start(chan); 01077 res = aswf(chan, context, exten, priority, callerid, datap); 01078 if (chan) 01079 ast_autoservice_stop(chan); 01080 } 01081 if (res) { /* Got a match */ 01082 q->swo = asw; 01083 q->data = datap; 01084 q->foundcontext = context; 01085 /* XXX keep status = STATUS_NO_CONTEXT ? */ 01086 return NULL; 01087 } 01088 } 01089 q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */ 01090 /* Now try any includes we have in this context */ 01091 for (i = tmp->includes; i; i = i->next) { 01092 if (include_valid(i)) { 01093 if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) 01094 return e; 01095 if (q->swo) 01096 return NULL; 01097 } 01098 } 01099 return NULL; 01100 }
struct ast_app* pbx_findapp | ( | const char * | app | ) |
Look up an application.
app | name of the app |
Definition at line 575 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sw::list, and ast_app::name.
Referenced by answer_exec_run(), ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), milliwatt_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), realtime_exec(), try_calling(), and tryexec_exec().
00576 { 00577 struct ast_app *tmp; 00578 00579 AST_LIST_LOCK(&apps); 00580 AST_LIST_TRAVERSE(&apps, tmp, list) { 00581 if (!strcasecmp(tmp->name, app)) 00582 break; 00583 } 00584 AST_LIST_UNLOCK(&apps); 00585 00586 return tmp; 00587 }
static struct ast_switch* pbx_findswitch | ( | const char * | sw | ) | [static] |
Definition at line 589 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sw::list, and ast_switch::name.
00590 { 00591 struct ast_switch *asw; 00592 00593 AST_LIST_LOCK(&switches); 00594 AST_LIST_TRAVERSE(&switches, asw, list) { 00595 if (!strcasecmp(asw->name, sw)) 00596 break; 00597 } 00598 AST_LIST_UNLOCK(&switches); 00599 00600 return asw; 00601 }
void pbx_retrieve_variable | ( | struct ast_channel * | c, | |
const char * | var, | |||
char ** | ret, | |||
char * | workspace, | |||
int | workspacelen, | |||
struct varshead * | headp | |||
) |
pbx_retrieve_variable: Support for Asterisk built-in variables ---
Definition at line 1174 of file pbx.c.
References ast_cause2str(), ast_channel_lock, ast_channel_unlock, ast_config_AST_SYSTEM_NAME, ast_copy_string(), 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, globalslock, ast_channel::hangupcause, ast_channel::name, offset, parse_variable_name(), ast_channel::priority, s, substring(), and ast_channel::uniqueid.
Referenced by action_getvar(), handle_getvariable(), and pbx_substitute_variables_helper_full().
01175 { 01176 const char not_found = '\0'; 01177 char *tmpvar; 01178 const char *s; /* the result */ 01179 int offset, length; 01180 int i, need_substring; 01181 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 01182 01183 if (c) { 01184 ast_channel_lock(c); 01185 places[0] = &c->varshead; 01186 } 01187 /* 01188 * Make a copy of var because parse_variable_name() modifies the string. 01189 * Then if called directly, we might need to run substring() on the result; 01190 * remember this for later in 'need_substring', 'offset' and 'length' 01191 */ 01192 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 01193 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 01194 01195 /* 01196 * Look first into predefined variables, then into variable lists. 01197 * Variable 's' points to the result, according to the following rules: 01198 * s == ¬_found (set at the beginning) means that we did not find a 01199 * matching variable and need to look into more places. 01200 * If s != ¬_found, s is a valid result string as follows: 01201 * s = NULL if the variable does not have a value; 01202 * you typically do this when looking for an unset predefined variable. 01203 * s = workspace if the result has been assembled there; 01204 * typically done when the result is built e.g. with an snprintf(), 01205 * so we don't need to do an additional copy. 01206 * s != workspace in case we have a string, that needs to be copied 01207 * (the ast_copy_string is done once for all at the end). 01208 * Typically done when the result is already available in some string. 01209 */ 01210 s = ¬_found; /* default value */ 01211 if (c) { /* This group requires a valid channel */ 01212 /* Names with common parts are looked up a piece at a time using strncmp. */ 01213 if (!strncmp(var, "CALL", 4)) { 01214 if (!strncmp(var + 4, "ING", 3)) { 01215 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 01216 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01217 s = workspace; 01218 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 01219 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01220 s = workspace; 01221 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 01222 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01223 s = workspace; 01224 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 01225 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01226 s = workspace; 01227 } 01228 } 01229 } else if (!strcmp(var, "HINT")) { 01230 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 01231 } else if (!strcmp(var, "HINTNAME")) { 01232 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 01233 } else if (!strcmp(var, "EXTEN")) { 01234 s = c->exten; 01235 } else if (!strcmp(var, "CONTEXT")) { 01236 s = c->context; 01237 } else if (!strcmp(var, "PRIORITY")) { 01238 snprintf(workspace, workspacelen, "%d", c->priority); 01239 s = workspace; 01240 } else if (!strcmp(var, "CHANNEL")) { 01241 s = c->name; 01242 } else if (!strcmp(var, "UNIQUEID")) { 01243 s = c->uniqueid; 01244 } else if (!strcmp(var, "HANGUPCAUSE")) { 01245 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01246 s = workspace; 01247 } else if (c && !strcmp(var, "HANGUPCAUSESTR")) { 01248 ast_copy_string(workspace, ast_cause2str(c->hangupcause), workspacelen); 01249 *ret = workspace; 01250 } 01251 } 01252 if (s == ¬_found) { /* look for more */ 01253 if (!strcmp(var, "EPOCH")) { 01254 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01255 s = workspace; 01256 } else if (!strcmp(var, "SYSTEMNAME")) { 01257 s = ast_config_AST_SYSTEM_NAME; 01258 } 01259 } 01260 /* if not found, look into chanvars or global vars */ 01261 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) { 01262 struct ast_var_t *variables; 01263 if (!places[i]) 01264 continue; 01265 if (places[i] == &globals) 01266 ast_mutex_lock(&globalslock); 01267 AST_LIST_TRAVERSE(places[i], variables, entries) { 01268 if (strcasecmp(ast_var_name(variables), var)==0) { 01269 s = ast_var_value(variables); 01270 break; 01271 } 01272 } 01273 if (places[i] == &globals) 01274 ast_mutex_unlock(&globalslock); 01275 } 01276 if (s == ¬_found || s == NULL) 01277 *ret = NULL; 01278 else { 01279 if (s != workspace) 01280 ast_copy_string(workspace, s, workspacelen); 01281 *ret = workspace; 01282 if (need_substring) 01283 *ret = substring(*ret, offset, length, workspace, workspacelen); 01284 } 01285 01286 if (c) 01287 ast_channel_unlock(c); 01288 }
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 2714 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02715 { 02716 int oldval = autofallthrough; 02717 autofallthrough = newval; 02718 return oldval; 02719 }
static void pbx_substitute_variables | ( | char * | passdata, | |
int | datalen, | |||
struct ast_channel * | c, | |||
struct ast_exten * | e | |||
) | [static] |
Definition at line 1803 of file pbx.c.
References ast_copy_string(), ast_exten::data, and pbx_substitute_variables_helper().
Referenced by pbx_extension_helper().
01804 { 01805 memset(passdata, 0, datalen); 01806 01807 /* No variables or expressions in e->data, so why scan it? */ 01808 if (e->data && !strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) { 01809 ast_copy_string(passdata, e->data, datalen); 01810 return; 01811 } 01812 01813 pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1); 01814 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1793 of file pbx.c.
References pbx_substitute_variables_helper_full(), and ast_channel::varshead.
Referenced by _macro_exec(), acf_odbc_read(), acf_odbc_write(), add_extensions(), custom_log(), cut_internal(), exec_exec(), function_eval(), function_fieldqty(), handle_getvariablefull(), launch_monitor_thread(), make_email_file(), pbx_builtin_importvar(), pbx_load_config(), pbx_substitute_variables(), realtime_exec(), rpt_do_lstats(), sendpage(), try_calling(), and tryexec_exec().
01794 { 01795 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01796 }
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 1599 of file pbx.c.
References ast_channel_alloc(), ast_channel_free(), ast_copy_string(), 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().
01600 { 01601 /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be 01602 zero-filled */ 01603 char *cp4; 01604 const char *tmp, *whereweare; 01605 int length, offset, offset2, isfunction; 01606 char *workspace = NULL; 01607 char *ltmp = NULL, *var = NULL; 01608 char *nextvar, *nextexp, *nextthing; 01609 char *vars, *vare; 01610 int pos, brackets, needsub, len; 01611 01612 whereweare=tmp=cp1; 01613 while (!ast_strlen_zero(whereweare) && count) { 01614 /* Assume we're copying the whole remaining string */ 01615 pos = strlen(whereweare); 01616 nextvar = NULL; 01617 nextexp = NULL; 01618 nextthing = strchr(whereweare, '$'); 01619 if (nextthing) { 01620 switch(nextthing[1]) { 01621 case '{': 01622 nextvar = nextthing; 01623 pos = nextvar - whereweare; 01624 break; 01625 case '[': 01626 nextexp = nextthing; 01627 pos = nextexp - whereweare; 01628 break; 01629 default: 01630 pos = 1; 01631 } 01632 } 01633 01634 if (pos) { 01635 /* Can't copy more than 'count' bytes */ 01636 if (pos > count) 01637 pos = count; 01638 01639 /* Copy that many bytes */ 01640 memcpy(cp2, whereweare, pos); 01641 01642 count -= pos; 01643 cp2 += pos; 01644 whereweare += pos; 01645 } 01646 01647 if (nextvar) { 01648 /* We have a variable. Find the start and end, and determine 01649 if we are going to have to recursively call ourselves on the 01650 contents */ 01651 vars = vare = nextvar + 2; 01652 brackets = 1; 01653 needsub = 0; 01654 01655 /* Find the end of it */ 01656 while (brackets && *vare) { 01657 if ((vare[0] == '$') && (vare[1] == '{')) { 01658 needsub++; 01659 } else if (vare[0] == '{') { 01660 brackets++; 01661 } else if (vare[0] == '}') { 01662 brackets--; 01663 } else if ((vare[0] == '$') && (vare[1] == '[')) 01664 needsub++; 01665 vare++; 01666 } 01667 if (brackets) 01668 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n"); 01669 len = vare - vars - 1; 01670 01671 /* Skip totally over variable string */ 01672 whereweare += (len + 3); 01673 01674 if (!var) 01675 var = alloca(VAR_BUF_SIZE); 01676 01677 /* Store variable name (and truncate) */ 01678 ast_copy_string(var, vars, len + 1); 01679 01680 /* Substitute if necessary */ 01681 if (needsub) { 01682 if (!ltmp) 01683 ltmp = alloca(VAR_BUF_SIZE); 01684 01685 memset(ltmp, 0, VAR_BUF_SIZE); 01686 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01687 vars = ltmp; 01688 } else { 01689 vars = var; 01690 } 01691 01692 if (!workspace) 01693 workspace = alloca(VAR_BUF_SIZE); 01694 01695 workspace[0] = '\0'; 01696 01697 parse_variable_name(vars, &offset, &offset2, &isfunction); 01698 if (isfunction) { 01699 /* Evaluate function */ 01700 if (c || !headp) 01701 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace; 01702 else { 01703 struct varshead old; 01704 struct ast_channel *c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/%p", vars); 01705 if (c) { 01706 memcpy(&old, &c->varshead, sizeof(old)); 01707 memcpy(&c->varshead, headp, sizeof(c->varshead)); 01708 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace; 01709 /* Don't deallocate the varshead that was passed in */ 01710 memcpy(&c->varshead, &old, sizeof(c->varshead)); 01711 ast_channel_free(c); 01712 } else 01713 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 01714 } 01715 01716 if (option_debug) 01717 ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)"); 01718 } else { 01719 /* Retrieve variable value */ 01720 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp); 01721 } 01722 if (cp4) { 01723 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE); 01724 01725 length = strlen(cp4); 01726 if (length > count) 01727 length = count; 01728 memcpy(cp2, cp4, length); 01729 count -= length; 01730 cp2 += length; 01731 } 01732 } else if (nextexp) { 01733 /* We have an expression. Find the start and end, and determine 01734 if we are going to have to recursively call ourselves on the 01735 contents */ 01736 vars = vare = nextexp + 2; 01737 brackets = 1; 01738 needsub = 0; 01739 01740 /* Find the end of it */ 01741 while(brackets && *vare) { 01742 if ((vare[0] == '$') && (vare[1] == '[')) { 01743 needsub++; 01744 brackets++; 01745 vare++; 01746 } else if (vare[0] == '[') { 01747 brackets++; 01748 } else if (vare[0] == ']') { 01749 brackets--; 01750 } else if ((vare[0] == '$') && (vare[1] == '{')) { 01751 needsub++; 01752 vare++; 01753 } 01754 vare++; 01755 } 01756 if (brackets) 01757 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n"); 01758 len = vare - vars - 1; 01759 01760 /* Skip totally over expression */ 01761 whereweare += (len + 3); 01762 01763 if (!var) 01764 var = alloca(VAR_BUF_SIZE); 01765 01766 /* Store variable name (and truncate) */ 01767 ast_copy_string(var, vars, len + 1); 01768 01769 /* Substitute if necessary */ 01770 if (needsub) { 01771 if (!ltmp) 01772 ltmp = alloca(VAR_BUF_SIZE); 01773 01774 memset(ltmp, 0, VAR_BUF_SIZE); 01775 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01776 vars = ltmp; 01777 } else { 01778 vars = var; 01779 } 01780 01781 length = ast_expr(vars, cp2, count); 01782 01783 if (length) { 01784 if (option_debug) 01785 ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2); 01786 count -= length; 01787 cp2 += length; 01788 } 01789 } 01790 } 01791 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1798 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_subst().
01799 { 01800 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01801 }
static void* pbx_thread | ( | void * | data | ) | [static] |
Definition at line 2649 of file pbx.c.
References __ast_pbx_run(), and decrease_call_count().
Referenced by ast_pbx_start().
02650 { 02651 /* Oh joyeous kernel, we're a new thread, with nothing to do but 02652 answer this channel and get it going. 02653 */ 02654 /* NOTE: 02655 The launcher of this function _MUST_ increment 'countcalls' 02656 before invoking the function; it will be decremented when the 02657 PBX has finished running on the channel 02658 */ 02659 struct ast_channel *c = data; 02660 02661 __ast_pbx_run(c); 02662 decrease_call_count(); 02663 02664 pthread_exit(NULL); 02665 02666 return NULL; 02667 }
static void print_ext | ( | struct ast_exten * | e, | |
char * | buf, | |||
int | buflen | |||
) | [static] |
helper function to print an extension
Definition at line 3533 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().
03534 { 03535 int prio = ast_get_extension_priority(e); 03536 if (prio == PRIORITY_HINT) { 03537 snprintf(buf, buflen, "hint: %s", 03538 ast_get_extension_app(e)); 03539 } else { 03540 snprintf(buf, buflen, "%d. %s(%s)", 03541 prio, ast_get_extension_app(e), 03542 (!ast_strlen_zero(ast_get_extension_app_data(e)) ? (char *)ast_get_extension_app_data(e) : "")); 03543 } 03544 }
static void set_ext_pri | ( | struct ast_channel * | c, | |
const char * | exten, | |||
int | pri | |||
) | [static] |
Definition at line 2349 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_channel::exten, and ast_channel::priority.
Referenced by __ast_pbx_run(), ast_pbx_outgoing_exten(), and pbx_builtin_waitexten().
02350 { 02351 ast_channel_lock(c); 02352 ast_copy_string(c->exten, exten, sizeof(c->exten)); 02353 c->priority = pri; 02354 ast_channel_unlock(c); 02355 }
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 3547 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().
03548 { 03549 struct ast_context *c = NULL; 03550 int res = 0, old_total_exten = dpc->total_exten; 03551 03552 ast_rdlock_contexts(); 03553 03554 /* walk all contexts ... */ 03555 while ( (c = ast_walk_contexts(c)) ) { 03556 struct ast_exten *e; 03557 struct ast_include *i; 03558 struct ast_ignorepat *ip; 03559 char buf[256], buf2[256]; 03560 int context_info_printed = 0; 03561 03562 if (context && strcmp(ast_get_context_name(c), context)) 03563 continue; /* skip this one, name doesn't match */ 03564 03565 dpc->context_existence = 1; 03566 03567 ast_lock_context(c); 03568 03569 /* are we looking for exten too? if yes, we print context 03570 * only if we find our extension. 03571 * Otherwise print context even if empty ? 03572 * XXX i am not sure how the rinclude is handled. 03573 * I think it ought to go inside. 03574 */ 03575 if (!exten) { 03576 dpc->total_context++; 03577 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03578 ast_get_context_name(c), ast_get_context_registrar(c)); 03579 context_info_printed = 1; 03580 } 03581 03582 /* walk extensions ... */ 03583 e = NULL; 03584 while ( (e = ast_walk_context_extensions(c, e)) ) { 03585 struct ast_exten *p; 03586 03587 if (exten && !ast_extension_match(ast_get_extension_name(e), exten)) 03588 continue; /* skip, extension match failed */ 03589 03590 dpc->extension_existence = 1; 03591 03592 /* may we print context info? */ 03593 if (!context_info_printed) { 03594 dpc->total_context++; 03595 if (rinclude) { /* TODO Print more info about rinclude */ 03596 ast_cli(fd, "[ Included context '%s' created by '%s' ]\n", 03597 ast_get_context_name(c), ast_get_context_registrar(c)); 03598 } else { 03599 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03600 ast_get_context_name(c), ast_get_context_registrar(c)); 03601 } 03602 context_info_printed = 1; 03603 } 03604 dpc->total_prio++; 03605 03606 /* write extension name and first peer */ 03607 snprintf(buf, sizeof(buf), "'%s' =>", ast_get_extension_name(e)); 03608 03609 print_ext(e, buf2, sizeof(buf2)); 03610 03611 ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2, 03612 ast_get_extension_registrar(e)); 03613 03614 dpc->total_exten++; 03615 /* walk next extension peers */ 03616 p = e; /* skip the first one, we already got it */ 03617 while ( (p = ast_walk_extension_priorities(e, p)) ) { 03618 const char *el = ast_get_extension_label(p); 03619 dpc->total_prio++; 03620 if (el) 03621 snprintf(buf, sizeof(buf), " [%s]", el); 03622 else 03623 buf[0] = '\0'; 03624 print_ext(p, buf2, sizeof(buf2)); 03625 03626 ast_cli(fd," %-17s %-45s [%s]\n", buf, buf2, 03627 ast_get_extension_registrar(p)); 03628 } 03629 } 03630 03631 /* walk included and write info ... */ 03632 i = NULL; 03633 while ( (i = ast_walk_context_includes(c, i)) ) { 03634 snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i)); 03635 if (exten) { 03636 /* Check all includes for the requested extension */ 03637 if (includecount >= AST_PBX_MAX_STACK) { 03638 ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n"); 03639 } else { 03640 int dupe=0; 03641 int x; 03642 for (x=0;x<includecount;x++) { 03643 if (!strcasecmp(includes[x], ast_get_include_name(i))) { 03644 dupe++; 03645 break; 03646 } 03647 } 03648 if (!dupe) { 03649 includes[includecount] = ast_get_include_name(i); 03650 show_dialplan_helper(fd, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes); 03651 } else { 03652 ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context); 03653 } 03654 } 03655 } else { 03656 ast_cli(fd, " Include => %-45s [%s]\n", 03657 buf, ast_get_include_registrar(i)); 03658 } 03659 } 03660 03661 /* walk ignore patterns and write info ... */ 03662 ip = NULL; 03663 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) { 03664 const char *ipname = ast_get_ignorepat_name(ip); 03665 char ignorepat[AST_MAX_EXTENSION]; 03666 snprintf(buf, sizeof(buf), "'%s'", ipname); 03667 snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname); 03668 if (!exten || ast_extension_match(ignorepat, exten)) { 03669 ast_cli(fd, " Ignore pattern => %-45s [%s]\n", 03670 buf, ast_get_ignorepat_registrar(ip)); 03671 } 03672 } 03673 if (!rinclude) { 03674 struct ast_sw *sw = NULL; 03675 while ( (sw = ast_walk_context_switches(c, sw)) ) { 03676 snprintf(buf, sizeof(buf), "'%s/%s'", 03677 ast_get_switch_name(sw), 03678 ast_get_switch_data(sw)); 03679 ast_cli(fd, " Alt. Switch => %-45s [%s]\n", 03680 buf, ast_get_switch_registrar(sw)); 03681 } 03682 } 03683 03684 ast_unlock_context(c); 03685 03686 /* if we print something in context, make an empty line */ 03687 if (context_info_printed) 03688 ast_cli(fd, "\n"); 03689 } 03690 ast_unlock_contexts(); 03691 03692 return (dpc->total_exten == old_total_exten) ? -1 : res; 03693 }
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 1136 of file pbx.c.
References ast_copy_string().
Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
01137 { 01138 char *ret = workspace; 01139 int lr; /* length of the input string after the copy */ 01140 01141 ast_copy_string(workspace, value, workspace_len); /* always make a copy */ 01142 01143 lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */ 01144 01145 /* Quick check if no need to do anything */ 01146 if (offset == 0 && length >= lr) /* take the whole string */ 01147 return ret; 01148 01149 if (offset < 0) { /* translate negative offset into positive ones */ 01150 offset = lr + offset; 01151 if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */ 01152 offset = 0; 01153 } 01154 01155 /* too large offset result in empty string so we know what to return */ 01156 if (offset >= lr) 01157 return ret + lr; /* the final '\0' */ 01158 01159 ret += offset; /* move to the start position */ 01160 if (length >= 0 && length < lr - offset) /* truncate if necessary */ 01161 ret[length] = '\0'; 01162 else if (length < 0) { 01163 if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */ 01164 ret[lr + length - offset] = '\0'; 01165 else 01166 ret[0] = '\0'; 01167 } 01168 01169 return ret; 01170 }
static void switch_data_init | ( | void | ) | [static] |
static void wait_for_hangup | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5394 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().
05395 { 05396 int res; 05397 struct ast_frame *f; 05398 int waittime; 05399 05400 if (ast_strlen_zero(data) || (sscanf(data, "%d", &waittime) != 1) || (waittime < 0)) 05401 waittime = -1; 05402 if (waittime > -1) { 05403 ast_safe_sleep(chan, waittime * 1000); 05404 } else do { 05405 res = ast_waitfor(chan, -1); 05406 if (res < 0) 05407 return; 05408 f = ast_read(chan); 05409 if (f) 05410 ast_frfree(f); 05411 } while(f); 05412 }
int autofallthrough = 1 [static] |
struct ast_app_option background_opts[128] = { [ 's' ] = { .flag = (1 << 0) }, [ 'n' ] = { .flag = (1 << 1) }, [ 'm' ] = { .flag = (1 << 2) }, [ 'p' ] = { .flag = (1 << 3) },} [static] |
struct pbx_builtin builtins[] [static] |
Declaration of builtin applications.
struct ast_cli_entry cli_set_global_deprecated [static] |
Initial value:
{ { "set", "global", NULL }, handle_set_global_deprecated, NULL, NULL }
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 }
ast_rwlock_t conlock = PTHREAD_RWLOCK_INITIALIZER [static] |
Lock for the ast_context list
Definition at line 518 of file pbx.c.
Referenced by ast_lock_contexts(), ast_rdlock_contexts(), ast_unlock_contexts(), and ast_wrlock_contexts().
struct ast_context* contexts [static] |
Definition at line 517 of file pbx.c.
Referenced by __ast_context_create(), __ast_context_destroy(), ast_merge_contexts_and_delete(), and ast_walk_contexts().
int countcalls [static] |
Definition at line 250 of file pbx.c.
Referenced by ast_active_calls(), decrease_call_count(), and increase_call_count().
char* days[] [static] |
struct cfextension_states extension_states[] [static] |
Referenced by ast_extension_state2str().
Definition at line 245 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().
ast_mutex_t globalslock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 244 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().
ast_mutex_t maxcalllock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 249 of file pbx.c.
Referenced by decrease_call_count(), and increase_call_count().
char* months[] [static] |
struct ast_cli_entry pbx_cli[] [static] |
struct ast_app_option resetcdr_opts[128] = { [ 'w' ] = { .flag = (1 << 1) }, [ 'a' ] = { .flag = (1 << 2) }, [ 'v' ] = { .flag = (1 << 0) },} [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 532 of file pbx.c.
Referenced by ast_extension_state_add(), ast_extension_state_del(), and ast_hint_state_changed().
struct ast_threadstorage switch_data = { .once = PTHREAD_ONCE_INIT, .key_init = switch_data_init , } [static] |
struct ast_app_option waitexten_opts[128] = { [ 'm' ] = { .flag = (1 << 0) , .arg_index = 0 + 1 },} [static] |