#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/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. | |
enum ast_extension_states | ast_devstate_to_extenstate (enum ast_device_state devstate) |
Map devstate to an extension state. | |
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_processed_calls (void) |
Retrieve the total number of calls processed through the PBX since last restart. | |
int | ast_rdlock_contexts (void) |
int | ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description) |
Register an application. | |
int | ast_register_switch (struct ast_switch *sw) |
Register an alternative dialplan switch. | |
static int | ast_remove_hint (struct ast_exten *e) |
ast_remove_hint: Remove hint from extension | |
int | ast_spawn_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
Launch a new extension (i.e. new stack). | |
int | ast_unlock_context (struct ast_context *con) |
int | ast_unlock_contexts () |
Unlocks contexts. | |
int | ast_unregister_application (const char *app) |
Unregister an application. | |
void | ast_unregister_switch (struct ast_switch *sw) |
Unregister an alternative switch. | |
ast_exten * | ast_walk_context_extensions (struct ast_context *con, struct ast_exten *exten) |
ast_ignorepat * | ast_walk_context_ignorepats (struct ast_context *con, struct ast_ignorepat *ip) |
ast_include * | ast_walk_context_includes (struct ast_context *con, struct ast_include *inc) |
ast_sw * | ast_walk_context_switches (struct ast_context *con, struct ast_sw *sw) |
ast_context * | ast_walk_contexts (struct ast_context *con) |
ast_exten * | ast_walk_extension_priorities (struct ast_exten *exten, struct ast_exten *priority) |
int | ast_wrlock_contexts (void) |
static void * | async_wait (void *data) |
static int | collect_digits (struct ast_channel *c, int waittime, char *buf, int buflen, int pos) |
collect digits from the channel into the buffer, return -1 on error, 0 on timeout or done. | |
static char * | complete_show_application (const char *line, const char *word, int pos, int state) |
static char * | complete_show_applications (const char *line, const char *word, int pos, int state) |
static char * | complete_show_applications_deprecated (const char *line, const char *word, int pos, int state) |
static char * | complete_show_dialplan_context (const char *line, const char *word, int pos, int state) |
static char * | complete_show_function (const char *line, const char *word, int pos, int state) |
static void | decrease_call_count (void) |
static void | destroy_exten (struct ast_exten *e) |
static int | ext_cmp (const char *a, const char *b) |
the full routine to compare extensions in rules. | |
static int | ext_cmp1 (const char **p) |
helper functions to sort extensions and patterns in the desired way, so that more specific patterns appear first. | |
static int | ext_strncpy (char *dst, const char *src, int len) |
copy a string skipping whitespace | |
static int | extension_match_core (const char *pattern, const char *data, enum ext_match_t mode) |
static struct ast_context * | find_context_locked (const char *context) |
static char * | func_args (char *function) |
return a pointer to the arguments of the function, and terminates the function name with '\0' | |
static unsigned | get_range (char *src, int max, char *const names[], const char *msg) |
helper function to return a range up to max (7, 12, 31 respectively). names, if supplied, is an array of names that should be mapped to numbers. | |
static void | get_timerange (struct ast_timing *i, char *times) |
store a bitmask of valid times, one bit each 2 minute | |
static int | handle_set_global (int fd, int argc, char *argv[]) |
static int | handle_set_global_deprecated (int fd, int argc, char *argv[]) |
CLI support for setting global variables. | |
static int | handle_show_application (int fd, int argc, char *argv[]) |
static int | handle_show_application_deprecated (int fd, int argc, char *argv[]) |
static int | handle_show_applications (int fd, int argc, char *argv[]) |
static int | handle_show_applications_deprecated (int fd, int argc, char *argv[]) |
static int | handle_show_dialplan (int fd, int argc, char *argv[]) |
static int | handle_show_function (int fd, int argc, char *argv[]) |
static int | handle_show_function_deprecated (int fd, int argc, char *argv[]) |
static int | handle_show_functions (int fd, int argc, char *argv[]) |
static int | handle_show_functions_deprecated (int fd, int argc, char *argv[]) |
static int | handle_show_globals (int fd, int argc, char *argv[]) |
CLI support for listing global variables in a parseable way. | |
static int | handle_show_hints (int fd, int argc, char *argv[]) |
handle_show_hints: CLI support for listing registered dial plan hints | |
static int | handle_show_switches (int fd, int argc, char *argv[]) |
handle_show_switches: CLI support for listing registered dial plan switches | |
static int | include_valid (struct ast_include *i) |
static int | increase_call_count (const struct ast_channel *c) |
int | load_pbx (void) |
static int | lookup_name (const char *s, char *const names[], int max) |
Helper for get_range. return the index of the matching entry, starting from 1. If names is not supplied, try numeric values. | |
static int | matchcid (const char *cidpattern, const char *callerid) |
static int | parse_variable_name (char *var, int *offset, int *length, int *isfunc) |
extract offset:length from variable name. Returns 1 if there is a offset:length part, which is trimmed off (values go into variables) | |
static int | pbx_builtin_answer (struct ast_channel *, void *) |
static int | pbx_builtin_background (struct ast_channel *, void *) |
static int | pbx_builtin_busy (struct ast_channel *, void *) |
void | pbx_builtin_clear_globals (void) |
static int | pbx_builtin_congestion (struct ast_channel *, void *) |
static int | pbx_builtin_execiftime (struct ast_channel *, void *) |
const char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
static int | pbx_builtin_goto (struct ast_channel *, void *) |
static int | pbx_builtin_gotoif (struct ast_channel *, void *) |
static int | pbx_builtin_gotoiftime (struct ast_channel *, void *) |
static int | pbx_builtin_hangup (struct ast_channel *, void *) |
static int | pbx_builtin_importvar (struct ast_channel *, void *) |
static int | pbx_builtin_noop (struct ast_channel *, void *) |
static int | pbx_builtin_progress (struct ast_channel *, void *) |
void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
static int | pbx_builtin_resetcdr (struct ast_channel *, void *) |
static int | pbx_builtin_ringing (struct ast_channel *, void *) |
static int | pbx_builtin_saycharacters (struct ast_channel *, void *) |
static int | pbx_builtin_saydate (struct ast_channel *, void *) |
static int | pbx_builtin_saydigits (struct ast_channel *, void *) |
static int | pbx_builtin_saynumber (struct ast_channel *, void *) |
static int | pbx_builtin_sayphonetic (struct ast_channel *, void *) |
static int | pbx_builtin_saytime (struct ast_channel *, void *) |
int | pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
static int | pbx_builtin_setamaflags (struct ast_channel *, void *) |
static int | pbx_builtin_setglobalvar (struct ast_channel *, void *) |
int | pbx_builtin_setvar (struct ast_channel *, void *) |
void | pbx_builtin_setvar_helper (struct ast_channel *chan, const char *name, const char *value) |
static int | pbx_builtin_wait (struct ast_channel *, void *) |
static int | pbx_builtin_waitexten (struct ast_channel *, void *) |
int | pbx_checkcondition (const char *condition) |
Evaluate a condition. | |
static void | pbx_destroy (struct ast_pbx *p) |
int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data) |
Execute an application. | |
static int | pbx_extension_helper (struct ast_channel *c, struct ast_context *con, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action) |
The return value depends on the action:. | |
static struct ast_exten * | pbx_find_extension (struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action) |
ast_app * | pbx_findapp (const char *app) |
Look up an application. | |
static struct ast_switch * | pbx_findswitch (const char *sw) |
void | pbx_retrieve_variable (struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp) |
pbx_retrieve_variable: Support for Asterisk built-in variables --- | |
int | pbx_set_autofallthrough (int newval) |
static void | pbx_substitute_variables (char *passdata, int datalen, struct ast_channel *c, struct ast_exten *e) |
void | pbx_substitute_variables_helper (struct ast_channel *c, const char *cp1, char *cp2, int count) |
static void | pbx_substitute_variables_helper_full (struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count) |
void | pbx_substitute_variables_varshead (struct varshead *headp, const char *cp1, char *cp2, int count) |
static void * | pbx_thread (void *data) |
static void | print_ext (struct ast_exten *e, char *buf, int buflen) |
helper function to print an extension | |
static void | set_ext_pri (struct ast_channel *c, const char *exten, int pri) |
static int | show_dialplan_helper (int fd, const char *context, const char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, const char *includes[]) |
static char * | substring (const char *value, int offset, int length, char *workspace, size_t workspace_len) |
takes a substring. It is ok to call with value == workspace. | |
static void | switch_data_init (void) |
static void | wait_for_hangup (struct ast_channel *chan, void *data) |
Variables | |
static int | autofallthrough = 1 |
static struct ast_app_option | background_opts [128] = { [ 's' ] = { .flag = (1 << 0) }, [ 'n' ] = { .flag = (1 << 1) }, [ 'm' ] = { .flag = (1 << 2) }, [ 'p' ] = { .flag = (1 << 3) },} |
static struct pbx_builtin | builtins [] |
Declaration of builtin applications. | |
static struct ast_cli_entry | cli_set_global_deprecated |
static struct ast_cli_entry | cli_show_application_deprecated |
static struct ast_cli_entry | cli_show_applications_deprecated |
static struct ast_cli_entry | cli_show_dialplan_deprecated |
static struct ast_cli_entry | cli_show_function_deprecated |
static struct ast_cli_entry | cli_show_functions_deprecated |
static struct ast_cli_entry | cli_show_globals_deprecated |
static struct ast_cli_entry | cli_show_hints_deprecated |
static struct ast_cli_entry | cli_show_switches_deprecated |
static ast_rwlock_t | conlock = PTHREAD_RWLOCK_INITIALIZER |
static struct ast_context * | contexts |
static int | countcalls |
static char * | days [] |
static struct cfextension_states | extension_states [] |
static struct varshead | globals = AST_LIST_HEAD_NOLOCK_INIT_VALUE |
static ast_mutex_t | globalslock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static ast_mutex_t | maxcalllock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static char * | months [] |
static struct ast_cli_entry | pbx_cli [] |
static struct ast_app_option | resetcdr_opts [128] = { [ 'w' ] = { .flag = (1 << 1) }, [ 'a' ] = { .flag = (1 << 2) }, [ 'v' ] = { .flag = (1 << 0) },} |
static char | set_global_help [] |
static char | show_application_help [] |
static char | show_applications_help [] |
static char | show_dialplan_help [] |
static char | show_function_help [] |
static char | show_functions_help [] |
static char | show_globals_help [] |
static char | show_hints_help [] |
static char | show_switches_help [] |
ast_state_cb * | statecbs |
static int | stateid = 1 |
static struct ast_threadstorage | switch_data = { .once = PTHREAD_ONCE_INIT, .key_init = switch_data_init , } |
static int | totalcalls |
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 77 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 82 of file pbx.c.
Referenced by ast_add_extension2(), pbx_builtin_importvar(), and pbx_substitute_variables_helper_full().
#define WAITEXTEN_MOH (1 << 0) |
enum ext_match_t |
When looking up extensions, we can have different requests identified by the 'action' argument, as follows. Note that the coding is such that the low 4 bits are the third argument to extension_match_core.
Definition at line 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 3904 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().
03905 { 03906 struct ast_context *tmp, **local_contexts; 03907 int length = sizeof(struct ast_context) + strlen(name) + 1; 03908 03909 if (!extcontexts) { 03910 ast_rdlock_contexts(); 03911 local_contexts = &contexts; 03912 } else 03913 local_contexts = extcontexts; 03914 03915 for (tmp = *local_contexts; tmp; tmp = tmp->next) { 03916 if (!strcasecmp(tmp->name, name)) { 03917 if (!existsokay) { 03918 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 03919 tmp = NULL; 03920 } 03921 if (!extcontexts) 03922 ast_unlock_contexts(); 03923 return tmp; 03924 } 03925 } 03926 03927 if (!extcontexts) 03928 ast_unlock_contexts(); 03929 03930 if ((tmp = ast_calloc(1, length))) { 03931 ast_mutex_init(&tmp->lock); 03932 ast_mutex_init(&tmp->macrolock); 03933 strcpy(tmp->name, name); 03934 tmp->registrar = registrar; 03935 if (!extcontexts) 03936 ast_wrlock_contexts(); 03937 tmp->next = *local_contexts; 03938 *local_contexts = tmp; 03939 if (!extcontexts) 03940 ast_unlock_contexts(); 03941 if (option_debug) 03942 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 03943 if (option_verbose > 2) 03944 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 03945 } 03946 03947 return tmp; 03948 }
void __ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
Definition at line 5333 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().
05334 { 05335 struct ast_context *tmp, *tmpl=NULL; 05336 struct ast_include *tmpi; 05337 struct ast_sw *sw; 05338 struct ast_exten *e, *el, *en; 05339 struct ast_ignorepat *ipi; 05340 05341 for (tmp = contexts; tmp; ) { 05342 struct ast_context *next; /* next starting point */ 05343 for (; tmp; tmpl = tmp, tmp = tmp->next) { 05344 if (option_debug) 05345 ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar); 05346 if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) && 05347 (!con || !strcasecmp(tmp->name, con->name)) ) 05348 break; /* found it */ 05349 } 05350 if (!tmp) /* not found, we are done */ 05351 break; 05352 ast_mutex_lock(&tmp->lock); 05353 if (option_debug) 05354 ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar); 05355 next = tmp->next; 05356 if (tmpl) 05357 tmpl->next = next; 05358 else 05359 contexts = next; 05360 /* Okay, now we're safe to let it go -- in a sense, we were 05361 ready to let it go as soon as we locked it. */ 05362 ast_mutex_unlock(&tmp->lock); 05363 for (tmpi = tmp->includes; tmpi; ) { /* Free includes */ 05364 struct ast_include *tmpil = tmpi; 05365 tmpi = tmpi->next; 05366 free(tmpil); 05367 } 05368 for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */ 05369 struct ast_ignorepat *ipl = ipi; 05370 ipi = ipi->next; 05371 free(ipl); 05372 } 05373 while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list))) 05374 free(sw); 05375 for (e = tmp->root; e;) { 05376 for (en = e->peer; en;) { 05377 el = en; 05378 en = en->peer; 05379 destroy_exten(el); 05380 } 05381 el = e; 05382 e = e->next; 05383 destroy_exten(el); 05384 } 05385 ast_mutex_destroy(&tmp->lock); 05386 free(tmp); 05387 /* if we have a specific match, we are done, otherwise continue */ 05388 tmp = con ? NULL : next; 05389 } 05390 }
static int __ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
int | async | |||
) | [static] |
Definition at line 6481 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().
06482 { 06483 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06484 06485 if (!chan) 06486 return -2; 06487 06488 if (context == NULL) 06489 context = chan->context; 06490 if (exten == NULL) 06491 exten = chan->exten; 06492 06493 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06494 if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num)) 06495 return goto_func(chan, context, exten, priority); 06496 else 06497 return -3; 06498 }
static int __ast_pbx_run | ( | struct ast_channel * | c | ) | [static] |
Definition at line 2351 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().
02352 { 02353 int found = 0; /* set if we find at least one match */ 02354 int res = 0; 02355 int autoloopflag; 02356 int error = 0; /* set an error conditions */ 02357 const char *emc; 02358 02359 /* A little initial setup here */ 02360 if (c->pbx) { 02361 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name); 02362 /* XXX and now what ? */ 02363 free(c->pbx); 02364 } 02365 if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx)))) 02366 return -1; 02367 /* Set reasonable defaults */ 02368 c->pbx->rtimeout = 10; 02369 c->pbx->dtimeout = 5; 02370 02371 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */ 02372 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP); 02373 02374 /* Start by trying whatever the channel is set to */ 02375 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02376 /* If not successful fall back to 's' */ 02377 if (option_verbose > 1) 02378 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); 02379 /* XXX the original code used the existing priority in the call to 02380 * ast_exists_extension(), and reset it to 1 afterwards. 02381 * I believe the correct thing is to set it to 1 immediately. 02382 */ 02383 set_ext_pri(c, "s", 1); 02384 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02385 /* JK02: And finally back to default if everything else failed */ 02386 if (option_verbose > 1) 02387 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); 02388 ast_copy_string(c->context, "default", sizeof(c->context)); 02389 } 02390 } 02391 for (;;) { 02392 char dst_exten[256]; /* buffer to accumulate digits */ 02393 int pos = 0; /* XXX should check bounds */ 02394 int digit = 0; 02395 02396 /* loop on priorities in this context/exten */ 02397 while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02398 found = 1; 02399 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02400 /* Something bad happened, or a hangup has been requested. */ 02401 if (strchr("0123456789ABCDEF*#", res)) { 02402 if (option_debug) 02403 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 02404 pos = 0; 02405 dst_exten[pos++] = digit = res; 02406 dst_exten[pos] = '\0'; 02407 break; 02408 } 02409 if (res == AST_PBX_KEEPALIVE) { 02410 if (option_debug) 02411 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02412 if (option_verbose > 1) 02413 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02414 error = 1; 02415 break; 02416 } 02417 if (option_debug) 02418 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02419 if (option_verbose > 1) 02420 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02421 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02422 c->_softhangup = 0; 02423 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02424 /* atimeout, nothing bad */ 02425 } else { 02426 if (c->cdr) 02427 ast_cdr_update(c); 02428 error = 1; 02429 break; 02430 } 02431 } 02432 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02433 c->_softhangup = 0; 02434 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c,c->context,"T",1,c->cid.cid_num)) { 02435 set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */ 02436 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */ 02437 c->whentohangup = 0; 02438 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT; 02439 } else if (c->_softhangup) { 02440 if (option_debug) 02441 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", 02442 c->exten, c->priority); 02443 error = 1; 02444 break; 02445 } 02446 c->priority++; 02447 } /* end while - from here on we can use 'break' to go out */ 02448 if (error) 02449 break; 02450 02451 /* XXX we get here on non-existing extension or a keypress or hangup ? */ 02452 02453 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { 02454 /* If there is no match at priority 1, it is not a valid extension anymore. 02455 * Try to continue at "i", 1 or exit if the latter does not exist. 02456 */ 02457 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02458 if (option_verbose > 2) 02459 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name); 02460 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten); 02461 set_ext_pri(c, "i", 1); 02462 } else { 02463 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n", 02464 c->name, c->exten, c->context); 02465 error = 1; /* we know what to do with it */ 02466 break; 02467 } 02468 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02469 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */ 02470 c->_softhangup = 0; 02471 } else { /* keypress received, get more digits for a full extension */ 02472 int waittime = 0; 02473 if (digit) 02474 waittime = c->pbx->dtimeout; 02475 else if (!autofallthrough) 02476 waittime = c->pbx->rtimeout; 02477 if (!waittime) { 02478 const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 02479 if (!status) 02480 status = "UNKNOWN"; 02481 if (option_verbose > 2) 02482 ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status); 02483 if (!strcasecmp(status, "CONGESTION")) 02484 res = pbx_builtin_congestion(c, "10"); 02485 else if (!strcasecmp(status, "CHANUNAVAIL")) 02486 res = pbx_builtin_congestion(c, "10"); 02487 else if (!strcasecmp(status, "BUSY")) 02488 res = pbx_builtin_busy(c, "10"); 02489 error = 1; /* XXX disable message */ 02490 break; /* exit from the 'for' loop */ 02491 } 02492 02493 if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos)) 02494 break; 02495 if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */ 02496 set_ext_pri(c, dst_exten, 1); 02497 else { 02498 /* No such extension */ 02499 if (!ast_strlen_zero(dst_exten)) { 02500 /* An invalid extension */ 02501 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02502 if (option_verbose > 2) 02503 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name); 02504 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten); 02505 set_ext_pri(c, "i", 1); 02506 } else { 02507 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context); 02508 found = 1; /* XXX disable message */ 02509 break; 02510 } 02511 } else { 02512 /* A simple timeout */ 02513 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) { 02514 if (option_verbose > 2) 02515 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name); 02516 set_ext_pri(c, "t", 1); 02517 } else { 02518 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context); 02519 found = 1; /* XXX disable message */ 02520 break; 02521 } 02522 } 02523 } 02524 if (c->cdr) { 02525 if (option_verbose > 2) 02526 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name); 02527 ast_cdr_update(c); 02528 } 02529 } 02530 } 02531 if (!found && !error) 02532 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); 02533 if (res != AST_PBX_KEEPALIVE) 02534 ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING); 02535 ast_channel_lock(c); 02536 if ((emc = pbx_builtin_getvar_helper(c, "EXIT_MACRO_CONTEXT"))) { 02537 emc = ast_strdupa(emc); 02538 } 02539 ast_channel_unlock(c); 02540 if ((res != AST_PBX_KEEPALIVE) && !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) && 02541 ((emc && ast_exists_extension(c, emc, "h", 1, c->cid.cid_num)) || 02542 (ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num) && (emc = c->context)))) { 02543 ast_copy_string(c->context, emc, sizeof(c->context)); 02544 set_ext_pri(c, "h", 1); 02545 if (c->cdr && ast_opt_end_cdr_before_h_exten) { 02546 ast_cdr_end(c->cdr); 02547 } 02548 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02549 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02550 /* Something bad happened, or a hangup has been requested. */ 02551 if (option_debug) 02552 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02553 if (option_verbose > 1) 02554 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02555 break; 02556 } 02557 c->priority++; 02558 } 02559 } 02560 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP); 02561 ast_clear_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */ 02562 pbx_destroy(c->pbx); 02563 c->pbx = NULL; 02564 if (res != AST_PBX_KEEPALIVE) 02565 ast_hangup(c); 02566 return 0; 02567 }
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 4727 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().
04729 { 04730 struct ast_exten *ep; 04731 04732 for (ep = NULL; e ; ep = e, e = e->peer) { 04733 if (e->priority >= tmp->priority) 04734 break; 04735 } 04736 if (!e) { /* go at the end, and ep is surely set because the list is not empty */ 04737 ep->peer = tmp; 04738 return 0; /* success */ 04739 } 04740 if (e->priority == tmp->priority) { 04741 /* Can't have something exactly the same. Is this a 04742 replacement? If so, replace, otherwise, bonk. */ 04743 if (!replace) { 04744 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04745 if (tmp->datad) 04746 tmp->datad(tmp->data); 04747 free(tmp); 04748 return -1; 04749 } 04750 /* we are replacing e, so copy the link fields and then update 04751 * whoever pointed to e to point to us 04752 */ 04753 tmp->next = e->next; /* not meaningful if we are not first in the peer list */ 04754 tmp->peer = e->peer; /* always meaningful */ 04755 if (ep) /* We're in the peer list, just insert ourselves */ 04756 ep->peer = tmp; 04757 else if (el) /* We're the first extension. Take over e's functions */ 04758 el->next = tmp; 04759 else /* We're the very first extension. */ 04760 con->root = tmp; 04761 if (tmp->priority == PRIORITY_HINT) 04762 ast_change_hint(e,tmp); 04763 /* Destroy the old one */ 04764 if (e->datad) 04765 e->datad(e->data); 04766 free(e); 04767 } else { /* Slip ourselves in just before e */ 04768 tmp->peer = e; 04769 tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */ 04770 if (ep) /* Easy enough, we're just in the peer list */ 04771 ep->peer = tmp; 04772 else { /* we are the first in some peer list, so link in the ext list */ 04773 if (el) 04774 el->next = tmp; /* in the middle... */ 04775 else 04776 con->root = tmp; /* ... or at the head */ 04777 e->next = NULL; /* e is no more at the head, so e->next must be reset */ 04778 } 04779 /* And immediately return success. */ 04780 if (tmp->priority == PRIORITY_HINT) 04781 ast_add_hint(tmp); 04782 } 04783 return 0; 04784 }
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2675 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02676 { 02677 return countcalls; 02678 }
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 4596 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().
04599 { 04600 int ret = -1; 04601 struct ast_context *c = find_context_locked(context); 04602 04603 if (c) { 04604 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04605 application, data, datad, registrar); 04606 ast_unlock_contexts(); 04607 } 04608 return ret; 04609 }
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 4811 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().
04815 { 04816 /* 04817 * Sort extensions (or patterns) according to the rules indicated above. 04818 * These are implemented by the function ext_cmp()). 04819 * All priorities for the same ext/pattern/cid are kept in a list, 04820 * using the 'peer' field as a link field.. 04821 */ 04822 struct ast_exten *tmp, *e, *el = NULL; 04823 int res; 04824 int length; 04825 char *p; 04826 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04827 04828 /* if we are adding a hint, and there are global variables, and the hint 04829 contains variable references, then expand them 04830 */ 04831 ast_mutex_lock(&globalslock); 04832 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04833 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04834 application = expand_buf; 04835 } 04836 ast_mutex_unlock(&globalslock); 04837 04838 length = sizeof(struct ast_exten); 04839 length += strlen(extension) + 1; 04840 length += strlen(application) + 1; 04841 if (label) 04842 length += strlen(label) + 1; 04843 if (callerid) 04844 length += strlen(callerid) + 1; 04845 else 04846 length ++; /* just the '\0' */ 04847 04848 /* Be optimistic: Build the extension structure first */ 04849 if (!(tmp = ast_calloc(1, length))) 04850 return -1; 04851 04852 /* use p as dst in assignments, as the fields are const char * */ 04853 p = tmp->stuff; 04854 if (label) { 04855 tmp->label = p; 04856 strcpy(p, label); 04857 p += strlen(label) + 1; 04858 } 04859 tmp->exten = p; 04860 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04861 tmp->priority = priority; 04862 tmp->cidmatch = p; /* but use p for assignments below */ 04863 if (callerid) { 04864 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04865 tmp->matchcid = 1; 04866 } else { 04867 *p++ = '\0'; 04868 tmp->matchcid = 0; 04869 } 04870 tmp->app = p; 04871 strcpy(p, application); 04872 tmp->parent = con; 04873 tmp->data = data; 04874 tmp->datad = datad; 04875 tmp->registrar = registrar; 04876 04877 ast_mutex_lock(&con->lock); 04878 res = 0; /* some compilers will think it is uninitialized otherwise */ 04879 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04880 res = ext_cmp(e->exten, tmp->exten); 04881 if (res == 0) { /* extension match, now look at cidmatch */ 04882 if (!e->matchcid && !tmp->matchcid) 04883 res = 0; 04884 else if (tmp->matchcid && !e->matchcid) 04885 res = 1; 04886 else if (e->matchcid && !tmp->matchcid) 04887 res = -1; 04888 else 04889 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04890 } 04891 if (res >= 0) 04892 break; 04893 } 04894 if (e && res == 0) { /* exact match, insert in the pri chain */ 04895 res = add_pri(con, tmp, el, e, replace); 04896 ast_mutex_unlock(&con->lock); 04897 if (res < 0) { 04898 errno = EEXIST; /* XXX do we care ? */ 04899 return 0; /* XXX should we return -1 maybe ? */ 04900 } 04901 } else { 04902 /* 04903 * not an exact match, this is the first entry with this pattern, 04904 * so insert in the main list right before 'e' (if any) 04905 */ 04906 tmp->next = e; 04907 if (el) 04908 el->next = tmp; 04909 else 04910 con->root = tmp; 04911 ast_mutex_unlock(&con->lock); 04912 if (tmp->priority == PRIORITY_HINT) 04913 ast_add_hint(tmp); 04914 } 04915 if (option_debug) { 04916 if (tmp->matchcid) { 04917 if (option_debug) 04918 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04919 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04920 } else { 04921 if (option_debug) 04922 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04923 tmp->exten, tmp->priority, con->name); 04924 } 04925 } 04926 if (option_verbose > 2) { 04927 if (tmp->matchcid) { 04928 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04929 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04930 } else { 04931 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04932 tmp->exten, tmp->priority, con->name); 04933 } 04934 } 04935 return 0; 04936 }
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 2173 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().
02174 { 02175 struct ast_hint *hint; 02176 02177 if (!e) 02178 return -1; 02179 02180 AST_LIST_LOCK(&hints); 02181 02182 /* Search if hint exists, do nothing */ 02183 AST_LIST_TRAVERSE(&hints, hint, list) { 02184 if (hint->exten == e) { 02185 AST_LIST_UNLOCK(&hints); 02186 if (option_debug > 1) 02187 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02188 return -1; 02189 } 02190 } 02191 02192 if (option_debug > 1) 02193 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02194 02195 if (!(hint = ast_calloc(1, sizeof(*hint)))) { 02196 AST_LIST_UNLOCK(&hints); 02197 return -1; 02198 } 02199 /* Initialize and insert new item at the top */ 02200 hint->exten = e; 02201 hint->laststate = ast_extension_state2(e); 02202 AST_LIST_INSERT_HEAD(&hints, hint, list); 02203 02204 AST_LIST_UNLOCK(&hints); 02205 return 0; 02206 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4634 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().
04635 { 04636 int res = 0; 04637 04638 ast_channel_lock(chan); 04639 04640 if (chan->pbx) { /* This channel is currently in the PBX */ 04641 ast_explicit_goto(chan, context, exten, priority); 04642 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04643 } else { 04644 /* In order to do it when the channel doesn't really exist within 04645 the PBX, we have to make a new channel, masquerade, and start the PBX 04646 at the new location */ 04647 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04648 if (!tmpchan) { 04649 res = -1; 04650 } else { 04651 if (chan->cdr) { 04652 ast_cdr_discard(tmpchan->cdr); 04653 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04654 } 04655 /* Make formats okay */ 04656 tmpchan->readformat = chan->readformat; 04657 tmpchan->writeformat = chan->writeformat; 04658 /* Setup proper location */ 04659 ast_explicit_goto(tmpchan, 04660 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04661 04662 /* Masquerade into temp channel */ 04663 if (ast_channel_masquerade(tmpchan, chan)) { 04664 /* Failed to set up the masquerade. It's probably chan_local 04665 * in the middle of optimizing itself out. Sad. :( */ 04666 ast_hangup(tmpchan); 04667 tmpchan = NULL; 04668 res = -1; 04669 } else { 04670 /* Grab the locks and get going */ 04671 ast_channel_lock(tmpchan); 04672 ast_do_masquerade(tmpchan); 04673 ast_channel_unlock(tmpchan); 04674 /* Start the PBX going on our stolen channel */ 04675 if (ast_pbx_start(tmpchan)) { 04676 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04677 ast_hangup(tmpchan); 04678 res = -1; 04679 } 04680 } 04681 } 04682 } 04683 ast_channel_unlock(chan); 04684 return res; 04685 }
int ast_async_goto_by_name | ( | const char * | channame, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4687 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04688 { 04689 struct ast_channel *chan; 04690 int res = -1; 04691 04692 chan = ast_get_channel_by_name_locked(channame); 04693 if (chan) { 04694 res = ast_async_goto(chan, context, exten, priority); 04695 ast_channel_unlock(chan); 04696 } 04697 return res; 04698 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6505 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06506 { 06507 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06508 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info_in | |||
) |
Definition at line 4274 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().
04275 { 04276 char info_save[256]; 04277 char *info; 04278 04279 /* Check for empty just in case */ 04280 if (ast_strlen_zero(info_in)) 04281 return 0; 04282 /* make a copy just in case we were passed a static string */ 04283 ast_copy_string(info_save, info_in, sizeof(info_save)); 04284 info = info_save; 04285 /* Assume everything except time */ 04286 i->monthmask = 0xfff; /* 12 bits */ 04287 i->daymask = 0x7fffffffU; /* 31 bits */ 04288 i->dowmask = 0x7f; /* 7 bits */ 04289 /* on each call, use strsep() to move info to the next argument */ 04290 get_timerange(i, strsep(&info, "|")); 04291 if (info) 04292 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04293 if (info) 04294 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04295 if (info) 04296 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04297 return 1; 04298 }
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 2297 of file pbx.c.
References E_CANMATCH, and pbx_extension_helper().
Referenced by background_detect_exec(), cb_events(), do_immediate_setup(), 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().
02298 { 02299 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02300 }
ast_change_hint: Change hint for an extension
Definition at line 2209 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().
02210 { 02211 struct ast_hint *hint; 02212 int res = -1; 02213 02214 AST_LIST_LOCK(&hints); 02215 AST_LIST_TRAVERSE(&hints, hint, list) { 02216 if (hint->exten == oe) { 02217 hint->exten = ne; 02218 res = 0; 02219 break; 02220 } 02221 } 02222 AST_LIST_UNLOCK(&hints); 02223 02224 return res; 02225 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4300 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().
04301 { 04302 struct tm tm; 04303 time_t t = time(NULL); 04304 04305 ast_localtime(&t, &tm, NULL); 04306 04307 /* If it's not the right month, return */ 04308 if (!(i->monthmask & (1 << tm.tm_mon))) 04309 return 0; 04310 04311 /* If it's not that time of the month.... */ 04312 /* Warning, tm_mday has range 1..31! */ 04313 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04314 return 0; 04315 04316 /* If it's not the right day of the week */ 04317 if (!(i->dowmask & (1 << tm.tm_wday))) 04318 return 0; 04319 04320 /* Sanity check the hour just to be safe */ 04321 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04322 ast_log(LOG_WARNING, "Insane time...\n"); 04323 return 0; 04324 } 04325 04326 /* Now the tough part, we calculate if it fits 04327 in the right time based on min/hour */ 04328 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04329 return 0; 04330 04331 /* If we got this far, then we're good */ 04332 return 1; 04333 }
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 4527 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().
04528 { 04529 int ret = -1; 04530 struct ast_context *c = find_context_locked(context); 04531 04532 if (c) { 04533 ret = ast_context_add_ignorepat2(c, value, registrar); 04534 ast_unlock_contexts(); 04535 } 04536 return ret; 04537 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | value, | |||
const char * | registrar | |||
) |
Definition at line 4539 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().
04540 { 04541 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04542 int length; 04543 char *pattern; 04544 length = sizeof(struct ast_ignorepat); 04545 length += strlen(value) + 1; 04546 if (!(ignorepat = ast_calloc(1, length))) 04547 return -1; 04548 /* The cast to char * is because we need to write the initial value. 04549 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04550 * sees the cast as dereferencing a type-punned pointer and warns about 04551 * it. This is the workaround (we're telling gcc, yes, that's really 04552 * what we wanted to do). 04553 */ 04554 pattern = (char *) ignorepat->pattern; 04555 strcpy(pattern, value); 04556 ignorepat->next = NULL; 04557 ignorepat->registrar = registrar; 04558 ast_mutex_lock(&con->lock); 04559 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04560 ignorepatl = ignorepatc; 04561 if (!strcasecmp(ignorepatc->pattern, value)) { 04562 /* Already there */ 04563 ast_mutex_unlock(&con->lock); 04564 errno = EEXIST; 04565 return -1; 04566 } 04567 } 04568 if (ignorepatl) 04569 ignorepatl->next = ignorepat; 04570 else 04571 con->ignorepats = ignorepat; 04572 ast_mutex_unlock(&con->lock); 04573 return 0; 04574 04575 }
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 4080 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().
04081 { 04082 int ret = -1; 04083 struct ast_context *c = find_context_locked(context); 04084 04085 if (c) { 04086 ret = ast_context_add_include2(c, include, registrar); 04087 ast_unlock_contexts(); 04088 } 04089 return ret; 04090 }
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 4342 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().
04344 { 04345 struct ast_include *new_include; 04346 char *c; 04347 struct ast_include *i, *il = NULL; /* include, include_last */ 04348 int length; 04349 char *p; 04350 04351 length = sizeof(struct ast_include); 04352 length += 2 * (strlen(value) + 1); 04353 04354 /* allocate new include structure ... */ 04355 if (!(new_include = ast_calloc(1, length))) 04356 return -1; 04357 /* Fill in this structure. Use 'p' for assignments, as the fields 04358 * in the structure are 'const char *' 04359 */ 04360 p = new_include->stuff; 04361 new_include->name = p; 04362 strcpy(p, value); 04363 p += strlen(value) + 1; 04364 new_include->rname = p; 04365 strcpy(p, value); 04366 /* Strip off timing info, and process if it is there */ 04367 if ( (c = strchr(p, '|')) ) { 04368 *c++ = '\0'; 04369 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04370 } 04371 new_include->next = NULL; 04372 new_include->registrar = registrar; 04373 04374 ast_mutex_lock(&con->lock); 04375 04376 /* ... go to last include and check if context is already included too... */ 04377 for (i = con->includes; i; i = i->next) { 04378 if (!strcasecmp(i->name, new_include->name)) { 04379 free(new_include); 04380 ast_mutex_unlock(&con->lock); 04381 errno = EEXIST; 04382 return -1; 04383 } 04384 il = i; 04385 } 04386 04387 /* ... include new context into context list, unlock, return */ 04388 if (il) 04389 il->next = new_include; 04390 else 04391 con->includes = new_include; 04392 if (option_verbose > 2) 04393 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04394 ast_mutex_unlock(&con->lock); 04395 04396 return 0; 04397 }
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 4404 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04405 { 04406 int ret = -1; 04407 struct ast_context *c = find_context_locked(context); 04408 04409 if (c) { /* found, add switch to this context */ 04410 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04411 ast_unlock_contexts(); 04412 } 04413 return ret; 04414 }
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 4423 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().
04425 { 04426 struct ast_sw *new_sw; 04427 struct ast_sw *i; 04428 int length; 04429 char *p; 04430 04431 length = sizeof(struct ast_sw); 04432 length += strlen(value) + 1; 04433 if (data) 04434 length += strlen(data); 04435 length++; 04436 04437 /* allocate new sw structure ... */ 04438 if (!(new_sw = ast_calloc(1, length))) 04439 return -1; 04440 /* ... fill in this structure ... */ 04441 p = new_sw->stuff; 04442 new_sw->name = p; 04443 strcpy(new_sw->name, value); 04444 p += strlen(value) + 1; 04445 new_sw->data = p; 04446 if (data) { 04447 strcpy(new_sw->data, data); 04448 p += strlen(data) + 1; 04449 } else { 04450 strcpy(new_sw->data, ""); 04451 p++; 04452 } 04453 new_sw->eval = eval; 04454 new_sw->registrar = registrar; 04455 04456 /* ... try to lock this context ... */ 04457 ast_mutex_lock(&con->lock); 04458 04459 /* ... go to last sw and check if context is already swd too... */ 04460 AST_LIST_TRAVERSE(&con->alts, i, list) { 04461 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04462 free(new_sw); 04463 ast_mutex_unlock(&con->lock); 04464 errno = EEXIST; 04465 return -1; 04466 } 04467 } 04468 04469 /* ... sw new context into context list, unlock, return */ 04470 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04471 04472 if (option_verbose > 2) 04473 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04474 04475 ast_mutex_unlock(&con->lock); 04476 04477 return 0; 04478 }
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 3950 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03951 { 03952 return __ast_context_create(extcontexts, name, registrar, 0); 03953 }
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 5392 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().
05393 { 05394 ast_wrlock_contexts(); 05395 __ast_context_destroy(con,registrar); 05396 ast_unlock_contexts(); 05397 }
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 3955 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03956 { 03957 return __ast_context_create(extcontexts, name, registrar, 1); 03958 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2917 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().
02918 { 02919 struct ast_context *c = NULL; 02920 int ret = -1; 02921 02922 ast_rdlock_contexts(); 02923 02924 while ((c = ast_walk_contexts(c))) { 02925 if (!strcmp(ast_get_context_name(c), context)) { 02926 ret = 0; 02927 break; 02928 } 02929 } 02930 02931 ast_unlock_contexts(); 02932 02933 /* if we found context, lock macrolock */ 02934 if (ret == 0) 02935 ret = ast_mutex_lock(&c->macrolock); 02936 02937 return ret; 02938 }
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 2818 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02819 { 02820 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02821 }
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 2845 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02846 { 02847 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02848 }
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 2823 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().
02824 { 02825 int ret = -1; /* default error return */ 02826 struct ast_context *c = find_context_locked(context); 02827 02828 if (c) { /* ... remove extension ... */ 02829 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02830 ast_unlock_contexts(); 02831 } 02832 return ret; 02833 }
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 2850 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().
02851 { 02852 struct ast_exten *exten, *prev_exten = NULL; 02853 struct ast_exten *peer; 02854 struct ast_exten *previous_peer = NULL; 02855 struct ast_exten *next_peer = NULL; 02856 int found = 0; 02857 02858 ast_mutex_lock(&con->lock); 02859 02860 /* scan the extension list to find first matching extension-registrar */ 02861 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02862 if (!strcmp(exten->exten, extension) && 02863 (!registrar || !strcmp(exten->registrar, registrar))) 02864 break; 02865 } 02866 if (!exten) { 02867 /* we can't find right extension */ 02868 ast_mutex_unlock(&con->lock); 02869 return -1; 02870 } 02871 02872 /* scan the priority list to remove extension with exten->priority == priority */ 02873 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02874 peer && !strcmp(peer->exten, extension); 02875 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02876 if ((priority == 0 || peer->priority == priority) && 02877 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02878 (!registrar || !strcmp(peer->registrar, registrar) )) { 02879 found = 1; 02880 02881 /* we are first priority extension? */ 02882 if (!previous_peer) { 02883 /* 02884 * We are first in the priority chain, so must update the extension chain. 02885 * The next node is either the next priority or the next extension 02886 */ 02887 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02888 02889 if (!prev_exten) { /* change the root... */ 02890 con->root = next_node; 02891 } else { 02892 prev_exten->next = next_node; /* unlink */ 02893 } 02894 if (peer->peer) { /* update the new head of the pri list */ 02895 peer->peer->next = peer->next; 02896 } 02897 } else { /* easy, we are not first priority in extension */ 02898 previous_peer->peer = peer->peer; 02899 } 02900 02901 /* now, free whole priority extension */ 02902 destroy_exten(peer); 02903 } else { 02904 previous_peer = peer; 02905 } 02906 } 02907 ast_mutex_unlock(&con->lock); 02908 return found ? 0 : -1; 02909 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4484 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().
04485 { 04486 int ret = -1; 04487 struct ast_context *c = find_context_locked(context); 04488 04489 if (c) { 04490 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04491 ast_unlock_contexts(); 04492 } 04493 return ret; 04494 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4496 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().
04497 { 04498 struct ast_ignorepat *ip, *ipl = NULL; 04499 04500 ast_mutex_lock(&con->lock); 04501 04502 for (ip = con->ignorepats; ip; ip = ip->next) { 04503 if (!strcmp(ip->pattern, ignorepat) && 04504 (!registrar || (registrar == ip->registrar))) { 04505 if (ipl) { 04506 ipl->next = ip->next; 04507 free(ip); 04508 } else { 04509 con->ignorepats = ip->next; 04510 free(ip); 04511 } 04512 ast_mutex_unlock(&con->lock); 04513 return 0; 04514 } 04515 ipl = ip; 04516 } 04517 04518 ast_mutex_unlock(&con->lock); 04519 errno = EINVAL; 04520 return -1; 04521 }
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 2714 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().
02715 { 02716 int ret = -1; 02717 struct ast_context *c = find_context_locked(context); 02718 02719 if (c) { 02720 /* found, remove include from this context ... */ 02721 ret = ast_context_remove_include2(c, include, registrar); 02722 ast_unlock_contexts(); 02723 } 02724 return ret; 02725 }
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 2735 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().
02736 { 02737 struct ast_include *i, *pi = NULL; 02738 int ret = -1; 02739 02740 ast_mutex_lock(&con->lock); 02741 02742 /* find our include */ 02743 for (i = con->includes; i; pi = i, i = i->next) { 02744 if (!strcmp(i->name, include) && 02745 (!registrar || !strcmp(i->registrar, registrar))) { 02746 /* remove from list */ 02747 if (pi) 02748 pi->next = i->next; 02749 else 02750 con->includes = i->next; 02751 /* free include and return */ 02752 free(i); 02753 ret = 0; 02754 break; 02755 } 02756 } 02757 02758 ast_mutex_unlock(&con->lock); 02759 return ret; 02760 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2767 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02768 { 02769 int ret = -1; /* default error return */ 02770 struct ast_context *c = find_context_locked(context); 02771 02772 if (c) { 02773 /* remove switch from this context ... */ 02774 ret = ast_context_remove_switch2(c, sw, data, registrar); 02775 ast_unlock_contexts(); 02776 } 02777 return ret; 02778 }
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 2788 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().
02789 { 02790 struct ast_sw *i; 02791 int ret = -1; 02792 02793 ast_mutex_lock(&con->lock); 02794 02795 /* walk switches */ 02796 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02797 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02798 (!registrar || !strcmp(i->registrar, registrar))) { 02799 /* found, remove from list */ 02800 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02801 free(i); /* free switch and return */ 02802 ret = 0; 02803 break; 02804 } 02805 } 02806 AST_LIST_TRAVERSE_SAFE_END 02807 02808 ast_mutex_unlock(&con->lock); 02809 02810 return ret; 02811 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2945 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().
02946 { 02947 struct ast_context *c = NULL; 02948 int ret = -1; 02949 02950 ast_rdlock_contexts(); 02951 02952 while ((c = ast_walk_contexts(c))) { 02953 if (!strcmp(ast_get_context_name(c), context)) { 02954 ret = 0; 02955 break; 02956 } 02957 } 02958 02959 ast_unlock_contexts(); 02960 02961 /* if we found context, unlock macrolock */ 02962 if (ret == 0) 02963 ret = ast_mutex_unlock(&c->macrolock); 02964 02965 return ret; 02966 }
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 6462 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().
06463 { 06464 struct ast_include *inc = NULL; 06465 int res = 0; 06466 06467 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06468 if (ast_context_find(inc->rname)) 06469 continue; 06470 06471 res = -1; 06472 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06473 ast_get_context_name(con), inc->rname); 06474 break; 06475 } 06476 06477 return res; 06478 }
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 }
enum ast_extension_states ast_devstate_to_extenstate | ( | enum ast_device_state | devstate | ) |
Map devstate to an extension state.
[in] | device | state |
Definition at line 1943 of file pbx.c.
References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_TOTAL, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_RINGING, and AST_EXTENSION_UNAVAILABLE.
Referenced by ast_extension_state2().
01944 { 01945 switch (devstate) { 01946 case AST_DEVICE_ONHOLD: 01947 return AST_EXTENSION_ONHOLD; 01948 case AST_DEVICE_BUSY: 01949 return AST_EXTENSION_BUSY; 01950 case AST_DEVICE_UNAVAILABLE: 01951 case AST_DEVICE_UNKNOWN: 01952 case AST_DEVICE_INVALID: 01953 return AST_EXTENSION_UNAVAILABLE; 01954 case AST_DEVICE_RINGINUSE: 01955 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 01956 case AST_DEVICE_RINGING: 01957 return AST_EXTENSION_RINGING; 01958 case AST_DEVICE_INUSE: 01959 return AST_EXTENSION_INUSE; 01960 case AST_DEVICE_NOT_INUSE: 01961 return AST_EXTENSION_NOT_INUSE; 01962 case AST_DEVICE_TOTAL: /* not a device state, included for completeness */ 01963 break; 01964 } 01965 01966 return AST_EXTENSION_NOT_INUSE; 01967 }
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 2282 of file pbx.c.
References E_MATCH, and pbx_extension_helper().
Referenced by __ast_goto_if_exists(), __ast_pbx_run(), __login_exec(), _macro_exec(), agentmonitoroutgoing_exec(), answer_call(), ast_app_dtget(), ast_bridge_call(), ast_pbx_outgoing_exten(), builtin_blindtransfer(), cb_events(), conf_run(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmfup(), disa_exec(), do_atxfer(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), handle_stimulus_message(), leave_voicemail(), local_alloc(), local_call(), local_devicestate(), local_dtmf_helper(), loopback_exists(), metermaidstate(), mgcp_ss(), misdn_overlap_dial_task(), park_space_reserve(), parkandannounce_exec(), pbx_builtin_waitexten(), phone_check_exception(), pri_dchannel(), process_ast_dsp(), register_peer_exten(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().
02283 { 02284 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02285 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4611 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().
04612 { 04613 if (!chan) 04614 return -1; 04615 04616 ast_channel_lock(chan); 04617 04618 if (!ast_strlen_zero(context)) 04619 ast_copy_string(chan->context, context, sizeof(chan->context)); 04620 if (!ast_strlen_zero(exten)) 04621 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04622 if (priority > -1) { 04623 chan->priority = priority; 04624 /* see flag description in channel.h for explanation */ 04625 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04626 chan->priority--; 04627 } 04628 04629 ast_channel_unlock(chan); 04630 04631 return 0; 04632 }
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 2004 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
02005 { 02006 struct ast_exten *e; 02007 02008 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 02009 if (!e) 02010 return -1; /* No hint, return -1 */ 02011 02012 return ast_extension_state2(e); /* Check all devices in the hint */ 02013 }
static int ast_extension_state2 | ( | struct ast_exten * | e | ) | [static] |
ast_extensions_state2: Check state of extension by using hints
Definition at line 1970 of file pbx.c.
References ast_copy_string(), ast_device_state(), ast_devstate_aggregate_add(), ast_devstate_aggregate_init(), ast_devstate_aggregate_result(), ast_devstate_to_extenstate(), ast_get_extension_app(), and AST_MAX_EXTENSION.
Referenced by ast_add_hint(), ast_extension_state(), and ast_hint_state_changed().
01971 { 01972 char hint[AST_MAX_EXTENSION]; 01973 char *cur, *rest; 01974 struct ast_devstate_aggregate agg; 01975 01976 ast_devstate_aggregate_init(&agg); 01977 01978 if (!e) 01979 return -1; 01980 01981 ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint)); 01982 01983 rest = hint; /* One or more devices separated with a & character */ 01984 while ( (cur = strsep(&rest, "&")) ) { 01985 int res = ast_device_state(cur); 01986 ast_devstate_aggregate_add(&agg, res); 01987 } 01988 return ast_devstate_to_extenstate(ast_devstate_aggregate_result(&agg)); 01989 }
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 1992 of file pbx.c.
References extension_states.
Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
01993 { 01994 int i; 01995 01996 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01997 if (extension_states[i].extension_state == extension_state) 01998 return extension_states[i].text; 01999 } 02000 return "Unknown"; 02001 }
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 2061 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().
02063 { 02064 struct ast_hint *hint; 02065 struct ast_state_cb *cblist; 02066 struct ast_exten *e; 02067 02068 /* If there's no context and extension: add callback to statecbs list */ 02069 if (!context && !exten) { 02070 AST_LIST_LOCK(&hints); 02071 02072 for (cblist = statecbs; cblist; cblist = cblist->next) { 02073 if (cblist->callback == callback) { 02074 cblist->data = data; 02075 AST_LIST_UNLOCK(&hints); 02076 return 0; 02077 } 02078 } 02079 02080 /* Now insert the callback */ 02081 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02082 AST_LIST_UNLOCK(&hints); 02083 return -1; 02084 } 02085 cblist->id = 0; 02086 cblist->callback = callback; 02087 cblist->data = data; 02088 02089 cblist->next = statecbs; 02090 statecbs = cblist; 02091 02092 AST_LIST_UNLOCK(&hints); 02093 return 0; 02094 } 02095 02096 if (!context || !exten) 02097 return -1; 02098 02099 /* This callback type is for only one hint, so get the hint */ 02100 e = ast_hint_extension(NULL, context, exten); 02101 if (!e) { 02102 return -1; 02103 } 02104 02105 /* Find the hint in the list of hints */ 02106 AST_LIST_LOCK(&hints); 02107 02108 AST_LIST_TRAVERSE(&hints, hint, list) { 02109 if (hint->exten == e) 02110 break; 02111 } 02112 02113 if (!hint) { 02114 /* We have no hint, sorry */ 02115 AST_LIST_UNLOCK(&hints); 02116 return -1; 02117 } 02118 02119 /* Now insert the callback in the callback list */ 02120 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02121 AST_LIST_UNLOCK(&hints); 02122 return -1; 02123 } 02124 cblist->id = stateid++; /* Unique ID for this callback */ 02125 cblist->callback = callback; /* Pointer to callback routine */ 02126 cblist->data = data; /* Data for the callback */ 02127 02128 cblist->next = hint->callbacks; 02129 hint->callbacks = cblist; 02130 02131 AST_LIST_UNLOCK(&hints); 02132 return cblist->id; 02133 }
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 2136 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().
02137 { 02138 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02139 int ret = -1; 02140 02141 if (!id && !callback) 02142 return -1; 02143 02144 AST_LIST_LOCK(&hints); 02145 02146 if (!id) { /* id == 0 is a callback without extension */ 02147 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02148 if ((*p_cur)->callback == callback) 02149 break; 02150 } 02151 } else { /* callback with extension, find the callback based on ID */ 02152 struct ast_hint *hint; 02153 AST_LIST_TRAVERSE(&hints, hint, list) { 02154 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02155 if ((*p_cur)->id == id) 02156 break; 02157 } 02158 if (*p_cur) /* found in the inner loop */ 02159 break; 02160 } 02161 } 02162 if (p_cur && *p_cur) { 02163 struct ast_state_cb *cur = *p_cur; 02164 *p_cur = cur->next; 02165 free(cur); 02166 ret = 0; 02167 } 02168 AST_LIST_UNLOCK(&hints); 02169 return ret; 02170 }
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 2287 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().
02288 { 02289 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02290 }
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 2292 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02293 { 02294 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02295 }
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 6319 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().
06320 { 06321 return con ? con->name : NULL; 06322 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6357 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06358 { 06359 return c ? c->registrar : NULL; 06360 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6387 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().
06388 { 06389 return e ? e->app : NULL; 06390 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6392 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06393 { 06394 return e ? e->data : NULL; 06395 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6382 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().
06383 { 06384 return e ? e->cidmatch : NULL; 06385 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | exten | ) |
Definition at line 6334 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 6377 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().
06378 { 06379 return e ? e->matchcid : 0; 06380 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6329 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 6349 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 6362 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06363 { 06364 return e ? e->registrar : NULL; 06365 }
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 2265 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().
02266 { 02267 struct ast_exten *e = ast_hint_extension(c, context, exten); 02268 02269 if (e) { 02270 if (hint) 02271 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02272 if (name) { 02273 const char *tmp = ast_get_extension_app_data(e); 02274 if (tmp) 02275 ast_copy_string(name, tmp, namesize); 02276 } 02277 return -1; 02278 } 02279 return 0; 02280 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6344 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().
06345 { 06346 return ip ? ip->pattern : NULL; 06347 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6372 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06373 { 06374 return ip ? ip->registrar : NULL; 06375 }
const char* ast_get_include_name | ( | struct ast_include * | inc | ) |
Definition at line 6339 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().
06340 { 06341 return inc ? inc->name : NULL; 06342 }
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6367 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06368 { 06369 return i ? i->registrar : NULL; 06370 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6402 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06403 { 06404 return sw ? sw->data : NULL; 06405 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6397 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06398 { 06399 return sw ? sw->name : NULL; 06400 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6407 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06408 { 06409 return sw ? sw->registrar : NULL; 06410 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6500 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().
06501 { 06502 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06503 }
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 1931 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().
01932 { 01933 struct ast_exten *e; 01934 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */ 01935 01936 ast_rdlock_contexts(); 01937 e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH); 01938 ast_unlock_contexts(); 01939 01940 return e; 01941 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 2015 of file pbx.c.
References ast_copy_string(), ast_extension_state2(), ast_get_extension_app(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_MAX_EXTENSION, ast_rdlock_contexts(), ast_unlock_contexts(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_exten::exten, ast_hint::laststate, ast_sw::list, ast_context::name, ast_state_cb::next, ast_exten::parent, parse(), and statecbs.
Referenced by do_state_change().
02016 { 02017 struct ast_hint *hint; 02018 02019 ast_rdlock_contexts(); 02020 AST_LIST_LOCK(&hints); 02021 02022 AST_LIST_TRAVERSE(&hints, hint, list) { 02023 struct ast_state_cb *cblist; 02024 char buf[AST_MAX_EXTENSION]; 02025 char *parse = buf; 02026 char *cur; 02027 int state; 02028 02029 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02030 while ( (cur = strsep(&parse, "&")) ) { 02031 if (!strcasecmp(cur, device)) 02032 break; 02033 } 02034 if (!cur) 02035 continue; 02036 02037 /* Get device state for this hint */ 02038 state = ast_extension_state2(hint->exten); 02039 02040 if ((state == -1) || (state == hint->laststate)) 02041 continue; 02042 02043 /* Device state changed since last check - notify the watchers */ 02044 02045 /* For general callbacks */ 02046 for (cblist = statecbs; cblist; cblist = cblist->next) 02047 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02048 02049 /* For extension callbacks */ 02050 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02051 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02052 02053 hint->laststate = state; /* record we saw the change */ 02054 } 02055 02056 AST_LIST_UNLOCK(&hints); 02057 ast_unlock_contexts(); 02058 }
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 4577 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().
04578 { 04579 struct ast_context *con = ast_context_find(context); 04580 if (con) { 04581 struct ast_ignorepat *pat; 04582 for (pat = con->ignorepats; pat; pat = pat->next) { 04583 if (ast_extension_match(pat->pattern, pattern)) 04584 return 1; 04585 } 04586 } 04587 04588 return 0; 04589 }
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 6306 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().
06307 { 06308 return ast_mutex_lock(&con->lock); 06309 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6283 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by find_matching_endwhile().
06284 { 06285 return ast_rwlock_wrlock(&conlock); 06286 }
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 2302 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(), pbx_builtin_background(), skinny_ss(), and ss_thread().
02303 { 02304 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02305 }
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 3973 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, ast_hint::exten, ast_exten::exten, store_hint::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().
03974 { 03975 struct ast_context *tmp, *lasttmp = NULL; 03976 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03977 struct store_hint *this; 03978 struct ast_hint *hint; 03979 struct ast_exten *exten; 03980 int length; 03981 struct ast_state_cb *thiscb, *prevcb; 03982 03983 /* it is very important that this function hold the hint list lock _and_ the conlock 03984 during its operation; not only do we need to ensure that the list of contexts 03985 and extensions does not change, but also that no hint callbacks (watchers) are 03986 added or removed during the merge/delete process 03987 03988 in addition, the locks _must_ be taken in this order, because there are already 03989 other code paths that use this order 03990 */ 03991 ast_wrlock_contexts(); 03992 AST_LIST_LOCK(&hints); 03993 03994 /* preserve all watchers for hints associated with this registrar */ 03995 AST_LIST_TRAVERSE(&hints, hint, list) { 03996 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03997 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03998 if (!(this = ast_calloc(1, length))) 03999 continue; 04000 this->callbacks = hint->callbacks; 04001 hint->callbacks = NULL; 04002 this->laststate = hint->laststate; 04003 this->context = this->data; 04004 strcpy(this->data, hint->exten->parent->name); 04005 this->exten = this->data + strlen(this->context) + 1; 04006 strcpy(this->exten, hint->exten->exten); 04007 AST_LIST_INSERT_HEAD(&store, this, list); 04008 } 04009 } 04010 04011 tmp = *extcontexts; 04012 if (registrar) { 04013 /* XXX remove previous contexts from same registrar */ 04014 if (option_debug) 04015 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 04016 __ast_context_destroy(NULL,registrar); 04017 while (tmp) { 04018 lasttmp = tmp; 04019 tmp = tmp->next; 04020 } 04021 } else { 04022 /* XXX remove contexts with the same name */ 04023 while (tmp) { 04024 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04025 __ast_context_destroy(tmp,tmp->registrar); 04026 lasttmp = tmp; 04027 tmp = tmp->next; 04028 } 04029 } 04030 if (lasttmp) { 04031 lasttmp->next = contexts; 04032 contexts = *extcontexts; 04033 *extcontexts = NULL; 04034 } else 04035 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04036 04037 /* restore the watchers for hints that can be found; notify those that 04038 cannot be restored 04039 */ 04040 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04041 struct pbx_find_info q = { .stacklen = 0 }; 04042 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04043 /* Find the hint in the list of hints */ 04044 AST_LIST_TRAVERSE(&hints, hint, list) { 04045 if (hint->exten == exten) 04046 break; 04047 } 04048 if (!exten || !hint) { 04049 /* this hint has been removed, notify the watchers */ 04050 prevcb = NULL; 04051 thiscb = this->callbacks; 04052 while (thiscb) { 04053 prevcb = thiscb; 04054 thiscb = thiscb->next; 04055 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04056 free(prevcb); 04057 } 04058 } else { 04059 thiscb = this->callbacks; 04060 while (thiscb->next) 04061 thiscb = thiscb->next; 04062 thiscb->next = hint->callbacks; 04063 hint->callbacks = this->callbacks; 04064 hint->laststate = this->laststate; 04065 } 04066 free(this); 04067 } 04068 04069 AST_LIST_UNLOCK(&hints); 04070 ast_unlock_contexts(); 04071 04072 return; 04073 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6510 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, 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().
06511 { 06512 char *exten, *pri, *context; 06513 char *stringp; 06514 int ipri; 06515 int mode = 0; 06516 06517 if (ast_strlen_zero(goto_string)) { 06518 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06519 return -1; 06520 } 06521 stringp = ast_strdupa(goto_string); 06522 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06523 exten = strsep(&stringp, "|"); 06524 pri = strsep(&stringp, "|"); 06525 if (!exten) { /* Only a priority in this one */ 06526 pri = context; 06527 exten = NULL; 06528 context = NULL; 06529 } else if (!pri) { /* Only an extension and priority in this one */ 06530 pri = exten; 06531 exten = context; 06532 context = NULL; 06533 } 06534 if (*pri == '+') { 06535 mode = 1; 06536 pri++; 06537 } else if (*pri == '-') { 06538 mode = -1; 06539 pri++; 06540 } 06541 if (sscanf(pri, "%30d", &ipri) != 1) { 06542 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06543 pri, chan->cid.cid_num)) < 1) { 06544 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06545 return -1; 06546 } else 06547 mode = 0; 06548 } 06549 /* At this point we have a priority and maybe an extension and a context */ 06550 06551 if (mode) 06552 ipri = chan->priority + (ipri * mode); 06553 06554 ast_explicit_goto(chan, context, exten, ipri); 06555 return 0; 06556 06557 }
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 5204 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().
05205 { 05206 struct ast_channel *chan; 05207 struct app_tmp *tmp; 05208 int res = -1, cdr_res = -1; 05209 struct outgoing_helper oh; 05210 pthread_attr_t attr; 05211 05212 memset(&oh, 0, sizeof(oh)); 05213 oh.vars = vars; 05214 oh.account = account; 05215 05216 if (locked_channel) 05217 *locked_channel = NULL; 05218 if (ast_strlen_zero(app)) { 05219 res = -1; 05220 goto outgoing_app_cleanup; 05221 } 05222 if (sync) { 05223 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05224 if (chan) { 05225 ast_set_variables(chan, vars); 05226 if (account) 05227 ast_cdr_setaccount(chan, account); 05228 if (chan->_state == AST_STATE_UP) { 05229 res = 0; 05230 if (option_verbose > 3) 05231 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05232 tmp = ast_calloc(1, sizeof(*tmp)); 05233 if (!tmp) 05234 res = -1; 05235 else { 05236 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05237 if (appdata) 05238 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05239 tmp->chan = chan; 05240 if (sync > 1) { 05241 if (locked_channel) 05242 ast_channel_unlock(chan); 05243 ast_pbx_run_app(tmp); 05244 } else { 05245 pthread_attr_init(&attr); 05246 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05247 if (locked_channel) 05248 ast_channel_lock(chan); 05249 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05250 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05251 free(tmp); 05252 if (locked_channel) 05253 ast_channel_unlock(chan); 05254 ast_hangup(chan); 05255 res = -1; 05256 } else { 05257 if (locked_channel) 05258 *locked_channel = chan; 05259 } 05260 pthread_attr_destroy(&attr); 05261 } 05262 } 05263 } else { 05264 if (option_verbose > 3) 05265 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05266 if (chan->cdr) { /* update the cdr */ 05267 /* here we update the status of the call, which sould be busy. 05268 * if that fails then we set the status to failed */ 05269 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05270 ast_cdr_failed(chan->cdr); 05271 } 05272 ast_hangup(chan); 05273 } 05274 } 05275 05276 if (res < 0) { /* the call failed for some reason */ 05277 if (*reason == 0) { /* if the call failed (not busy or no answer) 05278 * update the cdr with the failed message */ 05279 cdr_res = ast_pbx_outgoing_cdr_failed(); 05280 if (cdr_res != 0) { 05281 res = cdr_res; 05282 goto outgoing_app_cleanup; 05283 } 05284 } 05285 } 05286 05287 } else { 05288 struct async_stat *as; 05289 if (!(as = ast_calloc(1, sizeof(*as)))) { 05290 res = -1; 05291 goto outgoing_app_cleanup; 05292 } 05293 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05294 if (!chan) { 05295 free(as); 05296 res = -1; 05297 goto outgoing_app_cleanup; 05298 } 05299 as->chan = chan; 05300 ast_copy_string(as->app, app, sizeof(as->app)); 05301 if (appdata) 05302 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05303 as->timeout = timeout; 05304 ast_set_variables(chan, vars); 05305 if (account) 05306 ast_cdr_setaccount(chan, account); 05307 /* Start a new thread, and get something handling this channel. */ 05308 pthread_attr_init(&attr); 05309 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05310 if (locked_channel) 05311 ast_channel_lock(chan); 05312 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05313 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05314 free(as); 05315 if (locked_channel) 05316 ast_channel_unlock(chan); 05317 ast_hangup(chan); 05318 res = -1; 05319 pthread_attr_destroy(&attr); 05320 goto outgoing_app_cleanup; 05321 } else { 05322 if (locked_channel) 05323 *locked_channel = chan; 05324 } 05325 pthread_attr_destroy(&attr); 05326 res = 0; 05327 } 05328 outgoing_app_cleanup: 05329 ast_variables_destroy(vars); 05330 return res; 05331 }
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 5012 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().
05013 { 05014 /* allocate a channel */ 05015 struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", ""); 05016 05017 if (!chan) 05018 return -1; /* failure */ 05019 05020 if (!chan->cdr) { 05021 /* allocation of the cdr failed */ 05022 ast_channel_free(chan); /* free the channel */ 05023 return -1; /* return failure */ 05024 } 05025 05026 /* allocation of the cdr was successful */ 05027 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05028 ast_cdr_start(chan->cdr); /* record the start and stop time */ 05029 ast_cdr_end(chan->cdr); 05030 ast_cdr_failed(chan->cdr); /* set the status to failed */ 05031 ast_cdr_detach(chan->cdr); /* post and free the record */ 05032 chan->cdr = NULL; 05033 ast_channel_free(chan); /* free the channel */ 05034 05035 return 0; /* success */ 05036 }
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 5038 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().
05039 { 05040 struct ast_channel *chan; 05041 struct async_stat *as; 05042 int res = -1, cdr_res = -1; 05043 struct outgoing_helper oh; 05044 pthread_attr_t attr; 05045 05046 if (sync) { 05047 LOAD_OH(oh); 05048 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05049 if (channel) { 05050 *channel = chan; 05051 if (chan) 05052 ast_channel_lock(chan); 05053 } 05054 if (chan) { 05055 if (chan->_state == AST_STATE_UP) { 05056 res = 0; 05057 if (option_verbose > 3) 05058 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05059 05060 if (sync > 1) { 05061 if (channel) 05062 ast_channel_unlock(chan); 05063 if (ast_pbx_run(chan)) { 05064 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05065 if (channel) 05066 *channel = NULL; 05067 ast_hangup(chan); 05068 chan = NULL; 05069 res = -1; 05070 } 05071 } else { 05072 if (ast_pbx_start(chan)) { 05073 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05074 if (channel) { 05075 *channel = NULL; 05076 ast_channel_unlock(chan); 05077 } 05078 ast_hangup(chan); 05079 res = -1; 05080 } 05081 chan = NULL; 05082 } 05083 } else { 05084 if (option_verbose > 3) 05085 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05086 05087 if (chan->cdr) { /* update the cdr */ 05088 /* here we update the status of the call, which sould be busy. 05089 * if that fails then we set the status to failed */ 05090 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05091 ast_cdr_failed(chan->cdr); 05092 } 05093 05094 if (channel) { 05095 *channel = NULL; 05096 ast_channel_unlock(chan); 05097 } 05098 ast_hangup(chan); 05099 chan = NULL; 05100 } 05101 } 05102 05103 if (res < 0) { /* the call failed for some reason */ 05104 if (*reason == 0) { /* if the call failed (not busy or no answer) 05105 * update the cdr with the failed message */ 05106 cdr_res = ast_pbx_outgoing_cdr_failed(); 05107 if (cdr_res != 0) { 05108 res = cdr_res; 05109 goto outgoing_exten_cleanup; 05110 } 05111 } 05112 05113 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05114 /* check if "failed" exists */ 05115 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05116 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05117 if (chan) { 05118 char failed_reason[4] = ""; 05119 if (!ast_strlen_zero(context)) 05120 ast_copy_string(chan->context, context, sizeof(chan->context)); 05121 set_ext_pri(chan, "failed", 1); 05122 ast_set_variables(chan, vars); 05123 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05124 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05125 if (account) 05126 ast_cdr_setaccount(chan, account); 05127 if (ast_pbx_run(chan)) { 05128 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05129 ast_hangup(chan); 05130 } 05131 chan = NULL; 05132 } 05133 } 05134 } 05135 } else { 05136 if (!(as = ast_calloc(1, sizeof(*as)))) { 05137 res = -1; 05138 goto outgoing_exten_cleanup; 05139 } 05140 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05141 if (channel) { 05142 *channel = chan; 05143 if (chan) 05144 ast_channel_lock(chan); 05145 } 05146 if (!chan) { 05147 free(as); 05148 res = -1; 05149 goto outgoing_exten_cleanup; 05150 } 05151 as->chan = chan; 05152 ast_copy_string(as->context, context, sizeof(as->context)); 05153 set_ext_pri(as->chan, exten, priority); 05154 as->timeout = timeout; 05155 ast_set_variables(chan, vars); 05156 if (account) 05157 ast_cdr_setaccount(chan, account); 05158 pthread_attr_init(&attr); 05159 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05160 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05161 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05162 free(as); 05163 if (channel) { 05164 *channel = NULL; 05165 ast_channel_unlock(chan); 05166 } 05167 ast_hangup(chan); 05168 res = -1; 05169 pthread_attr_destroy(&attr); 05170 goto outgoing_exten_cleanup; 05171 } 05172 pthread_attr_destroy(&attr); 05173 res = 0; 05174 } 05175 outgoing_exten_cleanup: 05176 ast_variables_destroy(vars); 05177 return res; 05178 }
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 2662 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().
02663 { 02664 enum ast_pbx_result res = AST_PBX_SUCCESS; 02665 02666 if (increase_call_count(c)) 02667 return AST_PBX_CALL_LIMIT; 02668 02669 res = __ast_pbx_run(c); 02670 decrease_call_count(); 02671 02672 return res; 02673 }
static void* ast_pbx_run_app | ( | void * | data | ) | [static] |
run the application and free the descriptor once done
Definition at line 5188 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().
05189 { 05190 struct app_tmp *tmp = data; 05191 struct ast_app *app; 05192 app = pbx_findapp(tmp->app); 05193 if (app) { 05194 if (option_verbose > 3) 05195 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05196 pbx_exec(tmp->chan, app, tmp->data); 05197 } else 05198 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05199 ast_hangup(tmp->chan); 05200 free(tmp); 05201 return NULL; 05202 }
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 2635 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().
02636 { 02637 pthread_t t; 02638 pthread_attr_t attr; 02639 02640 if (!c) { 02641 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02642 return AST_PBX_FAILED; 02643 } 02644 02645 if (increase_call_count(c)) 02646 return AST_PBX_CALL_LIMIT; 02647 02648 /* Start a new thread, and get something handling this channel. */ 02649 pthread_attr_init(&attr); 02650 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02651 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02652 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02653 pthread_attr_destroy(&attr); 02654 decrease_call_count(); 02655 return AST_PBX_FAILED; 02656 } 02657 pthread_attr_destroy(&attr); 02658 02659 return AST_PBX_SUCCESS; 02660 }
int ast_processed_calls | ( | void | ) |
Retrieve the total number of calls processed through the PBX since last restart.
Definition at line 2680 of file pbx.c.
References totalcalls.
02681 { 02682 return totalcalls; 02683 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6288 of file pbx.c.
References ast_rwlock_rdlock(), and conlock.
Referenced by __ast_context_create(), _macro_exec(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().
06289 { 06290 return ast_rwlock_rdlock(&conlock); 06291 }
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 2969 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().
02970 { 02971 struct ast_app *tmp, *cur = NULL; 02972 char tmps[80]; 02973 int length; 02974 02975 AST_LIST_LOCK(&apps); 02976 AST_LIST_TRAVERSE(&apps, tmp, list) { 02977 if (!strcasecmp(app, tmp->name)) { 02978 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02979 AST_LIST_UNLOCK(&apps); 02980 return -1; 02981 } 02982 } 02983 02984 length = sizeof(*tmp) + strlen(app) + 1; 02985 02986 if (!(tmp = ast_calloc(1, length))) { 02987 AST_LIST_UNLOCK(&apps); 02988 return -1; 02989 } 02990 02991 strcpy(tmp->name, app); 02992 tmp->execute = execute; 02993 tmp->synopsis = synopsis; 02994 tmp->description = description; 02995 02996 /* Store in alphabetical order */ 02997 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 02998 if (strcasecmp(tmp->name, cur->name) < 0) { 02999 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03000 break; 03001 } 03002 } 03003 AST_LIST_TRAVERSE_SAFE_END 03004 if (!cur) 03005 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03006 03007 if (option_verbose > 1) 03008 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03009 03010 AST_LIST_UNLOCK(&apps); 03011 03012 return 0; 03013 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3019 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().
03020 { 03021 struct ast_switch *tmp; 03022 03023 AST_LIST_LOCK(&switches); 03024 AST_LIST_TRAVERSE(&switches, tmp, list) { 03025 if (!strcasecmp(tmp->name, sw->name)) { 03026 AST_LIST_UNLOCK(&switches); 03027 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03028 return -1; 03029 } 03030 } 03031 AST_LIST_INSERT_TAIL(&switches, sw, list); 03032 AST_LIST_UNLOCK(&switches); 03033 03034 return 0; 03035 }
static int ast_remove_hint | ( | struct ast_exten * | e | ) | [static] |
ast_remove_hint: Remove hint from extension
Definition at line 2228 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().
02229 { 02230 /* Cleanup the Notifys if hint is removed */ 02231 struct ast_hint *hint; 02232 struct ast_state_cb *cblist, *cbprev; 02233 int res = -1; 02234 02235 if (!e) 02236 return -1; 02237 02238 AST_LIST_LOCK(&hints); 02239 AST_LIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) { 02240 if (hint->exten == e) { 02241 cbprev = NULL; 02242 cblist = hint->callbacks; 02243 while (cblist) { 02244 /* Notify with -1 and remove all callbacks */ 02245 cbprev = cblist; 02246 cblist = cblist->next; 02247 cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data); 02248 free(cbprev); 02249 } 02250 hint->callbacks = NULL; 02251 AST_LIST_REMOVE_CURRENT(&hints, list); 02252 free(hint); 02253 res = 0; 02254 break; 02255 } 02256 } 02257 AST_LIST_TRAVERSE_SAFE_END 02258 AST_LIST_UNLOCK(&hints); 02259 02260 return res; 02261 }
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 2307 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), and loopback_exec().
02308 { 02309 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02310 }
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 6311 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().
06312 { 06313 return ast_mutex_unlock(&con->lock); 06314 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6298 of file pbx.c.
References ast_rwlock_unlock(), and conlock.
Referenced by __ast_context_create(), _macro_exec(), ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_destroy(), ast_context_find(), ast_context_lockmacro(), ast_context_remove_extension_callerid(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_unlockmacro(), ast_hint_extension(), ast_hint_state_changed(), ast_merge_contexts_and_delete(), complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), complete_context_remove_include(), complete_show_dialplan_context(), dundi_precache_full(), find_context_locked(), find_matching_endwhile(), handle_save_dialplan(), pbx_extension_helper(), and show_dialplan_helper().
06299 { 06300 return ast_rwlock_unlock(&conlock); 06301 }
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 3884 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().
03885 { 03886 struct ast_app *tmp; 03887 03888 AST_LIST_LOCK(&apps); 03889 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03890 if (!strcasecmp(app, tmp->name)) { 03891 AST_LIST_REMOVE_CURRENT(&apps, list); 03892 if (option_verbose > 1) 03893 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03894 free(tmp); 03895 break; 03896 } 03897 } 03898 AST_LIST_TRAVERSE_SAFE_END 03899 AST_LIST_UNLOCK(&apps); 03900 03901 return tmp ? 0 : -1; 03902 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3037 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().
03038 { 03039 AST_LIST_LOCK(&switches); 03040 AST_LIST_REMOVE(&switches, sw, list); 03041 AST_LIST_UNLOCK(&switches); 03042 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | exten | |||
) |
Definition at line 6420 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().
06422 { 06423 if (!exten) 06424 return con ? con->root : NULL; 06425 else 06426 return exten->next; 06427 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6453 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().
06455 { 06456 if (!ip) 06457 return con ? con->ignorepats : NULL; 06458 else 06459 return ip->next; 06460 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6444 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().
06446 { 06447 if (!inc) 06448 return con ? con->includes : NULL; 06449 else 06450 return inc->next; 06451 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6429 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().
06431 { 06432 if (!sw) 06433 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06434 else 06435 return AST_LIST_NEXT(sw, list); 06436 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6415 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 6438 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 6293 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().
06294 { 06295 return ast_rwlock_wrlock(&conlock); 06296 }
static void* async_wait | ( | void * | data | ) | [static] |
Definition at line 4949 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().
04950 { 04951 struct async_stat *as = data; 04952 struct ast_channel *chan = as->chan; 04953 int timeout = as->timeout; 04954 int res; 04955 struct ast_frame *f; 04956 struct ast_app *app; 04957 04958 while (timeout && (chan->_state != AST_STATE_UP)) { 04959 res = ast_waitfor(chan, timeout); 04960 if (res < 1) 04961 break; 04962 if (timeout > -1) 04963 timeout = res; 04964 f = ast_read(chan); 04965 if (!f) 04966 break; 04967 if (f->frametype == AST_FRAME_CONTROL) { 04968 if ((f->subclass == AST_CONTROL_BUSY) || 04969 (f->subclass == AST_CONTROL_CONGESTION) ) { 04970 ast_frfree(f); 04971 break; 04972 } 04973 } 04974 ast_frfree(f); 04975 } 04976 if (chan->_state == AST_STATE_UP) { 04977 if (!ast_strlen_zero(as->app)) { 04978 app = pbx_findapp(as->app); 04979 if (app) { 04980 if (option_verbose > 2) 04981 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 04982 pbx_exec(chan, app, as->appdata); 04983 } else 04984 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 04985 } else { 04986 if (!ast_strlen_zero(as->context)) 04987 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 04988 if (!ast_strlen_zero(as->exten)) 04989 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 04990 if (as->priority > 0) 04991 chan->priority = as->priority; 04992 /* Run the PBX */ 04993 if (ast_pbx_run(chan)) { 04994 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 04995 } else { 04996 /* PBX will have taken care of this */ 04997 chan = NULL; 04998 } 04999 } 05000 } 05001 free(as); 05002 if (chan) 05003 ast_hangup(chan); 05004 return NULL; 05005 }
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 2325 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.
02326 { 02327 int digit; 02328 02329 buf[pos] = '\0'; /* make sure it is properly terminated */ 02330 while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) { 02331 /* As long as we're willing to wait, and as long as it's not defined, 02332 keep reading digits until we can't possibly get a right answer anymore. */ 02333 digit = ast_waitfordigit(c, waittime * 1000); 02334 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02335 c->_softhangup = 0; 02336 } else { 02337 if (!digit) /* No entry */ 02338 break; 02339 if (digit < 0) /* Error, maybe a hangup */ 02340 return -1; 02341 if (pos < buflen - 1) { /* XXX maybe error otherwise ? */ 02342 buf[pos++] = digit; 02343 buf[pos] = '\0'; 02344 } 02345 waittime = c->pbx->dtimeout; 02346 } 02347 } 02348 return 0; 02349 }
static char* complete_show_application | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3102 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::list, ast_app::name, and strdup.
03103 { 03104 struct ast_app *a; 03105 char *ret = NULL; 03106 int which = 0; 03107 int wordlen = strlen(word); 03108 03109 /* return the n-th [partial] matching entry */ 03110 AST_LIST_LOCK(&apps); 03111 AST_LIST_TRAVERSE(&apps, a, list) { 03112 if (!strncasecmp(word, a->name, wordlen) && ++which > state) { 03113 ret = strdup(a->name); 03114 break; 03115 } 03116 } 03117 AST_LIST_UNLOCK(&apps); 03118 03119 return ret; 03120 }
static char* complete_show_applications | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3463 of file pbx.c.
References ast_cli_complete().
03464 { 03465 static char* choices[] = { "like", "describing", NULL }; 03466 03467 return (pos != 3) ? NULL : ast_cli_complete(word, choices, state); 03468 }
static char* complete_show_applications_deprecated | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3456 of file pbx.c.
References ast_cli_complete().
03457 { 03458 static char* choices[] = { "like", "describing", NULL }; 03459 03460 return (pos != 2) ? NULL : ast_cli_complete(word, choices, state); 03461 }
static char* complete_show_dialplan_context | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3473 of file pbx.c.
References ast_get_context_name(), ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), and ast_walk_contexts().
03475 { 03476 struct ast_context *c = NULL; 03477 char *ret = NULL; 03478 int which = 0; 03479 int wordlen; 03480 03481 /* we are do completion of [exten@]context on second position only */ 03482 if (pos != 2) 03483 return NULL; 03484 03485 ast_rdlock_contexts(); 03486 03487 wordlen = strlen(word); 03488 03489 /* walk through all contexts and return the n-th match */ 03490 while ( (c = ast_walk_contexts(c)) ) { 03491 if (!strncasecmp(word, ast_get_context_name(c), wordlen) && ++which > state) { 03492 ret = ast_strdup(ast_get_context_name(c)); 03493 break; 03494 } 03495 } 03496 03497 ast_unlock_contexts(); 03498 03499 return ret; 03500 }
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 2597 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().
02598 { 02599 ast_mutex_lock(&maxcalllock); 02600 if (countcalls > 0) 02601 countcalls--; 02602 ast_mutex_unlock(&maxcalllock); 02603 }
static void destroy_exten | ( | struct ast_exten * | e | ) | [static] |
Definition at line 2605 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().
02606 { 02607 if (e->priority == PRIORITY_HINT) 02608 ast_remove_hint(e); 02609 02610 if (e->datad) 02611 e->datad(e->data); 02612 free(e); 02613 }
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 4701 of file pbx.c.
Referenced by ast_add_extension2().
04702 { 04703 int count=0; 04704 04705 while (*src && (count < len - 1)) { 04706 switch(*src) { 04707 case ' ': 04708 /* otherwise exten => [a-b],1,... doesn't work */ 04709 /* case '-': */ 04710 /* Ignore */ 04711 break; 04712 default: 04713 *dst = *src; 04714 dst++; 04715 } 04716 src++; 04717 count++; 04718 } 04719 *dst = '\0'; 04720 04721 return count; 04722 }
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 2695 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().
02696 { 02697 struct ast_context *c = NULL; 02698 02699 ast_rdlock_contexts(); 02700 while ( (c = ast_walk_contexts(c)) ) { 02701 if (!strcmp(ast_get_context_name(c), context)) 02702 return c; 02703 } 02704 ast_unlock_contexts(); 02705 02706 return NULL; 02707 }
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 4114 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, lookup_name(), and s.
Referenced by ast_build_timing().
04115 { 04116 int s, e; /* start and ending position */ 04117 unsigned int mask = 0; 04118 04119 /* Check for whole range */ 04120 if (ast_strlen_zero(src) || !strcmp(src, "*")) { 04121 s = 0; 04122 e = max - 1; 04123 } else { 04124 /* Get start and ending position */ 04125 char *c = strchr(src, '-'); 04126 if (c) 04127 *c++ = '\0'; 04128 /* Find the start */ 04129 s = lookup_name(src, names, max); 04130 if (!s) { 04131 ast_log(LOG_WARNING, "Invalid %s '%s', assuming none\n", msg, src); 04132 return 0; 04133 } 04134 s--; 04135 if (c) { /* find end of range */ 04136 e = lookup_name(c, names, max); 04137 if (!e) { 04138 ast_log(LOG_WARNING, "Invalid end %s '%s', assuming none\n", msg, c); 04139 return 0; 04140 } 04141 e--; 04142 } else 04143 e = s; 04144 } 04145 /* Fill the mask. Remember that ranges are cyclic */ 04146 mask = 1 << e; /* initialize with last element */ 04147 while (s != e) { 04148 if (s >= max) { 04149 s = 0; 04150 mask |= (1 << s); 04151 } else { 04152 mask |= (1 << s); 04153 s++; 04154 } 04155 } 04156 return mask; 04157 }
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 4160 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask.
Referenced by ast_build_timing().
04161 { 04162 char *e; 04163 int x; 04164 int s1, s2; 04165 int e1, e2; 04166 /* int cth, ctm; */ 04167 04168 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 04169 memset(i->minmask, 0, sizeof(i->minmask)); 04170 04171 /* 2-minutes per bit, since the mask has only 32 bits :( */ 04172 /* Star is all times */ 04173 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 04174 for (x=0; x<24; x++) 04175 i->minmask[x] = 0x3fffffff; /* 30 bits */ 04176 return; 04177 } 04178 /* Otherwise expect a range */ 04179 e = strchr(times, '-'); 04180 if (!e) { 04181 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n"); 04182 return; 04183 } 04184 *e++ = '\0'; 04185 /* XXX why skip non digits ? */ 04186 while (*e && !isdigit(*e)) 04187 e++; 04188 if (!*e) { 04189 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n"); 04190 return; 04191 } 04192 if (sscanf(times, "%2d:%2d", &s1, &s2) != 2) { 04193 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times); 04194 return; 04195 } 04196 if (sscanf(e, "%2d:%2d", &e1, &e2) != 2) { 04197 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e); 04198 return; 04199 } 04200 /* XXX this needs to be optimized */ 04201 #if 1 04202 s1 = s1 * 30 + s2/2; 04203 if ((s1 < 0) || (s1 >= 24*30)) { 04204 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times); 04205 return; 04206 } 04207 e1 = e1 * 30 + e2/2; 04208 if ((e1 < 0) || (e1 >= 24*30)) { 04209 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e); 04210 return; 04211 } 04212 /* Go through the time and enable each appropriate bit */ 04213 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) { 04214 i->minmask[x/30] |= (1 << (x % 30)); 04215 } 04216 /* Do the last one */ 04217 i->minmask[x/30] |= (1 << (x % 30)); 04218 #else 04219 for (cth=0; cth<24; cth++) { 04220 /* Initialize masks to blank */ 04221 i->minmask[cth] = 0; 04222 for (ctm=0; ctm<30; ctm++) { 04223 if ( 04224 /* First hour with more than one hour */ 04225 (((cth == s1) && (ctm >= s2)) && 04226 ((cth < e1))) 04227 /* Only one hour */ 04228 || (((cth == s1) && (ctm >= s2)) && 04229 ((cth == e1) && (ctm <= e2))) 04230 /* In between first and last hours (more than 2 hours) */ 04231 || ((cth > s1) && 04232 (cth < e1)) 04233 /* Last hour with more than one hour */ 04234 || ((cth > s1) && 04235 ((cth == e1) && (ctm <= e2))) 04236 ) 04237 i->minmask[cth] |= (1 << (ctm / 2)); 04238 } 04239 } 04240 #endif 04241 /* All done */ 04242 return; 04243 }
static int handle_set_global | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3761 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03762 { 03763 if (argc != 5) 03764 return RESULT_SHOWUSAGE; 03765 03766 pbx_builtin_setvar_helper(NULL, argv[3], argv[4]); 03767 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[3], argv[4]); 03768 03769 return RESULT_SUCCESS; 03770 }
static int handle_set_global_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI support for setting global variables.
Definition at line 3749 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03750 { 03751 if (argc != 4) 03752 return RESULT_SHOWUSAGE; 03753 03754 pbx_builtin_setvar_helper(NULL, argv[2], argv[3]); 03755 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[2], argv[3]); 03756 03757 return RESULT_SUCCESS; 03758 }
static int handle_show_application | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3192 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().
03193 { 03194 struct ast_app *a; 03195 int app, no_registered_app = 1; 03196 03197 if (argc < 4) 03198 return RESULT_SHOWUSAGE; 03199 03200 /* ... go through all applications ... */ 03201 AST_LIST_LOCK(&apps); 03202 AST_LIST_TRAVERSE(&apps, a, list) { 03203 /* ... compare this application name with all arguments given 03204 * to 'show application' command ... */ 03205 for (app = 3; app < argc; app++) { 03206 if (!strcasecmp(a->name, argv[app])) { 03207 /* Maximum number of characters added by terminal coloring is 22 */ 03208 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03209 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03210 int synopsis_size, description_size; 03211 03212 no_registered_app = 0; 03213 03214 if (a->synopsis) 03215 synopsis_size = strlen(a->synopsis) + 23; 03216 else 03217 synopsis_size = strlen("Not available") + 23; 03218 synopsis = alloca(synopsis_size); 03219 03220 if (a->description) 03221 description_size = strlen(a->description) + 23; 03222 else 03223 description_size = strlen("Not available") + 23; 03224 description = alloca(description_size); 03225 03226 if (synopsis && description) { 03227 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03228 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03229 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03230 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03231 term_color(synopsis, 03232 a->synopsis ? a->synopsis : "Not available", 03233 COLOR_CYAN, 0, synopsis_size); 03234 term_color(description, 03235 a->description ? a->description : "Not available", 03236 COLOR_CYAN, 0, description_size); 03237 03238 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03239 } else { 03240 /* ... one of our applications, show info ...*/ 03241 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03242 "[Synopsis]\n %s\n\n" 03243 "[Description]\n%s\n", 03244 a->name, 03245 a->synopsis ? a->synopsis : "Not available", 03246 a->description ? a->description : "Not available"); 03247 } 03248 } 03249 } 03250 } 03251 AST_LIST_UNLOCK(&apps); 03252 03253 /* we found at least one app? no? */ 03254 if (no_registered_app) { 03255 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03256 return RESULT_FAILURE; 03257 } 03258 03259 return RESULT_SUCCESS; 03260 }
static int handle_show_application_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3122 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().
03123 { 03124 struct ast_app *a; 03125 int app, no_registered_app = 1; 03126 03127 if (argc < 3) 03128 return RESULT_SHOWUSAGE; 03129 03130 /* ... go through all applications ... */ 03131 AST_LIST_LOCK(&apps); 03132 AST_LIST_TRAVERSE(&apps, a, list) { 03133 /* ... compare this application name with all arguments given 03134 * to 'show application' command ... */ 03135 for (app = 2; app < argc; app++) { 03136 if (!strcasecmp(a->name, argv[app])) { 03137 /* Maximum number of characters added by terminal coloring is 22 */ 03138 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03139 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03140 int synopsis_size, description_size; 03141 03142 no_registered_app = 0; 03143 03144 if (a->synopsis) 03145 synopsis_size = strlen(a->synopsis) + 23; 03146 else 03147 synopsis_size = strlen("Not available") + 23; 03148 synopsis = alloca(synopsis_size); 03149 03150 if (a->description) 03151 description_size = strlen(a->description) + 23; 03152 else 03153 description_size = strlen("Not available") + 23; 03154 description = alloca(description_size); 03155 03156 if (synopsis && description) { 03157 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03158 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03159 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03160 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03161 term_color(synopsis, 03162 a->synopsis ? a->synopsis : "Not available", 03163 COLOR_CYAN, 0, synopsis_size); 03164 term_color(description, 03165 a->description ? a->description : "Not available", 03166 COLOR_CYAN, 0, description_size); 03167 03168 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03169 } else { 03170 /* ... one of our applications, show info ...*/ 03171 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03172 "[Synopsis]\n %s\n\n" 03173 "[Description]\n%s\n", 03174 a->name, 03175 a->synopsis ? a->synopsis : "Not available", 03176 a->description ? a->description : "Not available"); 03177 } 03178 } 03179 } 03180 } 03181 AST_LIST_UNLOCK(&apps); 03182 03183 /* we found at least one app? no? */ 03184 if (no_registered_app) { 03185 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03186 return RESULT_FAILURE; 03187 } 03188 03189 return RESULT_SUCCESS; 03190 }
static int handle_show_applications | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3387 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.
03388 { 03389 struct ast_app *a; 03390 int like = 0, describing = 0; 03391 int total_match = 0; /* Number of matches in like clause */ 03392 int total_apps = 0; /* Number of apps registered */ 03393 03394 AST_LIST_LOCK(&apps); 03395 03396 if (AST_LIST_EMPTY(&apps)) { 03397 ast_cli(fd, "There are no registered applications\n"); 03398 AST_LIST_UNLOCK(&apps); 03399 return -1; 03400 } 03401 03402 /* core list applications like <keyword> */ 03403 if ((argc == 5) && (!strcmp(argv[3], "like"))) { 03404 like = 1; 03405 } else if ((argc > 4) && (!strcmp(argv[3], "describing"))) { 03406 describing = 1; 03407 } 03408 03409 /* core list applications describing <keyword1> [<keyword2>] [...] */ 03410 if ((!like) && (!describing)) { 03411 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03412 } else { 03413 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03414 } 03415 03416 AST_LIST_TRAVERSE(&apps, a, list) { 03417 int printapp = 0; 03418 total_apps++; 03419 if (like) { 03420 if (strcasestr(a->name, argv[4])) { 03421 printapp = 1; 03422 total_match++; 03423 } 03424 } else if (describing) { 03425 if (a->description) { 03426 /* Match all words on command line */ 03427 int i; 03428 printapp = 1; 03429 for (i = 4; i < argc; i++) { 03430 if (!strcasestr(a->description, argv[i])) { 03431 printapp = 0; 03432 } else { 03433 total_match++; 03434 } 03435 } 03436 } 03437 } else { 03438 printapp = 1; 03439 } 03440 03441 if (printapp) { 03442 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03443 } 03444 } 03445 if ((!like) && (!describing)) { 03446 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03447 } else { 03448 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03449 } 03450 03451 AST_LIST_UNLOCK(&apps); 03452 03453 return RESULT_SUCCESS; 03454 }
static int handle_show_applications_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3319 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.
03320 { 03321 struct ast_app *a; 03322 int like = 0, describing = 0; 03323 int total_match = 0; /* Number of matches in like clause */ 03324 int total_apps = 0; /* Number of apps registered */ 03325 03326 AST_LIST_LOCK(&apps); 03327 03328 if (AST_LIST_EMPTY(&apps)) { 03329 ast_cli(fd, "There are no registered applications\n"); 03330 AST_LIST_UNLOCK(&apps); 03331 return -1; 03332 } 03333 03334 /* show applications like <keyword> */ 03335 if ((argc == 4) && (!strcmp(argv[2], "like"))) { 03336 like = 1; 03337 } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { 03338 describing = 1; 03339 } 03340 03341 /* show applications describing <keyword1> [<keyword2>] [...] */ 03342 if ((!like) && (!describing)) { 03343 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03344 } else { 03345 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03346 } 03347 03348 AST_LIST_TRAVERSE(&apps, a, list) { 03349 int printapp = 0; 03350 total_apps++; 03351 if (like) { 03352 if (strcasestr(a->name, argv[3])) { 03353 printapp = 1; 03354 total_match++; 03355 } 03356 } else if (describing) { 03357 if (a->description) { 03358 /* Match all words on command line */ 03359 int i; 03360 printapp = 1; 03361 for (i = 3; i < argc; i++) { 03362 if (!strcasestr(a->description, argv[i])) { 03363 printapp = 0; 03364 } else { 03365 total_match++; 03366 } 03367 } 03368 } 03369 } else { 03370 printapp = 1; 03371 } 03372 03373 if (printapp) { 03374 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03375 } 03376 } 03377 if ((!like) && (!describing)) { 03378 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03379 } else { 03380 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03381 } 03382 03383 AST_LIST_UNLOCK(&apps); 03384 03385 return RESULT_SUCCESS; 03386 }
static int handle_show_dialplan | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3676 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().
03677 { 03678 char *exten = NULL, *context = NULL; 03679 /* Variables used for different counters */ 03680 struct dialplan_counters counters; 03681 03682 const char *incstack[AST_PBX_MAX_STACK]; 03683 memset(&counters, 0, sizeof(counters)); 03684 03685 if (argc != 2 && argc != 3) 03686 return RESULT_SHOWUSAGE; 03687 03688 /* we obtain [exten@]context? if yes, split them ... */ 03689 if (argc == 3) { 03690 if (strchr(argv[2], '@')) { /* split into exten & context */ 03691 context = ast_strdupa(argv[2]); 03692 exten = strsep(&context, "@"); 03693 /* change empty strings to NULL */ 03694 if (ast_strlen_zero(exten)) 03695 exten = NULL; 03696 } else { /* no '@' char, only context given */ 03697 context = argv[2]; 03698 } 03699 if (ast_strlen_zero(context)) 03700 context = NULL; 03701 } 03702 /* else Show complete dial plan, context and exten are NULL */ 03703 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03704 03705 /* check for input failure and throw some error messages */ 03706 if (context && !counters.context_existence) { 03707 ast_cli(fd, "There is no existence of '%s' context\n", context); 03708 return RESULT_FAILURE; 03709 } 03710 03711 if (exten && !counters.extension_existence) { 03712 if (context) 03713 ast_cli(fd, "There is no existence of %s@%s extension\n", 03714 exten, context); 03715 else 03716 ast_cli(fd, 03717 "There is no existence of '%s' extension in all contexts\n", 03718 exten); 03719 return RESULT_FAILURE; 03720 } 03721 03722 ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", 03723 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions", 03724 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities", 03725 counters.total_context, counters.total_context == 1 ? "context" : "contexts"); 03726 03727 /* everything ok */ 03728 return RESULT_SUCCESS; 03729 }
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 3732 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.
03733 { 03734 int i = 0; 03735 struct ast_var_t *newvariable; 03736 03737 ast_mutex_lock(&globalslock); 03738 AST_LIST_TRAVERSE (&globals, newvariable, entries) { 03739 i++; 03740 ast_cli(fd, " %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable)); 03741 } 03742 ast_mutex_unlock(&globalslock); 03743 ast_cli(fd, "\n -- %d variables\n", i); 03744 03745 return RESULT_SUCCESS; 03746 }
static int handle_show_hints | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
handle_show_hints: CLI support for listing registered dial plan hints
Definition at line 3263 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.
03264 { 03265 struct ast_hint *hint; 03266 int num = 0; 03267 int watchers; 03268 struct ast_state_cb *watcher; 03269 03270 if (AST_LIST_EMPTY(&hints)) { 03271 ast_cli(fd, "There are no registered dialplan hints\n"); 03272 return RESULT_SUCCESS; 03273 } 03274 /* ... we have hints ... */ 03275 ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); 03276 AST_LIST_LOCK(&hints); 03277 AST_LIST_TRAVERSE(&hints, hint, list) { 03278 watchers = 0; 03279 for (watcher = hint->callbacks; watcher; watcher = watcher->next) 03280 watchers++; 03281 ast_cli(fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", 03282 ast_get_extension_name(hint->exten), 03283 ast_get_context_name(ast_get_extension_context(hint->exten)), 03284 ast_get_extension_app(hint->exten), 03285 ast_extension_state2str(hint->laststate), watchers); 03286 num++; 03287 } 03288 ast_cli(fd, "----------------\n"); 03289 ast_cli(fd, "- %d hints registered\n", num); 03290 AST_LIST_UNLOCK(&hints); 03291 return RESULT_SUCCESS; 03292 }
static int handle_show_switches | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
handle_show_switches: CLI support for listing registered dial plan switches
Definition at line 3295 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.
03296 { 03297 struct ast_switch *sw; 03298 03299 AST_LIST_LOCK(&switches); 03300 03301 if (AST_LIST_EMPTY(&switches)) { 03302 AST_LIST_UNLOCK(&switches); 03303 ast_cli(fd, "There are no registered alternative switches\n"); 03304 return RESULT_SUCCESS; 03305 } 03306 03307 ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); 03308 AST_LIST_TRAVERSE(&switches, sw, list) 03309 ast_cli(fd, "%s: %s\n", sw->name, sw->description); 03310 03311 AST_LIST_UNLOCK(&switches); 03312 03313 return RESULT_SUCCESS; 03314 }
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 2570 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), countcalls, LOG_NOTICE, maxcalllock, ast_channel::name, option_maxcalls, option_maxload, and totalcalls.
Referenced by ast_pbx_run(), and ast_pbx_start().
02571 { 02572 int failed = 0; 02573 double curloadavg; 02574 ast_mutex_lock(&maxcalllock); 02575 if (option_maxcalls) { 02576 if (countcalls >= option_maxcalls) { 02577 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name); 02578 failed = -1; 02579 } 02580 } 02581 if (option_maxload) { 02582 getloadavg(&curloadavg, 1); 02583 if (curloadavg >= option_maxload) { 02584 ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg); 02585 failed = -1; 02586 } 02587 } 02588 if (!failed) { 02589 countcalls++; 02590 totalcalls++; 02591 } 02592 ast_mutex_unlock(&maxcalllock); 02593 02594 return failed; 02595 }
int load_pbx | ( | void | ) |
Provided by pbx.c
Definition at line 6257 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().
06258 { 06259 int x; 06260 06261 /* Initialize the PBX */ 06262 if (option_verbose) { 06263 ast_verbose( "Asterisk PBX Core Initializing\n"); 06264 ast_verbose( "Registering builtin applications:\n"); 06265 } 06266 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(struct ast_cli_entry)); 06267 06268 /* Register builtin applications */ 06269 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06270 if (option_verbose) 06271 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06272 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06273 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06274 return -1; 06275 } 06276 } 06277 return 0; 06278 }
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 4096 of file pbx.c.
Referenced by get_range().
04097 { 04098 int i; 04099 04100 if (names) { 04101 for (i = 0; names[i]; i++) { 04102 if (!strcasecmp(s, names[i])) 04103 return i+1; 04104 } 04105 } else if (sscanf(s, "%30d", &i) == 1 && i >= 1 && i <= max) { 04106 return i; 04107 } 04108 return 0; /* error return */ 04109 }
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, "%30d:%30d", offset, length); 01122 return 1; /* offset:length valid */ 01123 } 01124 } 01125 return 0; 01126 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6059 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().
06060 { 06061 struct ast_var_t *vardata; 06062 06063 ast_mutex_lock(&globalslock); 06064 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06065 ast_var_delete(vardata); 06066 ast_mutex_unlock(&globalslock); 06067 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5836 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_call_forward(), ast_monitor_stop(), builtin_automonitor(), check_goto_on_transfer(), common_exec(), conf_exec(), conf_run(), dahdi_call(), dahdi_hangup(), dundi_exec(), dundi_helper(), feature_interpret(), get_also_info(), get_index(), get_refer_info(), global_read(), iax2_exec(), import_ch(), leave_voicemail(), local_hangup(), macro_fixup(), misdn_answer(), misdn_hangup(), morsecode_exec(), notify_new_message(), oh323_call(), oh323_hangup(), park_call_full(), park_space_reserve(), pickup_by_mark(), queue_exec(), real_ctx(), retrydial_exec(), return_exec(), ring_entry(), run_agi(), set_config_flags(), sip_addheader(), sla_trunk_exec(), speech_background(), try_suggested_sip_codec(), update_bridgepeer(), and wait_for_answer().
05837 { 05838 struct ast_var_t *variables; 05839 const char *ret = NULL; 05840 int i; 05841 struct varshead *places[2] = { NULL, &globals }; 05842 05843 if (!name) 05844 return NULL; 05845 05846 if (chan) { 05847 ast_channel_lock(chan); 05848 places[0] = &chan->varshead; 05849 } 05850 05851 for (i = 0; i < 2; i++) { 05852 if (!places[i]) 05853 continue; 05854 if (places[i] == &globals) 05855 ast_mutex_lock(&globalslock); 05856 AST_LIST_TRAVERSE(places[i], variables, entries) { 05857 if (!strcmp(name, ast_var_name(variables))) { 05858 ret = ast_var_value(variables); 05859 break; 05860 } 05861 } 05862 if (places[i] == &globals) 05863 ast_mutex_unlock(&globalslock); 05864 if (ret) 05865 break; 05866 } 05867 05868 if (chan) 05869 ast_channel_unlock(chan); 05870 05871 return ret; 05872 }
static int pbx_builtin_gotoif | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6079 of file pbx.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_goto(), and pbx_checkcondition().
06080 { 06081 char *condition, *branch1, *branch2, *branch; 06082 int rc; 06083 char *stringp; 06084 06085 if (ast_strlen_zero(data)) { 06086 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06087 return 0; 06088 } 06089 06090 stringp = ast_strdupa(data); 06091 condition = strsep(&stringp,"?"); 06092 branch1 = strsep(&stringp,":"); 06093 branch2 = strsep(&stringp,""); 06094 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06095 06096 if (ast_strlen_zero(branch)) { 06097 if (option_debug) 06098 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06099 return 0; 06100 } 06101 06102 rc = pbx_builtin_goto(chan, branch); 06103 06104 return rc; 06105 }
int pbx_builtin_importvar | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 5998 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.
05999 { 06000 char *name; 06001 char *value; 06002 char *channel; 06003 char tmp[VAR_BUF_SIZE]=""; 06004 06005 if (ast_strlen_zero(data)) { 06006 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06007 return 0; 06008 } 06009 06010 value = ast_strdupa(data); 06011 name = strsep(&value,"="); 06012 channel = strsep(&value,"|"); 06013 if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */ 06014 struct ast_channel *chan2 = ast_get_channel_by_name_locked(channel); 06015 if (chan2) { 06016 char *s = alloca(strlen(value) + 4); 06017 if (s) { 06018 sprintf(s, "${%s}", value); 06019 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 06020 } 06021 ast_channel_unlock(chan2); 06022 } 06023 pbx_builtin_setvar_helper(chan, name, tmp); 06024 } 06025 06026 return(0); 06027 }
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 5874 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().
05875 { 05876 struct ast_var_t *newvariable; 05877 struct varshead *headp; 05878 05879 if (name[strlen(name)-1] == ')') { 05880 char *function = ast_strdupa(name); 05881 05882 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05883 ast_func_write(chan, function, value); 05884 return; 05885 } 05886 05887 if (chan) { 05888 ast_channel_lock(chan); 05889 headp = &chan->varshead; 05890 } else { 05891 ast_mutex_lock(&globalslock); 05892 headp = &globals; 05893 } 05894 05895 if (value) { 05896 if ((option_verbose > 1) && (headp == &globals)) 05897 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05898 newvariable = ast_var_assign(name, value); 05899 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05900 } 05901 05902 if (chan) 05903 ast_channel_unlock(chan); 05904 else 05905 ast_mutex_unlock(&globalslock); 05906 }
static int pbx_builtin_saycharacters | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6144 of file pbx.c.
References ast_say_character_str(), and ast_channel::language.
06145 { 06146 int res = 0; 06147 06148 if (data) 06149 res = ast_say_character_str(chan, data, "", chan->language); 06150 return res; 06151 }
static int pbx_builtin_saydate | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6162 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().
06163 { 06164 int res = 0; 06165 char *parse; 06166 int unixdate = 0; 06167 char charascii[2]; 06168 06169 AST_DECLARE_APP_ARGS(args, 06170 AST_APP_ARG(datestr); 06171 AST_APP_ARG(digits); 06172 ); 06173 06174 06175 if (ast_strlen_zero(data)) { 06176 ast_log(LOG_WARNING, "SayDate requires an argument (date)\n"); 06177 return -1; 06178 } 06179 06180 if (!(parse = ast_strdupa(data))) { 06181 ast_log(LOG_WARNING, "Memory Error!\n"); 06182 return -1; 06183 } 06184 06185 AST_STANDARD_APP_ARGS(args, parse); 06186 06187 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06188 ast_log(LOG_WARNING, "SayDate escape digits must be a subset from '0123456789*#'\n"); 06189 args.digits = ""; 06190 } 06191 06192 if (sscanf(args.datestr, "%d", &unixdate) != 1) { 06193 ast_log(LOG_WARNING, "Firt argument to SayDate must be numeric (date)\n"); 06194 return -1; 06195 } 06196 06197 res = ast_say_date(chan, (time_t)unixdate, args.digits, chan->language); 06198 if (res > 0) { 06199 if (isdigit(res) || (res == '*') || (res == '#')) { 06200 snprintf(charascii, 2, "%c", res); 06201 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06202 res = 0; 06203 } else { 06204 ast_log(LOG_WARNING, "SayDate: invalid return value (%d) detected\n", res); 06205 } 06206 } 06207 return res; 06208 }
static int pbx_builtin_saydigits | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6135 of file pbx.c.
References ast_say_digit_str(), and ast_channel::language.
06136 { 06137 int res = 0; 06138 06139 if (data) 06140 res = ast_say_digit_str(chan, data, "", chan->language); 06141 return res; 06142 }
static int pbx_builtin_saynumber | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6107 of file pbx.c.
References ast_copy_string(), ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, and LOG_WARNING.
06108 { 06109 char tmp[256]; 06110 char *number = tmp; 06111 char *options; 06112 06113 if (ast_strlen_zero(data)) { 06114 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06115 return -1; 06116 } 06117 ast_copy_string(tmp, data, sizeof(tmp)); 06118 strsep(&number, "|"); 06119 options = strsep(&number, "|"); 06120 if (options) { 06121 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06122 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06123 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06124 return -1; 06125 } 06126 } 06127 06128 if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) { 06129 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp); 06130 } 06131 06132 return 0; 06133 }
static int pbx_builtin_sayphonetic | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6153 of file pbx.c.
References ast_say_phonetic_str(), and ast_channel::language.
06154 { 06155 int res = 0; 06156 06157 if (data) 06158 res = ast_say_phonetic_str(chan, data, "", chan->language); 06159 return res; 06160 }
static int pbx_builtin_saytime | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6210 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().
06211 { 06212 int res = 0; 06213 char *parse; 06214 int secs = 0; 06215 char charascii[2]; 06216 06217 AST_DECLARE_APP_ARGS(args, 06218 AST_APP_ARG(timestr); 06219 AST_APP_ARG(digits); 06220 ); 06221 06222 if (ast_strlen_zero(data)) { 06223 ast_log(LOG_WARNING, "SayTime requires an argument (time in seconds)\n"); 06224 return -1; 06225 } 06226 06227 if (!(parse = ast_strdupa(data))) { 06228 ast_log(LOG_WARNING, "Memory Error!\n"); 06229 return -1; 06230 } 06231 06232 AST_STANDARD_APP_ARGS(args, parse); 06233 06234 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06235 ast_log(LOG_WARNING, "SayTime escape digits must be a subset from '0123456789*#'\n"); 06236 args.digits = ""; 06237 } 06238 06239 if (sscanf(args.timestr, "%d", &secs) != 1) { 06240 ast_log(LOG_WARNING, "Firt argument to SayTime must be numeric (time in seconds)\n"); 06241 return -1; 06242 } 06243 06244 res = ast_say_time(chan, (time_t)secs, args.digits, chan->language); 06245 if (res > 0) { 06246 if (isdigit(res) || (res == '*') || (res == '#')) { 06247 snprintf(charascii, 2, "%c", res); 06248 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06249 res = 0; 06250 } else { 06251 ast_log(LOG_WARNING, "SayTime: invalid return value (%d) detected\n", res); 06252 } 06253 } 06254 return res; 06255 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5805 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().
05806 { 05807 struct ast_var_t *variables; 05808 const char *var, *val; 05809 int total = 0; 05810 05811 if (!chan) 05812 return 0; 05813 05814 memset(buf, 0, size); 05815 05816 ast_channel_lock(chan); 05817 05818 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05819 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05820 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05821 ) { 05822 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05823 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05824 break; 05825 } else 05826 total++; 05827 } else 05828 break; 05829 } 05830 05831 ast_channel_unlock(chan); 05832 05833 return total; 05834 }
static int pbx_builtin_setglobalvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 6030 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and pbx_builtin_setvar_helper().
06031 { 06032 char *name; 06033 char *stringp = data; 06034 static int dep_warning = 0; 06035 06036 if (ast_strlen_zero(data)) { 06037 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06038 return 0; 06039 } 06040 06041 name = strsep(&stringp, "="); 06042 06043 if (!dep_warning) { 06044 dep_warning = 1; 06045 ast_log(LOG_WARNING, "SetGlobalVar is deprecated. Please use Set(GLOBAL(%s)=%s) instead.\n", name, stringp); 06046 } 06047 06048 /*! \todo XXX watch out, leading whitespace ? */ 06049 pbx_builtin_setvar_helper(NULL, name, stringp); 06050 06051 return(0); 06052 }
int pbx_builtin_setvar | ( | struct ast_channel * | , | |
void * | ||||
) |
Definition at line 5958 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().
05959 { 05960 char *name, *value, *mydata; 05961 int argc; 05962 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 05963 int global = 0; 05964 int x; 05965 05966 if (ast_strlen_zero(data)) { 05967 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 05968 return 0; 05969 } 05970 05971 mydata = ast_strdupa(data); 05972 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 05973 05974 /* check for a trailing flags argument */ 05975 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 05976 argc--; 05977 if (strchr(argv[argc], 'g')) { 05978 ast_log(LOG_WARNING, "The use of the 'g' flag is deprecated. Please use Set(GLOBAL(foo)=bar) instead\n"); 05979 global = 1; 05980 } 05981 } 05982 05983 if (argc > 1) 05984 ast_log(LOG_WARNING, "Setting multiple variables at once within Set is deprecated. Please separate each name/value pair into its own line.\n"); 05985 05986 for (x = 0; x < argc; x++) { 05987 name = argv[x]; 05988 if ((value = strchr(name, '='))) { 05989 *value++ = '\0'; 05990 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 05991 } else 05992 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 05993 } 05994 05995 return(0); 05996 }
void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5908 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_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(), tryexec_exec(), update_bridgepeer(), upqm_exec(), vm_box_exists(), vm_exec(), and vmauthenticate().
05909 { 05910 struct ast_var_t *newvariable; 05911 struct varshead *headp; 05912 const char *nametail = name; 05913 05914 if (name[strlen(name)-1] == ')') { 05915 char *function = ast_strdupa(name); 05916 05917 ast_func_write(chan, function, value); 05918 return; 05919 } 05920 05921 if (chan) { 05922 ast_channel_lock(chan); 05923 headp = &chan->varshead; 05924 } else { 05925 ast_mutex_lock(&globalslock); 05926 headp = &globals; 05927 } 05928 05929 /* For comparison purposes, we have to strip leading underscores */ 05930 if (*nametail == '_') { 05931 nametail++; 05932 if (*nametail == '_') 05933 nametail++; 05934 } 05935 05936 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05937 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05938 /* there is already such a variable, delete it */ 05939 AST_LIST_REMOVE(headp, newvariable, entries); 05940 ast_var_delete(newvariable); 05941 break; 05942 } 05943 } 05944 05945 if (value) { 05946 if ((option_verbose > 1) && (headp == &globals)) 05947 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05948 newvariable = ast_var_assign(name, value); 05949 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05950 } 05951 05952 if (chan) 05953 ast_channel_unlock(chan); 05954 else 05955 ast_mutex_unlock(&globalslock); 05956 }
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 6069 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().
06070 { 06071 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06072 return 0; 06073 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06074 return atoi(condition); 06075 else /* Strings are true */ 06076 return 1; 06077 }
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(), 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 1833 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().
01836 { 01837 struct ast_exten *e; 01838 struct ast_app *app; 01839 int res; 01840 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */ 01841 char passdata[EXT_DATA_SIZE]; 01842 01843 int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE); 01844 01845 ast_rdlock_contexts(); 01846 e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action); 01847 if (e) { 01848 if (matching_action) { 01849 ast_unlock_contexts(); 01850 return -1; /* success, we found it */ 01851 } else if (action == E_FINDLABEL) { /* map the label to a priority */ 01852 res = e->priority; 01853 ast_unlock_contexts(); 01854 return res; /* the priority we were looking for */ 01855 } else { /* spawn */ 01856 app = pbx_findapp(e->app); 01857 ast_unlock_contexts(); 01858 if (!app) { 01859 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority); 01860 return -1; 01861 } 01862 if (c->context != context) 01863 ast_copy_string(c->context, context, sizeof(c->context)); 01864 if (c->exten != exten) 01865 ast_copy_string(c->exten, exten, sizeof(c->exten)); 01866 c->priority = priority; 01867 pbx_substitute_variables(passdata, sizeof(passdata), c, e); 01868 if (option_debug) { 01869 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name); 01870 } 01871 if (option_verbose > 2) { 01872 char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE]; 01873 ast_verbose( VERBOSE_PREFIX_3 "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n", 01874 exten, context, priority, 01875 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)), 01876 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 01877 term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)), 01878 "in new stack"); 01879 } 01880 manager_event(EVENT_FLAG_CALL, "Newexten", 01881 "Channel: %s\r\n" 01882 "Context: %s\r\n" 01883 "Extension: %s\r\n" 01884 "Priority: %d\r\n" 01885 "Application: %s\r\n" 01886 "AppData: %s\r\n" 01887 "Uniqueid: %s\r\n", 01888 c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid); 01889 return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */ 01890 } 01891 } else if (q.swo) { /* not found here, but in another switch */ 01892 ast_unlock_contexts(); 01893 if (matching_action) { 01894 return -1; 01895 } else { 01896 if (!q.swo->exec) { 01897 ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name); 01898 res = -1; 01899 } 01900 return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data); 01901 } 01902 } else { /* not found anywhere, see what happened */ 01903 ast_unlock_contexts(); 01904 switch (q.status) { 01905 case STATUS_NO_CONTEXT: 01906 if (!matching_action) 01907 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context); 01908 break; 01909 case STATUS_NO_EXTENSION: 01910 if (!matching_action) 01911 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context); 01912 break; 01913 case STATUS_NO_PRIORITY: 01914 if (!matching_action) 01915 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context); 01916 break; 01917 case STATUS_NO_LABEL: 01918 if (context) 01919 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context); 01920 break; 01921 default: 01922 if (option_debug) 01923 ast_log(LOG_DEBUG, "Shouldn't happen!\n"); 01924 } 01925 01926 return (matching_action) ? 0 : -1; 01927 } 01928 }
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(), 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 2685 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02686 { 02687 int oldval = autofallthrough; 02688 autofallthrough = newval; 02689 return oldval; 02690 }
static void pbx_substitute_variables | ( | char * | passdata, | |
int | datalen, | |||
struct ast_channel * | c, | |||
struct ast_exten * | e | |||
) | [static] |
Definition at line 1804 of file pbx.c.
References ast_copy_string(), ast_exten::data, and pbx_substitute_variables_helper().
Referenced by pbx_extension_helper().
01805 { 01806 memset(passdata, 0, datalen); 01807 01808 /* No variables or expressions in e->data, so why scan it? */ 01809 if (e->data && !strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) { 01810 ast_copy_string(passdata, e->data, datalen); 01811 return; 01812 } 01813 01814 pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1); 01815 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1794 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(), and tryexec_exec().
01795 { 01796 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01797 }
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_WARNING, 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, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!! */ 01602 char *cp4; 01603 const char *tmp, *whereweare; 01604 int length, offset, offset2, isfunction; 01605 char *workspace = NULL; 01606 char *ltmp = NULL, *var = NULL; 01607 char *nextvar, *nextexp, *nextthing; 01608 char *vars, *vare; 01609 int pos, brackets, needsub, len; 01610 01611 *cp2 = 0; /* just in case nothing ends up there */ 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 *cp2 = 0; 01646 } 01647 01648 if (nextvar) { 01649 /* We have a variable. Find the start and end, and determine 01650 if we are going to have to recursively call ourselves on the 01651 contents */ 01652 vars = vare = nextvar + 2; 01653 brackets = 1; 01654 needsub = 0; 01655 01656 /* Find the end of it */ 01657 while (brackets && *vare) { 01658 if ((vare[0] == '$') && (vare[1] == '{')) { 01659 needsub++; 01660 } else if (vare[0] == '{') { 01661 brackets++; 01662 } else if (vare[0] == '}') { 01663 brackets--; 01664 } else if ((vare[0] == '$') && (vare[1] == '[')) 01665 needsub++; 01666 vare++; 01667 } 01668 if (brackets) 01669 ast_log(LOG_WARNING, "Error in extension logic (missing '}')\n"); 01670 len = vare - vars - 1; 01671 01672 /* Skip totally over variable string */ 01673 whereweare += (len + 3); 01674 01675 if (!var) 01676 var = alloca(VAR_BUF_SIZE); 01677 01678 /* Store variable name (and truncate) */ 01679 ast_copy_string(var, vars, len + 1); 01680 01681 /* Substitute if necessary */ 01682 if (needsub) { 01683 if (!ltmp) 01684 ltmp = alloca(VAR_BUF_SIZE); 01685 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 *cp2 = 0; 01732 } 01733 } else if (nextexp) { 01734 /* We have an expression. Find the start and end, and determine 01735 if we are going to have to recursively call ourselves on the 01736 contents */ 01737 vars = vare = nextexp + 2; 01738 brackets = 1; 01739 needsub = 0; 01740 01741 /* Find the end of it */ 01742 while (brackets && *vare) { 01743 if ((vare[0] == '$') && (vare[1] == '[')) { 01744 needsub++; 01745 brackets++; 01746 vare++; 01747 } else if (vare[0] == '[') { 01748 brackets++; 01749 } else if (vare[0] == ']') { 01750 brackets--; 01751 } else if ((vare[0] == '$') && (vare[1] == '{')) { 01752 needsub++; 01753 vare++; 01754 } 01755 vare++; 01756 } 01757 if (brackets) 01758 ast_log(LOG_WARNING, "Error in extension logic (missing ']')\n"); 01759 len = vare - vars - 1; 01760 01761 /* Skip totally over expression */ 01762 whereweare += (len + 3); 01763 01764 if (!var) 01765 var = alloca(VAR_BUF_SIZE); 01766 01767 /* Store variable name (and truncate) */ 01768 ast_copy_string(var, vars, len + 1); 01769 01770 /* Substitute if necessary */ 01771 if (needsub) { 01772 if (!ltmp) 01773 ltmp = alloca(VAR_BUF_SIZE); 01774 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 *cp2 = 0; 01789 } 01790 } 01791 } 01792 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1799 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_subst().
01800 { 01801 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01802 }
static void* pbx_thread | ( | void * | data | ) | [static] |
Definition at line 2615 of file pbx.c.
References __ast_pbx_run(), and decrease_call_count().
Referenced by ast_pbx_start().
02616 { 02617 /* Oh joyeous kernel, we're a new thread, with nothing to do but 02618 answer this channel and get it going. 02619 */ 02620 /* NOTE: 02621 The launcher of this function _MUST_ increment 'countcalls' 02622 before invoking the function; it will be decremented when the 02623 PBX has finished running on the channel 02624 */ 02625 struct ast_channel *c = data; 02626 02627 __ast_pbx_run(c); 02628 decrease_call_count(); 02629 02630 pthread_exit(NULL); 02631 02632 return NULL; 02633 }
static void print_ext | ( | struct ast_exten * | e, | |
char * | buf, | |||
int | buflen | |||
) | [static] |
helper function to print an extension
Definition at line 3511 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().
03512 { 03513 int prio = ast_get_extension_priority(e); 03514 if (prio == PRIORITY_HINT) { 03515 snprintf(buf, buflen, "hint: %s", 03516 ast_get_extension_app(e)); 03517 } else { 03518 snprintf(buf, buflen, "%d. %s(%s)", 03519 prio, ast_get_extension_app(e), 03520 (!ast_strlen_zero(ast_get_extension_app_data(e)) ? (char *)ast_get_extension_app_data(e) : "")); 03521 } 03522 }
static void set_ext_pri | ( | struct ast_channel * | c, | |
const char * | exten, | |||
int | pri | |||
) | [static] |
Definition at line 2313 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().
02314 { 02315 ast_channel_lock(c); 02316 ast_copy_string(c->exten, exten, sizeof(c->exten)); 02317 c->priority = pri; 02318 ast_channel_unlock(c); 02319 }
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 3525 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(), ast_exten::cidmatch, dialplan_counters::context_existence, el, dialplan_counters::extension_existence, LOG_NOTICE, LOG_WARNING, ast_exten::matchcid, print_ext(), dialplan_counters::total_context, dialplan_counters::total_exten, and dialplan_counters::total_prio.
Referenced by handle_show_dialplan().
03526 { 03527 struct ast_context *c = NULL; 03528 int res = 0, old_total_exten = dpc->total_exten; 03529 03530 ast_rdlock_contexts(); 03531 03532 /* walk all contexts ... */ 03533 while ( (c = ast_walk_contexts(c)) ) { 03534 struct ast_exten *e; 03535 struct ast_include *i; 03536 struct ast_ignorepat *ip; 03537 char buf[256], buf2[256]; 03538 int context_info_printed = 0; 03539 03540 if (context && strcmp(ast_get_context_name(c), context)) 03541 continue; /* skip this one, name doesn't match */ 03542 03543 dpc->context_existence = 1; 03544 03545 ast_lock_context(c); 03546 03547 /* are we looking for exten too? if yes, we print context 03548 * only if we find our extension. 03549 * Otherwise print context even if empty ? 03550 * XXX i am not sure how the rinclude is handled. 03551 * I think it ought to go inside. 03552 */ 03553 if (!exten) { 03554 dpc->total_context++; 03555 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03556 ast_get_context_name(c), ast_get_context_registrar(c)); 03557 context_info_printed = 1; 03558 } 03559 03560 /* walk extensions ... */ 03561 e = NULL; 03562 while ( (e = ast_walk_context_extensions(c, e)) ) { 03563 struct ast_exten *p; 03564 03565 if (exten && !ast_extension_match(ast_get_extension_name(e), exten)) 03566 continue; /* skip, extension match failed */ 03567 03568 dpc->extension_existence = 1; 03569 03570 /* may we print context info? */ 03571 if (!context_info_printed) { 03572 dpc->total_context++; 03573 if (rinclude) { /* TODO Print more info about rinclude */ 03574 ast_cli(fd, "[ Included context '%s' created by '%s' ]\n", 03575 ast_get_context_name(c), ast_get_context_registrar(c)); 03576 } else { 03577 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03578 ast_get_context_name(c), ast_get_context_registrar(c)); 03579 } 03580 context_info_printed = 1; 03581 } 03582 dpc->total_prio++; 03583 03584 /* write extension name and first peer */ 03585 if (e->matchcid) 03586 snprintf(buf, sizeof(buf), "'%s' (CID match '%s') => ", ast_get_extension_name(e), e->cidmatch); 03587 else 03588 snprintf(buf, sizeof(buf), "'%s' =>", ast_get_extension_name(e)); 03589 03590 print_ext(e, buf2, sizeof(buf2)); 03591 03592 ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2, 03593 ast_get_extension_registrar(e)); 03594 03595 dpc->total_exten++; 03596 /* walk next extension peers */ 03597 p = e; /* skip the first one, we already got it */ 03598 while ( (p = ast_walk_extension_priorities(e, p)) ) { 03599 const char *el = ast_get_extension_label(p); 03600 dpc->total_prio++; 03601 if (el) 03602 snprintf(buf, sizeof(buf), " [%s]", el); 03603 else 03604 buf[0] = '\0'; 03605 print_ext(p, buf2, sizeof(buf2)); 03606 03607 ast_cli(fd," %-17s %-45s [%s]\n", buf, buf2, 03608 ast_get_extension_registrar(p)); 03609 } 03610 } 03611 03612 /* walk included and write info ... */ 03613 i = NULL; 03614 while ( (i = ast_walk_context_includes(c, i)) ) { 03615 snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i)); 03616 if (exten) { 03617 /* Check all includes for the requested extension */ 03618 if (includecount >= AST_PBX_MAX_STACK) { 03619 ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n"); 03620 } else { 03621 int dupe=0; 03622 int x; 03623 for (x=0;x<includecount;x++) { 03624 if (!strcasecmp(includes[x], ast_get_include_name(i))) { 03625 dupe++; 03626 break; 03627 } 03628 } 03629 if (!dupe) { 03630 includes[includecount] = ast_get_include_name(i); 03631 show_dialplan_helper(fd, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes); 03632 } else { 03633 ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context); 03634 } 03635 } 03636 } else { 03637 ast_cli(fd, " Include => %-45s [%s]\n", 03638 buf, ast_get_include_registrar(i)); 03639 } 03640 } 03641 03642 /* walk ignore patterns and write info ... */ 03643 ip = NULL; 03644 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) { 03645 const char *ipname = ast_get_ignorepat_name(ip); 03646 char ignorepat[AST_MAX_EXTENSION]; 03647 snprintf(buf, sizeof(buf), "'%s'", ipname); 03648 snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname); 03649 if (!exten || ast_extension_match(ignorepat, exten)) { 03650 ast_cli(fd, " Ignore pattern => %-45s [%s]\n", 03651 buf, ast_get_ignorepat_registrar(ip)); 03652 } 03653 } 03654 if (!rinclude) { 03655 struct ast_sw *sw = NULL; 03656 while ( (sw = ast_walk_context_switches(c, sw)) ) { 03657 snprintf(buf, sizeof(buf), "'%s/%s'", 03658 ast_get_switch_name(sw), 03659 ast_get_switch_data(sw)); 03660 ast_cli(fd, " Alt. Switch => %-45s [%s]\n", 03661 buf, ast_get_switch_registrar(sw)); 03662 } 03663 } 03664 03665 ast_unlock_context(c); 03666 03667 /* if we print something in context, make an empty line */ 03668 if (context_info_printed) 03669 ast_cli(fd, "\n"); 03670 } 03671 ast_unlock_contexts(); 03672 03673 return (dpc->total_exten == old_total_exten) ? -1 : res; 03674 }
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 5399 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().
05400 { 05401 int res; 05402 struct ast_frame *f; 05403 int waittime; 05404 05405 if (ast_strlen_zero(data) || (sscanf(data, "%30d", &waittime) != 1) || (waittime < 0)) 05406 waittime = -1; 05407 if (waittime > -1) { 05408 ast_safe_sleep(chan, waittime * 1000); 05409 } else do { 05410 res = ast_waitfor(chan, -1); 05411 if (res < 0) 05412 return; 05413 f = ast_read(chan); 05414 if (f) 05415 ast_frfree(f); 05416 } while(f); 05417 }
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 249 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 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 globalslock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 243 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 248 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] |
int totalcalls [static] |
Definition at line 250 of file pbx.c.
Referenced by ast_processed_calls(), increase_call_count(), and timing_read().
struct ast_app_option waitexten_opts[128] = { [ 'm' ] = { .flag = (1 << 0) , .arg_index = 0 + 1 },} [static] |