#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 registred dial plan hints | |
static int | handle_show_switches (int fd, int argc, char *argv[]) |
handle_show_switches: CLI support for listing registred dial plan switches | |
static int | include_valid (struct ast_include *i) |
static int | increase_call_count (const struct ast_channel *c) |
int | load_pbx (void) |
static int | lookup_name (const char *s, char *const names[], int max) |
Helper for get_range. return the index of the matching entry, starting from 1. If names is not supplied, try numeric values. | |
static int | matchcid (const char *cidpattern, const char *callerid) |
static int | parse_variable_name (char *var, int *offset, int *length, int *isfunc) |
extract offset:length from variable name. Returns 1 if there is a offset:length part, which is trimmed off (values go into variables) | |
static int | pbx_builtin_answer (struct ast_channel *, void *) |
static int | pbx_builtin_background (struct ast_channel *, void *) |
static int | pbx_builtin_busy (struct ast_channel *, void *) |
void | pbx_builtin_clear_globals (void) |
static int | pbx_builtin_congestion (struct ast_channel *, void *) |
static int | pbx_builtin_execiftime (struct ast_channel *, void *) |
const char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
static int | pbx_builtin_goto (struct ast_channel *, void *) |
static int | pbx_builtin_gotoif (struct ast_channel *, void *) |
static int | pbx_builtin_gotoiftime (struct ast_channel *, void *) |
static int | pbx_builtin_hangup (struct ast_channel *, void *) |
static int | pbx_builtin_importvar (struct ast_channel *, void *) |
static int | pbx_builtin_noop (struct ast_channel *, void *) |
static int | pbx_builtin_progress (struct ast_channel *, void *) |
void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
static int | pbx_builtin_resetcdr (struct ast_channel *, void *) |
static int | pbx_builtin_ringing (struct ast_channel *, void *) |
static int | pbx_builtin_saycharacters (struct ast_channel *, void *) |
static int | pbx_builtin_saydate (struct ast_channel *, void *) |
static int | pbx_builtin_saydigits (struct ast_channel *, void *) |
static int | pbx_builtin_saynumber (struct ast_channel *, void *) |
static int | pbx_builtin_sayphonetic (struct ast_channel *, void *) |
static int | pbx_builtin_saytime (struct ast_channel *, void *) |
int | pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
static int | pbx_builtin_setamaflags (struct ast_channel *, void *) |
static int | pbx_builtin_setglobalvar (struct ast_channel *, void *) |
int | pbx_builtin_setvar (struct ast_channel *, void *) |
void | pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value) |
static int | pbx_builtin_wait (struct ast_channel *, void *) |
static int | pbx_builtin_waitexten (struct ast_channel *, void *) |
int | pbx_checkcondition (const char *condition) |
Evaluate a condition. | |
static void | pbx_destroy (struct ast_pbx *p) |
int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data) |
Execute an application. | |
static int | pbx_extension_helper (struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action) |
The return value depends on the action:. | |
static struct ast_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 3885 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().
03886 { 03887 struct ast_context *tmp, **local_contexts; 03888 int length = sizeof(struct ast_context) + strlen(name) + 1; 03889 03890 if (!extcontexts) { 03891 ast_rdlock_contexts(); 03892 local_contexts = &contexts; 03893 } else 03894 local_contexts = extcontexts; 03895 03896 for (tmp = *local_contexts; tmp; tmp = tmp->next) { 03897 if (!strcasecmp(tmp->name, name)) { 03898 if (!existsokay) { 03899 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 03900 tmp = NULL; 03901 } 03902 if (!extcontexts) 03903 ast_unlock_contexts(); 03904 return tmp; 03905 } 03906 } 03907 03908 if (!extcontexts) 03909 ast_unlock_contexts(); 03910 03911 if ((tmp = ast_calloc(1, length))) { 03912 ast_mutex_init(&tmp->lock); 03913 ast_mutex_init(&tmp->macrolock); 03914 strcpy(tmp->name, name); 03915 tmp->registrar = registrar; 03916 if (!extcontexts) 03917 ast_wrlock_contexts(); 03918 tmp->next = *local_contexts; 03919 *local_contexts = tmp; 03920 if (!extcontexts) 03921 ast_unlock_contexts(); 03922 if (option_debug) 03923 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 03924 if (option_verbose > 2) 03925 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 03926 } 03927 03928 return tmp; 03929 }
void __ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
Definition at line 5314 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().
05315 { 05316 struct ast_context *tmp, *tmpl=NULL; 05317 struct ast_include *tmpi; 05318 struct ast_sw *sw; 05319 struct ast_exten *e, *el, *en; 05320 struct ast_ignorepat *ipi; 05321 05322 for (tmp = contexts; tmp; ) { 05323 struct ast_context *next; /* next starting point */ 05324 for (; tmp; tmpl = tmp, tmp = tmp->next) { 05325 if (option_debug) 05326 ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar); 05327 if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) && 05328 (!con || !strcasecmp(tmp->name, con->name)) ) 05329 break; /* found it */ 05330 } 05331 if (!tmp) /* not found, we are done */ 05332 break; 05333 ast_mutex_lock(&tmp->lock); 05334 if (option_debug) 05335 ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar); 05336 next = tmp->next; 05337 if (tmpl) 05338 tmpl->next = next; 05339 else 05340 contexts = next; 05341 /* Okay, now we're safe to let it go -- in a sense, we were 05342 ready to let it go as soon as we locked it. */ 05343 ast_mutex_unlock(&tmp->lock); 05344 for (tmpi = tmp->includes; tmpi; ) { /* Free includes */ 05345 struct ast_include *tmpil = tmpi; 05346 tmpi = tmpi->next; 05347 free(tmpil); 05348 } 05349 for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */ 05350 struct ast_ignorepat *ipl = ipi; 05351 ipi = ipi->next; 05352 free(ipl); 05353 } 05354 while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list))) 05355 free(sw); 05356 for (e = tmp->root; e;) { 05357 for (en = e->peer; en;) { 05358 el = en; 05359 en = en->peer; 05360 destroy_exten(el); 05361 } 05362 el = e; 05363 e = e->next; 05364 destroy_exten(el); 05365 } 05366 ast_mutex_destroy(&tmp->lock); 05367 free(tmp); 05368 /* if we have a specific match, we are done, otherwise continue */ 05369 tmp = con ? NULL : next; 05370 } 05371 }
static int __ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
int | async | |||
) | [static] |
Definition at line 6445 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().
06446 { 06447 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06448 06449 if (!chan) 06450 return -2; 06451 06452 if (context == NULL) 06453 context = chan->context; 06454 if (exten == NULL) 06455 exten = chan->exten; 06456 06457 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06458 if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num)) 06459 return goto_func(chan, context, exten, priority); 06460 else 06461 return -3; 06462 }
static int __ast_pbx_run | ( | struct ast_channel * | c | ) | [static] |
Definition at line 2385 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().
02386 { 02387 int found = 0; /* set if we find at least one match */ 02388 int res = 0; 02389 int autoloopflag; 02390 int error = 0; /* set an error conditions */ 02391 02392 /* A little initial setup here */ 02393 if (c->pbx) { 02394 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name); 02395 /* XXX and now what ? */ 02396 free(c->pbx); 02397 } 02398 if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx)))) 02399 return -1; 02400 /* Set reasonable defaults */ 02401 c->pbx->rtimeout = 10; 02402 c->pbx->dtimeout = 5; 02403 02404 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */ 02405 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP); 02406 02407 /* Start by trying whatever the channel is set to */ 02408 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02409 /* If not successful fall back to 's' */ 02410 if (option_verbose > 1) 02411 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); 02412 /* XXX the original code used the existing priority in the call to 02413 * ast_exists_extension(), and reset it to 1 afterwards. 02414 * I believe the correct thing is to set it to 1 immediately. 02415 */ 02416 set_ext_pri(c, "s", 1); 02417 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02418 /* JK02: And finally back to default if everything else failed */ 02419 if (option_verbose > 1) 02420 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); 02421 ast_copy_string(c->context, "default", sizeof(c->context)); 02422 } 02423 } 02424 for (;;) { 02425 char dst_exten[256]; /* buffer to accumulate digits */ 02426 int pos = 0; /* XXX should check bounds */ 02427 int digit = 0; 02428 02429 /* loop on priorities in this context/exten */ 02430 while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02431 found = 1; 02432 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02433 /* Something bad happened, or a hangup has been requested. */ 02434 if (strchr("0123456789ABCDEF*#", res)) { 02435 if (option_debug) 02436 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 02437 pos = 0; 02438 dst_exten[pos++] = digit = res; 02439 dst_exten[pos] = '\0'; 02440 break; 02441 } 02442 if (res == AST_PBX_KEEPALIVE) { 02443 if (option_debug) 02444 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02445 if (option_verbose > 1) 02446 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02447 error = 1; 02448 break; 02449 } 02450 if (option_debug) 02451 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02452 if (option_verbose > 1) 02453 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02454 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02455 c->_softhangup = 0; 02456 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02457 /* atimeout, nothing bad */ 02458 } else { 02459 if (c->cdr) 02460 ast_cdr_update(c); 02461 error = 1; 02462 break; 02463 } 02464 } 02465 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02466 c->_softhangup = 0; 02467 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c,c->context,"T",1,c->cid.cid_num)) { 02468 set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */ 02469 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */ 02470 c->whentohangup = 0; 02471 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT; 02472 } else if (c->_softhangup) { 02473 if (option_debug) 02474 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", 02475 c->exten, c->priority); 02476 error = 1; 02477 break; 02478 } 02479 c->priority++; 02480 } /* end while - from here on we can use 'break' to go out */ 02481 if (error) 02482 break; 02483 02484 /* XXX we get here on non-existing extension or a keypress or hangup ? */ 02485 02486 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { 02487 /* If there is no match at priority 1, it is not a valid extension anymore. 02488 * Try to continue at "i", 1 or exit if the latter does not exist. 02489 */ 02490 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02491 if (option_verbose > 2) 02492 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name); 02493 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten); 02494 set_ext_pri(c, "i", 1); 02495 } else { 02496 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n", 02497 c->name, c->exten, c->context); 02498 error = 1; /* we know what to do with it */ 02499 break; 02500 } 02501 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02502 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */ 02503 c->_softhangup = 0; 02504 } else { /* keypress received, get more digits for a full extension */ 02505 int waittime = 0; 02506 if (digit) 02507 waittime = c->pbx->dtimeout; 02508 else if (!autofallthrough) 02509 waittime = c->pbx->rtimeout; 02510 if (!waittime) { 02511 const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 02512 if (!status) 02513 status = "UNKNOWN"; 02514 if (option_verbose > 2) 02515 ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status); 02516 if (!strcasecmp(status, "CONGESTION")) 02517 res = pbx_builtin_congestion(c, "10"); 02518 else if (!strcasecmp(status, "CHANUNAVAIL")) 02519 res = pbx_builtin_congestion(c, "10"); 02520 else if (!strcasecmp(status, "BUSY")) 02521 res = pbx_builtin_busy(c, "10"); 02522 error = 1; /* XXX disable message */ 02523 break; /* exit from the 'for' loop */ 02524 } 02525 02526 if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos)) 02527 break; 02528 if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */ 02529 set_ext_pri(c, dst_exten, 1); 02530 else { 02531 /* No such extension */ 02532 if (!ast_strlen_zero(dst_exten)) { 02533 /* An invalid extension */ 02534 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02535 if (option_verbose > 2) 02536 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name); 02537 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten); 02538 set_ext_pri(c, "i", 1); 02539 } else { 02540 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context); 02541 found = 1; /* XXX disable message */ 02542 break; 02543 } 02544 } else { 02545 /* A simple timeout */ 02546 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) { 02547 if (option_verbose > 2) 02548 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name); 02549 set_ext_pri(c, "t", 1); 02550 } else { 02551 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context); 02552 found = 1; /* XXX disable message */ 02553 break; 02554 } 02555 } 02556 } 02557 if (c->cdr) { 02558 if (option_verbose > 2) 02559 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name); 02560 ast_cdr_update(c); 02561 } 02562 } 02563 } 02564 if (!found && !error) 02565 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); 02566 if (res != AST_PBX_KEEPALIVE) 02567 ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING); 02568 if ((res != AST_PBX_KEEPALIVE) && !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) { 02569 set_ext_pri(c, "h", 1); 02570 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02571 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02572 /* Something bad happened, or a hangup has been requested. */ 02573 if (option_debug) 02574 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02575 if (option_verbose > 1) 02576 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02577 break; 02578 } 02579 c->priority++; 02580 } 02581 } 02582 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP); 02583 ast_clear_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */ 02584 pbx_destroy(c->pbx); 02585 c->pbx = NULL; 02586 if (res != AST_PBX_KEEPALIVE) 02587 ast_hangup(c); 02588 return 0; 02589 }
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 4708 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().
04710 { 04711 struct ast_exten *ep; 04712 04713 for (ep = NULL; e ; ep = e, e = e->peer) { 04714 if (e->priority >= tmp->priority) 04715 break; 04716 } 04717 if (!e) { /* go at the end, and ep is surely set because the list is not empty */ 04718 ep->peer = tmp; 04719 return 0; /* success */ 04720 } 04721 if (e->priority == tmp->priority) { 04722 /* Can't have something exactly the same. Is this a 04723 replacement? If so, replace, otherwise, bonk. */ 04724 if (!replace) { 04725 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04726 if (tmp->datad) 04727 tmp->datad(tmp->data); 04728 free(tmp); 04729 return -1; 04730 } 04731 /* we are replacing e, so copy the link fields and then update 04732 * whoever pointed to e to point to us 04733 */ 04734 tmp->next = e->next; /* not meaningful if we are not first in the peer list */ 04735 tmp->peer = e->peer; /* always meaningful */ 04736 if (ep) /* We're in the peer list, just insert ourselves */ 04737 ep->peer = tmp; 04738 else if (el) /* We're the first extension. Take over e's functions */ 04739 el->next = tmp; 04740 else /* We're the very first extension. */ 04741 con->root = tmp; 04742 if (tmp->priority == PRIORITY_HINT) 04743 ast_change_hint(e,tmp); 04744 /* Destroy the old one */ 04745 if (e->datad) 04746 e->datad(e->data); 04747 free(e); 04748 } else { /* Slip ourselves in just before e */ 04749 tmp->peer = e; 04750 tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */ 04751 if (ep) /* Easy enough, we're just in the peer list */ 04752 ep->peer = tmp; 04753 else { /* we are the first in some peer list, so link in the ext list */ 04754 if (el) 04755 el->next = tmp; /* in the middle... */ 04756 else 04757 con->root = tmp; /* ... or at the head */ 04758 e->next = NULL; /* e is no more at the head, so e->next must be reset */ 04759 } 04760 /* And immediately return success. */ 04761 if (tmp->priority == PRIORITY_HINT) 04762 ast_add_hint(tmp); 04763 } 04764 return 0; 04765 }
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2695 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02696 { 02697 return countcalls; 02698 }
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 4577 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().
04580 { 04581 int ret = -1; 04582 struct ast_context *c = find_context_locked(context); 04583 04584 if (c) { 04585 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04586 application, data, datad, registrar); 04587 ast_unlock_contexts(); 04588 } 04589 return ret; 04590 }
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 4792 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().
04796 { 04797 /* 04798 * Sort extensions (or patterns) according to the rules indicated above. 04799 * These are implemented by the function ext_cmp()). 04800 * All priorities for the same ext/pattern/cid are kept in a list, 04801 * using the 'peer' field as a link field.. 04802 */ 04803 struct ast_exten *tmp, *e, *el = NULL; 04804 int res; 04805 int length; 04806 char *p; 04807 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04808 04809 /* if we are adding a hint, and there are global variables, and the hint 04810 contains variable references, then expand them 04811 */ 04812 ast_mutex_lock(&globalslock); 04813 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04814 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04815 application = expand_buf; 04816 } 04817 ast_mutex_unlock(&globalslock); 04818 04819 length = sizeof(struct ast_exten); 04820 length += strlen(extension) + 1; 04821 length += strlen(application) + 1; 04822 if (label) 04823 length += strlen(label) + 1; 04824 if (callerid) 04825 length += strlen(callerid) + 1; 04826 else 04827 length ++; /* just the '\0' */ 04828 04829 /* Be optimistic: Build the extension structure first */ 04830 if (!(tmp = ast_calloc(1, length))) 04831 return -1; 04832 04833 /* use p as dst in assignments, as the fields are const char * */ 04834 p = tmp->stuff; 04835 if (label) { 04836 tmp->label = p; 04837 strcpy(p, label); 04838 p += strlen(label) + 1; 04839 } 04840 tmp->exten = p; 04841 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04842 tmp->priority = priority; 04843 tmp->cidmatch = p; /* but use p for assignments below */ 04844 if (callerid) { 04845 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04846 tmp->matchcid = 1; 04847 } else { 04848 *p++ = '\0'; 04849 tmp->matchcid = 0; 04850 } 04851 tmp->app = p; 04852 strcpy(p, application); 04853 tmp->parent = con; 04854 tmp->data = data; 04855 tmp->datad = datad; 04856 tmp->registrar = registrar; 04857 04858 ast_mutex_lock(&con->lock); 04859 res = 0; /* some compilers will think it is uninitialized otherwise */ 04860 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04861 res = ext_cmp(e->exten, tmp->exten); 04862 if (res == 0) { /* extension match, now look at cidmatch */ 04863 if (!e->matchcid && !tmp->matchcid) 04864 res = 0; 04865 else if (tmp->matchcid && !e->matchcid) 04866 res = 1; 04867 else if (e->matchcid && !tmp->matchcid) 04868 res = -1; 04869 else 04870 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04871 } 04872 if (res >= 0) 04873 break; 04874 } 04875 if (e && res == 0) { /* exact match, insert in the pri chain */ 04876 res = add_pri(con, tmp, el, e, replace); 04877 ast_mutex_unlock(&con->lock); 04878 if (res < 0) { 04879 errno = EEXIST; /* XXX do we care ? */ 04880 return 0; /* XXX should we return -1 maybe ? */ 04881 } 04882 } else { 04883 /* 04884 * not an exact match, this is the first entry with this pattern, 04885 * so insert in the main list right before 'e' (if any) 04886 */ 04887 tmp->next = e; 04888 if (el) 04889 el->next = tmp; 04890 else 04891 con->root = tmp; 04892 ast_mutex_unlock(&con->lock); 04893 if (tmp->priority == PRIORITY_HINT) 04894 ast_add_hint(tmp); 04895 } 04896 if (option_debug) { 04897 if (tmp->matchcid) { 04898 if (option_debug) 04899 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04900 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04901 } else { 04902 if (option_debug) 04903 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04904 tmp->exten, tmp->priority, con->name); 04905 } 04906 } 04907 if (option_verbose > 2) { 04908 if (tmp->matchcid) { 04909 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04910 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04911 } else { 04912 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04913 tmp->exten, tmp->priority, con->name); 04914 } 04915 } 04916 return 0; 04917 }
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 2207 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().
02208 { 02209 struct ast_hint *hint; 02210 02211 if (!e) 02212 return -1; 02213 02214 AST_LIST_LOCK(&hints); 02215 02216 /* Search if hint exists, do nothing */ 02217 AST_LIST_TRAVERSE(&hints, hint, list) { 02218 if (hint->exten == e) { 02219 AST_LIST_UNLOCK(&hints); 02220 if (option_debug > 1) 02221 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02222 return -1; 02223 } 02224 } 02225 02226 if (option_debug > 1) 02227 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02228 02229 if (!(hint = ast_calloc(1, sizeof(*hint)))) { 02230 AST_LIST_UNLOCK(&hints); 02231 return -1; 02232 } 02233 /* Initialize and insert new item at the top */ 02234 hint->exten = e; 02235 hint->laststate = ast_extension_state2(e); 02236 AST_LIST_INSERT_HEAD(&hints, hint, list); 02237 02238 AST_LIST_UNLOCK(&hints); 02239 return 0; 02240 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4615 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().
04616 { 04617 int res = 0; 04618 04619 ast_channel_lock(chan); 04620 04621 if (chan->pbx) { /* This channel is currently in the PBX */ 04622 ast_explicit_goto(chan, context, exten, priority); 04623 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04624 } else { 04625 /* In order to do it when the channel doesn't really exist within 04626 the PBX, we have to make a new channel, masquerade, and start the PBX 04627 at the new location */ 04628 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04629 if (!tmpchan) { 04630 res = -1; 04631 } else { 04632 if (chan->cdr) { 04633 ast_cdr_discard(tmpchan->cdr); 04634 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04635 } 04636 /* Make formats okay */ 04637 tmpchan->readformat = chan->readformat; 04638 tmpchan->writeformat = chan->writeformat; 04639 /* Setup proper location */ 04640 ast_explicit_goto(tmpchan, 04641 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04642 04643 /* Masquerade into temp channel */ 04644 if (ast_channel_masquerade(tmpchan, chan)) { 04645 /* Failed to set up the masquerade. It's probably chan_local 04646 * in the middle of optimizing itself out. Sad. :( */ 04647 ast_hangup(tmpchan); 04648 tmpchan = NULL; 04649 res = -1; 04650 } else { 04651 /* Grab the locks and get going */ 04652 ast_channel_lock(tmpchan); 04653 ast_do_masquerade(tmpchan); 04654 ast_channel_unlock(tmpchan); 04655 /* Start the PBX going on our stolen channel */ 04656 if (ast_pbx_start(tmpchan)) { 04657 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04658 ast_hangup(tmpchan); 04659 res = -1; 04660 } 04661 } 04662 } 04663 } 04664 ast_channel_unlock(chan); 04665 return res; 04666 }
int ast_async_goto_by_name | ( | const char * | channame, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4668 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04669 { 04670 struct ast_channel *chan; 04671 int res = -1; 04672 04673 chan = ast_get_channel_by_name_locked(channame); 04674 if (chan) { 04675 res = ast_async_goto(chan, context, exten, priority); 04676 ast_channel_unlock(chan); 04677 } 04678 return res; 04679 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6469 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06470 { 06471 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06472 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info_in | |||
) |
Definition at line 4255 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().
04256 { 04257 char info_save[256]; 04258 char *info; 04259 04260 /* Check for empty just in case */ 04261 if (ast_strlen_zero(info_in)) 04262 return 0; 04263 /* make a copy just in case we were passed a static string */ 04264 ast_copy_string(info_save, info_in, sizeof(info_save)); 04265 info = info_save; 04266 /* Assume everything except time */ 04267 i->monthmask = 0xfff; /* 12 bits */ 04268 i->daymask = 0x7fffffffU; /* 31 bits */ 04269 i->dowmask = 0x7f; /* 7 bits */ 04270 /* on each call, use strsep() to move info to the next argument */ 04271 get_timerange(i, strsep(&info, "|")); 04272 if (info) 04273 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04274 if (info) 04275 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04276 if (info) 04277 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04278 return 1; 04279 }
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 2331 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().
02332 { 02333 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02334 }
ast_change_hint: Change hint for an extension
Definition at line 2243 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().
02244 { 02245 struct ast_hint *hint; 02246 int res = -1; 02247 02248 AST_LIST_LOCK(&hints); 02249 AST_LIST_TRAVERSE(&hints, hint, list) { 02250 if (hint->exten == oe) { 02251 hint->exten = ne; 02252 res = 0; 02253 break; 02254 } 02255 } 02256 AST_LIST_UNLOCK(&hints); 02257 02258 return res; 02259 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4281 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().
04282 { 04283 struct tm tm; 04284 time_t t = time(NULL); 04285 04286 ast_localtime(&t, &tm, NULL); 04287 04288 /* If it's not the right month, return */ 04289 if (!(i->monthmask & (1 << tm.tm_mon))) 04290 return 0; 04291 04292 /* If it's not that time of the month.... */ 04293 /* Warning, tm_mday has range 1..31! */ 04294 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04295 return 0; 04296 04297 /* If it's not the right day of the week */ 04298 if (!(i->dowmask & (1 << tm.tm_wday))) 04299 return 0; 04300 04301 /* Sanity check the hour just to be safe */ 04302 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04303 ast_log(LOG_WARNING, "Insane time...\n"); 04304 return 0; 04305 } 04306 04307 /* Now the tough part, we calculate if it fits 04308 in the right time based on min/hour */ 04309 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04310 return 0; 04311 04312 /* If we got this far, then we're good */ 04313 return 1; 04314 }
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 4508 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().
04509 { 04510 int ret = -1; 04511 struct ast_context *c = find_context_locked(context); 04512 04513 if (c) { 04514 ret = ast_context_add_ignorepat2(c, value, registrar); 04515 ast_unlock_contexts(); 04516 } 04517 return ret; 04518 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | value, | |||
const char * | registrar | |||
) |
Definition at line 4520 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().
04521 { 04522 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04523 int length; 04524 char *pattern; 04525 length = sizeof(struct ast_ignorepat); 04526 length += strlen(value) + 1; 04527 if (!(ignorepat = ast_calloc(1, length))) 04528 return -1; 04529 /* The cast to char * is because we need to write the initial value. 04530 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04531 * sees the cast as dereferencing a type-punned pointer and warns about 04532 * it. This is the workaround (we're telling gcc, yes, that's really 04533 * what we wanted to do). 04534 */ 04535 pattern = (char *) ignorepat->pattern; 04536 strcpy(pattern, value); 04537 ignorepat->next = NULL; 04538 ignorepat->registrar = registrar; 04539 ast_mutex_lock(&con->lock); 04540 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04541 ignorepatl = ignorepatc; 04542 if (!strcasecmp(ignorepatc->pattern, value)) { 04543 /* Already there */ 04544 ast_mutex_unlock(&con->lock); 04545 errno = EEXIST; 04546 return -1; 04547 } 04548 } 04549 if (ignorepatl) 04550 ignorepatl->next = ignorepat; 04551 else 04552 con->ignorepats = ignorepat; 04553 ast_mutex_unlock(&con->lock); 04554 return 0; 04555 04556 }
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 4061 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().
04062 { 04063 int ret = -1; 04064 struct ast_context *c = find_context_locked(context); 04065 04066 if (c) { 04067 ret = ast_context_add_include2(c, include, registrar); 04068 ast_unlock_contexts(); 04069 } 04070 return ret; 04071 }
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 4323 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().
04325 { 04326 struct ast_include *new_include; 04327 char *c; 04328 struct ast_include *i, *il = NULL; /* include, include_last */ 04329 int length; 04330 char *p; 04331 04332 length = sizeof(struct ast_include); 04333 length += 2 * (strlen(value) + 1); 04334 04335 /* allocate new include structure ... */ 04336 if (!(new_include = ast_calloc(1, length))) 04337 return -1; 04338 /* Fill in this structure. Use 'p' for assignments, as the fields 04339 * in the structure are 'const char *' 04340 */ 04341 p = new_include->stuff; 04342 new_include->name = p; 04343 strcpy(p, value); 04344 p += strlen(value) + 1; 04345 new_include->rname = p; 04346 strcpy(p, value); 04347 /* Strip off timing info, and process if it is there */ 04348 if ( (c = strchr(p, '|')) ) { 04349 *c++ = '\0'; 04350 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04351 } 04352 new_include->next = NULL; 04353 new_include->registrar = registrar; 04354 04355 ast_mutex_lock(&con->lock); 04356 04357 /* ... go to last include and check if context is already included too... */ 04358 for (i = con->includes; i; i = i->next) { 04359 if (!strcasecmp(i->name, new_include->name)) { 04360 free(new_include); 04361 ast_mutex_unlock(&con->lock); 04362 errno = EEXIST; 04363 return -1; 04364 } 04365 il = i; 04366 } 04367 04368 /* ... include new context into context list, unlock, return */ 04369 if (il) 04370 il->next = new_include; 04371 else 04372 con->includes = new_include; 04373 if (option_verbose > 2) 04374 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04375 ast_mutex_unlock(&con->lock); 04376 04377 return 0; 04378 }
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 4385 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04386 { 04387 int ret = -1; 04388 struct ast_context *c = find_context_locked(context); 04389 04390 if (c) { /* found, add switch to this context */ 04391 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04392 ast_unlock_contexts(); 04393 } 04394 return ret; 04395 }
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 4404 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().
04406 { 04407 struct ast_sw *new_sw; 04408 struct ast_sw *i; 04409 int length; 04410 char *p; 04411 04412 length = sizeof(struct ast_sw); 04413 length += strlen(value) + 1; 04414 if (data) 04415 length += strlen(data); 04416 length++; 04417 04418 /* allocate new sw structure ... */ 04419 if (!(new_sw = ast_calloc(1, length))) 04420 return -1; 04421 /* ... fill in this structure ... */ 04422 p = new_sw->stuff; 04423 new_sw->name = p; 04424 strcpy(new_sw->name, value); 04425 p += strlen(value) + 1; 04426 new_sw->data = p; 04427 if (data) { 04428 strcpy(new_sw->data, data); 04429 p += strlen(data) + 1; 04430 } else { 04431 strcpy(new_sw->data, ""); 04432 p++; 04433 } 04434 new_sw->eval = eval; 04435 new_sw->registrar = registrar; 04436 04437 /* ... try to lock this context ... */ 04438 ast_mutex_lock(&con->lock); 04439 04440 /* ... go to last sw and check if context is already swd too... */ 04441 AST_LIST_TRAVERSE(&con->alts, i, list) { 04442 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04443 free(new_sw); 04444 ast_mutex_unlock(&con->lock); 04445 errno = EEXIST; 04446 return -1; 04447 } 04448 } 04449 04450 /* ... sw new context into context list, unlock, return */ 04451 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04452 04453 if (option_verbose > 2) 04454 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04455 04456 ast_mutex_unlock(&con->lock); 04457 04458 return 0; 04459 }
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 3931 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03932 { 03933 return __ast_context_create(extcontexts, name, registrar, 0); 03934 }
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 5373 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().
05374 { 05375 ast_wrlock_contexts(); 05376 __ast_context_destroy(con,registrar); 05377 ast_unlock_contexts(); 05378 }
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 3936 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03937 { 03938 return __ast_context_create(extcontexts, name, registrar, 1); 03939 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2932 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().
02933 { 02934 struct ast_context *c = NULL; 02935 int ret = -1; 02936 02937 ast_rdlock_contexts(); 02938 02939 while ((c = ast_walk_contexts(c))) { 02940 if (!strcmp(ast_get_context_name(c), context)) { 02941 ret = 0; 02942 break; 02943 } 02944 } 02945 02946 ast_unlock_contexts(); 02947 02948 /* if we found context, lock macrolock */ 02949 if (ret == 0) 02950 ret = ast_mutex_lock(&c->macrolock); 02951 02952 return ret; 02953 }
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 2833 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02834 { 02835 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02836 }
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 2860 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02861 { 02862 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02863 }
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 2838 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().
02839 { 02840 int ret = -1; /* default error return */ 02841 struct ast_context *c = find_context_locked(context); 02842 02843 if (c) { /* ... remove extension ... */ 02844 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02845 ast_unlock_contexts(); 02846 } 02847 return ret; 02848 }
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 2865 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().
02866 { 02867 struct ast_exten *exten, *prev_exten = NULL; 02868 struct ast_exten *peer; 02869 struct ast_exten *previous_peer = NULL; 02870 struct ast_exten *next_peer = NULL; 02871 int found = 0; 02872 02873 ast_mutex_lock(&con->lock); 02874 02875 /* scan the extension list to find first matching extension-registrar */ 02876 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02877 if (!strcmp(exten->exten, extension) && 02878 (!registrar || !strcmp(exten->registrar, registrar))) 02879 break; 02880 } 02881 if (!exten) { 02882 /* we can't find right extension */ 02883 ast_mutex_unlock(&con->lock); 02884 return -1; 02885 } 02886 02887 /* scan the priority list to remove extension with exten->priority == priority */ 02888 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02889 peer && !strcmp(peer->exten, extension); 02890 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02891 if ((priority == 0 || peer->priority == priority) && 02892 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02893 (!registrar || !strcmp(peer->registrar, registrar) )) { 02894 found = 1; 02895 02896 /* we are first priority extension? */ 02897 if (!previous_peer) { 02898 /* 02899 * We are first in the priority chain, so must update the extension chain. 02900 * The next node is either the next priority or the next extension 02901 */ 02902 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02903 02904 if (!prev_exten) { /* change the root... */ 02905 con->root = next_node; 02906 } else { 02907 prev_exten->next = next_node; /* unlink */ 02908 } 02909 if (peer->peer) { /* update the new head of the pri list */ 02910 peer->peer->next = peer->next; 02911 } 02912 } else { /* easy, we are not first priority in extension */ 02913 previous_peer->peer = peer->peer; 02914 } 02915 02916 /* now, free whole priority extension */ 02917 destroy_exten(peer); 02918 } else { 02919 previous_peer = peer; 02920 } 02921 } 02922 ast_mutex_unlock(&con->lock); 02923 return found ? 0 : -1; 02924 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4465 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().
04466 { 04467 int ret = -1; 04468 struct ast_context *c = find_context_locked(context); 04469 04470 if (c) { 04471 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04472 ast_unlock_contexts(); 04473 } 04474 return ret; 04475 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4477 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().
04478 { 04479 struct ast_ignorepat *ip, *ipl = NULL; 04480 04481 ast_mutex_lock(&con->lock); 04482 04483 for (ip = con->ignorepats; ip; ip = ip->next) { 04484 if (!strcmp(ip->pattern, ignorepat) && 04485 (!registrar || (registrar == ip->registrar))) { 04486 if (ipl) { 04487 ipl->next = ip->next; 04488 free(ip); 04489 } else { 04490 con->ignorepats = ip->next; 04491 free(ip); 04492 } 04493 ast_mutex_unlock(&con->lock); 04494 return 0; 04495 } 04496 ipl = ip; 04497 } 04498 04499 ast_mutex_unlock(&con->lock); 04500 errno = EINVAL; 04501 return -1; 04502 }
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 2729 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().
02730 { 02731 int ret = -1; 02732 struct ast_context *c = find_context_locked(context); 02733 02734 if (c) { 02735 /* found, remove include from this context ... */ 02736 ret = ast_context_remove_include2(c, include, registrar); 02737 ast_unlock_contexts(); 02738 } 02739 return ret; 02740 }
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 2750 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().
02751 { 02752 struct ast_include *i, *pi = NULL; 02753 int ret = -1; 02754 02755 ast_mutex_lock(&con->lock); 02756 02757 /* find our include */ 02758 for (i = con->includes; i; pi = i, i = i->next) { 02759 if (!strcmp(i->name, include) && 02760 (!registrar || !strcmp(i->registrar, registrar))) { 02761 /* remove from list */ 02762 if (pi) 02763 pi->next = i->next; 02764 else 02765 con->includes = i->next; 02766 /* free include and return */ 02767 free(i); 02768 ret = 0; 02769 break; 02770 } 02771 } 02772 02773 ast_mutex_unlock(&con->lock); 02774 return ret; 02775 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2782 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02783 { 02784 int ret = -1; /* default error return */ 02785 struct ast_context *c = find_context_locked(context); 02786 02787 if (c) { 02788 /* remove switch from this context ... */ 02789 ret = ast_context_remove_switch2(c, sw, data, registrar); 02790 ast_unlock_contexts(); 02791 } 02792 return ret; 02793 }
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 2803 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().
02804 { 02805 struct ast_sw *i; 02806 int ret = -1; 02807 02808 ast_mutex_lock(&con->lock); 02809 02810 /* walk switches */ 02811 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02812 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02813 (!registrar || !strcmp(i->registrar, registrar))) { 02814 /* found, remove from list */ 02815 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02816 free(i); /* free switch and return */ 02817 ret = 0; 02818 break; 02819 } 02820 } 02821 AST_LIST_TRAVERSE_SAFE_END 02822 02823 ast_mutex_unlock(&con->lock); 02824 02825 return ret; 02826 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2960 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().
02961 { 02962 struct ast_context *c = NULL; 02963 int ret = -1; 02964 02965 ast_rdlock_contexts(); 02966 02967 while ((c = ast_walk_contexts(c))) { 02968 if (!strcmp(ast_get_context_name(c), context)) { 02969 ret = 0; 02970 break; 02971 } 02972 } 02973 02974 ast_unlock_contexts(); 02975 02976 /* if we found context, unlock macrolock */ 02977 if (ret == 0) 02978 ret = ast_mutex_unlock(&c->macrolock); 02979 02980 return ret; 02981 }
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 6426 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().
06427 { 06428 struct ast_include *inc = NULL; 06429 int res = 0; 06430 06431 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06432 if (ast_context_find(inc->rname)) 06433 continue; 06434 06435 res = -1; 06436 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06437 ast_get_context_name(con), inc->rname); 06438 break; 06439 } 06440 06441 return res; 06442 }
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 2316 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_call_full(), 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().
02317 { 02318 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02319 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4592 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().
04593 { 04594 if (!chan) 04595 return -1; 04596 04597 ast_channel_lock(chan); 04598 04599 if (!ast_strlen_zero(context)) 04600 ast_copy_string(chan->context, context, sizeof(chan->context)); 04601 if (!ast_strlen_zero(exten)) 04602 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04603 if (priority > -1) { 04604 chan->priority = priority; 04605 /* see flag description in channel.h for explanation */ 04606 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04607 chan->priority--; 04608 } 04609 04610 ast_channel_unlock(chan); 04611 04612 return 0; 04613 }
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 2095 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().
02097 { 02098 struct ast_hint *hint; 02099 struct ast_state_cb *cblist; 02100 struct ast_exten *e; 02101 02102 /* If there's no context and extension: add callback to statecbs list */ 02103 if (!context && !exten) { 02104 AST_LIST_LOCK(&hints); 02105 02106 for (cblist = statecbs; cblist; cblist = cblist->next) { 02107 if (cblist->callback == callback) { 02108 cblist->data = data; 02109 AST_LIST_UNLOCK(&hints); 02110 return 0; 02111 } 02112 } 02113 02114 /* Now insert the callback */ 02115 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02116 AST_LIST_UNLOCK(&hints); 02117 return -1; 02118 } 02119 cblist->id = 0; 02120 cblist->callback = callback; 02121 cblist->data = data; 02122 02123 cblist->next = statecbs; 02124 statecbs = cblist; 02125 02126 AST_LIST_UNLOCK(&hints); 02127 return 0; 02128 } 02129 02130 if (!context || !exten) 02131 return -1; 02132 02133 /* This callback type is for only one hint, so get the hint */ 02134 e = ast_hint_extension(NULL, context, exten); 02135 if (!e) { 02136 return -1; 02137 } 02138 02139 /* Find the hint in the list of hints */ 02140 AST_LIST_LOCK(&hints); 02141 02142 AST_LIST_TRAVERSE(&hints, hint, list) { 02143 if (hint->exten == e) 02144 break; 02145 } 02146 02147 if (!hint) { 02148 /* We have no hint, sorry */ 02149 AST_LIST_UNLOCK(&hints); 02150 return -1; 02151 } 02152 02153 /* Now insert the callback in the callback list */ 02154 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02155 AST_LIST_UNLOCK(&hints); 02156 return -1; 02157 } 02158 cblist->id = stateid++; /* Unique ID for this callback */ 02159 cblist->callback = callback; /* Pointer to callback routine */ 02160 cblist->data = data; /* Data for the callback */ 02161 02162 cblist->next = hint->callbacks; 02163 hint->callbacks = cblist; 02164 02165 AST_LIST_UNLOCK(&hints); 02166 return cblist->id; 02167 }
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 2170 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().
02171 { 02172 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02173 int ret = -1; 02174 02175 if (!id && !callback) 02176 return -1; 02177 02178 AST_LIST_LOCK(&hints); 02179 02180 if (!id) { /* id == 0 is a callback without extension */ 02181 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02182 if ((*p_cur)->callback == callback) 02183 break; 02184 } 02185 } else { /* callback with extension, find the callback based on ID */ 02186 struct ast_hint *hint; 02187 AST_LIST_TRAVERSE(&hints, hint, list) { 02188 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02189 if ((*p_cur)->id == id) 02190 break; 02191 } 02192 if (*p_cur) /* found in the inner loop */ 02193 break; 02194 } 02195 } 02196 if (p_cur && *p_cur) { 02197 struct ast_state_cb *cur = *p_cur; 02198 *p_cur = cur->next; 02199 free(cur); 02200 ret = 0; 02201 } 02202 AST_LIST_UNLOCK(&hints); 02203 return ret; 02204 }
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 2321 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().
02322 { 02323 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02324 }
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 2326 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02327 { 02328 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02329 }
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 6283 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().
06284 { 06285 return con ? con->name : NULL; 06286 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6321 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06322 { 06323 return c ? c->registrar : NULL; 06324 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6351 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().
06352 { 06353 return e ? e->app : NULL; 06354 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6356 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06357 { 06358 return e ? e->data : NULL; 06359 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6346 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().
06347 { 06348 return e ? e->cidmatch : NULL; 06349 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | exten | ) |
Definition at line 6298 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 6341 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().
06342 { 06343 return e ? e->matchcid : 0; 06344 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6293 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 6313 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 6326 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06327 { 06328 return e ? e->registrar : NULL; 06329 }
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 2299 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().
02300 { 02301 struct ast_exten *e = ast_hint_extension(c, context, exten); 02302 02303 if (e) { 02304 if (hint) 02305 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02306 if (name) { 02307 const char *tmp = ast_get_extension_app_data(e); 02308 if (tmp) 02309 ast_copy_string(name, tmp, namesize); 02310 } 02311 return -1; 02312 } 02313 return 0; 02314 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6308 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().
06309 { 06310 return ip ? ip->pattern : NULL; 06311 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6336 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06337 { 06338 return ip ? ip->registrar : NULL; 06339 }
const char* ast_get_include_name | ( | struct ast_include * | inc | ) |
Definition at line 6303 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().
06304 { 06305 return inc ? inc->name : NULL; 06306 }
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6331 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06332 { 06333 return i ? i->registrar : NULL; 06334 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6366 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06367 { 06368 return sw ? sw->data : NULL; 06369 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6361 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06362 { 06363 return sw ? sw->name : NULL; 06364 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6371 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06372 { 06373 return sw ? sw->registrar : NULL; 06374 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6464 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().
06465 { 06466 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06467 }
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_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_LIST_LOCK(&hints); 02056 02057 AST_LIST_TRAVERSE(&hints, hint, list) { 02058 struct ast_state_cb *cblist; 02059 char buf[AST_MAX_EXTENSION]; 02060 char *parse = buf; 02061 char *cur; 02062 int state; 02063 02064 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02065 while ( (cur = strsep(&parse, "&")) ) { 02066 if (!strcasecmp(cur, device)) 02067 break; 02068 } 02069 if (!cur) 02070 continue; 02071 02072 /* Get device state for this hint */ 02073 state = ast_extension_state2(hint->exten); 02074 02075 if ((state == -1) || (state == hint->laststate)) 02076 continue; 02077 02078 /* Device state changed since last check - notify the watchers */ 02079 02080 /* For general callbacks */ 02081 for (cblist = statecbs; cblist; cblist = cblist->next) 02082 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02083 02084 /* For extension callbacks */ 02085 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02086 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02087 02088 hint->laststate = state; /* record we saw the change */ 02089 } 02090 02091 AST_LIST_UNLOCK(&hints); 02092 }
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 4558 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().
04559 { 04560 struct ast_context *con = ast_context_find(context); 04561 if (con) { 04562 struct ast_ignorepat *pat; 04563 for (pat = con->ignorepats; pat; pat = pat->next) { 04564 if (ast_extension_match(pat->pattern, pattern)) 04565 return 1; 04566 } 04567 } 04568 04569 return 0; 04570 }
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 6270 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().
06271 { 06272 return ast_mutex_lock(&con->lock); 06273 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6247 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by find_matching_endwhile().
06248 { 06249 return ast_rwlock_wrlock(&conlock); 06250 }
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 2336 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().
02337 { 02338 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02339 }
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 3954 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().
03955 { 03956 struct ast_context *tmp, *lasttmp = NULL; 03957 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03958 struct store_hint *this; 03959 struct ast_hint *hint; 03960 struct ast_exten *exten; 03961 int length; 03962 struct ast_state_cb *thiscb, *prevcb; 03963 03964 /* it is very important that this function hold the hint list lock _and_ the conlock 03965 during its operation; not only do we need to ensure that the list of contexts 03966 and extensions does not change, but also that no hint callbacks (watchers) are 03967 added or removed during the merge/delete process 03968 03969 in addition, the locks _must_ be taken in this order, because there are already 03970 other code paths that use this order 03971 */ 03972 ast_wrlock_contexts(); 03973 AST_LIST_LOCK(&hints); 03974 03975 /* preserve all watchers for hints associated with this registrar */ 03976 AST_LIST_TRAVERSE(&hints, hint, list) { 03977 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03978 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03979 if (!(this = ast_calloc(1, length))) 03980 continue; 03981 this->callbacks = hint->callbacks; 03982 hint->callbacks = NULL; 03983 this->laststate = hint->laststate; 03984 this->context = this->data; 03985 strcpy(this->data, hint->exten->parent->name); 03986 this->exten = this->data + strlen(this->context) + 1; 03987 strcpy(this->exten, hint->exten->exten); 03988 AST_LIST_INSERT_HEAD(&store, this, list); 03989 } 03990 } 03991 03992 tmp = *extcontexts; 03993 if (registrar) { 03994 /* XXX remove previous contexts from same registrar */ 03995 if (option_debug) 03996 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 03997 __ast_context_destroy(NULL,registrar); 03998 while (tmp) { 03999 lasttmp = tmp; 04000 tmp = tmp->next; 04001 } 04002 } else { 04003 /* XXX remove contexts with the same name */ 04004 while (tmp) { 04005 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04006 __ast_context_destroy(tmp,tmp->registrar); 04007 lasttmp = tmp; 04008 tmp = tmp->next; 04009 } 04010 } 04011 if (lasttmp) { 04012 lasttmp->next = contexts; 04013 contexts = *extcontexts; 04014 *extcontexts = NULL; 04015 } else 04016 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04017 04018 /* restore the watchers for hints that can be found; notify those that 04019 cannot be restored 04020 */ 04021 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04022 struct pbx_find_info q = { .stacklen = 0 }; 04023 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04024 /* Find the hint in the list of hints */ 04025 AST_LIST_TRAVERSE(&hints, hint, list) { 04026 if (hint->exten == exten) 04027 break; 04028 } 04029 if (!exten || !hint) { 04030 /* this hint has been removed, notify the watchers */ 04031 prevcb = NULL; 04032 thiscb = this->callbacks; 04033 while (thiscb) { 04034 prevcb = thiscb; 04035 thiscb = thiscb->next; 04036 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04037 free(prevcb); 04038 } 04039 } else { 04040 thiscb = this->callbacks; 04041 while (thiscb->next) 04042 thiscb = thiscb->next; 04043 thiscb->next = hint->callbacks; 04044 hint->callbacks = this->callbacks; 04045 hint->laststate = this->laststate; 04046 } 04047 free(this); 04048 } 04049 04050 AST_LIST_UNLOCK(&hints); 04051 ast_unlock_contexts(); 04052 04053 return; 04054 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6474 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().
06475 { 06476 char *exten, *pri, *context; 06477 char *stringp; 06478 int ipri; 06479 int mode = 0; 06480 06481 if (ast_strlen_zero(goto_string)) { 06482 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06483 return -1; 06484 } 06485 stringp = ast_strdupa(goto_string); 06486 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06487 exten = strsep(&stringp, "|"); 06488 pri = strsep(&stringp, "|"); 06489 if (!exten) { /* Only a priority in this one */ 06490 pri = context; 06491 exten = NULL; 06492 context = NULL; 06493 } else if (!pri) { /* Only an extension and priority in this one */ 06494 pri = exten; 06495 exten = context; 06496 context = NULL; 06497 } 06498 if (*pri == '+') { 06499 mode = 1; 06500 pri++; 06501 } else if (*pri == '-') { 06502 mode = -1; 06503 pri++; 06504 } 06505 if (sscanf(pri, "%d", &ipri) != 1) { 06506 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06507 pri, chan->cid.cid_num)) < 1) { 06508 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06509 return -1; 06510 } else 06511 mode = 0; 06512 } 06513 /* At this point we have a priority and maybe an extension and a context */ 06514 06515 if (mode) 06516 ipri = chan->priority + (ipri * mode); 06517 06518 ast_explicit_goto(chan, context, exten, ipri); 06519 return 0; 06520 06521 }
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 5185 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().
05186 { 05187 struct ast_channel *chan; 05188 struct app_tmp *tmp; 05189 int res = -1, cdr_res = -1; 05190 struct outgoing_helper oh; 05191 pthread_attr_t attr; 05192 05193 memset(&oh, 0, sizeof(oh)); 05194 oh.vars = vars; 05195 oh.account = account; 05196 05197 if (locked_channel) 05198 *locked_channel = NULL; 05199 if (ast_strlen_zero(app)) { 05200 res = -1; 05201 goto outgoing_app_cleanup; 05202 } 05203 if (sync) { 05204 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05205 if (chan) { 05206 ast_set_variables(chan, vars); 05207 if (account) 05208 ast_cdr_setaccount(chan, account); 05209 if (chan->_state == AST_STATE_UP) { 05210 res = 0; 05211 if (option_verbose > 3) 05212 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05213 tmp = ast_calloc(1, sizeof(*tmp)); 05214 if (!tmp) 05215 res = -1; 05216 else { 05217 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05218 if (appdata) 05219 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05220 tmp->chan = chan; 05221 if (sync > 1) { 05222 if (locked_channel) 05223 ast_channel_unlock(chan); 05224 ast_pbx_run_app(tmp); 05225 } else { 05226 pthread_attr_init(&attr); 05227 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05228 if (locked_channel) 05229 ast_channel_lock(chan); 05230 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05231 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05232 free(tmp); 05233 if (locked_channel) 05234 ast_channel_unlock(chan); 05235 ast_hangup(chan); 05236 res = -1; 05237 } else { 05238 if (locked_channel) 05239 *locked_channel = chan; 05240 } 05241 pthread_attr_destroy(&attr); 05242 } 05243 } 05244 } else { 05245 if (option_verbose > 3) 05246 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05247 if (chan->cdr) { /* update the cdr */ 05248 /* here we update the status of the call, which sould be busy. 05249 * if that fails then we set the status to failed */ 05250 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05251 ast_cdr_failed(chan->cdr); 05252 } 05253 ast_hangup(chan); 05254 } 05255 } 05256 05257 if (res < 0) { /* the call failed for some reason */ 05258 if (*reason == 0) { /* if the call failed (not busy or no answer) 05259 * update the cdr with the failed message */ 05260 cdr_res = ast_pbx_outgoing_cdr_failed(); 05261 if (cdr_res != 0) { 05262 res = cdr_res; 05263 goto outgoing_app_cleanup; 05264 } 05265 } 05266 } 05267 05268 } else { 05269 struct async_stat *as; 05270 if (!(as = ast_calloc(1, sizeof(*as)))) { 05271 res = -1; 05272 goto outgoing_app_cleanup; 05273 } 05274 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05275 if (!chan) { 05276 free(as); 05277 res = -1; 05278 goto outgoing_app_cleanup; 05279 } 05280 as->chan = chan; 05281 ast_copy_string(as->app, app, sizeof(as->app)); 05282 if (appdata) 05283 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05284 as->timeout = timeout; 05285 ast_set_variables(chan, vars); 05286 if (account) 05287 ast_cdr_setaccount(chan, account); 05288 /* Start a new thread, and get something handling this channel. */ 05289 pthread_attr_init(&attr); 05290 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05291 if (locked_channel) 05292 ast_channel_lock(chan); 05293 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05294 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05295 free(as); 05296 if (locked_channel) 05297 ast_channel_unlock(chan); 05298 ast_hangup(chan); 05299 res = -1; 05300 pthread_attr_destroy(&attr); 05301 goto outgoing_app_cleanup; 05302 } else { 05303 if (locked_channel) 05304 *locked_channel = chan; 05305 } 05306 pthread_attr_destroy(&attr); 05307 res = 0; 05308 } 05309 outgoing_app_cleanup: 05310 ast_variables_destroy(vars); 05311 return res; 05312 }
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 4993 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().
04994 { 04995 /* allocate a channel */ 04996 struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", ""); 04997 04998 if (!chan) 04999 return -1; /* failure */ 05000 05001 if (!chan->cdr) { 05002 /* allocation of the cdr failed */ 05003 ast_channel_free(chan); /* free the channel */ 05004 return -1; /* return failure */ 05005 } 05006 05007 /* allocation of the cdr was successful */ 05008 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05009 ast_cdr_start(chan->cdr); /* record the start and stop time */ 05010 ast_cdr_end(chan->cdr); 05011 ast_cdr_failed(chan->cdr); /* set the status to failed */ 05012 ast_cdr_detach(chan->cdr); /* post and free the record */ 05013 chan->cdr = NULL; 05014 ast_channel_free(chan); /* free the channel */ 05015 05016 return 0; /* success */ 05017 }
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 5019 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().
05020 { 05021 struct ast_channel *chan; 05022 struct async_stat *as; 05023 int res = -1, cdr_res = -1; 05024 struct outgoing_helper oh; 05025 pthread_attr_t attr; 05026 05027 if (sync) { 05028 LOAD_OH(oh); 05029 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05030 if (channel) { 05031 *channel = chan; 05032 if (chan) 05033 ast_channel_lock(chan); 05034 } 05035 if (chan) { 05036 if (chan->_state == AST_STATE_UP) { 05037 res = 0; 05038 if (option_verbose > 3) 05039 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05040 05041 if (sync > 1) { 05042 if (channel) 05043 ast_channel_unlock(chan); 05044 if (ast_pbx_run(chan)) { 05045 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05046 if (channel) 05047 *channel = NULL; 05048 ast_hangup(chan); 05049 chan = NULL; 05050 res = -1; 05051 } 05052 } else { 05053 if (ast_pbx_start(chan)) { 05054 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05055 if (channel) { 05056 *channel = NULL; 05057 ast_channel_unlock(chan); 05058 } 05059 ast_hangup(chan); 05060 res = -1; 05061 } 05062 chan = NULL; 05063 } 05064 } else { 05065 if (option_verbose > 3) 05066 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05067 05068 if (chan->cdr) { /* update the cdr */ 05069 /* here we update the status of the call, which sould be busy. 05070 * if that fails then we set the status to failed */ 05071 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05072 ast_cdr_failed(chan->cdr); 05073 } 05074 05075 if (channel) { 05076 *channel = NULL; 05077 ast_channel_unlock(chan); 05078 } 05079 ast_hangup(chan); 05080 chan = NULL; 05081 } 05082 } 05083 05084 if (res < 0) { /* the call failed for some reason */ 05085 if (*reason == 0) { /* if the call failed (not busy or no answer) 05086 * update the cdr with the failed message */ 05087 cdr_res = ast_pbx_outgoing_cdr_failed(); 05088 if (cdr_res != 0) { 05089 res = cdr_res; 05090 goto outgoing_exten_cleanup; 05091 } 05092 } 05093 05094 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05095 /* check if "failed" exists */ 05096 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05097 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05098 if (chan) { 05099 char failed_reason[4] = ""; 05100 if (!ast_strlen_zero(context)) 05101 ast_copy_string(chan->context, context, sizeof(chan->context)); 05102 set_ext_pri(chan, "failed", 1); 05103 ast_set_variables(chan, vars); 05104 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05105 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05106 if (account) 05107 ast_cdr_setaccount(chan, account); 05108 if (ast_pbx_run(chan)) { 05109 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05110 ast_hangup(chan); 05111 } 05112 chan = NULL; 05113 } 05114 } 05115 } 05116 } else { 05117 if (!(as = ast_calloc(1, sizeof(*as)))) { 05118 res = -1; 05119 goto outgoing_exten_cleanup; 05120 } 05121 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05122 if (channel) { 05123 *channel = chan; 05124 if (chan) 05125 ast_channel_lock(chan); 05126 } 05127 if (!chan) { 05128 free(as); 05129 res = -1; 05130 goto outgoing_exten_cleanup; 05131 } 05132 as->chan = chan; 05133 ast_copy_string(as->context, context, sizeof(as->context)); 05134 set_ext_pri(as->chan, exten, priority); 05135 as->timeout = timeout; 05136 ast_set_variables(chan, vars); 05137 if (account) 05138 ast_cdr_setaccount(chan, account); 05139 pthread_attr_init(&attr); 05140 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05141 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05142 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05143 free(as); 05144 if (channel) { 05145 *channel = NULL; 05146 ast_channel_unlock(chan); 05147 } 05148 ast_hangup(chan); 05149 res = -1; 05150 pthread_attr_destroy(&attr); 05151 goto outgoing_exten_cleanup; 05152 } 05153 pthread_attr_destroy(&attr); 05154 res = 0; 05155 } 05156 outgoing_exten_cleanup: 05157 ast_variables_destroy(vars); 05158 return res; 05159 }
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 2682 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().
02683 { 02684 enum ast_pbx_result res = AST_PBX_SUCCESS; 02685 02686 if (increase_call_count(c)) 02687 return AST_PBX_CALL_LIMIT; 02688 02689 res = __ast_pbx_run(c); 02690 decrease_call_count(); 02691 02692 return res; 02693 }
static void* ast_pbx_run_app | ( | void * | data | ) | [static] |
run the application and free the descriptor once done
Definition at line 5169 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().
05170 { 05171 struct app_tmp *tmp = data; 05172 struct ast_app *app; 05173 app = pbx_findapp(tmp->app); 05174 if (app) { 05175 if (option_verbose > 3) 05176 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05177 pbx_exec(tmp->chan, app, tmp->data); 05178 } else 05179 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05180 ast_hangup(tmp->chan); 05181 free(tmp); 05182 return NULL; 05183 }
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 2655 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().
02656 { 02657 pthread_t t; 02658 pthread_attr_t attr; 02659 02660 if (!c) { 02661 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02662 return AST_PBX_FAILED; 02663 } 02664 02665 if (increase_call_count(c)) 02666 return AST_PBX_CALL_LIMIT; 02667 02668 /* Start a new thread, and get something handling this channel. */ 02669 pthread_attr_init(&attr); 02670 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02671 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02672 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02673 pthread_attr_destroy(&attr); 02674 decrease_call_count(); 02675 return AST_PBX_FAILED; 02676 } 02677 pthread_attr_destroy(&attr); 02678 02679 return AST_PBX_SUCCESS; 02680 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6252 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(), 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().
06253 { 06254 return ast_rwlock_rdlock(&conlock); 06255 }
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 2984 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().
02985 { 02986 struct ast_app *tmp, *cur = NULL; 02987 char tmps[80]; 02988 int length; 02989 02990 AST_LIST_LOCK(&apps); 02991 AST_LIST_TRAVERSE(&apps, tmp, list) { 02992 if (!strcasecmp(app, tmp->name)) { 02993 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02994 AST_LIST_UNLOCK(&apps); 02995 return -1; 02996 } 02997 } 02998 02999 length = sizeof(*tmp) + strlen(app) + 1; 03000 03001 if (!(tmp = ast_calloc(1, length))) { 03002 AST_LIST_UNLOCK(&apps); 03003 return -1; 03004 } 03005 03006 strcpy(tmp->name, app); 03007 tmp->execute = execute; 03008 tmp->synopsis = synopsis; 03009 tmp->description = description; 03010 03011 /* Store in alphabetical order */ 03012 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 03013 if (strcasecmp(tmp->name, cur->name) < 0) { 03014 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03015 break; 03016 } 03017 } 03018 AST_LIST_TRAVERSE_SAFE_END 03019 if (!cur) 03020 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03021 03022 if (option_verbose > 1) 03023 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03024 03025 AST_LIST_UNLOCK(&apps); 03026 03027 return 0; 03028 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3034 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().
03035 { 03036 struct ast_switch *tmp; 03037 03038 AST_LIST_LOCK(&switches); 03039 AST_LIST_TRAVERSE(&switches, tmp, list) { 03040 if (!strcasecmp(tmp->name, sw->name)) { 03041 AST_LIST_UNLOCK(&switches); 03042 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03043 return -1; 03044 } 03045 } 03046 AST_LIST_INSERT_TAIL(&switches, sw, list); 03047 AST_LIST_UNLOCK(&switches); 03048 03049 return 0; 03050 }
static int ast_remove_hint | ( | struct ast_exten * | e | ) | [static] |
ast_remove_hint: Remove hint from extension
Definition at line 2262 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().
02263 { 02264 /* Cleanup the Notifys if hint is removed */ 02265 struct ast_hint *hint; 02266 struct ast_state_cb *cblist, *cbprev; 02267 int res = -1; 02268 02269 if (!e) 02270 return -1; 02271 02272 AST_LIST_LOCK(&hints); 02273 AST_LIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) { 02274 if (hint->exten == e) { 02275 cbprev = NULL; 02276 cblist = hint->callbacks; 02277 while (cblist) { 02278 /* Notify with -1 and remove all callbacks */ 02279 cbprev = cblist; 02280 cblist = cblist->next; 02281 cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data); 02282 free(cbprev); 02283 } 02284 hint->callbacks = NULL; 02285 AST_LIST_REMOVE_CURRENT(&hints, list); 02286 free(hint); 02287 res = 0; 02288 break; 02289 } 02290 } 02291 AST_LIST_TRAVERSE_SAFE_END 02292 AST_LIST_UNLOCK(&hints); 02293 02294 return res; 02295 }
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 2341 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), and loopback_exec().
02342 { 02343 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02344 }
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 6275 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().
06276 { 06277 return ast_mutex_unlock(&con->lock); 06278 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6262 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_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().
06263 { 06264 return ast_rwlock_unlock(&conlock); 06265 }
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 3865 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().
03866 { 03867 struct ast_app *tmp; 03868 03869 AST_LIST_LOCK(&apps); 03870 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03871 if (!strcasecmp(app, tmp->name)) { 03872 AST_LIST_REMOVE_CURRENT(&apps, list); 03873 if (option_verbose > 1) 03874 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03875 free(tmp); 03876 break; 03877 } 03878 } 03879 AST_LIST_TRAVERSE_SAFE_END 03880 AST_LIST_UNLOCK(&apps); 03881 03882 return tmp ? 0 : -1; 03883 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3052 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().
03053 { 03054 AST_LIST_LOCK(&switches); 03055 AST_LIST_REMOVE(&switches, sw, list); 03056 AST_LIST_UNLOCK(&switches); 03057 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | exten | |||
) |
Definition at line 6384 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().
06386 { 06387 if (!exten) 06388 return con ? con->root : NULL; 06389 else 06390 return exten->next; 06391 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6417 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().
06419 { 06420 if (!ip) 06421 return con ? con->ignorepats : NULL; 06422 else 06423 return ip->next; 06424 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6408 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().
06410 { 06411 if (!inc) 06412 return con ? con->includes : NULL; 06413 else 06414 return inc->next; 06415 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6393 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().
06395 { 06396 if (!sw) 06397 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06398 else 06399 return AST_LIST_NEXT(sw, list); 06400 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6379 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 6402 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 6257 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().
06258 { 06259 return ast_rwlock_wrlock(&conlock); 06260 }
static void* async_wait | ( | void * | data | ) | [static] |
Definition at line 4930 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().
04931 { 04932 struct async_stat *as = data; 04933 struct ast_channel *chan = as->chan; 04934 int timeout = as->timeout; 04935 int res; 04936 struct ast_frame *f; 04937 struct ast_app *app; 04938 04939 while (timeout && (chan->_state != AST_STATE_UP)) { 04940 res = ast_waitfor(chan, timeout); 04941 if (res < 1) 04942 break; 04943 if (timeout > -1) 04944 timeout = res; 04945 f = ast_read(chan); 04946 if (!f) 04947 break; 04948 if (f->frametype == AST_FRAME_CONTROL) { 04949 if ((f->subclass == AST_CONTROL_BUSY) || 04950 (f->subclass == AST_CONTROL_CONGESTION) ) { 04951 ast_frfree(f); 04952 break; 04953 } 04954 } 04955 ast_frfree(f); 04956 } 04957 if (chan->_state == AST_STATE_UP) { 04958 if (!ast_strlen_zero(as->app)) { 04959 app = pbx_findapp(as->app); 04960 if (app) { 04961 if (option_verbose > 2) 04962 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 04963 pbx_exec(chan, app, as->appdata); 04964 } else 04965 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 04966 } else { 04967 if (!ast_strlen_zero(as->context)) 04968 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 04969 if (!ast_strlen_zero(as->exten)) 04970 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 04971 if (as->priority > 0) 04972 chan->priority = as->priority; 04973 /* Run the PBX */ 04974 if (ast_pbx_run(chan)) { 04975 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 04976 } else { 04977 /* PBX will have taken care of this */ 04978 chan = NULL; 04979 } 04980 } 04981 } 04982 free(as); 04983 if (chan) 04984 ast_hangup(chan); 04985 return NULL; 04986 }
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 2359 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.
02360 { 02361 int digit; 02362 02363 buf[pos] = '\0'; /* make sure it is properly terminated */ 02364 while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) { 02365 /* As long as we're willing to wait, and as long as it's not defined, 02366 keep reading digits until we can't possibly get a right answer anymore. */ 02367 digit = ast_waitfordigit(c, waittime * 1000); 02368 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02369 c->_softhangup = 0; 02370 } else { 02371 if (!digit) /* No entry */ 02372 break; 02373 if (digit < 0) /* Error, maybe a hangup */ 02374 return -1; 02375 if (pos < buflen - 1) { /* XXX maybe error otherwise ? */ 02376 buf[pos++] = digit; 02377 buf[pos] = '\0'; 02378 } 02379 waittime = c->pbx->dtimeout; 02380 } 02381 } 02382 return 0; 02383 }
static char* complete_show_application | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3110 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::list, ast_app::name, and strdup.
03111 { 03112 struct ast_app *a; 03113 char *ret = NULL; 03114 int which = 0; 03115 int wordlen = strlen(word); 03116 03117 /* return the n-th [partial] matching entry */ 03118 AST_LIST_LOCK(&apps); 03119 AST_LIST_TRAVERSE(&apps, a, list) { 03120 if (!strncasecmp(word, a->name, wordlen) && ++which > state) { 03121 ret = strdup(a->name); 03122 break; 03123 } 03124 } 03125 AST_LIST_UNLOCK(&apps); 03126 03127 return ret; 03128 }
static char* complete_show_applications | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3471 of file pbx.c.
References ast_cli_complete().
03472 { 03473 static char* choices[] = { "like", "describing", NULL }; 03474 03475 return (pos != 3) ? NULL : ast_cli_complete(word, choices, state); 03476 }
static char* complete_show_applications_deprecated | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3464 of file pbx.c.
References ast_cli_complete().
03465 { 03466 static char* choices[] = { "like", "describing", NULL }; 03467 03468 return (pos != 2) ? NULL : ast_cli_complete(word, choices, state); 03469 }
static char* complete_show_dialplan_context | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3481 of file pbx.c.
References ast_get_context_name(), ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), and ast_walk_contexts().
03483 { 03484 struct ast_context *c = NULL; 03485 char *ret = NULL; 03486 int which = 0; 03487 int wordlen; 03488 03489 /* we are do completion of [exten@]context on second position only */ 03490 if (pos != 2) 03491 return NULL; 03492 03493 ast_rdlock_contexts(); 03494 03495 wordlen = strlen(word); 03496 03497 /* walk through all contexts and return the n-th match */ 03498 while ( (c = ast_walk_contexts(c)) ) { 03499 if (!strncasecmp(word, ast_get_context_name(c), wordlen) && ++which > state) { 03500 ret = ast_strdup(ast_get_context_name(c)); 03501 break; 03502 } 03503 } 03504 03505 ast_unlock_contexts(); 03506 03507 return ret; 03508 }
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 2617 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().
02618 { 02619 ast_mutex_lock(&maxcalllock); 02620 if (countcalls > 0) 02621 countcalls--; 02622 ast_mutex_unlock(&maxcalllock); 02623 }
static void destroy_exten | ( | struct ast_exten * | e | ) | [static] |
Definition at line 2625 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().
02626 { 02627 if (e->priority == PRIORITY_HINT) 02628 ast_remove_hint(e); 02629 02630 if (e->datad) 02631 e->datad(e->data); 02632 free(e); 02633 }
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 4682 of file pbx.c.
Referenced by ast_add_extension2().
04683 { 04684 int count=0; 04685 04686 while (*src && (count < len - 1)) { 04687 switch(*src) { 04688 case ' ': 04689 /* otherwise exten => [a-b],1,... doesn't work */ 04690 /* case '-': */ 04691 /* Ignore */ 04692 break; 04693 default: 04694 *dst = *src; 04695 dst++; 04696 } 04697 src++; 04698 count++; 04699 } 04700 *dst = '\0'; 04701 04702 return count; 04703 }
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 2710 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().
02711 { 02712 struct ast_context *c = NULL; 02713 02714 ast_rdlock_contexts(); 02715 while ( (c = ast_walk_contexts(c)) ) { 02716 if (!strcmp(ast_get_context_name(c), context)) 02717 return c; 02718 } 02719 ast_unlock_contexts(); 02720 02721 return NULL; 02722 }
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 4095 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, lookup_name(), and s.
Referenced by ast_build_timing().
04096 { 04097 int s, e; /* start and ending position */ 04098 unsigned int mask = 0; 04099 04100 /* Check for whole range */ 04101 if (ast_strlen_zero(src) || !strcmp(src, "*")) { 04102 s = 0; 04103 e = max - 1; 04104 } else { 04105 /* Get start and ending position */ 04106 char *c = strchr(src, '-'); 04107 if (c) 04108 *c++ = '\0'; 04109 /* Find the start */ 04110 s = lookup_name(src, names, max); 04111 if (!s) { 04112 ast_log(LOG_WARNING, "Invalid %s '%s', assuming none\n", msg, src); 04113 return 0; 04114 } 04115 s--; 04116 if (c) { /* find end of range */ 04117 e = lookup_name(c, names, max); 04118 if (!e) { 04119 ast_log(LOG_WARNING, "Invalid end %s '%s', assuming none\n", msg, c); 04120 return 0; 04121 } 04122 e--; 04123 } else 04124 e = s; 04125 } 04126 /* Fill the mask. Remember that ranges are cyclic */ 04127 mask = 1 << e; /* initialize with last element */ 04128 while (s != e) { 04129 if (s >= max) { 04130 s = 0; 04131 mask |= (1 << s); 04132 } else { 04133 mask |= (1 << s); 04134 s++; 04135 } 04136 } 04137 return mask; 04138 }
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 4141 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask.
Referenced by ast_build_timing().
04142 { 04143 char *e; 04144 int x; 04145 int s1, s2; 04146 int e1, e2; 04147 /* int cth, ctm; */ 04148 04149 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 04150 memset(i->minmask, 0, sizeof(i->minmask)); 04151 04152 /* 2-minutes per bit, since the mask has only 32 bits :( */ 04153 /* Star is all times */ 04154 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 04155 for (x=0; x<24; x++) 04156 i->minmask[x] = 0x3fffffff; /* 30 bits */ 04157 return; 04158 } 04159 /* Otherwise expect a range */ 04160 e = strchr(times, '-'); 04161 if (!e) { 04162 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n"); 04163 return; 04164 } 04165 *e++ = '\0'; 04166 /* XXX why skip non digits ? */ 04167 while (*e && !isdigit(*e)) 04168 e++; 04169 if (!*e) { 04170 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n"); 04171 return; 04172 } 04173 if (sscanf(times, "%d:%d", &s1, &s2) != 2) { 04174 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times); 04175 return; 04176 } 04177 if (sscanf(e, "%d:%d", &e1, &e2) != 2) { 04178 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e); 04179 return; 04180 } 04181 /* XXX this needs to be optimized */ 04182 #if 1 04183 s1 = s1 * 30 + s2/2; 04184 if ((s1 < 0) || (s1 >= 24*30)) { 04185 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times); 04186 return; 04187 } 04188 e1 = e1 * 30 + e2/2; 04189 if ((e1 < 0) || (e1 >= 24*30)) { 04190 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e); 04191 return; 04192 } 04193 /* Go through the time and enable each appropriate bit */ 04194 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) { 04195 i->minmask[x/30] |= (1 << (x % 30)); 04196 } 04197 /* Do the last one */ 04198 i->minmask[x/30] |= (1 << (x % 30)); 04199 #else 04200 for (cth=0; cth<24; cth++) { 04201 /* Initialize masks to blank */ 04202 i->minmask[cth] = 0; 04203 for (ctm=0; ctm<30; ctm++) { 04204 if ( 04205 /* First hour with more than one hour */ 04206 (((cth == s1) && (ctm >= s2)) && 04207 ((cth < e1))) 04208 /* Only one hour */ 04209 || (((cth == s1) && (ctm >= s2)) && 04210 ((cth == e1) && (ctm <= e2))) 04211 /* In between first and last hours (more than 2 hours) */ 04212 || ((cth > s1) && 04213 (cth < e1)) 04214 /* Last hour with more than one hour */ 04215 || ((cth > s1) && 04216 ((cth == e1) && (ctm <= e2))) 04217 ) 04218 i->minmask[cth] |= (1 << (ctm / 2)); 04219 } 04220 } 04221 #endif 04222 /* All done */ 04223 return; 04224 }
static int handle_set_global | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3766 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03767 { 03768 if (argc != 5) 03769 return RESULT_SHOWUSAGE; 03770 03771 pbx_builtin_setvar_helper(NULL, argv[3], argv[4]); 03772 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[3], argv[4]); 03773 03774 return RESULT_SUCCESS; 03775 }
static int handle_set_global_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI support for setting global variables.
Definition at line 3754 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03755 { 03756 if (argc != 4) 03757 return RESULT_SHOWUSAGE; 03758 03759 pbx_builtin_setvar_helper(NULL, argv[2], argv[3]); 03760 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[2], argv[3]); 03761 03762 return RESULT_SUCCESS; 03763 }
static int handle_show_application | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3200 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().
03201 { 03202 struct ast_app *a; 03203 int app, no_registered_app = 1; 03204 03205 if (argc < 4) 03206 return RESULT_SHOWUSAGE; 03207 03208 /* ... go through all applications ... */ 03209 AST_LIST_LOCK(&apps); 03210 AST_LIST_TRAVERSE(&apps, a, list) { 03211 /* ... compare this application name with all arguments given 03212 * to 'show application' command ... */ 03213 for (app = 3; app < argc; app++) { 03214 if (!strcasecmp(a->name, argv[app])) { 03215 /* Maximum number of characters added by terminal coloring is 22 */ 03216 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03217 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03218 int synopsis_size, description_size; 03219 03220 no_registered_app = 0; 03221 03222 if (a->synopsis) 03223 synopsis_size = strlen(a->synopsis) + 23; 03224 else 03225 synopsis_size = strlen("Not available") + 23; 03226 synopsis = alloca(synopsis_size); 03227 03228 if (a->description) 03229 description_size = strlen(a->description) + 23; 03230 else 03231 description_size = strlen("Not available") + 23; 03232 description = alloca(description_size); 03233 03234 if (synopsis && description) { 03235 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03236 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03237 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03238 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03239 term_color(synopsis, 03240 a->synopsis ? a->synopsis : "Not available", 03241 COLOR_CYAN, 0, synopsis_size); 03242 term_color(description, 03243 a->description ? a->description : "Not available", 03244 COLOR_CYAN, 0, description_size); 03245 03246 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03247 } else { 03248 /* ... one of our applications, show info ...*/ 03249 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03250 "[Synopsis]\n %s\n\n" 03251 "[Description]\n%s\n", 03252 a->name, 03253 a->synopsis ? a->synopsis : "Not available", 03254 a->description ? a->description : "Not available"); 03255 } 03256 } 03257 } 03258 } 03259 AST_LIST_UNLOCK(&apps); 03260 03261 /* we found at least one app? no? */ 03262 if (no_registered_app) { 03263 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03264 return RESULT_FAILURE; 03265 } 03266 03267 return RESULT_SUCCESS; 03268 }
static int handle_show_application_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3130 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().
03131 { 03132 struct ast_app *a; 03133 int app, no_registered_app = 1; 03134 03135 if (argc < 3) 03136 return RESULT_SHOWUSAGE; 03137 03138 /* ... go through all applications ... */ 03139 AST_LIST_LOCK(&apps); 03140 AST_LIST_TRAVERSE(&apps, a, list) { 03141 /* ... compare this application name with all arguments given 03142 * to 'show application' command ... */ 03143 for (app = 2; app < argc; app++) { 03144 if (!strcasecmp(a->name, argv[app])) { 03145 /* Maximum number of characters added by terminal coloring is 22 */ 03146 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03147 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03148 int synopsis_size, description_size; 03149 03150 no_registered_app = 0; 03151 03152 if (a->synopsis) 03153 synopsis_size = strlen(a->synopsis) + 23; 03154 else 03155 synopsis_size = strlen("Not available") + 23; 03156 synopsis = alloca(synopsis_size); 03157 03158 if (a->description) 03159 description_size = strlen(a->description) + 23; 03160 else 03161 description_size = strlen("Not available") + 23; 03162 description = alloca(description_size); 03163 03164 if (synopsis && description) { 03165 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03166 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03167 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03168 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03169 term_color(synopsis, 03170 a->synopsis ? a->synopsis : "Not available", 03171 COLOR_CYAN, 0, synopsis_size); 03172 term_color(description, 03173 a->description ? a->description : "Not available", 03174 COLOR_CYAN, 0, description_size); 03175 03176 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03177 } else { 03178 /* ... one of our applications, show info ...*/ 03179 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03180 "[Synopsis]\n %s\n\n" 03181 "[Description]\n%s\n", 03182 a->name, 03183 a->synopsis ? a->synopsis : "Not available", 03184 a->description ? a->description : "Not available"); 03185 } 03186 } 03187 } 03188 } 03189 AST_LIST_UNLOCK(&apps); 03190 03191 /* we found at least one app? no? */ 03192 if (no_registered_app) { 03193 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03194 return RESULT_FAILURE; 03195 } 03196 03197 return RESULT_SUCCESS; 03198 }
static int handle_show_applications | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3395 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.
03396 { 03397 struct ast_app *a; 03398 int like = 0, describing = 0; 03399 int total_match = 0; /* Number of matches in like clause */ 03400 int total_apps = 0; /* Number of apps registered */ 03401 03402 AST_LIST_LOCK(&apps); 03403 03404 if (AST_LIST_EMPTY(&apps)) { 03405 ast_cli(fd, "There are no registered applications\n"); 03406 AST_LIST_UNLOCK(&apps); 03407 return -1; 03408 } 03409 03410 /* core list applications like <keyword> */ 03411 if ((argc == 5) && (!strcmp(argv[3], "like"))) { 03412 like = 1; 03413 } else if ((argc > 4) && (!strcmp(argv[3], "describing"))) { 03414 describing = 1; 03415 } 03416 03417 /* core list applications describing <keyword1> [<keyword2>] [...] */ 03418 if ((!like) && (!describing)) { 03419 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03420 } else { 03421 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03422 } 03423 03424 AST_LIST_TRAVERSE(&apps, a, list) { 03425 int printapp = 0; 03426 total_apps++; 03427 if (like) { 03428 if (strcasestr(a->name, argv[4])) { 03429 printapp = 1; 03430 total_match++; 03431 } 03432 } else if (describing) { 03433 if (a->description) { 03434 /* Match all words on command line */ 03435 int i; 03436 printapp = 1; 03437 for (i = 4; i < argc; i++) { 03438 if (!strcasestr(a->description, argv[i])) { 03439 printapp = 0; 03440 } else { 03441 total_match++; 03442 } 03443 } 03444 } 03445 } else { 03446 printapp = 1; 03447 } 03448 03449 if (printapp) { 03450 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03451 } 03452 } 03453 if ((!like) && (!describing)) { 03454 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03455 } else { 03456 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03457 } 03458 03459 AST_LIST_UNLOCK(&apps); 03460 03461 return RESULT_SUCCESS; 03462 }
static int handle_show_applications_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3327 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.
03328 { 03329 struct ast_app *a; 03330 int like = 0, describing = 0; 03331 int total_match = 0; /* Number of matches in like clause */ 03332 int total_apps = 0; /* Number of apps registered */ 03333 03334 AST_LIST_LOCK(&apps); 03335 03336 if (AST_LIST_EMPTY(&apps)) { 03337 ast_cli(fd, "There are no registered applications\n"); 03338 AST_LIST_UNLOCK(&apps); 03339 return -1; 03340 } 03341 03342 /* show applications like <keyword> */ 03343 if ((argc == 4) && (!strcmp(argv[2], "like"))) { 03344 like = 1; 03345 } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { 03346 describing = 1; 03347 } 03348 03349 /* show applications describing <keyword1> [<keyword2>] [...] */ 03350 if ((!like) && (!describing)) { 03351 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03352 } else { 03353 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03354 } 03355 03356 AST_LIST_TRAVERSE(&apps, a, list) { 03357 int printapp = 0; 03358 total_apps++; 03359 if (like) { 03360 if (strcasestr(a->name, argv[3])) { 03361 printapp = 1; 03362 total_match++; 03363 } 03364 } else if (describing) { 03365 if (a->description) { 03366 /* Match all words on command line */ 03367 int i; 03368 printapp = 1; 03369 for (i = 3; i < argc; i++) { 03370 if (!strcasestr(a->description, argv[i])) { 03371 printapp = 0; 03372 } else { 03373 total_match++; 03374 } 03375 } 03376 } 03377 } else { 03378 printapp = 1; 03379 } 03380 03381 if (printapp) { 03382 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03383 } 03384 } 03385 if ((!like) && (!describing)) { 03386 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03387 } else { 03388 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03389 } 03390 03391 AST_LIST_UNLOCK(&apps); 03392 03393 return RESULT_SUCCESS; 03394 }
static int handle_show_dialplan | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3681 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().
03682 { 03683 char *exten = NULL, *context = NULL; 03684 /* Variables used for different counters */ 03685 struct dialplan_counters counters; 03686 03687 const char *incstack[AST_PBX_MAX_STACK]; 03688 memset(&counters, 0, sizeof(counters)); 03689 03690 if (argc != 2 && argc != 3) 03691 return RESULT_SHOWUSAGE; 03692 03693 /* we obtain [exten@]context? if yes, split them ... */ 03694 if (argc == 3) { 03695 if (strchr(argv[2], '@')) { /* split into exten & context */ 03696 context = ast_strdupa(argv[2]); 03697 exten = strsep(&context, "@"); 03698 /* change empty strings to NULL */ 03699 if (ast_strlen_zero(exten)) 03700 exten = NULL; 03701 } else { /* no '@' char, only context given */ 03702 context = argv[2]; 03703 } 03704 if (ast_strlen_zero(context)) 03705 context = NULL; 03706 } 03707 /* else Show complete dial plan, context and exten are NULL */ 03708 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03709 03710 /* check for input failure and throw some error messages */ 03711 if (context && !counters.context_existence) { 03712 ast_cli(fd, "There is no existence of '%s' context\n", context); 03713 return RESULT_FAILURE; 03714 } 03715 03716 if (exten && !counters.extension_existence) { 03717 if (context) 03718 ast_cli(fd, "There is no existence of %s@%s extension\n", 03719 exten, context); 03720 else 03721 ast_cli(fd, 03722 "There is no existence of '%s' extension in all contexts\n", 03723 exten); 03724 return RESULT_FAILURE; 03725 } 03726 03727 ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", 03728 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions", 03729 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities", 03730 counters.total_context, counters.total_context == 1 ? "context" : "contexts"); 03731 03732 /* everything ok */ 03733 return RESULT_SUCCESS; 03734 }
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 3737 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.
03738 { 03739 int i = 0; 03740 struct ast_var_t *newvariable; 03741 03742 ast_mutex_lock(&globalslock); 03743 AST_LIST_TRAVERSE (&globals, newvariable, entries) { 03744 i++; 03745 ast_cli(fd, " %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable)); 03746 } 03747 ast_mutex_unlock(&globalslock); 03748 ast_cli(fd, "\n -- %d variables\n", i); 03749 03750 return RESULT_SUCCESS; 03751 }
static int handle_show_hints | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
handle_show_hints: CLI support for listing registred dial plan hints
Definition at line 3271 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.
03272 { 03273 struct ast_hint *hint; 03274 int num = 0; 03275 int watchers; 03276 struct ast_state_cb *watcher; 03277 03278 if (AST_LIST_EMPTY(&hints)) { 03279 ast_cli(fd, "There are no registered dialplan hints\n"); 03280 return RESULT_SUCCESS; 03281 } 03282 /* ... we have hints ... */ 03283 ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); 03284 AST_LIST_LOCK(&hints); 03285 AST_LIST_TRAVERSE(&hints, hint, list) { 03286 watchers = 0; 03287 for (watcher = hint->callbacks; watcher; watcher = watcher->next) 03288 watchers++; 03289 ast_cli(fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", 03290 ast_get_extension_name(hint->exten), 03291 ast_get_context_name(ast_get_extension_context(hint->exten)), 03292 ast_get_extension_app(hint->exten), 03293 ast_extension_state2str(hint->laststate), watchers); 03294 num++; 03295 } 03296 ast_cli(fd, "----------------\n"); 03297 ast_cli(fd, "- %d hints registered\n", num); 03298 AST_LIST_UNLOCK(&hints); 03299 return RESULT_SUCCESS; 03300 }
static int handle_show_switches | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
handle_show_switches: CLI support for listing registred dial plan switches
Definition at line 3303 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.
03304 { 03305 struct ast_switch *sw; 03306 03307 AST_LIST_LOCK(&switches); 03308 03309 if (AST_LIST_EMPTY(&switches)) { 03310 AST_LIST_UNLOCK(&switches); 03311 ast_cli(fd, "There are no registered alternative switches\n"); 03312 return RESULT_SUCCESS; 03313 } 03314 03315 ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); 03316 AST_LIST_TRAVERSE(&switches, sw, list) 03317 ast_cli(fd, "%s: %s\n", sw->name, sw->description); 03318 03319 AST_LIST_UNLOCK(&switches); 03320 03321 return RESULT_SUCCESS; 03322 }
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 2592 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().
02593 { 02594 int failed = 0; 02595 double curloadavg; 02596 ast_mutex_lock(&maxcalllock); 02597 if (option_maxcalls) { 02598 if (countcalls >= option_maxcalls) { 02599 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name); 02600 failed = -1; 02601 } 02602 } 02603 if (option_maxload) { 02604 getloadavg(&curloadavg, 1); 02605 if (curloadavg >= option_maxload) { 02606 ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg); 02607 failed = -1; 02608 } 02609 } 02610 if (!failed) 02611 countcalls++; 02612 ast_mutex_unlock(&maxcalllock); 02613 02614 return failed; 02615 }
int load_pbx | ( | void | ) |
Provided by pbx.c
Definition at line 6221 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().
06222 { 06223 int x; 06224 06225 /* Initialize the PBX */ 06226 if (option_verbose) { 06227 ast_verbose( "Asterisk PBX Core Initializing\n"); 06228 ast_verbose( "Registering builtin applications:\n"); 06229 } 06230 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(struct ast_cli_entry)); 06231 06232 /* Register builtin applications */ 06233 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06234 if (option_verbose) 06235 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06236 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06237 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06238 return -1; 06239 } 06240 } 06241 return 0; 06242 }
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 4077 of file pbx.c.
Referenced by get_range().
04078 { 04079 int i; 04080 04081 if (names) { 04082 for (i = 0; names[i]; i++) { 04083 if (!strcasecmp(s, names[i])) 04084 return i+1; 04085 } 04086 } else if (sscanf(s, "%d", &i) == 1 && i >= 1 && i <= max) { 04087 return i; 04088 } 04089 return 0; /* error return */ 04090 }
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 6023 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().
06024 { 06025 struct ast_var_t *vardata; 06026 06027 ast_mutex_lock(&globalslock); 06028 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06029 ast_var_delete(vardata); 06030 ast_mutex_unlock(&globalslock); 06031 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5800 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(), 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().
05801 { 05802 struct ast_var_t *variables; 05803 const char *ret = NULL; 05804 int i; 05805 struct varshead *places[2] = { NULL, &globals }; 05806 05807 if (!name) 05808 return NULL; 05809 05810 if (chan) { 05811 ast_channel_lock(chan); 05812 places[0] = &chan->varshead; 05813 } 05814 05815 for (i = 0; i < 2; i++) { 05816 if (!places[i]) 05817 continue; 05818 if (places[i] == &globals) 05819 ast_mutex_lock(&globalslock); 05820 AST_LIST_TRAVERSE(places[i], variables, entries) { 05821 if (!strcmp(name, ast_var_name(variables))) { 05822 ret = ast_var_value(variables); 05823 break; 05824 } 05825 } 05826 if (places[i] == &globals) 05827 ast_mutex_unlock(&globalslock); 05828 if (ret) 05829 break; 05830 } 05831 05832 if (chan) 05833 ast_channel_unlock(chan); 05834 05835 return ret; 05836 }
static int pbx_builtin_gotoif | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6043 of file pbx.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_goto(), and pbx_checkcondition().
06044 { 06045 char *condition, *branch1, *branch2, *branch; 06046 int rc; 06047 char *stringp; 06048 06049 if (ast_strlen_zero(data)) { 06050 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06051 return 0; 06052 } 06053 06054 stringp = ast_strdupa(data); 06055 condition = strsep(&stringp,"?"); 06056 branch1 = strsep(&stringp,":"); 06057 branch2 = strsep(&stringp,""); 06058 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06059 06060 if (ast_strlen_zero(branch)) { 06061 if (option_debug) 06062 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06063 return 0; 06064 } 06065 06066 rc = pbx_builtin_goto(chan, branch); 06067 06068 return rc; 06069 }
int pbx_builtin_importvar | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 5962 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.
05963 { 05964 char *name; 05965 char *value; 05966 char *channel; 05967 char tmp[VAR_BUF_SIZE]=""; 05968 05969 if (ast_strlen_zero(data)) { 05970 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 05971 return 0; 05972 } 05973 05974 value = ast_strdupa(data); 05975 name = strsep(&value,"="); 05976 channel = strsep(&value,"|"); 05977 if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */ 05978 struct ast_channel *chan2 = ast_get_channel_by_name_locked(channel); 05979 if (chan2) { 05980 char *s = alloca(strlen(value) + 4); 05981 if (s) { 05982 sprintf(s, "${%s}", value); 05983 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 05984 } 05985 ast_channel_unlock(chan2); 05986 } 05987 pbx_builtin_setvar_helper(chan, name, tmp); 05988 } 05989 05990 return(0); 05991 }
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 5838 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().
05839 { 05840 struct ast_var_t *newvariable; 05841 struct varshead *headp; 05842 05843 if (name[strlen(name)-1] == ')') { 05844 char *function = ast_strdupa(name); 05845 05846 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05847 ast_func_write(chan, function, value); 05848 return; 05849 } 05850 05851 if (chan) { 05852 ast_channel_lock(chan); 05853 headp = &chan->varshead; 05854 } else { 05855 ast_mutex_lock(&globalslock); 05856 headp = &globals; 05857 } 05858 05859 if (value) { 05860 if ((option_verbose > 1) && (headp == &globals)) 05861 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05862 newvariable = ast_var_assign(name, value); 05863 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05864 } 05865 05866 if (chan) 05867 ast_channel_unlock(chan); 05868 else 05869 ast_mutex_unlock(&globalslock); 05870 }
static int pbx_builtin_saycharacters | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6108 of file pbx.c.
References ast_say_character_str(), and ast_channel::language.
06109 { 06110 int res = 0; 06111 06112 if (data) 06113 res = ast_say_character_str(chan, data, "", chan->language); 06114 return res; 06115 }
static int pbx_builtin_saydate | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6126 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().
06127 { 06128 int res = 0; 06129 char *parse; 06130 int unixdate = 0; 06131 char charascii[2]; 06132 06133 AST_DECLARE_APP_ARGS(args, 06134 AST_APP_ARG(datestr); 06135 AST_APP_ARG(digits); 06136 ); 06137 06138 06139 if (ast_strlen_zero(data)) { 06140 ast_log(LOG_WARNING, "SayDate requires an argument (date)\n"); 06141 return -1; 06142 } 06143 06144 if (!(parse = ast_strdupa(data))) { 06145 ast_log(LOG_WARNING, "Memory Error!\n"); 06146 return -1; 06147 } 06148 06149 AST_STANDARD_APP_ARGS(args, parse); 06150 06151 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06152 ast_log(LOG_WARNING, "SayDate escape digits must be a subset from '0123456789*#'\n"); 06153 args.digits = ""; 06154 } 06155 06156 if (sscanf(args.datestr, "%d", &unixdate) != 1) { 06157 ast_log(LOG_WARNING, "Firt argument to SayDate must be numeric (date)\n"); 06158 return -1; 06159 } 06160 06161 res = ast_say_date(chan, (time_t)unixdate, args.digits, chan->language); 06162 if (res > 0) { 06163 if (isdigit(res) || (res == '*') || (res == '#')) { 06164 snprintf(charascii, 2, "%c", res); 06165 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06166 res = 0; 06167 } else { 06168 ast_log(LOG_WARNING, "SayDate: invalid return value (%d) detected\n", res); 06169 } 06170 } 06171 return res; 06172 }
static int pbx_builtin_saydigits | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6099 of file pbx.c.
References ast_say_digit_str(), and ast_channel::language.
06100 { 06101 int res = 0; 06102 06103 if (data) 06104 res = ast_say_digit_str(chan, data, "", chan->language); 06105 return res; 06106 }
static int pbx_builtin_saynumber | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6071 of file pbx.c.
References ast_copy_string(), ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, and LOG_WARNING.
06072 { 06073 char tmp[256]; 06074 char *number = tmp; 06075 char *options; 06076 06077 if (ast_strlen_zero(data)) { 06078 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06079 return -1; 06080 } 06081 ast_copy_string(tmp, data, sizeof(tmp)); 06082 strsep(&number, "|"); 06083 options = strsep(&number, "|"); 06084 if (options) { 06085 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06086 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06087 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06088 return -1; 06089 } 06090 } 06091 06092 if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) { 06093 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp); 06094 } 06095 06096 return 0; 06097 }
static int pbx_builtin_sayphonetic | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6117 of file pbx.c.
References ast_say_phonetic_str(), and ast_channel::language.
06118 { 06119 int res = 0; 06120 06121 if (data) 06122 res = ast_say_phonetic_str(chan, data, "", chan->language); 06123 return res; 06124 }
static int pbx_builtin_saytime | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6174 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().
06175 { 06176 int res = 0; 06177 char *parse; 06178 int secs = 0; 06179 char charascii[2]; 06180 06181 AST_DECLARE_APP_ARGS(args, 06182 AST_APP_ARG(timestr); 06183 AST_APP_ARG(digits); 06184 ); 06185 06186 if (ast_strlen_zero(data)) { 06187 ast_log(LOG_WARNING, "SayTime requires an argument (time in seconds)\n"); 06188 return -1; 06189 } 06190 06191 if (!(parse = ast_strdupa(data))) { 06192 ast_log(LOG_WARNING, "Memory Error!\n"); 06193 return -1; 06194 } 06195 06196 AST_STANDARD_APP_ARGS(args, parse); 06197 06198 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06199 ast_log(LOG_WARNING, "SayTime escape digits must be a subset from '0123456789*#'\n"); 06200 args.digits = ""; 06201 } 06202 06203 if (sscanf(args.timestr, "%d", &secs) != 1) { 06204 ast_log(LOG_WARNING, "Firt argument to SayTime must be numeric (time in seconds)\n"); 06205 return -1; 06206 } 06207 06208 res = ast_say_time(chan, (time_t)secs, args.digits, chan->language); 06209 if (res > 0) { 06210 if (isdigit(res) || (res == '*') || (res == '#')) { 06211 snprintf(charascii, 2, "%c", res); 06212 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06213 res = 0; 06214 } else { 06215 ast_log(LOG_WARNING, "SayTime: invalid return value (%d) detected\n", res); 06216 } 06217 } 06218 return res; 06219 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5769 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().
05770 { 05771 struct ast_var_t *variables; 05772 const char *var, *val; 05773 int total = 0; 05774 05775 if (!chan) 05776 return 0; 05777 05778 memset(buf, 0, size); 05779 05780 ast_channel_lock(chan); 05781 05782 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05783 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05784 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05785 ) { 05786 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05787 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05788 break; 05789 } else 05790 total++; 05791 } else 05792 break; 05793 } 05794 05795 ast_channel_unlock(chan); 05796 05797 return total; 05798 }
static int pbx_builtin_setglobalvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5994 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and pbx_builtin_setvar_helper().
05995 { 05996 char *name; 05997 char *stringp = data; 05998 static int dep_warning = 0; 05999 06000 if (ast_strlen_zero(data)) { 06001 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06002 return 0; 06003 } 06004 06005 name = strsep(&stringp, "="); 06006 06007 if (!dep_warning) { 06008 dep_warning = 1; 06009 ast_log(LOG_WARNING, "SetGlobalVar is deprecated. Please use Set(GLOBAL(%s)=%s) instead.\n", name, stringp); 06010 } 06011 06012 /*! \todo XXX watch out, leading whitespace ? */ 06013 pbx_builtin_setvar_helper(NULL, name, stringp); 06014 06015 return(0); 06016 }
int pbx_builtin_setvar | ( | struct ast_channel * | , | |
void * | ||||
) |
Definition at line 5922 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().
05923 { 05924 char *name, *value, *mydata; 05925 int argc; 05926 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 05927 int global = 0; 05928 int x; 05929 05930 if (ast_strlen_zero(data)) { 05931 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 05932 return 0; 05933 } 05934 05935 mydata = ast_strdupa(data); 05936 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 05937 05938 /* check for a trailing flags argument */ 05939 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 05940 argc--; 05941 if (strchr(argv[argc], 'g')) { 05942 ast_log(LOG_WARNING, "The use of the 'g' flag is deprecated. Please use Set(GLOBAL(foo)=bar) instead\n"); 05943 global = 1; 05944 } 05945 } 05946 05947 if (argc > 1) 05948 ast_log(LOG_WARNING, "Setting multiple variables at once within Set is deprecated. Please separate each name/value pair into its own line.\n"); 05949 05950 for (x = 0; x < argc; x++) { 05951 name = argv[x]; 05952 if ((value = strchr(name, '='))) { 05953 *value++ = '\0'; 05954 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 05955 } else 05956 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 05957 } 05958 05959 return(0); 05960 }
void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5872 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().
05873 { 05874 struct ast_var_t *newvariable; 05875 struct varshead *headp; 05876 const char *nametail = name; 05877 05878 if (name[strlen(name)-1] == ')') { 05879 char *function = ast_strdupa(name); 05880 05881 ast_func_write(chan, function, value); 05882 return; 05883 } 05884 05885 if (chan) { 05886 ast_channel_lock(chan); 05887 headp = &chan->varshead; 05888 } else { 05889 ast_mutex_lock(&globalslock); 05890 headp = &globals; 05891 } 05892 05893 /* For comparison purposes, we have to strip leading underscores */ 05894 if (*nametail == '_') { 05895 nametail++; 05896 if (*nametail == '_') 05897 nametail++; 05898 } 05899 05900 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05901 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05902 /* there is already such a variable, delete it */ 05903 AST_LIST_REMOVE(headp, newvariable, entries); 05904 ast_var_delete(newvariable); 05905 break; 05906 } 05907 } 05908 05909 if (value) { 05910 if ((option_verbose > 1) && (headp == &globals)) 05911 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05912 newvariable = ast_var_assign(name, value); 05913 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05914 } 05915 05916 if (chan) 05917 ast_channel_unlock(chan); 05918 else 05919 ast_mutex_unlock(&globalslock); 05920 }
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 6033 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().
06034 { 06035 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06036 return 0; 06037 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06038 return atoi(condition); 06039 else /* Strings are true */ 06040 return 1; 06041 }
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 2700 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02701 { 02702 int oldval = autofallthrough; 02703 autofallthrough = newval; 02704 return oldval; 02705 }
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 2635 of file pbx.c.
References __ast_pbx_run(), and decrease_call_count().
Referenced by ast_pbx_start().
02636 { 02637 /* Oh joyeous kernel, we're a new thread, with nothing to do but 02638 answer this channel and get it going. 02639 */ 02640 /* NOTE: 02641 The launcher of this function _MUST_ increment 'countcalls' 02642 before invoking the function; it will be decremented when the 02643 PBX has finished running on the channel 02644 */ 02645 struct ast_channel *c = data; 02646 02647 __ast_pbx_run(c); 02648 decrease_call_count(); 02649 02650 pthread_exit(NULL); 02651 02652 return NULL; 02653 }
static void print_ext | ( | struct ast_exten * | e, | |
char * | buf, | |||
int | buflen | |||
) | [static] |
helper function to print an extension
Definition at line 3519 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().
03520 { 03521 int prio = ast_get_extension_priority(e); 03522 if (prio == PRIORITY_HINT) { 03523 snprintf(buf, buflen, "hint: %s", 03524 ast_get_extension_app(e)); 03525 } else { 03526 snprintf(buf, buflen, "%d. %s(%s)", 03527 prio, ast_get_extension_app(e), 03528 (!ast_strlen_zero(ast_get_extension_app_data(e)) ? (char *)ast_get_extension_app_data(e) : "")); 03529 } 03530 }
static void set_ext_pri | ( | struct ast_channel * | c, | |
const char * | exten, | |||
int | pri | |||
) | [static] |
Definition at line 2347 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().
02348 { 02349 ast_channel_lock(c); 02350 ast_copy_string(c->exten, exten, sizeof(c->exten)); 02351 c->priority = pri; 02352 ast_channel_unlock(c); 02353 }
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 3533 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().
03534 { 03535 struct ast_context *c = NULL; 03536 int res = 0, old_total_exten = dpc->total_exten; 03537 03538 ast_rdlock_contexts(); 03539 03540 /* walk all contexts ... */ 03541 while ( (c = ast_walk_contexts(c)) ) { 03542 struct ast_exten *e; 03543 struct ast_include *i; 03544 struct ast_ignorepat *ip; 03545 char buf[256], buf2[256]; 03546 int context_info_printed = 0; 03547 03548 if (context && strcmp(ast_get_context_name(c), context)) 03549 continue; /* skip this one, name doesn't match */ 03550 03551 dpc->context_existence = 1; 03552 03553 ast_lock_context(c); 03554 03555 /* are we looking for exten too? if yes, we print context 03556 * only if we find our extension. 03557 * Otherwise print context even if empty ? 03558 * XXX i am not sure how the rinclude is handled. 03559 * I think it ought to go inside. 03560 */ 03561 if (!exten) { 03562 dpc->total_context++; 03563 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03564 ast_get_context_name(c), ast_get_context_registrar(c)); 03565 context_info_printed = 1; 03566 } 03567 03568 /* walk extensions ... */ 03569 e = NULL; 03570 while ( (e = ast_walk_context_extensions(c, e)) ) { 03571 struct ast_exten *p; 03572 03573 if (exten && !ast_extension_match(ast_get_extension_name(e), exten)) 03574 continue; /* skip, extension match failed */ 03575 03576 dpc->extension_existence = 1; 03577 03578 /* may we print context info? */ 03579 if (!context_info_printed) { 03580 dpc->total_context++; 03581 if (rinclude) { /* TODO Print more info about rinclude */ 03582 ast_cli(fd, "[ Included context '%s' created by '%s' ]\n", 03583 ast_get_context_name(c), ast_get_context_registrar(c)); 03584 } else { 03585 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03586 ast_get_context_name(c), ast_get_context_registrar(c)); 03587 } 03588 context_info_printed = 1; 03589 } 03590 dpc->total_prio++; 03591 03592 /* write extension name and first peer */ 03593 snprintf(buf, sizeof(buf), "'%s' =>", ast_get_extension_name(e)); 03594 03595 print_ext(e, buf2, sizeof(buf2)); 03596 03597 ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2, 03598 ast_get_extension_registrar(e)); 03599 03600 dpc->total_exten++; 03601 /* walk next extension peers */ 03602 p = e; /* skip the first one, we already got it */ 03603 while ( (p = ast_walk_extension_priorities(e, p)) ) { 03604 const char *el = ast_get_extension_label(p); 03605 dpc->total_prio++; 03606 if (el) 03607 snprintf(buf, sizeof(buf), " [%s]", el); 03608 else 03609 buf[0] = '\0'; 03610 print_ext(p, buf2, sizeof(buf2)); 03611 03612 ast_cli(fd," %-17s %-45s [%s]\n", buf, buf2, 03613 ast_get_extension_registrar(p)); 03614 } 03615 } 03616 03617 /* walk included and write info ... */ 03618 i = NULL; 03619 while ( (i = ast_walk_context_includes(c, i)) ) { 03620 snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i)); 03621 if (exten) { 03622 /* Check all includes for the requested extension */ 03623 if (includecount >= AST_PBX_MAX_STACK) { 03624 ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n"); 03625 } else { 03626 int dupe=0; 03627 int x; 03628 for (x=0;x<includecount;x++) { 03629 if (!strcasecmp(includes[x], ast_get_include_name(i))) { 03630 dupe++; 03631 break; 03632 } 03633 } 03634 if (!dupe) { 03635 includes[includecount] = ast_get_include_name(i); 03636 show_dialplan_helper(fd, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes); 03637 } else { 03638 ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context); 03639 } 03640 } 03641 } else { 03642 ast_cli(fd, " Include => %-45s [%s]\n", 03643 buf, ast_get_include_registrar(i)); 03644 } 03645 } 03646 03647 /* walk ignore patterns and write info ... */ 03648 ip = NULL; 03649 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) { 03650 const char *ipname = ast_get_ignorepat_name(ip); 03651 char ignorepat[AST_MAX_EXTENSION]; 03652 snprintf(buf, sizeof(buf), "'%s'", ipname); 03653 snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname); 03654 if (!exten || ast_extension_match(ignorepat, exten)) { 03655 ast_cli(fd, " Ignore pattern => %-45s [%s]\n", 03656 buf, ast_get_ignorepat_registrar(ip)); 03657 } 03658 } 03659 if (!rinclude) { 03660 struct ast_sw *sw = NULL; 03661 while ( (sw = ast_walk_context_switches(c, sw)) ) { 03662 snprintf(buf, sizeof(buf), "'%s/%s'", 03663 ast_get_switch_name(sw), 03664 ast_get_switch_data(sw)); 03665 ast_cli(fd, " Alt. Switch => %-45s [%s]\n", 03666 buf, ast_get_switch_registrar(sw)); 03667 } 03668 } 03669 03670 ast_unlock_context(c); 03671 03672 /* if we print something in context, make an empty line */ 03673 if (context_info_printed) 03674 ast_cli(fd, "\r\n"); 03675 } 03676 ast_unlock_contexts(); 03677 03678 return (dpc->total_exten == old_total_exten) ? -1 : res; 03679 }
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 5380 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().
05381 { 05382 int res; 05383 struct ast_frame *f; 05384 int waittime; 05385 05386 if (ast_strlen_zero(data) || (sscanf(data, "%d", &waittime) != 1) || (waittime < 0)) 05387 waittime = -1; 05388 if (waittime > -1) { 05389 ast_safe_sleep(chan, waittime * 1000); 05390 } else do { 05391 res = ast_waitfor(chan, -1); 05392 if (res < 0) 05393 return; 05394 f = ast_read(chan); 05395 if (f) 05396 ast_frfree(f); 05397 } while(f); 05398 }
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] |