#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, unsigned char *bitwise) |
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 952 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_EXTENSION 2 |
Definition at line 953 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_LABEL 4 |
Definition at line 955 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_PRIORITY 3 |
Definition at line 954 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 795 of file pbx.c.
00795 { 00796 E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */ 00797 E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */ 00798 E_MATCH = 0x02, /* extension is an exact match */ 00799 E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */ 00800 E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */ 00801 E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */ 00802 };
static struct ast_context* __ast_context_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar, | |||
int | existsokay | |||
) | [static] |
Definition at line 3924 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().
03925 { 03926 struct ast_context *tmp, **local_contexts; 03927 int length = sizeof(struct ast_context) + strlen(name) + 1; 03928 03929 if (!extcontexts) { 03930 ast_rdlock_contexts(); 03931 local_contexts = &contexts; 03932 } else 03933 local_contexts = extcontexts; 03934 03935 for (tmp = *local_contexts; tmp; tmp = tmp->next) { 03936 if (!strcasecmp(tmp->name, name)) { 03937 if (!existsokay) { 03938 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 03939 tmp = NULL; 03940 } 03941 if (!extcontexts) 03942 ast_unlock_contexts(); 03943 return tmp; 03944 } 03945 } 03946 03947 if (!extcontexts) 03948 ast_unlock_contexts(); 03949 03950 if ((tmp = ast_calloc(1, length))) { 03951 ast_mutex_init(&tmp->lock); 03952 ast_mutex_init(&tmp->macrolock); 03953 strcpy(tmp->name, name); 03954 tmp->registrar = registrar; 03955 if (!extcontexts) 03956 ast_wrlock_contexts(); 03957 tmp->next = *local_contexts; 03958 *local_contexts = tmp; 03959 if (!extcontexts) 03960 ast_unlock_contexts(); 03961 if (option_debug) 03962 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 03963 if (option_verbose > 2) 03964 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 03965 } 03966 03967 return tmp; 03968 }
void __ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
Definition at line 5353 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().
05354 { 05355 struct ast_context *tmp, *tmpl=NULL; 05356 struct ast_include *tmpi; 05357 struct ast_sw *sw; 05358 struct ast_exten *e, *el, *en; 05359 struct ast_ignorepat *ipi; 05360 05361 for (tmp = contexts; tmp; ) { 05362 struct ast_context *next; /* next starting point */ 05363 for (; tmp; tmpl = tmp, tmp = tmp->next) { 05364 if (option_debug) 05365 ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar); 05366 if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) && 05367 (!con || !strcasecmp(tmp->name, con->name)) ) 05368 break; /* found it */ 05369 } 05370 if (!tmp) /* not found, we are done */ 05371 break; 05372 ast_mutex_lock(&tmp->lock); 05373 if (option_debug) 05374 ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar); 05375 next = tmp->next; 05376 if (tmpl) 05377 tmpl->next = next; 05378 else 05379 contexts = next; 05380 /* Okay, now we're safe to let it go -- in a sense, we were 05381 ready to let it go as soon as we locked it. */ 05382 ast_mutex_unlock(&tmp->lock); 05383 for (tmpi = tmp->includes; tmpi; ) { /* Free includes */ 05384 struct ast_include *tmpil = tmpi; 05385 tmpi = tmpi->next; 05386 free(tmpil); 05387 } 05388 for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */ 05389 struct ast_ignorepat *ipl = ipi; 05390 ipi = ipi->next; 05391 free(ipl); 05392 } 05393 while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list))) 05394 free(sw); 05395 for (e = tmp->root; e;) { 05396 for (en = e->peer; en;) { 05397 el = en; 05398 en = en->peer; 05399 destroy_exten(el); 05400 } 05401 el = e; 05402 e = e->next; 05403 destroy_exten(el); 05404 } 05405 ast_mutex_destroy(&tmp->lock); 05406 free(tmp); 05407 /* if we have a specific match, we are done, otherwise continue */ 05408 tmp = con ? NULL : next; 05409 } 05410 }
static int __ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
int | async | |||
) | [static] |
Definition at line 6501 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().
06502 { 06503 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06504 06505 if (!chan) 06506 return -2; 06507 06508 if (context == NULL) 06509 context = chan->context; 06510 if (exten == NULL) 06511 exten = chan->exten; 06512 06513 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06514 if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num)) 06515 return goto_func(chan, context, exten, priority); 06516 else 06517 return -3; 06518 }
static int __ast_pbx_run | ( | struct ast_channel * | c | ) | [static] |
Definition at line 2370 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().
02371 { 02372 int found = 0; /* set if we find at least one match */ 02373 int res = 0; 02374 int autoloopflag; 02375 int error = 0; /* set an error conditions */ 02376 const char *emc; 02377 02378 /* A little initial setup here */ 02379 if (c->pbx) { 02380 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name); 02381 /* XXX and now what ? */ 02382 free(c->pbx); 02383 } 02384 if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx)))) 02385 return -1; 02386 /* Set reasonable defaults */ 02387 c->pbx->rtimeout = 10; 02388 c->pbx->dtimeout = 5; 02389 02390 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */ 02391 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP); 02392 02393 /* Start by trying whatever the channel is set to */ 02394 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02395 /* If not successful fall back to 's' */ 02396 if (option_verbose > 1) 02397 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); 02398 /* XXX the original code used the existing priority in the call to 02399 * ast_exists_extension(), and reset it to 1 afterwards. 02400 * I believe the correct thing is to set it to 1 immediately. 02401 */ 02402 set_ext_pri(c, "s", 1); 02403 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02404 /* JK02: And finally back to default if everything else failed */ 02405 if (option_verbose > 1) 02406 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); 02407 ast_copy_string(c->context, "default", sizeof(c->context)); 02408 } 02409 } 02410 for (;;) { 02411 char dst_exten[256]; /* buffer to accumulate digits */ 02412 int pos = 0; /* XXX should check bounds */ 02413 int digit = 0; 02414 02415 /* loop on priorities in this context/exten */ 02416 while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02417 found = 1; 02418 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02419 /* Something bad happened, or a hangup has been requested. */ 02420 if (strchr("0123456789ABCDEF*#", res)) { 02421 if (option_debug) 02422 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 02423 pos = 0; 02424 dst_exten[pos++] = digit = res; 02425 dst_exten[pos] = '\0'; 02426 break; 02427 } 02428 if (res == AST_PBX_KEEPALIVE) { 02429 if (option_debug) 02430 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02431 if (option_verbose > 1) 02432 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02433 error = 1; 02434 break; 02435 } 02436 if (option_debug) 02437 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02438 if (option_verbose > 1) 02439 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02440 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02441 c->_softhangup = 0; 02442 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02443 /* atimeout, nothing bad */ 02444 } else { 02445 if (c->cdr) 02446 ast_cdr_update(c); 02447 error = 1; 02448 break; 02449 } 02450 } 02451 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02452 c->_softhangup = 0; 02453 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c,c->context,"T",1,c->cid.cid_num)) { 02454 set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */ 02455 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */ 02456 c->whentohangup = 0; 02457 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT; 02458 } else if (c->_softhangup) { 02459 if (option_debug) 02460 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", 02461 c->exten, c->priority); 02462 error = 1; 02463 break; 02464 } 02465 c->priority++; 02466 } /* end while - from here on we can use 'break' to go out */ 02467 if (error) 02468 break; 02469 02470 /* XXX we get here on non-existing extension or a keypress or hangup ? */ 02471 02472 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { 02473 /* If there is no match at priority 1, it is not a valid extension anymore. 02474 * Try to continue at "i", 1 or exit if the latter does not exist. 02475 */ 02476 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02477 if (option_verbose > 2) 02478 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name); 02479 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten); 02480 set_ext_pri(c, "i", 1); 02481 } else { 02482 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n", 02483 c->name, c->exten, c->context); 02484 error = 1; /* we know what to do with it */ 02485 break; 02486 } 02487 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02488 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */ 02489 c->_softhangup = 0; 02490 } else { /* keypress received, get more digits for a full extension */ 02491 int waittime = 0; 02492 if (digit) 02493 waittime = c->pbx->dtimeout; 02494 else if (!autofallthrough) 02495 waittime = c->pbx->rtimeout; 02496 if (!waittime) { 02497 const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 02498 if (!status) 02499 status = "UNKNOWN"; 02500 if (option_verbose > 2) 02501 ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status); 02502 if (!strcasecmp(status, "CONGESTION")) 02503 res = pbx_builtin_congestion(c, "10"); 02504 else if (!strcasecmp(status, "CHANUNAVAIL")) 02505 res = pbx_builtin_congestion(c, "10"); 02506 else if (!strcasecmp(status, "BUSY")) 02507 res = pbx_builtin_busy(c, "10"); 02508 error = 1; /* XXX disable message */ 02509 break; /* exit from the 'for' loop */ 02510 } 02511 02512 if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos)) 02513 break; 02514 if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */ 02515 set_ext_pri(c, dst_exten, 1); 02516 else { 02517 /* No such extension */ 02518 if (!ast_strlen_zero(dst_exten)) { 02519 /* An invalid extension */ 02520 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02521 if (option_verbose > 2) 02522 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name); 02523 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten); 02524 set_ext_pri(c, "i", 1); 02525 } else { 02526 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context); 02527 found = 1; /* XXX disable message */ 02528 break; 02529 } 02530 } else { 02531 /* A simple timeout */ 02532 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) { 02533 if (option_verbose > 2) 02534 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name); 02535 set_ext_pri(c, "t", 1); 02536 } else { 02537 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context); 02538 found = 1; /* XXX disable message */ 02539 break; 02540 } 02541 } 02542 } 02543 if (c->cdr) { 02544 if (option_verbose > 2) 02545 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name); 02546 ast_cdr_update(c); 02547 } 02548 } 02549 } 02550 if (!found && !error) 02551 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); 02552 if (res != AST_PBX_KEEPALIVE) { 02553 ast_softhangup(c, AST_SOFTHANGUP_APPUNLOAD); 02554 } 02555 ast_channel_lock(c); 02556 if ((emc = pbx_builtin_getvar_helper(c, "EXIT_MACRO_CONTEXT"))) { 02557 emc = ast_strdupa(emc); 02558 } 02559 ast_channel_unlock(c); 02560 if ((res != AST_PBX_KEEPALIVE) && !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) && 02561 ((emc && ast_exists_extension(c, emc, "h", 1, c->cid.cid_num)) || 02562 (ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num) && (emc = c->context)))) { 02563 ast_copy_string(c->context, emc, sizeof(c->context)); 02564 set_ext_pri(c, "h", 1); 02565 if (c->cdr && ast_opt_end_cdr_before_h_exten) { 02566 ast_cdr_end(c->cdr); 02567 } 02568 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02569 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02570 /* Something bad happened, or a hangup has been requested. */ 02571 if (option_debug) 02572 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02573 if (option_verbose > 1) 02574 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02575 break; 02576 } 02577 c->priority++; 02578 } 02579 } 02580 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP); 02581 ast_clear_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */ 02582 pbx_destroy(c->pbx); 02583 c->pbx = NULL; 02584 if (res != AST_PBX_KEEPALIVE) 02585 ast_hangup(c); 02586 return 0; 02587 }
static int _extension_match_core | ( | const char * | pattern, | |
const char * | data, | |||
enum ext_match_t | mode | |||
) | [static] |
Definition at line 813 of file pbx.c.
References ast_log(), E_MATCH, E_MATCH_MASK, E_MATCHMORE, and LOG_WARNING.
Referenced by extension_match_core().
00814 { 00815 mode &= E_MATCH_MASK; /* only consider the relevant bits */ 00816 00817 if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */ 00818 return 1; 00819 00820 if (pattern[0] != '_') { /* not a pattern, try exact or partial match */ 00821 int ld = strlen(data), lp = strlen(pattern); 00822 00823 if (lp < ld) /* pattern too short, cannot match */ 00824 return 0; 00825 /* depending on the mode, accept full or partial match or both */ 00826 if (mode == E_MATCH) 00827 return !strcmp(pattern, data); /* 1 on match, 0 on fail */ 00828 if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */ 00829 return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */ 00830 else 00831 return 0; 00832 } 00833 pattern++; /* skip leading _ */ 00834 /* 00835 * XXX below we stop at '/' which is a separator for the CID info. However we should 00836 * not store '/' in the pattern at all. When we insure it, we can remove the checks. 00837 */ 00838 while (*data && *pattern && *pattern != '/') { 00839 const char *end; 00840 00841 if (*data == '-') { /* skip '-' in data (just a separator) */ 00842 data++; 00843 continue; 00844 } 00845 switch (toupper(*pattern)) { 00846 case '[': /* a range */ 00847 end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */ 00848 if (end == NULL) { 00849 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n"); 00850 return 0; /* unconditional failure */ 00851 } 00852 for (pattern++; pattern != end; pattern++) { 00853 if (pattern+2 < end && pattern[1] == '-') { /* this is a range */ 00854 if (*data >= pattern[0] && *data <= pattern[2]) 00855 break; /* match found */ 00856 else { 00857 pattern += 2; /* skip a total of 3 chars */ 00858 continue; 00859 } 00860 } else if (*data == pattern[0]) 00861 break; /* match found */ 00862 } 00863 if (pattern == end) 00864 return 0; 00865 pattern = end; /* skip and continue */ 00866 break; 00867 case 'N': 00868 if (*data < '2' || *data > '9') 00869 return 0; 00870 break; 00871 case 'X': 00872 if (*data < '0' || *data > '9') 00873 return 0; 00874 break; 00875 case 'Z': 00876 if (*data < '1' || *data > '9') 00877 return 0; 00878 break; 00879 case '.': /* Must match, even with more digits */ 00880 return 1; 00881 case '!': /* Early match */ 00882 return 2; 00883 case ' ': 00884 case '-': /* Ignore these in patterns */ 00885 data--; /* compensate the final data++ */ 00886 break; 00887 default: 00888 if (*data != *pattern) 00889 return 0; 00890 } 00891 data++; 00892 pattern++; 00893 } 00894 if (*data) /* data longer than pattern, no match */ 00895 return 0; 00896 /* 00897 * match so far, but ran off the end of the data. 00898 * Depending on what is next, determine match or not. 00899 */ 00900 if (*pattern == '\0' || *pattern == '/') /* exact match */ 00901 return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */ 00902 else if (*pattern == '!') /* early match */ 00903 return 2; 00904 else /* partial match */ 00905 return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */ 00906 }
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 4747 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().
04749 { 04750 struct ast_exten *ep; 04751 04752 for (ep = NULL; e ; ep = e, e = e->peer) { 04753 if (e->priority >= tmp->priority) 04754 break; 04755 } 04756 if (!e) { /* go at the end, and ep is surely set because the list is not empty */ 04757 ep->peer = tmp; 04758 return 0; /* success */ 04759 } 04760 if (e->priority == tmp->priority) { 04761 /* Can't have something exactly the same. Is this a 04762 replacement? If so, replace, otherwise, bonk. */ 04763 if (!replace) { 04764 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04765 if (tmp->datad) 04766 tmp->datad(tmp->data); 04767 free(tmp); 04768 return -1; 04769 } 04770 /* we are replacing e, so copy the link fields and then update 04771 * whoever pointed to e to point to us 04772 */ 04773 tmp->next = e->next; /* not meaningful if we are not first in the peer list */ 04774 tmp->peer = e->peer; /* always meaningful */ 04775 if (ep) /* We're in the peer list, just insert ourselves */ 04776 ep->peer = tmp; 04777 else if (el) /* We're the first extension. Take over e's functions */ 04778 el->next = tmp; 04779 else /* We're the very first extension. */ 04780 con->root = tmp; 04781 if (tmp->priority == PRIORITY_HINT) 04782 ast_change_hint(e,tmp); 04783 /* Destroy the old one */ 04784 if (e->datad) 04785 e->datad(e->data); 04786 free(e); 04787 } else { /* Slip ourselves in just before e */ 04788 tmp->peer = e; 04789 tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */ 04790 if (ep) /* Easy enough, we're just in the peer list */ 04791 ep->peer = tmp; 04792 else { /* we are the first in some peer list, so link in the ext list */ 04793 if (el) 04794 el->next = tmp; /* in the middle... */ 04795 else 04796 con->root = tmp; /* ... or at the head */ 04797 e->next = NULL; /* e is no more at the head, so e->next must be reset */ 04798 } 04799 /* And immediately return success. */ 04800 if (tmp->priority == PRIORITY_HINT) 04801 ast_add_hint(tmp); 04802 } 04803 return 0; 04804 }
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2695 of file pbx.c.
References countcalls.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02696 { 02697 return countcalls; 02698 }
int ast_add_extension | ( | const char * | context, | |
int | replace, | |||
const char * | extension, | |||
int | priority, | |||
const char * | label, | |||
const char * | callerid, | |||
const char * | application, | |||
void * | data, | |||
void(*)(void *) | datad, | |||
const char * | registrar | |||
) |
Add and extension to an extension context.
context | context to add the extension to | |
replace | ||
extension | extension to add | |
priority | priority level of extension addition | |
label | extension label | |
callerid | pattern to match CallerID, or NULL to match any CallerID | |
application | application to run on the extension with that priority level | |
data | data to pass to the application | |
datad | ||
registrar | who registered the extension |
0 | success | |
-1 | failure |
Definition at line 4616 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().
04619 { 04620 int ret = -1; 04621 struct ast_context *c = find_context_locked(context); 04622 04623 if (c) { 04624 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04625 application, data, datad, registrar); 04626 ast_unlock_contexts(); 04627 } 04628 return ret; 04629 }
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 4831 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().
04835 { 04836 /* 04837 * Sort extensions (or patterns) according to the rules indicated above. 04838 * These are implemented by the function ext_cmp()). 04839 * All priorities for the same ext/pattern/cid are kept in a list, 04840 * using the 'peer' field as a link field.. 04841 */ 04842 struct ast_exten *tmp, *e, *el = NULL; 04843 int res; 04844 int length; 04845 char *p; 04846 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04847 04848 /* if we are adding a hint, and there are global variables, and the hint 04849 contains variable references, then expand them 04850 */ 04851 ast_mutex_lock(&globalslock); 04852 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04853 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04854 application = expand_buf; 04855 } 04856 ast_mutex_unlock(&globalslock); 04857 04858 length = sizeof(struct ast_exten); 04859 length += strlen(extension) + 1; 04860 length += strlen(application) + 1; 04861 if (label) 04862 length += strlen(label) + 1; 04863 if (callerid) 04864 length += strlen(callerid) + 1; 04865 else 04866 length ++; /* just the '\0' */ 04867 04868 /* Be optimistic: Build the extension structure first */ 04869 if (!(tmp = ast_calloc(1, length))) 04870 return -1; 04871 04872 /* use p as dst in assignments, as the fields are const char * */ 04873 p = tmp->stuff; 04874 if (label) { 04875 tmp->label = p; 04876 strcpy(p, label); 04877 p += strlen(label) + 1; 04878 } 04879 tmp->exten = p; 04880 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04881 tmp->priority = priority; 04882 tmp->cidmatch = p; /* but use p for assignments below */ 04883 if (callerid) { 04884 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04885 tmp->matchcid = 1; 04886 } else { 04887 *p++ = '\0'; 04888 tmp->matchcid = 0; 04889 } 04890 tmp->app = p; 04891 strcpy(p, application); 04892 tmp->parent = con; 04893 tmp->data = data; 04894 tmp->datad = datad; 04895 tmp->registrar = registrar; 04896 04897 ast_mutex_lock(&con->lock); 04898 res = 0; /* some compilers will think it is uninitialized otherwise */ 04899 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04900 res = ext_cmp(e->exten, tmp->exten); 04901 if (res == 0) { /* extension match, now look at cidmatch */ 04902 if (!e->matchcid && !tmp->matchcid) 04903 res = 0; 04904 else if (tmp->matchcid && !e->matchcid) 04905 res = 1; 04906 else if (e->matchcid && !tmp->matchcid) 04907 res = -1; 04908 else 04909 res = ext_cmp(e->cidmatch, tmp->cidmatch); 04910 } 04911 if (res >= 0) 04912 break; 04913 } 04914 if (e && res == 0) { /* exact match, insert in the pri chain */ 04915 res = add_pri(con, tmp, el, e, replace); 04916 ast_mutex_unlock(&con->lock); 04917 if (res < 0) { 04918 errno = EEXIST; /* XXX do we care ? */ 04919 return 0; /* XXX should we return -1 maybe ? */ 04920 } 04921 } else { 04922 /* 04923 * not an exact match, this is the first entry with this pattern, 04924 * so insert in the main list right before 'e' (if any) 04925 */ 04926 tmp->next = e; 04927 if (el) 04928 el->next = tmp; 04929 else 04930 con->root = tmp; 04931 ast_mutex_unlock(&con->lock); 04932 if (tmp->priority == PRIORITY_HINT) 04933 ast_add_hint(tmp); 04934 } 04935 if (option_debug) { 04936 if (tmp->matchcid) { 04937 if (option_debug) 04938 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 04939 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04940 } else { 04941 if (option_debug) 04942 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 04943 tmp->exten, tmp->priority, con->name); 04944 } 04945 } 04946 if (option_verbose > 2) { 04947 if (tmp->matchcid) { 04948 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 04949 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 04950 } else { 04951 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 04952 tmp->exten, tmp->priority, con->name); 04953 } 04954 } 04955 return 0; 04956 }
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 2192 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().
02193 { 02194 struct ast_hint *hint; 02195 02196 if (!e) 02197 return -1; 02198 02199 AST_LIST_LOCK(&hints); 02200 02201 /* Search if hint exists, do nothing */ 02202 AST_LIST_TRAVERSE(&hints, hint, list) { 02203 if (hint->exten == e) { 02204 AST_LIST_UNLOCK(&hints); 02205 if (option_debug > 1) 02206 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02207 return -1; 02208 } 02209 } 02210 02211 if (option_debug > 1) 02212 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02213 02214 if (!(hint = ast_calloc(1, sizeof(*hint)))) { 02215 AST_LIST_UNLOCK(&hints); 02216 return -1; 02217 } 02218 /* Initialize and insert new item at the top */ 02219 hint->exten = e; 02220 hint->laststate = ast_extension_state2(e); 02221 AST_LIST_INSERT_HEAD(&hints, hint, list); 02222 02223 AST_LIST_UNLOCK(&hints); 02224 return 0; 02225 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4654 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().
04655 { 04656 int res = 0; 04657 04658 ast_channel_lock(chan); 04659 04660 if (chan->pbx) { /* This channel is currently in the PBX */ 04661 ast_explicit_goto(chan, context, exten, priority); 04662 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04663 } else { 04664 /* In order to do it when the channel doesn't really exist within 04665 the PBX, we have to make a new channel, masquerade, and start the PBX 04666 at the new location */ 04667 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04668 if (!tmpchan) { 04669 res = -1; 04670 } else { 04671 if (chan->cdr) { 04672 ast_cdr_discard(tmpchan->cdr); 04673 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04674 } 04675 /* Make formats okay */ 04676 tmpchan->readformat = chan->readformat; 04677 tmpchan->writeformat = chan->writeformat; 04678 /* Setup proper location */ 04679 ast_explicit_goto(tmpchan, 04680 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04681 04682 /* Masquerade into temp channel */ 04683 if (ast_channel_masquerade(tmpchan, chan)) { 04684 /* Failed to set up the masquerade. It's probably chan_local 04685 * in the middle of optimizing itself out. Sad. :( */ 04686 ast_hangup(tmpchan); 04687 tmpchan = NULL; 04688 res = -1; 04689 } else { 04690 /* Grab the locks and get going */ 04691 ast_channel_lock(tmpchan); 04692 ast_do_masquerade(tmpchan); 04693 ast_channel_unlock(tmpchan); 04694 /* Start the PBX going on our stolen channel */ 04695 if (ast_pbx_start(tmpchan)) { 04696 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04697 ast_hangup(tmpchan); 04698 res = -1; 04699 } 04700 } 04701 } 04702 } 04703 ast_channel_unlock(chan); 04704 return res; 04705 }
int ast_async_goto_by_name | ( | const char * | channame, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4707 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04708 { 04709 struct ast_channel *chan; 04710 int res = -1; 04711 04712 chan = ast_get_channel_by_name_locked(channame); 04713 if (chan) { 04714 res = ast_async_goto(chan, context, exten, priority); 04715 ast_channel_unlock(chan); 04716 } 04717 return res; 04718 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6525 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06526 { 06527 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06528 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info_in | |||
) |
Definition at line 4294 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().
04295 { 04296 char info_save[256]; 04297 char *info; 04298 04299 /* Check for empty just in case */ 04300 if (ast_strlen_zero(info_in)) 04301 return 0; 04302 /* make a copy just in case we were passed a static string */ 04303 ast_copy_string(info_save, info_in, sizeof(info_save)); 04304 info = info_save; 04305 /* Assume everything except time */ 04306 i->monthmask = 0xfff; /* 12 bits */ 04307 i->daymask = 0x7fffffffU; /* 31 bits */ 04308 i->dowmask = 0x7f; /* 7 bits */ 04309 /* on each call, use strsep() to move info to the next argument */ 04310 get_timerange(i, strsep(&info, "|")); 04311 if (info) 04312 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04313 if (info) 04314 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04315 if (info) 04316 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04317 return 1; 04318 }
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 2316 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().
02317 { 02318 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02319 }
ast_change_hint: Change hint for an extension
Definition at line 2228 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().
02229 { 02230 struct ast_hint *hint; 02231 int res = -1; 02232 02233 AST_LIST_LOCK(&hints); 02234 AST_LIST_TRAVERSE(&hints, hint, list) { 02235 if (hint->exten == oe) { 02236 hint->exten = ne; 02237 res = 0; 02238 break; 02239 } 02240 } 02241 AST_LIST_UNLOCK(&hints); 02242 02243 return res; 02244 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4320 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().
04321 { 04322 struct tm tm; 04323 time_t t = time(NULL); 04324 04325 ast_localtime(&t, &tm, NULL); 04326 04327 /* If it's not the right month, return */ 04328 if (!(i->monthmask & (1 << tm.tm_mon))) 04329 return 0; 04330 04331 /* If it's not that time of the month.... */ 04332 /* Warning, tm_mday has range 1..31! */ 04333 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04334 return 0; 04335 04336 /* If it's not the right day of the week */ 04337 if (!(i->dowmask & (1 << tm.tm_wday))) 04338 return 0; 04339 04340 /* Sanity check the hour just to be safe */ 04341 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04342 ast_log(LOG_WARNING, "Insane time...\n"); 04343 return 0; 04344 } 04345 04346 /* Now the tough part, we calculate if it fits 04347 in the right time based on min/hour */ 04348 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04349 return 0; 04350 04351 /* If we got this far, then we're good */ 04352 return 1; 04353 }
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 4547 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().
04548 { 04549 int ret = -1; 04550 struct ast_context *c = find_context_locked(context); 04551 04552 if (c) { 04553 ret = ast_context_add_ignorepat2(c, value, registrar); 04554 ast_unlock_contexts(); 04555 } 04556 return ret; 04557 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | value, | |||
const char * | registrar | |||
) |
Definition at line 4559 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().
04560 { 04561 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04562 int length; 04563 char *pattern; 04564 length = sizeof(struct ast_ignorepat); 04565 length += strlen(value) + 1; 04566 if (!(ignorepat = ast_calloc(1, length))) 04567 return -1; 04568 /* The cast to char * is because we need to write the initial value. 04569 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04570 * sees the cast as dereferencing a type-punned pointer and warns about 04571 * it. This is the workaround (we're telling gcc, yes, that's really 04572 * what we wanted to do). 04573 */ 04574 pattern = (char *) ignorepat->pattern; 04575 strcpy(pattern, value); 04576 ignorepat->next = NULL; 04577 ignorepat->registrar = registrar; 04578 ast_mutex_lock(&con->lock); 04579 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04580 ignorepatl = ignorepatc; 04581 if (!strcasecmp(ignorepatc->pattern, value)) { 04582 /* Already there */ 04583 ast_mutex_unlock(&con->lock); 04584 errno = EEXIST; 04585 return -1; 04586 } 04587 } 04588 if (ignorepatl) 04589 ignorepatl->next = ignorepat; 04590 else 04591 con->ignorepats = ignorepat; 04592 ast_mutex_unlock(&con->lock); 04593 return 0; 04594 04595 }
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 4100 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().
04101 { 04102 int ret = -1; 04103 struct ast_context *c = find_context_locked(context); 04104 04105 if (c) { 04106 ret = ast_context_add_include2(c, include, registrar); 04107 ast_unlock_contexts(); 04108 } 04109 return ret; 04110 }
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 4362 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().
04364 { 04365 struct ast_include *new_include; 04366 char *c; 04367 struct ast_include *i, *il = NULL; /* include, include_last */ 04368 int length; 04369 char *p; 04370 04371 length = sizeof(struct ast_include); 04372 length += 2 * (strlen(value) + 1); 04373 04374 /* allocate new include structure ... */ 04375 if (!(new_include = ast_calloc(1, length))) 04376 return -1; 04377 /* Fill in this structure. Use 'p' for assignments, as the fields 04378 * in the structure are 'const char *' 04379 */ 04380 p = new_include->stuff; 04381 new_include->name = p; 04382 strcpy(p, value); 04383 p += strlen(value) + 1; 04384 new_include->rname = p; 04385 strcpy(p, value); 04386 /* Strip off timing info, and process if it is there */ 04387 if ( (c = strchr(p, '|')) ) { 04388 *c++ = '\0'; 04389 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04390 } 04391 new_include->next = NULL; 04392 new_include->registrar = registrar; 04393 04394 ast_mutex_lock(&con->lock); 04395 04396 /* ... go to last include and check if context is already included too... */ 04397 for (i = con->includes; i; i = i->next) { 04398 if (!strcasecmp(i->name, new_include->name)) { 04399 free(new_include); 04400 ast_mutex_unlock(&con->lock); 04401 errno = EEXIST; 04402 return -1; 04403 } 04404 il = i; 04405 } 04406 04407 /* ... include new context into context list, unlock, return */ 04408 if (il) 04409 il->next = new_include; 04410 else 04411 con->includes = new_include; 04412 if (option_verbose > 2) 04413 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04414 ast_mutex_unlock(&con->lock); 04415 04416 return 0; 04417 }
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 4424 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04425 { 04426 int ret = -1; 04427 struct ast_context *c = find_context_locked(context); 04428 04429 if (c) { /* found, add switch to this context */ 04430 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04431 ast_unlock_contexts(); 04432 } 04433 return ret; 04434 }
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 4443 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().
04445 { 04446 struct ast_sw *new_sw; 04447 struct ast_sw *i; 04448 int length; 04449 char *p; 04450 04451 length = sizeof(struct ast_sw); 04452 length += strlen(value) + 1; 04453 if (data) 04454 length += strlen(data); 04455 length++; 04456 04457 /* allocate new sw structure ... */ 04458 if (!(new_sw = ast_calloc(1, length))) 04459 return -1; 04460 /* ... fill in this structure ... */ 04461 p = new_sw->stuff; 04462 new_sw->name = p; 04463 strcpy(new_sw->name, value); 04464 p += strlen(value) + 1; 04465 new_sw->data = p; 04466 if (data) { 04467 strcpy(new_sw->data, data); 04468 p += strlen(data) + 1; 04469 } else { 04470 strcpy(new_sw->data, ""); 04471 p++; 04472 } 04473 new_sw->eval = eval; 04474 new_sw->registrar = registrar; 04475 04476 /* ... try to lock this context ... */ 04477 ast_mutex_lock(&con->lock); 04478 04479 /* ... go to last sw and check if context is already swd too... */ 04480 AST_LIST_TRAVERSE(&con->alts, i, list) { 04481 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04482 free(new_sw); 04483 ast_mutex_unlock(&con->lock); 04484 errno = EEXIST; 04485 return -1; 04486 } 04487 } 04488 04489 /* ... sw new context into context list, unlock, return */ 04490 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04491 04492 if (option_verbose > 2) 04493 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04494 04495 ast_mutex_unlock(&con->lock); 04496 04497 return 0; 04498 }
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 3970 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), park_call_full(), and set_config().
03971 { 03972 return __ast_context_create(extcontexts, name, registrar, 0); 03973 }
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 5412 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().
05413 { 05414 ast_wrlock_contexts(); 05415 __ast_context_destroy(con,registrar); 05416 ast_unlock_contexts(); 05417 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 936 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().
00937 { 00938 struct ast_context *tmp = NULL; 00939 00940 ast_rdlock_contexts(); 00941 00942 while ( (tmp = ast_walk_contexts(tmp)) ) { 00943 if (!name || !strcasecmp(name, tmp->name)) 00944 break; 00945 } 00946 00947 ast_unlock_contexts(); 00948 00949 return tmp; 00950 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
Definition at line 3975 of file pbx.c.
References __ast_context_create().
Referenced by pbx_load_config(), and pbx_load_users().
03976 { 03977 return __ast_context_create(extcontexts, name, registrar, 1); 03978 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 2937 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().
02938 { 02939 struct ast_context *c = NULL; 02940 int ret = -1; 02941 02942 ast_rdlock_contexts(); 02943 02944 while ((c = ast_walk_contexts(c))) { 02945 if (!strcmp(ast_get_context_name(c), context)) { 02946 ret = 0; 02947 break; 02948 } 02949 } 02950 02951 ast_unlock_contexts(); 02952 02953 /* if we found context, lock macrolock */ 02954 if (ret == 0) 02955 ret = ast_mutex_lock(&c->macrolock); 02956 02957 return ret; 02958 }
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 2838 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02839 { 02840 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02841 }
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 2865 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02866 { 02867 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02868 }
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 2843 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().
02844 { 02845 int ret = -1; /* default error return */ 02846 struct ast_context *c = find_context_locked(context); 02847 02848 if (c) { /* ... remove extension ... */ 02849 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02850 ast_unlock_contexts(); 02851 } 02852 return ret; 02853 }
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 2870 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().
02871 { 02872 struct ast_exten *exten, *prev_exten = NULL; 02873 struct ast_exten *peer; 02874 struct ast_exten *previous_peer = NULL; 02875 struct ast_exten *next_peer = NULL; 02876 int found = 0; 02877 02878 ast_mutex_lock(&con->lock); 02879 02880 /* scan the extension list to find first matching extension-registrar */ 02881 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02882 if (!strcmp(exten->exten, extension) && 02883 (!registrar || !strcmp(exten->registrar, registrar))) 02884 break; 02885 } 02886 if (!exten) { 02887 /* we can't find right extension */ 02888 ast_mutex_unlock(&con->lock); 02889 return -1; 02890 } 02891 02892 /* scan the priority list to remove extension with exten->priority == priority */ 02893 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02894 peer && !strcmp(peer->exten, extension); 02895 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02896 if ((priority == 0 || peer->priority == priority) && 02897 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02898 (!registrar || !strcmp(peer->registrar, registrar) )) { 02899 found = 1; 02900 02901 /* we are first priority extension? */ 02902 if (!previous_peer) { 02903 /* 02904 * We are first in the priority chain, so must update the extension chain. 02905 * The next node is either the next priority or the next extension 02906 */ 02907 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02908 02909 if (!prev_exten) { /* change the root... */ 02910 con->root = next_node; 02911 } else { 02912 prev_exten->next = next_node; /* unlink */ 02913 } 02914 if (peer->peer) { /* update the new head of the pri list */ 02915 peer->peer->next = peer->next; 02916 } 02917 } else { /* easy, we are not first priority in extension */ 02918 previous_peer->peer = peer->peer; 02919 } 02920 02921 /* now, free whole priority extension */ 02922 destroy_exten(peer); 02923 } else { 02924 previous_peer = peer; 02925 } 02926 } 02927 ast_mutex_unlock(&con->lock); 02928 return found ? 0 : -1; 02929 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4504 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().
04505 { 04506 int ret = -1; 04507 struct ast_context *c = find_context_locked(context); 04508 04509 if (c) { 04510 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04511 ast_unlock_contexts(); 04512 } 04513 return ret; 04514 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4516 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().
04517 { 04518 struct ast_ignorepat *ip, *ipl = NULL; 04519 04520 ast_mutex_lock(&con->lock); 04521 04522 for (ip = con->ignorepats; ip; ip = ip->next) { 04523 if (!strcmp(ip->pattern, ignorepat) && 04524 (!registrar || (registrar == ip->registrar))) { 04525 if (ipl) { 04526 ipl->next = ip->next; 04527 free(ip); 04528 } else { 04529 con->ignorepats = ip->next; 04530 free(ip); 04531 } 04532 ast_mutex_unlock(&con->lock); 04533 return 0; 04534 } 04535 ipl = ip; 04536 } 04537 04538 ast_mutex_unlock(&con->lock); 04539 errno = EINVAL; 04540 return -1; 04541 }
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 2734 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().
02735 { 02736 int ret = -1; 02737 struct ast_context *c = find_context_locked(context); 02738 02739 if (c) { 02740 /* found, remove include from this context ... */ 02741 ret = ast_context_remove_include2(c, include, registrar); 02742 ast_unlock_contexts(); 02743 } 02744 return ret; 02745 }
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 2755 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().
02756 { 02757 struct ast_include *i, *pi = NULL; 02758 int ret = -1; 02759 02760 ast_mutex_lock(&con->lock); 02761 02762 /* find our include */ 02763 for (i = con->includes; i; pi = i, i = i->next) { 02764 if (!strcmp(i->name, include) && 02765 (!registrar || !strcmp(i->registrar, registrar))) { 02766 /* remove from list */ 02767 if (pi) 02768 pi->next = i->next; 02769 else 02770 con->includes = i->next; 02771 /* free include and return */ 02772 free(i); 02773 ret = 0; 02774 break; 02775 } 02776 } 02777 02778 ast_mutex_unlock(&con->lock); 02779 return ret; 02780 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2787 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02788 { 02789 int ret = -1; /* default error return */ 02790 struct ast_context *c = find_context_locked(context); 02791 02792 if (c) { 02793 /* remove switch from this context ... */ 02794 ret = ast_context_remove_switch2(c, sw, data, registrar); 02795 ast_unlock_contexts(); 02796 } 02797 return ret; 02798 }
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 2808 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().
02809 { 02810 struct ast_sw *i; 02811 int ret = -1; 02812 02813 ast_mutex_lock(&con->lock); 02814 02815 /* walk switches */ 02816 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02817 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02818 (!registrar || !strcmp(i->registrar, registrar))) { 02819 /* found, remove from list */ 02820 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02821 free(i); /* free switch and return */ 02822 ret = 0; 02823 break; 02824 } 02825 } 02826 AST_LIST_TRAVERSE_SAFE_END 02827 02828 ast_mutex_unlock(&con->lock); 02829 02830 return ret; 02831 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 2965 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().
02966 { 02967 struct ast_context *c = NULL; 02968 int ret = -1; 02969 02970 ast_rdlock_contexts(); 02971 02972 while ((c = ast_walk_contexts(c))) { 02973 if (!strcmp(ast_get_context_name(c), context)) { 02974 ret = 0; 02975 break; 02976 } 02977 } 02978 02979 ast_unlock_contexts(); 02980 02981 /* if we found context, unlock macrolock */ 02982 if (ret == 0) 02983 ret = ast_mutex_unlock(&c->macrolock); 02984 02985 return ret; 02986 }
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 6482 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().
06483 { 06484 struct ast_include *inc = NULL; 06485 int res = 0; 06486 06487 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06488 if (ast_context_find(inc->rname)) 06489 continue; 06490 06491 res = -1; 06492 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06493 ast_get_context_name(con), inc->rname); 06494 break; 06495 } 06496 06497 return res; 06498 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 1498 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().
01499 { 01500 struct ast_custom_function *acf = NULL; 01501 01502 AST_LIST_LOCK(&acf_root); 01503 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01504 if (!strcmp(name, acf->name)) 01505 break; 01506 } 01507 AST_LIST_UNLOCK(&acf_root); 01508 01509 return acf; 01510 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1534 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().
01535 { 01536 struct ast_custom_function *cur; 01537 01538 if (!acf) 01539 return -1; 01540 01541 AST_LIST_LOCK(&acf_root); 01542 01543 if (ast_custom_function_find(acf->name)) { 01544 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01545 AST_LIST_UNLOCK(&acf_root); 01546 return -1; 01547 } 01548 01549 /* Store in alphabetical order */ 01550 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01551 if (strcasecmp(acf->name, cur->name) < 0) { 01552 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01553 break; 01554 } 01555 } 01556 AST_LIST_TRAVERSE_SAFE_END 01557 if (!cur) 01558 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01559 01560 AST_LIST_UNLOCK(&acf_root); 01561 01562 if (option_verbose > 1) 01563 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01564 01565 return 0; 01566 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1512 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().
01513 { 01514 struct ast_custom_function *cur; 01515 01516 if (!acf) 01517 return -1; 01518 01519 AST_LIST_LOCK(&acf_root); 01520 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01521 if (cur == acf) { 01522 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01523 if (option_verbose > 1) 01524 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01525 break; 01526 } 01527 } 01528 AST_LIST_TRAVERSE_SAFE_END 01529 AST_LIST_UNLOCK(&acf_root); 01530 01531 return acf ? 0 : -1; 01532 }
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 1962 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().
01963 { 01964 switch (devstate) { 01965 case AST_DEVICE_ONHOLD: 01966 return AST_EXTENSION_ONHOLD; 01967 case AST_DEVICE_BUSY: 01968 return AST_EXTENSION_BUSY; 01969 case AST_DEVICE_UNAVAILABLE: 01970 case AST_DEVICE_UNKNOWN: 01971 case AST_DEVICE_INVALID: 01972 return AST_EXTENSION_UNAVAILABLE; 01973 case AST_DEVICE_RINGINUSE: 01974 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 01975 case AST_DEVICE_RINGING: 01976 return AST_EXTENSION_RINGING; 01977 case AST_DEVICE_INUSE: 01978 return AST_EXTENSION_INUSE; 01979 case AST_DEVICE_NOT_INUSE: 01980 return AST_EXTENSION_NOT_INUSE; 01981 case AST_DEVICE_TOTAL: /* not a device state, included for completeness */ 01982 break; 01983 } 01984 01985 return AST_EXTENSION_NOT_INUSE; 01986 }
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 2301 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(), dahdi_r2_on_call_offered(), dahdi_r2_on_dnis_digit_received(), 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().
02302 { 02303 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02304 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4631 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().
04632 { 04633 if (!chan) 04634 return -1; 04635 04636 ast_channel_lock(chan); 04637 04638 if (!ast_strlen_zero(context)) 04639 ast_copy_string(chan->context, context, sizeof(chan->context)); 04640 if (!ast_strlen_zero(exten)) 04641 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04642 if (priority > -1) { 04643 chan->priority = priority; 04644 /* see flag description in channel.h for explanation */ 04645 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04646 chan->priority--; 04647 } 04648 04649 ast_channel_unlock(chan); 04650 04651 return 0; 04652 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 929 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00930 { 00931 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00932 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00933 return extension_match_core(pattern, data, needmore); 00934 }
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 924 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().
00925 { 00926 return extension_match_core(pattern, data, E_MATCH); 00927 }
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 2023 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
02024 { 02025 struct ast_exten *e; 02026 02027 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 02028 if (!e) 02029 return -1; /* No hint, return -1 */ 02030 02031 return ast_extension_state2(e); /* Check all devices in the hint */ 02032 }
static int ast_extension_state2 | ( | struct ast_exten * | e | ) | [static] |
ast_extensions_state2: Check state of extension by using hints
Definition at line 1989 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().
01990 { 01991 char hint[AST_MAX_EXTENSION]; 01992 char *cur, *rest; 01993 struct ast_devstate_aggregate agg; 01994 01995 ast_devstate_aggregate_init(&agg); 01996 01997 if (!e) 01998 return -1; 01999 02000 ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint)); 02001 02002 rest = hint; /* One or more devices separated with a & character */ 02003 while ( (cur = strsep(&rest, "&")) ) { 02004 int res = ast_device_state(cur); 02005 ast_devstate_aggregate_add(&agg, res); 02006 } 02007 return ast_devstate_to_extenstate(ast_devstate_aggregate_result(&agg)); 02008 }
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 2011 of file pbx.c.
References extension_states.
Referenced by cb_extensionstate(), handle_request_subscribe(), and handle_show_hints().
02012 { 02013 int i; 02014 02015 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 02016 if (extension_states[i].extension_state == extension_state) 02017 return extension_states[i].text; 02018 } 02019 return "Unknown"; 02020 }
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 2080 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().
02082 { 02083 struct ast_hint *hint; 02084 struct ast_state_cb *cblist; 02085 struct ast_exten *e; 02086 02087 /* If there's no context and extension: add callback to statecbs list */ 02088 if (!context && !exten) { 02089 AST_LIST_LOCK(&hints); 02090 02091 for (cblist = statecbs; cblist; cblist = cblist->next) { 02092 if (cblist->callback == callback) { 02093 cblist->data = data; 02094 AST_LIST_UNLOCK(&hints); 02095 return 0; 02096 } 02097 } 02098 02099 /* Now insert the callback */ 02100 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02101 AST_LIST_UNLOCK(&hints); 02102 return -1; 02103 } 02104 cblist->id = 0; 02105 cblist->callback = callback; 02106 cblist->data = data; 02107 02108 cblist->next = statecbs; 02109 statecbs = cblist; 02110 02111 AST_LIST_UNLOCK(&hints); 02112 return 0; 02113 } 02114 02115 if (!context || !exten) 02116 return -1; 02117 02118 /* This callback type is for only one hint, so get the hint */ 02119 e = ast_hint_extension(NULL, context, exten); 02120 if (!e) { 02121 return -1; 02122 } 02123 02124 /* Find the hint in the list of hints */ 02125 AST_LIST_LOCK(&hints); 02126 02127 AST_LIST_TRAVERSE(&hints, hint, list) { 02128 if (hint->exten == e) 02129 break; 02130 } 02131 02132 if (!hint) { 02133 /* We have no hint, sorry */ 02134 AST_LIST_UNLOCK(&hints); 02135 return -1; 02136 } 02137 02138 /* Now insert the callback in the callback list */ 02139 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02140 AST_LIST_UNLOCK(&hints); 02141 return -1; 02142 } 02143 cblist->id = stateid++; /* Unique ID for this callback */ 02144 cblist->callback = callback; /* Pointer to callback routine */ 02145 cblist->data = data; /* Data for the callback */ 02146 02147 cblist->next = hint->callbacks; 02148 hint->callbacks = cblist; 02149 02150 AST_LIST_UNLOCK(&hints); 02151 return cblist->id; 02152 }
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 2155 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().
02156 { 02157 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02158 int ret = -1; 02159 02160 if (!id && !callback) 02161 return -1; 02162 02163 AST_LIST_LOCK(&hints); 02164 02165 if (!id) { /* id == 0 is a callback without extension */ 02166 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02167 if ((*p_cur)->callback == callback) 02168 break; 02169 } 02170 } else { /* callback with extension, find the callback based on ID */ 02171 struct ast_hint *hint; 02172 AST_LIST_TRAVERSE(&hints, hint, list) { 02173 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02174 if ((*p_cur)->id == id) 02175 break; 02176 } 02177 if (*p_cur) /* found in the inner loop */ 02178 break; 02179 } 02180 } 02181 if (p_cur && *p_cur) { 02182 struct ast_state_cb *cur = *p_cur; 02183 *p_cur = cur->next; 02184 free(cur); 02185 ret = 0; 02186 } 02187 AST_LIST_UNLOCK(&hints); 02188 return ret; 02189 }
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 2306 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().
02307 { 02308 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02309 }
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 2311 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02312 { 02313 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02314 }
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 1588 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().
01589 { 01590 char *args = func_args(function); 01591 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01592 01593 if (acfptr == NULL) 01594 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01595 else if (!acfptr->read) 01596 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01597 else 01598 return acfptr->read(chan, function, args, workspace, len); 01599 return -1; 01600 }
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 1602 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().
01603 { 01604 char *args = func_args(function); 01605 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01606 01607 if (acfptr == NULL) 01608 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01609 else if (!acfptr->write) 01610 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01611 else 01612 return acfptr->write(chan, function, args, value); 01613 01614 return -1; 01615 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6339 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().
06340 { 06341 return con ? con->name : NULL; 06342 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6377 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06378 { 06379 return c ? c->registrar : NULL; 06380 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6407 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().
06408 { 06409 return e ? e->app : NULL; 06410 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6412 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06413 { 06414 return e ? e->data : NULL; 06415 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6402 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().
06403 { 06404 return e ? e->cidmatch : NULL; 06405 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | exten | ) |
Definition at line 6354 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 6397 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().
06398 { 06399 return e ? e->matchcid : 0; 06400 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6349 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 6369 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 6382 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06383 { 06384 return e ? e->registrar : NULL; 06385 }
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 2284 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().
02285 { 02286 struct ast_exten *e = ast_hint_extension(c, context, exten); 02287 02288 if (e) { 02289 if (hint) 02290 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02291 if (name) { 02292 const char *tmp = ast_get_extension_app_data(e); 02293 if (tmp) 02294 ast_copy_string(name, tmp, namesize); 02295 } 02296 return -1; 02297 } 02298 return 0; 02299 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6364 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().
06365 { 06366 return ip ? ip->pattern : NULL; 06367 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6392 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06393 { 06394 return ip ? ip->registrar : NULL; 06395 }
const char* ast_get_include_name | ( | struct ast_include * | inc | ) |
Definition at line 6359 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().
06360 { 06361 return inc ? inc->name : NULL; 06362 }
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6387 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06388 { 06389 return i ? i->registrar : NULL; 06390 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6422 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06423 { 06424 return sw ? sw->data : NULL; 06425 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6417 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06418 { 06419 return sw ? sw->name : NULL; 06420 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6427 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06428 { 06429 return sw ? sw->registrar : NULL; 06430 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6520 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().
06521 { 06522 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06523 }
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 1950 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().
01951 { 01952 struct ast_exten *e; 01953 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */ 01954 01955 ast_rdlock_contexts(); 01956 e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH); 01957 ast_unlock_contexts(); 01958 01959 return e; 01960 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 2034 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().
02035 { 02036 struct ast_hint *hint; 02037 02038 ast_rdlock_contexts(); 02039 AST_LIST_LOCK(&hints); 02040 02041 AST_LIST_TRAVERSE(&hints, hint, list) { 02042 struct ast_state_cb *cblist; 02043 char buf[AST_MAX_EXTENSION]; 02044 char *parse = buf; 02045 char *cur; 02046 int state; 02047 02048 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 02049 while ( (cur = strsep(&parse, "&")) ) { 02050 if (!strcasecmp(cur, device)) 02051 break; 02052 } 02053 if (!cur) 02054 continue; 02055 02056 /* Get device state for this hint */ 02057 state = ast_extension_state2(hint->exten); 02058 02059 if ((state == -1) || (state == hint->laststate)) 02060 continue; 02061 02062 /* Device state changed since last check - notify the watchers */ 02063 02064 /* For general callbacks */ 02065 for (cblist = statecbs; cblist; cblist = cblist->next) 02066 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02067 02068 /* For extension callbacks */ 02069 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 02070 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02071 02072 hint->laststate = state; /* record we saw the change */ 02073 } 02074 02075 AST_LIST_UNLOCK(&hints); 02076 ast_unlock_contexts(); 02077 }
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 4597 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().
04598 { 04599 struct ast_context *con = ast_context_find(context); 04600 if (con) { 04601 struct ast_ignorepat *pat; 04602 for (pat = con->ignorepats; pat; pat = pat->next) { 04603 if (ast_extension_match(pat->pattern, pattern)) 04604 return 1; 04605 } 04606 } 04607 04608 return 0; 04609 }
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 6326 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().
06327 { 06328 return ast_mutex_lock(&con->lock); 06329 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6303 of file pbx.c.
References ast_rwlock_wrlock(), and conlock.
Referenced by find_matching_endwhile().
06304 { 06305 return ast_rwlock_wrlock(&conlock); 06306 }
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 2321 of file pbx.c.
References E_MATCHMORE, and pbx_extension_helper().
Referenced by ast_app_dtget(), collect_digits(), dahdi_r2_on_dnis_digit_received(), disa_exec(), dp_lookup(), dundi_lookup_local(), handle_stimulus_message(), loopback_matchmore(), mgcp_ss(), pbx_builtin_background(), skinny_ss(), and ss_thread().
02322 { 02323 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02324 }
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 3993 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().
03994 { 03995 struct ast_context *tmp, *lasttmp = NULL; 03996 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 03997 struct store_hint *this; 03998 struct ast_hint *hint; 03999 struct ast_exten *exten; 04000 int length; 04001 struct ast_state_cb *thiscb, *prevcb; 04002 04003 /* it is very important that this function hold the hint list lock _and_ the conlock 04004 during its operation; not only do we need to ensure that the list of contexts 04005 and extensions does not change, but also that no hint callbacks (watchers) are 04006 added or removed during the merge/delete process 04007 04008 in addition, the locks _must_ be taken in this order, because there are already 04009 other code paths that use this order 04010 */ 04011 ast_wrlock_contexts(); 04012 AST_LIST_LOCK(&hints); 04013 04014 /* preserve all watchers for hints associated with this registrar */ 04015 AST_LIST_TRAVERSE(&hints, hint, list) { 04016 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 04017 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 04018 if (!(this = ast_calloc(1, length))) 04019 continue; 04020 this->callbacks = hint->callbacks; 04021 hint->callbacks = NULL; 04022 this->laststate = hint->laststate; 04023 this->context = this->data; 04024 strcpy(this->data, hint->exten->parent->name); 04025 this->exten = this->data + strlen(this->context) + 1; 04026 strcpy(this->exten, hint->exten->exten); 04027 AST_LIST_INSERT_HEAD(&store, this, list); 04028 } 04029 } 04030 04031 tmp = *extcontexts; 04032 if (registrar) { 04033 /* XXX remove previous contexts from same registrar */ 04034 if (option_debug) 04035 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 04036 __ast_context_destroy(NULL,registrar); 04037 while (tmp) { 04038 lasttmp = tmp; 04039 tmp = tmp->next; 04040 } 04041 } else { 04042 /* XXX remove contexts with the same name */ 04043 while (tmp) { 04044 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04045 __ast_context_destroy(tmp,tmp->registrar); 04046 lasttmp = tmp; 04047 tmp = tmp->next; 04048 } 04049 } 04050 if (lasttmp) { 04051 lasttmp->next = contexts; 04052 contexts = *extcontexts; 04053 *extcontexts = NULL; 04054 } else 04055 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04056 04057 /* restore the watchers for hints that can be found; notify those that 04058 cannot be restored 04059 */ 04060 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04061 struct pbx_find_info q = { .stacklen = 0 }; 04062 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04063 /* Find the hint in the list of hints */ 04064 AST_LIST_TRAVERSE(&hints, hint, list) { 04065 if (hint->exten == exten) 04066 break; 04067 } 04068 if (!exten || !hint) { 04069 /* this hint has been removed, notify the watchers */ 04070 prevcb = NULL; 04071 thiscb = this->callbacks; 04072 while (thiscb) { 04073 prevcb = thiscb; 04074 thiscb = thiscb->next; 04075 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04076 free(prevcb); 04077 } 04078 } else { 04079 thiscb = this->callbacks; 04080 while (thiscb->next) 04081 thiscb = thiscb->next; 04082 thiscb->next = hint->callbacks; 04083 hint->callbacks = this->callbacks; 04084 hint->laststate = this->laststate; 04085 } 04086 free(this); 04087 } 04088 04089 AST_LIST_UNLOCK(&hints); 04090 ast_unlock_contexts(); 04091 04092 return; 04093 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6530 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().
06531 { 06532 char *exten, *pri, *context; 06533 char *stringp; 06534 int ipri; 06535 int mode = 0; 06536 06537 if (ast_strlen_zero(goto_string)) { 06538 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06539 return -1; 06540 } 06541 stringp = ast_strdupa(goto_string); 06542 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06543 exten = strsep(&stringp, "|"); 06544 pri = strsep(&stringp, "|"); 06545 if (!exten) { /* Only a priority in this one */ 06546 pri = context; 06547 exten = NULL; 06548 context = NULL; 06549 } else if (!pri) { /* Only an extension and priority in this one */ 06550 pri = exten; 06551 exten = context; 06552 context = NULL; 06553 } 06554 if (*pri == '+') { 06555 mode = 1; 06556 pri++; 06557 } else if (*pri == '-') { 06558 mode = -1; 06559 pri++; 06560 } 06561 if (sscanf(pri, "%30d", &ipri) != 1) { 06562 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06563 pri, chan->cid.cid_num)) < 1) { 06564 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06565 return -1; 06566 } else 06567 mode = 0; 06568 } 06569 /* At this point we have a priority and maybe an extension and a context */ 06570 06571 if (mode) 06572 ipri = chan->priority + (ipri * mode); 06573 06574 ast_explicit_goto(chan, context, exten, ipri); 06575 return 0; 06576 06577 }
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 5224 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().
05225 { 05226 struct ast_channel *chan; 05227 struct app_tmp *tmp; 05228 int res = -1, cdr_res = -1; 05229 struct outgoing_helper oh; 05230 pthread_attr_t attr; 05231 05232 memset(&oh, 0, sizeof(oh)); 05233 oh.vars = vars; 05234 oh.account = account; 05235 05236 if (locked_channel) 05237 *locked_channel = NULL; 05238 if (ast_strlen_zero(app)) { 05239 res = -1; 05240 goto outgoing_app_cleanup; 05241 } 05242 if (sync) { 05243 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05244 if (chan) { 05245 ast_set_variables(chan, vars); 05246 if (account) 05247 ast_cdr_setaccount(chan, account); 05248 if (chan->_state == AST_STATE_UP) { 05249 res = 0; 05250 if (option_verbose > 3) 05251 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05252 tmp = ast_calloc(1, sizeof(*tmp)); 05253 if (!tmp) 05254 res = -1; 05255 else { 05256 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05257 if (appdata) 05258 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05259 tmp->chan = chan; 05260 if (sync > 1) { 05261 if (locked_channel) 05262 ast_channel_unlock(chan); 05263 ast_pbx_run_app(tmp); 05264 } else { 05265 pthread_attr_init(&attr); 05266 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05267 if (locked_channel) 05268 ast_channel_lock(chan); 05269 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05270 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05271 free(tmp); 05272 if (locked_channel) 05273 ast_channel_unlock(chan); 05274 ast_hangup(chan); 05275 res = -1; 05276 } else { 05277 if (locked_channel) 05278 *locked_channel = chan; 05279 } 05280 pthread_attr_destroy(&attr); 05281 } 05282 } 05283 } else { 05284 if (option_verbose > 3) 05285 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05286 if (chan->cdr) { /* update the cdr */ 05287 /* here we update the status of the call, which sould be busy. 05288 * if that fails then we set the status to failed */ 05289 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05290 ast_cdr_failed(chan->cdr); 05291 } 05292 ast_hangup(chan); 05293 } 05294 } 05295 05296 if (res < 0) { /* the call failed for some reason */ 05297 if (*reason == 0) { /* if the call failed (not busy or no answer) 05298 * update the cdr with the failed message */ 05299 cdr_res = ast_pbx_outgoing_cdr_failed(); 05300 if (cdr_res != 0) { 05301 res = cdr_res; 05302 goto outgoing_app_cleanup; 05303 } 05304 } 05305 } 05306 05307 } else { 05308 struct async_stat *as; 05309 if (!(as = ast_calloc(1, sizeof(*as)))) { 05310 res = -1; 05311 goto outgoing_app_cleanup; 05312 } 05313 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05314 if (!chan) { 05315 free(as); 05316 res = -1; 05317 goto outgoing_app_cleanup; 05318 } 05319 as->chan = chan; 05320 ast_copy_string(as->app, app, sizeof(as->app)); 05321 if (appdata) 05322 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05323 as->timeout = timeout; 05324 ast_set_variables(chan, vars); 05325 if (account) 05326 ast_cdr_setaccount(chan, account); 05327 /* Start a new thread, and get something handling this channel. */ 05328 pthread_attr_init(&attr); 05329 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05330 if (locked_channel) 05331 ast_channel_lock(chan); 05332 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05333 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05334 free(as); 05335 if (locked_channel) 05336 ast_channel_unlock(chan); 05337 ast_hangup(chan); 05338 res = -1; 05339 pthread_attr_destroy(&attr); 05340 goto outgoing_app_cleanup; 05341 } else { 05342 if (locked_channel) 05343 *locked_channel = chan; 05344 } 05345 pthread_attr_destroy(&attr); 05346 res = 0; 05347 } 05348 outgoing_app_cleanup: 05349 ast_variables_destroy(vars); 05350 return res; 05351 }
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 5032 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().
05033 { 05034 /* allocate a channel */ 05035 struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", ""); 05036 05037 if (!chan) 05038 return -1; /* failure */ 05039 05040 if (!chan->cdr) { 05041 /* allocation of the cdr failed */ 05042 ast_channel_free(chan); /* free the channel */ 05043 return -1; /* return failure */ 05044 } 05045 05046 /* allocation of the cdr was successful */ 05047 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05048 ast_cdr_start(chan->cdr); /* record the start and stop time */ 05049 ast_cdr_end(chan->cdr); 05050 ast_cdr_failed(chan->cdr); /* set the status to failed */ 05051 ast_cdr_detach(chan->cdr); /* post and free the record */ 05052 chan->cdr = NULL; 05053 ast_channel_free(chan); /* free the channel */ 05054 05055 return 0; /* success */ 05056 }
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 5058 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().
05059 { 05060 struct ast_channel *chan; 05061 struct async_stat *as; 05062 int res = -1, cdr_res = -1; 05063 struct outgoing_helper oh; 05064 pthread_attr_t attr; 05065 05066 if (sync) { 05067 LOAD_OH(oh); 05068 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05069 if (channel) { 05070 *channel = chan; 05071 if (chan) 05072 ast_channel_lock(chan); 05073 } 05074 if (chan) { 05075 if (chan->_state == AST_STATE_UP) { 05076 res = 0; 05077 if (option_verbose > 3) 05078 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05079 05080 if (sync > 1) { 05081 if (channel) 05082 ast_channel_unlock(chan); 05083 if (ast_pbx_run(chan)) { 05084 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05085 if (channel) 05086 *channel = NULL; 05087 ast_hangup(chan); 05088 chan = NULL; 05089 res = -1; 05090 } 05091 } else { 05092 if (ast_pbx_start(chan)) { 05093 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05094 if (channel) { 05095 *channel = NULL; 05096 ast_channel_unlock(chan); 05097 } 05098 ast_hangup(chan); 05099 res = -1; 05100 } 05101 chan = NULL; 05102 } 05103 } else { 05104 if (option_verbose > 3) 05105 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05106 05107 if (chan->cdr) { /* update the cdr */ 05108 /* here we update the status of the call, which sould be busy. 05109 * if that fails then we set the status to failed */ 05110 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05111 ast_cdr_failed(chan->cdr); 05112 } 05113 05114 if (channel) { 05115 *channel = NULL; 05116 ast_channel_unlock(chan); 05117 } 05118 ast_hangup(chan); 05119 chan = NULL; 05120 } 05121 } 05122 05123 if (res < 0) { /* the call failed for some reason */ 05124 if (*reason == 0) { /* if the call failed (not busy or no answer) 05125 * update the cdr with the failed message */ 05126 cdr_res = ast_pbx_outgoing_cdr_failed(); 05127 if (cdr_res != 0) { 05128 res = cdr_res; 05129 goto outgoing_exten_cleanup; 05130 } 05131 } 05132 05133 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05134 /* check if "failed" exists */ 05135 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05136 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05137 if (chan) { 05138 char failed_reason[4] = ""; 05139 if (!ast_strlen_zero(context)) 05140 ast_copy_string(chan->context, context, sizeof(chan->context)); 05141 set_ext_pri(chan, "failed", 1); 05142 ast_set_variables(chan, vars); 05143 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05144 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05145 if (account) 05146 ast_cdr_setaccount(chan, account); 05147 if (ast_pbx_run(chan)) { 05148 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05149 ast_hangup(chan); 05150 } 05151 chan = NULL; 05152 } 05153 } 05154 } 05155 } else { 05156 if (!(as = ast_calloc(1, sizeof(*as)))) { 05157 res = -1; 05158 goto outgoing_exten_cleanup; 05159 } 05160 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05161 if (channel) { 05162 *channel = chan; 05163 if (chan) 05164 ast_channel_lock(chan); 05165 } 05166 if (!chan) { 05167 free(as); 05168 res = -1; 05169 goto outgoing_exten_cleanup; 05170 } 05171 as->chan = chan; 05172 ast_copy_string(as->context, context, sizeof(as->context)); 05173 set_ext_pri(as->chan, exten, priority); 05174 as->timeout = timeout; 05175 ast_set_variables(chan, vars); 05176 if (account) 05177 ast_cdr_setaccount(chan, account); 05178 pthread_attr_init(&attr); 05179 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05180 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05181 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05182 free(as); 05183 if (channel) { 05184 *channel = NULL; 05185 ast_channel_unlock(chan); 05186 } 05187 ast_hangup(chan); 05188 res = -1; 05189 pthread_attr_destroy(&attr); 05190 goto outgoing_exten_cleanup; 05191 } 05192 pthread_attr_destroy(&attr); 05193 res = 0; 05194 } 05195 outgoing_exten_cleanup: 05196 ast_variables_destroy(vars); 05197 return res; 05198 }
enum ast_pbx_result ast_pbx_run | ( | struct ast_channel * | c | ) |
Execute the PBX in the current thread.
c | channel to run the pbx on |
Definition at line 2682 of file pbx.c.
References __ast_pbx_run(), AST_PBX_CALL_LIMIT, AST_PBX_SUCCESS, decrease_call_count(), and increase_call_count().
Referenced by ast_pbx_outgoing_exten(), async_wait(), do_idle_thread(), mgcp_ss(), skinny_newcall(), and ss_thread().
02683 { 02684 enum ast_pbx_result res = AST_PBX_SUCCESS; 02685 02686 if (increase_call_count(c)) 02687 return AST_PBX_CALL_LIMIT; 02688 02689 res = __ast_pbx_run(c); 02690 decrease_call_count(); 02691 02692 return res; 02693 }
static void* ast_pbx_run_app | ( | void * | data | ) | [static] |
run the application and free the descriptor once done
Definition at line 5208 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().
05209 { 05210 struct app_tmp *tmp = data; 05211 struct ast_app *app; 05212 app = pbx_findapp(tmp->app); 05213 if (app) { 05214 if (option_verbose > 3) 05215 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05216 pbx_exec(tmp->chan, app, tmp->data); 05217 } else 05218 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05219 ast_hangup(tmp->chan); 05220 free(tmp); 05221 return NULL; 05222 }
enum ast_pbx_result ast_pbx_start | ( | struct ast_channel * | c | ) |
Create a new thread and start the PBX.
c | channel to start the pbx on |
Definition at line 2655 of file pbx.c.
References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, decrease_call_count(), increase_call_count(), LOG_WARNING, pbx_thread(), and t.
Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_exten(), check_goto_on_transfer(), dahdi_new(), do_parking_thread(), gtalk_new(), gtalk_newcall(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), and skinny_new().
02656 { 02657 pthread_t t; 02658 pthread_attr_t attr; 02659 02660 if (!c) { 02661 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02662 return AST_PBX_FAILED; 02663 } 02664 02665 if (increase_call_count(c)) 02666 return AST_PBX_CALL_LIMIT; 02667 02668 /* Start a new thread, and get something handling this channel. */ 02669 pthread_attr_init(&attr); 02670 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02671 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02672 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02673 pthread_attr_destroy(&attr); 02674 decrease_call_count(); 02675 return AST_PBX_FAILED; 02676 } 02677 pthread_attr_destroy(&attr); 02678 02679 return AST_PBX_SUCCESS; 02680 }
int ast_processed_calls | ( | void | ) |
Retrieve the total number of calls processed through the PBX since last restart.
Definition at line 2700 of file pbx.c.
References totalcalls.
02701 { 02702 return totalcalls; 02703 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6308 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().
06309 { 06310 return ast_rwlock_rdlock(&conlock); 06311 }
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 2989 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().
02990 { 02991 struct ast_app *tmp, *cur = NULL; 02992 char tmps[80]; 02993 int length; 02994 02995 AST_LIST_LOCK(&apps); 02996 AST_LIST_TRAVERSE(&apps, tmp, list) { 02997 if (!strcasecmp(app, tmp->name)) { 02998 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02999 AST_LIST_UNLOCK(&apps); 03000 return -1; 03001 } 03002 } 03003 03004 length = sizeof(*tmp) + strlen(app) + 1; 03005 03006 if (!(tmp = ast_calloc(1, length))) { 03007 AST_LIST_UNLOCK(&apps); 03008 return -1; 03009 } 03010 03011 strcpy(tmp->name, app); 03012 tmp->execute = execute; 03013 tmp->synopsis = synopsis; 03014 tmp->description = description; 03015 03016 /* Store in alphabetical order */ 03017 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 03018 if (strcasecmp(tmp->name, cur->name) < 0) { 03019 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03020 break; 03021 } 03022 } 03023 AST_LIST_TRAVERSE_SAFE_END 03024 if (!cur) 03025 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03026 03027 if (option_verbose > 1) 03028 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03029 03030 AST_LIST_UNLOCK(&apps); 03031 03032 return 0; 03033 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3039 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().
03040 { 03041 struct ast_switch *tmp; 03042 03043 AST_LIST_LOCK(&switches); 03044 AST_LIST_TRAVERSE(&switches, tmp, list) { 03045 if (!strcasecmp(tmp->name, sw->name)) { 03046 AST_LIST_UNLOCK(&switches); 03047 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03048 return -1; 03049 } 03050 } 03051 AST_LIST_INSERT_TAIL(&switches, sw, list); 03052 AST_LIST_UNLOCK(&switches); 03053 03054 return 0; 03055 }
static int ast_remove_hint | ( | struct ast_exten * | e | ) | [static] |
ast_remove_hint: Remove hint from extension
Definition at line 2247 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().
02248 { 02249 /* Cleanup the Notifys if hint is removed */ 02250 struct ast_hint *hint; 02251 struct ast_state_cb *cblist, *cbprev; 02252 int res = -1; 02253 02254 if (!e) 02255 return -1; 02256 02257 AST_LIST_LOCK(&hints); 02258 AST_LIST_TRAVERSE_SAFE_BEGIN(&hints, hint, list) { 02259 if (hint->exten == e) { 02260 cbprev = NULL; 02261 cblist = hint->callbacks; 02262 while (cblist) { 02263 /* Notify with -1 and remove all callbacks */ 02264 cbprev = cblist; 02265 cblist = cblist->next; 02266 cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data); 02267 free(cbprev); 02268 } 02269 hint->callbacks = NULL; 02270 AST_LIST_REMOVE_CURRENT(&hints, list); 02271 free(hint); 02272 res = 0; 02273 break; 02274 } 02275 } 02276 AST_LIST_TRAVERSE_SAFE_END 02277 AST_LIST_UNLOCK(&hints); 02278 02279 return res; 02280 }
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 2326 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), and loopback_exec().
02327 { 02328 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02329 }
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 6331 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().
06332 { 06333 return ast_mutex_unlock(&con->lock); 06334 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6318 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().
06319 { 06320 return ast_rwlock_unlock(&conlock); 06321 }
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 3904 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().
03905 { 03906 struct ast_app *tmp; 03907 03908 AST_LIST_LOCK(&apps); 03909 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03910 if (!strcasecmp(app, tmp->name)) { 03911 AST_LIST_REMOVE_CURRENT(&apps, list); 03912 if (option_verbose > 1) 03913 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03914 free(tmp); 03915 break; 03916 } 03917 } 03918 AST_LIST_TRAVERSE_SAFE_END 03919 AST_LIST_UNLOCK(&apps); 03920 03921 return tmp ? 0 : -1; 03922 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3057 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().
03058 { 03059 AST_LIST_LOCK(&switches); 03060 AST_LIST_REMOVE(&switches, sw, list); 03061 AST_LIST_UNLOCK(&switches); 03062 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | exten | |||
) |
Definition at line 6440 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().
06442 { 06443 if (!exten) 06444 return con ? con->root : NULL; 06445 else 06446 return exten->next; 06447 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6473 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().
06475 { 06476 if (!ip) 06477 return con ? con->ignorepats : NULL; 06478 else 06479 return ip->next; 06480 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6464 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().
06466 { 06467 if (!inc) 06468 return con ? con->includes : NULL; 06469 else 06470 return inc->next; 06471 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6449 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().
06451 { 06452 if (!sw) 06453 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06454 else 06455 return AST_LIST_NEXT(sw, list); 06456 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6435 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 6458 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 6313 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().
06314 { 06315 return ast_rwlock_wrlock(&conlock); 06316 }
static void* async_wait | ( | void * | data | ) | [static] |
Definition at line 4969 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().
04970 { 04971 struct async_stat *as = data; 04972 struct ast_channel *chan = as->chan; 04973 int timeout = as->timeout; 04974 int res; 04975 struct ast_frame *f; 04976 struct ast_app *app; 04977 04978 while (timeout && (chan->_state != AST_STATE_UP)) { 04979 res = ast_waitfor(chan, timeout); 04980 if (res < 1) 04981 break; 04982 if (timeout > -1) 04983 timeout = res; 04984 f = ast_read(chan); 04985 if (!f) 04986 break; 04987 if (f->frametype == AST_FRAME_CONTROL) { 04988 if ((f->subclass == AST_CONTROL_BUSY) || 04989 (f->subclass == AST_CONTROL_CONGESTION) ) { 04990 ast_frfree(f); 04991 break; 04992 } 04993 } 04994 ast_frfree(f); 04995 } 04996 if (chan->_state == AST_STATE_UP) { 04997 if (!ast_strlen_zero(as->app)) { 04998 app = pbx_findapp(as->app); 04999 if (app) { 05000 if (option_verbose > 2) 05001 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 05002 pbx_exec(chan, app, as->appdata); 05003 } else 05004 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 05005 } else { 05006 if (!ast_strlen_zero(as->context)) 05007 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 05008 if (!ast_strlen_zero(as->exten)) 05009 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 05010 if (as->priority > 0) 05011 chan->priority = as->priority; 05012 /* Run the PBX */ 05013 if (ast_pbx_run(chan)) { 05014 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 05015 } else { 05016 /* PBX will have taken care of this */ 05017 chan = NULL; 05018 } 05019 } 05020 } 05021 free(as); 05022 if (chan) 05023 ast_hangup(chan); 05024 return NULL; 05025 }
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 2344 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.
02345 { 02346 int digit; 02347 02348 buf[pos] = '\0'; /* make sure it is properly terminated */ 02349 while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) { 02350 /* As long as we're willing to wait, and as long as it's not defined, 02351 keep reading digits until we can't possibly get a right answer anymore. */ 02352 digit = ast_waitfordigit(c, waittime * 1000); 02353 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02354 c->_softhangup = 0; 02355 } else { 02356 if (!digit) /* No entry */ 02357 break; 02358 if (digit < 0) /* Error, maybe a hangup */ 02359 return -1; 02360 if (pos < buflen - 1) { /* XXX maybe error otherwise ? */ 02361 buf[pos++] = digit; 02362 buf[pos] = '\0'; 02363 } 02364 waittime = c->pbx->dtimeout; 02365 } 02366 } 02367 return 0; 02368 }
static char* complete_show_application | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3122 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::list, ast_app::name, and strdup.
03123 { 03124 struct ast_app *a; 03125 char *ret = NULL; 03126 int which = 0; 03127 int wordlen = strlen(word); 03128 03129 /* return the n-th [partial] matching entry */ 03130 AST_LIST_LOCK(&apps); 03131 AST_LIST_TRAVERSE(&apps, a, list) { 03132 if (!strncasecmp(word, a->name, wordlen) && ++which > state) { 03133 ret = strdup(a->name); 03134 break; 03135 } 03136 } 03137 AST_LIST_UNLOCK(&apps); 03138 03139 return ret; 03140 }
static char* complete_show_applications | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3483 of file pbx.c.
References ast_cli_complete().
03484 { 03485 static char* choices[] = { "like", "describing", NULL }; 03486 03487 return (pos != 3) ? NULL : ast_cli_complete(word, choices, state); 03488 }
static char* complete_show_applications_deprecated | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3476 of file pbx.c.
References ast_cli_complete().
03477 { 03478 static char* choices[] = { "like", "describing", NULL }; 03479 03480 return (pos != 2) ? NULL : ast_cli_complete(word, choices, state); 03481 }
static char* complete_show_dialplan_context | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3493 of file pbx.c.
References ast_get_context_name(), ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), and ast_walk_contexts().
03495 { 03496 struct ast_context *c = NULL; 03497 char *ret = NULL; 03498 int which = 0; 03499 int wordlen; 03500 03501 /* we are do completion of [exten@]context on second position only */ 03502 if (pos != 2) 03503 return NULL; 03504 03505 ast_rdlock_contexts(); 03506 03507 wordlen = strlen(word); 03508 03509 /* walk through all contexts and return the n-th match */ 03510 while ( (c = ast_walk_contexts(c)) ) { 03511 if (!strncasecmp(word, ast_get_context_name(c), wordlen) && ++which > state) { 03512 ret = ast_strdup(ast_get_context_name(c)); 03513 break; 03514 } 03515 } 03516 03517 ast_unlock_contexts(); 03518 03519 return ret; 03520 }
static char* complete_show_function | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1478 of file pbx.c.
References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_custom_function::name, and strdup.
01479 { 01480 struct ast_custom_function *acf; 01481 char *ret = NULL; 01482 int which = 0; 01483 int wordlen = strlen(word); 01484 01485 /* case-insensitive for convenience in this 'complete' function */ 01486 AST_LIST_LOCK(&acf_root); 01487 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01488 if (!strncasecmp(word, acf->name, wordlen) && ++which > state) { 01489 ret = strdup(acf->name); 01490 break; 01491 } 01492 } 01493 AST_LIST_UNLOCK(&acf_root); 01494 01495 return ret; 01496 }
static void decrease_call_count | ( | void | ) | [static] |
Definition at line 2617 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), countcalls, and maxcalllock.
Referenced by ast_pbx_run(), ast_pbx_start(), and pbx_thread().
02618 { 02619 ast_mutex_lock(&maxcalllock); 02620 if (countcalls > 0) 02621 countcalls--; 02622 ast_mutex_unlock(&maxcalllock); 02623 }
static void destroy_exten | ( | struct ast_exten * | e | ) | [static] |
Definition at line 2625 of file pbx.c.
References ast_remove_hint(), free, ast_exten::priority, and PRIORITY_HINT.
Referenced by __ast_context_destroy(), and ast_context_remove_extension_callerid2().
02626 { 02627 if (e->priority == PRIORITY_HINT) 02628 ast_remove_hint(e); 02629 02630 if (e->datad) 02631 e->datad(e->data); 02632 free(e); 02633 }
static int ext_cmp | ( | const char * | a, | |
const char * | b | |||
) | [static] |
the full routine to compare extensions in rules.
Definition at line 758 of file pbx.c.
References ext_cmp1().
Referenced by ast_add_extension2().
00759 { 00760 /* make sure non-patterns come first. 00761 * If a is not a pattern, it either comes first or 00762 * we do a more complex pattern comparison. 00763 */ 00764 unsigned char bitwise[2][32]; 00765 int ret = 0; 00766 00767 if (a[0] != '_') 00768 return (b[0] == '_') ? -1 : strcmp(a, b); 00769 00770 /* Now we know a is a pattern; if b is not, a comes first */ 00771 if (b[0] != '_') 00772 return 1; 00773 00774 /* ok we need full pattern sorting routine */ 00775 while (!ret && a && b) { 00776 ret = ext_cmp1(&a, bitwise[0]) - ext_cmp1(&b, bitwise[1]); 00777 if (ret == 0) { 00778 /* Are the classes different, even though they score the same? */ 00779 ret = memcmp(bitwise[0], bitwise[1], 32); 00780 } 00781 } 00782 if (ret == 0) { 00783 return 0; 00784 } else { 00785 return (ret > 0) ? 1 : -1; 00786 } 00787 }
static int ext_cmp1 | ( | const char ** | p, | |
unsigned char * | bitwise | |||
) | [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 int c, cmin = 0xff, count = 0; 00676 const char *end; 00677 00678 /* load, sign extend and advance pointer until we find 00679 * a valid character. 00680 */ 00681 while ( (c = *(*p)++) && (c == ' ' || c == '-') ) 00682 ; /* ignore some characters */ 00683 memset(bitwise, 0xff, 32); 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 bitwise[6] = 0x01; 00692 bitwise[7] = 0xfe; 00693 return 0x0800 | '2'; 00694 00695 case 'X': /* 0..9 */ 00696 bitwise[5] = 0x7f; 00697 bitwise[6] = 0x00; 00698 bitwise[7] = 0xfe; 00699 return 0x0A00 | '0'; 00700 00701 case 'Z': /* 1..9 */ 00702 bitwise[6] = 0x00; 00703 bitwise[7] = 0xfe; 00704 return 0x0900 | '1'; 00705 00706 case '.': /* wildcard */ 00707 return 0x10000; 00708 00709 case '!': /* earlymatch */ 00710 return 0x20000; /* less specific than NULL */ 00711 00712 case '\0': /* empty string */ 00713 *p = NULL; 00714 return 0x30000; 00715 00716 case '[': /* pattern */ 00717 break; 00718 } 00719 /* locate end of set */ 00720 end = strchr(*p, ']'); 00721 00722 if (end == NULL) { 00723 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n"); 00724 return 0x40000; /* XXX make this entry go last... */ 00725 } 00726 00727 for (; *p < end ; (*p)++) { 00728 unsigned char c1, c2; /* first-last char in range */ 00729 c1 = (unsigned char)((*p)[0]); 00730 if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */ 00731 c2 = (unsigned char)((*p)[2]); 00732 *p += 2; /* skip a total of 3 chars */ 00733 } else { /* individual character */ 00734 c2 = c1; 00735 } 00736 if (c1 < cmin) { 00737 cmin = c1; 00738 } 00739 for (; c1 <= c2; c1++) { 00740 unsigned char mask = 1 << (c1 % 8); 00741 /* Count the number of characters in the class, discarding duplicates. */ 00742 if ( (bitwise[ c1 / 8 ] & mask) == 1) { 00743 count += 0x100; 00744 } 00745 /*!\note If two patterns score the same, but one includes '0' (as 00746 * the lowest ASCII value in the given class) and the other does 00747 * not, then the one including '0' will compare as coming first. */ 00748 bitwise[ c1 / 8 ] &= ~mask; 00749 } 00750 } 00751 (*p)++; 00752 return count == 0 ? 0x30000 : (count | cmin); 00753 }
static int ext_strncpy | ( | char * | dst, | |
const char * | src, | |||
int | len | |||
) | [static] |
copy a string skipping whitespace
Definition at line 4721 of file pbx.c.
Referenced by ast_add_extension2().
04722 { 04723 int count=0; 04724 04725 while (*src && (count < len - 1)) { 04726 switch(*src) { 04727 case ' ': 04728 /* otherwise exten => [a-b],1,... doesn't work */ 04729 /* case '-': */ 04730 /* Ignore */ 04731 break; 04732 default: 04733 *dst = *src; 04734 dst++; 04735 } 04736 src++; 04737 count++; 04738 } 04739 *dst = '\0'; 04740 04741 return count; 04742 }
static int extension_match_core | ( | const char * | pattern, | |
const char * | data, | |||
enum ext_match_t | mode | |||
) | [static] |
Definition at line 912 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().
00913 { 00914 int i; 00915 static int prof_id = -2; /* marker for 'unallocated' id */ 00916 if (prof_id == -2) 00917 prof_id = ast_add_profile("ext_match", 0); 00918 ast_mark(prof_id, 1); 00919 i = _extension_match_core(pattern, data, mode); 00920 ast_mark(prof_id, 0); 00921 return i; 00922 }
static struct ast_context* find_context_locked | ( | const char * | context | ) | [static] |
Definition at line 2715 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().
02716 { 02717 struct ast_context *c = NULL; 02718 02719 ast_rdlock_contexts(); 02720 while ( (c = ast_walk_contexts(c)) ) { 02721 if (!strcmp(ast_get_context_name(c), context)) 02722 return c; 02723 } 02724 ast_unlock_contexts(); 02725 02726 return NULL; 02727 }
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 1571 of file pbx.c.
References ast_log(), and LOG_WARNING.
Referenced by ast_func_read(), and ast_func_write().
01572 { 01573 char *args = strchr(function, '('); 01574 01575 if (!args) 01576 ast_log(LOG_WARNING, "Function '%s' doesn't contain parentheses. Assuming null argument.\n", function); 01577 else { 01578 char *p; 01579 *args++ = '\0'; 01580 if ((p = strrchr(args, ')')) ) 01581 *p = '\0'; 01582 else 01583 ast_log(LOG_WARNING, "Can't find trailing parenthesis for function '%s(%s'?\n", function, args); 01584 } 01585 return args; 01586 }
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 4134 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, lookup_name(), and s.
Referenced by ast_build_timing().
04135 { 04136 int s, e; /* start and ending position */ 04137 unsigned int mask = 0; 04138 04139 /* Check for whole range */ 04140 if (ast_strlen_zero(src) || !strcmp(src, "*")) { 04141 s = 0; 04142 e = max - 1; 04143 } else { 04144 /* Get start and ending position */ 04145 char *c = strchr(src, '-'); 04146 if (c) 04147 *c++ = '\0'; 04148 /* Find the start */ 04149 s = lookup_name(src, names, max); 04150 if (!s) { 04151 ast_log(LOG_WARNING, "Invalid %s '%s', assuming none\n", msg, src); 04152 return 0; 04153 } 04154 s--; 04155 if (c) { /* find end of range */ 04156 e = lookup_name(c, names, max); 04157 if (!e) { 04158 ast_log(LOG_WARNING, "Invalid end %s '%s', assuming none\n", msg, c); 04159 return 0; 04160 } 04161 e--; 04162 } else 04163 e = s; 04164 } 04165 /* Fill the mask. Remember that ranges are cyclic */ 04166 mask = 1 << e; /* initialize with last element */ 04167 while (s != e) { 04168 if (s >= max) { 04169 s = 0; 04170 mask |= (1 << s); 04171 } else { 04172 mask |= (1 << s); 04173 s++; 04174 } 04175 } 04176 return mask; 04177 }
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 4180 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask.
Referenced by ast_build_timing().
04181 { 04182 char *e; 04183 int x; 04184 int s1, s2; 04185 int e1, e2; 04186 /* int cth, ctm; */ 04187 04188 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 04189 memset(i->minmask, 0, sizeof(i->minmask)); 04190 04191 /* 2-minutes per bit, since the mask has only 32 bits :( */ 04192 /* Star is all times */ 04193 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 04194 for (x=0; x<24; x++) 04195 i->minmask[x] = 0x3fffffff; /* 30 bits */ 04196 return; 04197 } 04198 /* Otherwise expect a range */ 04199 e = strchr(times, '-'); 04200 if (!e) { 04201 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n"); 04202 return; 04203 } 04204 *e++ = '\0'; 04205 /* XXX why skip non digits ? */ 04206 while (*e && !isdigit(*e)) 04207 e++; 04208 if (!*e) { 04209 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n"); 04210 return; 04211 } 04212 if (sscanf(times, "%2d:%2d", &s1, &s2) != 2) { 04213 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times); 04214 return; 04215 } 04216 if (sscanf(e, "%2d:%2d", &e1, &e2) != 2) { 04217 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e); 04218 return; 04219 } 04220 /* XXX this needs to be optimized */ 04221 #if 1 04222 s1 = s1 * 30 + s2/2; 04223 if ((s1 < 0) || (s1 >= 24*30)) { 04224 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times); 04225 return; 04226 } 04227 e1 = e1 * 30 + e2/2; 04228 if ((e1 < 0) || (e1 >= 24*30)) { 04229 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e); 04230 return; 04231 } 04232 /* Go through the time and enable each appropriate bit */ 04233 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) { 04234 i->minmask[x/30] |= (1 << (x % 30)); 04235 } 04236 /* Do the last one */ 04237 i->minmask[x/30] |= (1 << (x % 30)); 04238 #else 04239 for (cth=0; cth<24; cth++) { 04240 /* Initialize masks to blank */ 04241 i->minmask[cth] = 0; 04242 for (ctm=0; ctm<30; ctm++) { 04243 if ( 04244 /* First hour with more than one hour */ 04245 (((cth == s1) && (ctm >= s2)) && 04246 ((cth < e1))) 04247 /* Only one hour */ 04248 || (((cth == s1) && (ctm >= s2)) && 04249 ((cth == e1) && (ctm <= e2))) 04250 /* In between first and last hours (more than 2 hours) */ 04251 || ((cth > s1) && 04252 (cth < e1)) 04253 /* Last hour with more than one hour */ 04254 || ((cth > s1) && 04255 ((cth == e1) && (ctm <= e2))) 04256 ) 04257 i->minmask[cth] |= (1 << (ctm / 2)); 04258 } 04259 } 04260 #endif 04261 /* All done */ 04262 return; 04263 }
static int handle_set_global | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3781 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03782 { 03783 if (argc != 5) 03784 return RESULT_SHOWUSAGE; 03785 03786 pbx_builtin_setvar_helper(NULL, argv[3], argv[4]); 03787 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[3], argv[4]); 03788 03789 return RESULT_SUCCESS; 03790 }
static int handle_set_global_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI support for setting global variables.
Definition at line 3769 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03770 { 03771 if (argc != 4) 03772 return RESULT_SHOWUSAGE; 03773 03774 pbx_builtin_setvar_helper(NULL, argv[2], argv[3]); 03775 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[2], argv[3]); 03776 03777 return RESULT_SUCCESS; 03778 }
static int handle_show_application | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3212 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().
03213 { 03214 struct ast_app *a; 03215 int app, no_registered_app = 1; 03216 03217 if (argc < 4) 03218 return RESULT_SHOWUSAGE; 03219 03220 /* ... go through all applications ... */ 03221 AST_LIST_LOCK(&apps); 03222 AST_LIST_TRAVERSE(&apps, a, list) { 03223 /* ... compare this application name with all arguments given 03224 * to 'show application' command ... */ 03225 for (app = 3; app < argc; app++) { 03226 if (!strcasecmp(a->name, argv[app])) { 03227 /* Maximum number of characters added by terminal coloring is 22 */ 03228 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03229 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03230 int synopsis_size, description_size; 03231 03232 no_registered_app = 0; 03233 03234 if (a->synopsis) 03235 synopsis_size = strlen(a->synopsis) + 23; 03236 else 03237 synopsis_size = strlen("Not available") + 23; 03238 synopsis = alloca(synopsis_size); 03239 03240 if (a->description) 03241 description_size = strlen(a->description) + 23; 03242 else 03243 description_size = strlen("Not available") + 23; 03244 description = alloca(description_size); 03245 03246 if (synopsis && description) { 03247 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03248 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03249 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03250 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03251 term_color(synopsis, 03252 a->synopsis ? a->synopsis : "Not available", 03253 COLOR_CYAN, 0, synopsis_size); 03254 term_color(description, 03255 a->description ? a->description : "Not available", 03256 COLOR_CYAN, 0, description_size); 03257 03258 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03259 } else { 03260 /* ... one of our applications, show info ...*/ 03261 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03262 "[Synopsis]\n %s\n\n" 03263 "[Description]\n%s\n", 03264 a->name, 03265 a->synopsis ? a->synopsis : "Not available", 03266 a->description ? a->description : "Not available"); 03267 } 03268 } 03269 } 03270 } 03271 AST_LIST_UNLOCK(&apps); 03272 03273 /* we found at least one app? no? */ 03274 if (no_registered_app) { 03275 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03276 return RESULT_FAILURE; 03277 } 03278 03279 return RESULT_SUCCESS; 03280 }
static int handle_show_application_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3142 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().
03143 { 03144 struct ast_app *a; 03145 int app, no_registered_app = 1; 03146 03147 if (argc < 3) 03148 return RESULT_SHOWUSAGE; 03149 03150 /* ... go through all applications ... */ 03151 AST_LIST_LOCK(&apps); 03152 AST_LIST_TRAVERSE(&apps, a, list) { 03153 /* ... compare this application name with all arguments given 03154 * to 'show application' command ... */ 03155 for (app = 2; app < argc; app++) { 03156 if (!strcasecmp(a->name, argv[app])) { 03157 /* Maximum number of characters added by terminal coloring is 22 */ 03158 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03159 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03160 int synopsis_size, description_size; 03161 03162 no_registered_app = 0; 03163 03164 if (a->synopsis) 03165 synopsis_size = strlen(a->synopsis) + 23; 03166 else 03167 synopsis_size = strlen("Not available") + 23; 03168 synopsis = alloca(synopsis_size); 03169 03170 if (a->description) 03171 description_size = strlen(a->description) + 23; 03172 else 03173 description_size = strlen("Not available") + 23; 03174 description = alloca(description_size); 03175 03176 if (synopsis && description) { 03177 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03178 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03179 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03180 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03181 term_color(synopsis, 03182 a->synopsis ? a->synopsis : "Not available", 03183 COLOR_CYAN, 0, synopsis_size); 03184 term_color(description, 03185 a->description ? a->description : "Not available", 03186 COLOR_CYAN, 0, description_size); 03187 03188 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03189 } else { 03190 /* ... one of our applications, show info ...*/ 03191 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03192 "[Synopsis]\n %s\n\n" 03193 "[Description]\n%s\n", 03194 a->name, 03195 a->synopsis ? a->synopsis : "Not available", 03196 a->description ? a->description : "Not available"); 03197 } 03198 } 03199 } 03200 } 03201 AST_LIST_UNLOCK(&apps); 03202 03203 /* we found at least one app? no? */ 03204 if (no_registered_app) { 03205 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03206 return RESULT_FAILURE; 03207 } 03208 03209 return RESULT_SUCCESS; 03210 }
static int handle_show_applications | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3407 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.
03408 { 03409 struct ast_app *a; 03410 int like = 0, describing = 0; 03411 int total_match = 0; /* Number of matches in like clause */ 03412 int total_apps = 0; /* Number of apps registered */ 03413 03414 AST_LIST_LOCK(&apps); 03415 03416 if (AST_LIST_EMPTY(&apps)) { 03417 ast_cli(fd, "There are no registered applications\n"); 03418 AST_LIST_UNLOCK(&apps); 03419 return -1; 03420 } 03421 03422 /* core list applications like <keyword> */ 03423 if ((argc == 5) && (!strcmp(argv[3], "like"))) { 03424 like = 1; 03425 } else if ((argc > 4) && (!strcmp(argv[3], "describing"))) { 03426 describing = 1; 03427 } 03428 03429 /* core list applications describing <keyword1> [<keyword2>] [...] */ 03430 if ((!like) && (!describing)) { 03431 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03432 } else { 03433 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03434 } 03435 03436 AST_LIST_TRAVERSE(&apps, a, list) { 03437 int printapp = 0; 03438 total_apps++; 03439 if (like) { 03440 if (strcasestr(a->name, argv[4])) { 03441 printapp = 1; 03442 total_match++; 03443 } 03444 } else if (describing) { 03445 if (a->description) { 03446 /* Match all words on command line */ 03447 int i; 03448 printapp = 1; 03449 for (i = 4; i < argc; i++) { 03450 if (!strcasestr(a->description, argv[i])) { 03451 printapp = 0; 03452 } else { 03453 total_match++; 03454 } 03455 } 03456 } 03457 } else { 03458 printapp = 1; 03459 } 03460 03461 if (printapp) { 03462 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03463 } 03464 } 03465 if ((!like) && (!describing)) { 03466 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03467 } else { 03468 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03469 } 03470 03471 AST_LIST_UNLOCK(&apps); 03472 03473 return RESULT_SUCCESS; 03474 }
static int handle_show_applications_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3339 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.
03340 { 03341 struct ast_app *a; 03342 int like = 0, describing = 0; 03343 int total_match = 0; /* Number of matches in like clause */ 03344 int total_apps = 0; /* Number of apps registered */ 03345 03346 AST_LIST_LOCK(&apps); 03347 03348 if (AST_LIST_EMPTY(&apps)) { 03349 ast_cli(fd, "There are no registered applications\n"); 03350 AST_LIST_UNLOCK(&apps); 03351 return -1; 03352 } 03353 03354 /* show applications like <keyword> */ 03355 if ((argc == 4) && (!strcmp(argv[2], "like"))) { 03356 like = 1; 03357 } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { 03358 describing = 1; 03359 } 03360 03361 /* show applications describing <keyword1> [<keyword2>] [...] */ 03362 if ((!like) && (!describing)) { 03363 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03364 } else { 03365 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03366 } 03367 03368 AST_LIST_TRAVERSE(&apps, a, list) { 03369 int printapp = 0; 03370 total_apps++; 03371 if (like) { 03372 if (strcasestr(a->name, argv[3])) { 03373 printapp = 1; 03374 total_match++; 03375 } 03376 } else if (describing) { 03377 if (a->description) { 03378 /* Match all words on command line */ 03379 int i; 03380 printapp = 1; 03381 for (i = 3; i < argc; i++) { 03382 if (!strcasestr(a->description, argv[i])) { 03383 printapp = 0; 03384 } else { 03385 total_match++; 03386 } 03387 } 03388 } 03389 } else { 03390 printapp = 1; 03391 } 03392 03393 if (printapp) { 03394 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03395 } 03396 } 03397 if ((!like) && (!describing)) { 03398 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03399 } else { 03400 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03401 } 03402 03403 AST_LIST_UNLOCK(&apps); 03404 03405 return RESULT_SUCCESS; 03406 }
static int handle_show_dialplan | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3696 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().
03697 { 03698 char *exten = NULL, *context = NULL; 03699 /* Variables used for different counters */ 03700 struct dialplan_counters counters; 03701 03702 const char *incstack[AST_PBX_MAX_STACK]; 03703 memset(&counters, 0, sizeof(counters)); 03704 03705 if (argc != 2 && argc != 3) 03706 return RESULT_SHOWUSAGE; 03707 03708 /* we obtain [exten@]context? if yes, split them ... */ 03709 if (argc == 3) { 03710 if (strchr(argv[2], '@')) { /* split into exten & context */ 03711 context = ast_strdupa(argv[2]); 03712 exten = strsep(&context, "@"); 03713 /* change empty strings to NULL */ 03714 if (ast_strlen_zero(exten)) 03715 exten = NULL; 03716 } else { /* no '@' char, only context given */ 03717 context = argv[2]; 03718 } 03719 if (ast_strlen_zero(context)) 03720 context = NULL; 03721 } 03722 /* else Show complete dial plan, context and exten are NULL */ 03723 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03724 03725 /* check for input failure and throw some error messages */ 03726 if (context && !counters.context_existence) { 03727 ast_cli(fd, "There is no existence of '%s' context\n", context); 03728 return RESULT_FAILURE; 03729 } 03730 03731 if (exten && !counters.extension_existence) { 03732 if (context) 03733 ast_cli(fd, "There is no existence of %s@%s extension\n", 03734 exten, context); 03735 else 03736 ast_cli(fd, 03737 "There is no existence of '%s' extension in all contexts\n", 03738 exten); 03739 return RESULT_FAILURE; 03740 } 03741 03742 ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", 03743 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions", 03744 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities", 03745 counters.total_context, counters.total_context == 1 ? "context" : "contexts"); 03746 03747 /* everything ok */ 03748 return RESULT_SUCCESS; 03749 }
static int handle_show_function | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1422 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().
01423 { 01424 struct ast_custom_function *acf; 01425 /* Maximum number of characters added by terminal coloring is 22 */ 01426 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01427 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01428 char stxtitle[40], *syntax = NULL; 01429 int synopsis_size, description_size, syntax_size; 01430 01431 if (argc < 4) 01432 return RESULT_SHOWUSAGE; 01433 01434 if (!(acf = ast_custom_function_find(argv[3]))) { 01435 ast_cli(fd, "No function by that name registered.\n"); 01436 return RESULT_FAILURE; 01437 01438 } 01439 01440 if (acf->synopsis) 01441 synopsis_size = strlen(acf->synopsis) + 23; 01442 else 01443 synopsis_size = strlen("Not available") + 23; 01444 synopsis = alloca(synopsis_size); 01445 01446 if (acf->desc) 01447 description_size = strlen(acf->desc) + 23; 01448 else 01449 description_size = strlen("Not available") + 23; 01450 description = alloca(description_size); 01451 01452 if (acf->syntax) 01453 syntax_size = strlen(acf->syntax) + 23; 01454 else 01455 syntax_size = strlen("Not available") + 23; 01456 syntax = alloca(syntax_size); 01457 01458 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01459 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01460 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01461 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01462 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01463 term_color(syntax, 01464 acf->syntax ? acf->syntax : "Not available", 01465 COLOR_CYAN, 0, syntax_size); 01466 term_color(synopsis, 01467 acf->synopsis ? acf->synopsis : "Not available", 01468 COLOR_CYAN, 0, synopsis_size); 01469 term_color(description, 01470 acf->desc ? acf->desc : "Not available", 01471 COLOR_CYAN, 0, description_size); 01472 01473 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01474 01475 return RESULT_SUCCESS; 01476 }
static int handle_show_function_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1366 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().
01367 { 01368 struct ast_custom_function *acf; 01369 /* Maximum number of characters added by terminal coloring is 22 */ 01370 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01371 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01372 char stxtitle[40], *syntax = NULL; 01373 int synopsis_size, description_size, syntax_size; 01374 01375 if (argc < 3) 01376 return RESULT_SHOWUSAGE; 01377 01378 if (!(acf = ast_custom_function_find(argv[2]))) { 01379 ast_cli(fd, "No function by that name registered.\n"); 01380 return RESULT_FAILURE; 01381 01382 } 01383 01384 if (acf->synopsis) 01385 synopsis_size = strlen(acf->synopsis) + 23; 01386 else 01387 synopsis_size = strlen("Not available") + 23; 01388 synopsis = alloca(synopsis_size); 01389 01390 if (acf->desc) 01391 description_size = strlen(acf->desc) + 23; 01392 else 01393 description_size = strlen("Not available") + 23; 01394 description = alloca(description_size); 01395 01396 if (acf->syntax) 01397 syntax_size = strlen(acf->syntax) + 23; 01398 else 01399 syntax_size = strlen("Not available") + 23; 01400 syntax = alloca(syntax_size); 01401 01402 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01403 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01404 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01405 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01406 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01407 term_color(syntax, 01408 acf->syntax ? acf->syntax : "Not available", 01409 COLOR_CYAN, 0, syntax_size); 01410 term_color(synopsis, 01411 acf->synopsis ? acf->synopsis : "Not available", 01412 COLOR_CYAN, 0, synopsis_size); 01413 term_color(description, 01414 acf->desc ? acf->desc : "Not available", 01415 COLOR_CYAN, 0, description_size); 01416 01417 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01418 01419 return RESULT_SUCCESS; 01420 }
static int handle_show_functions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1338 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.
01339 { 01340 struct ast_custom_function *acf; 01341 int count_acf = 0; 01342 int like = 0; 01343 01344 if (argc == 5 && (!strcmp(argv[3], "like")) ) { 01345 like = 1; 01346 } else if (argc != 3) { 01347 return RESULT_SHOWUSAGE; 01348 } 01349 01350 ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed"); 01351 01352 AST_LIST_LOCK(&acf_root); 01353 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01354 if (!like || strstr(acf->name, argv[4])) { 01355 count_acf++; 01356 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01357 } 01358 } 01359 AST_LIST_UNLOCK(&acf_root); 01360 01361 ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : ""); 01362 01363 return RESULT_SUCCESS; 01364 }
static int handle_show_functions_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1311 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.
01312 { 01313 struct ast_custom_function *acf; 01314 int count_acf = 0; 01315 int like = 0; 01316 01317 if (argc == 4 && (!strcmp(argv[2], "like")) ) { 01318 like = 1; 01319 } else if (argc != 2) { 01320 return RESULT_SHOWUSAGE; 01321 } 01322 01323 ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed"); 01324 01325 AST_LIST_LOCK(&acf_root); 01326 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01327 if (!like || strstr(acf->name, argv[3])) { 01328 count_acf++; 01329 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01330 } 01331 } 01332 AST_LIST_UNLOCK(&acf_root); 01333 01334 ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : ""); 01335 01336 return RESULT_SUCCESS; 01337 }
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 3752 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.
03753 { 03754 int i = 0; 03755 struct ast_var_t *newvariable; 03756 03757 ast_mutex_lock(&globalslock); 03758 AST_LIST_TRAVERSE (&globals, newvariable, entries) { 03759 i++; 03760 ast_cli(fd, " %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable)); 03761 } 03762 ast_mutex_unlock(&globalslock); 03763 ast_cli(fd, "\n -- %d variables\n", i); 03764 03765 return RESULT_SUCCESS; 03766 }
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 3283 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.
03284 { 03285 struct ast_hint *hint; 03286 int num = 0; 03287 int watchers; 03288 struct ast_state_cb *watcher; 03289 03290 if (AST_LIST_EMPTY(&hints)) { 03291 ast_cli(fd, "There are no registered dialplan hints\n"); 03292 return RESULT_SUCCESS; 03293 } 03294 /* ... we have hints ... */ 03295 ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); 03296 AST_LIST_LOCK(&hints); 03297 AST_LIST_TRAVERSE(&hints, hint, list) { 03298 watchers = 0; 03299 for (watcher = hint->callbacks; watcher; watcher = watcher->next) 03300 watchers++; 03301 ast_cli(fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", 03302 ast_get_extension_name(hint->exten), 03303 ast_get_context_name(ast_get_extension_context(hint->exten)), 03304 ast_get_extension_app(hint->exten), 03305 ast_extension_state2str(hint->laststate), watchers); 03306 num++; 03307 } 03308 ast_cli(fd, "----------------\n"); 03309 ast_cli(fd, "- %d hints registered\n", num); 03310 AST_LIST_UNLOCK(&hints); 03311 return RESULT_SUCCESS; 03312 }
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 3315 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.
03316 { 03317 struct ast_switch *sw; 03318 03319 AST_LIST_LOCK(&switches); 03320 03321 if (AST_LIST_EMPTY(&switches)) { 03322 AST_LIST_UNLOCK(&switches); 03323 ast_cli(fd, "There are no registered alternative switches\n"); 03324 return RESULT_SUCCESS; 03325 } 03326 03327 ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); 03328 AST_LIST_TRAVERSE(&switches, sw, list) 03329 ast_cli(fd, "%s: %s\n", sw->name, sw->description); 03330 03331 AST_LIST_UNLOCK(&switches); 03332 03333 return RESULT_SUCCESS; 03334 }
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 2590 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().
02591 { 02592 int failed = 0; 02593 double curloadavg; 02594 ast_mutex_lock(&maxcalllock); 02595 if (option_maxcalls) { 02596 if (countcalls >= option_maxcalls) { 02597 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name); 02598 failed = -1; 02599 } 02600 } 02601 if (option_maxload) { 02602 getloadavg(&curloadavg, 1); 02603 if (curloadavg >= option_maxload) { 02604 ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg); 02605 failed = -1; 02606 } 02607 } 02608 if (!failed) { 02609 countcalls++; 02610 totalcalls++; 02611 } 02612 ast_mutex_unlock(&maxcalllock); 02613 02614 return failed; 02615 }
int load_pbx | ( | void | ) |
Provided by pbx.c
Definition at line 6277 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().
06278 { 06279 int x; 06280 06281 /* Initialize the PBX */ 06282 if (option_verbose) { 06283 ast_verbose( "Asterisk PBX Core Initializing\n"); 06284 ast_verbose( "Registering builtin applications:\n"); 06285 } 06286 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(struct ast_cli_entry)); 06287 06288 /* Register builtin applications */ 06289 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06290 if (option_verbose) 06291 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06292 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06293 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06294 return -1; 06295 } 06296 } 06297 return 0; 06298 }
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 4116 of file pbx.c.
Referenced by get_range().
04117 { 04118 int i; 04119 04120 if (names) { 04121 for (i = 0; names[i]; i++) { 04122 if (!strcasecmp(s, names[i])) 04123 return i+1; 04124 } 04125 } else if (sscanf(s, "%30d", &i) == 1 && i >= 1 && i <= max) { 04126 return i; 04127 } 04128 return 0; /* error return */ 04129 }
static int matchcid | ( | const char * | cidpattern, | |
const char * | callerid | |||
) | [static] |
Definition at line 958 of file pbx.c.
References ast_extension_match(), and ast_strlen_zero().
Referenced by pbx_find_extension().
00959 { 00960 /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so 00961 failing to get a number should count as a match, otherwise not */ 00962 00963 if (ast_strlen_zero(callerid)) 00964 return ast_strlen_zero(cidpattern) ? 1 : 0; 00965 00966 return ast_extension_match(cidpattern, callerid); 00967 }
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 1124 of file pbx.c.
Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
01125 { 01126 int parens=0; 01127 01128 *offset = 0; 01129 *length = INT_MAX; 01130 *isfunc = 0; 01131 for (; *var; var++) { 01132 if (*var == '(') { 01133 (*isfunc)++; 01134 parens++; 01135 } else if (*var == ')') { 01136 parens--; 01137 } else if (*var == ':' && parens == 0) { 01138 *var++ = '\0'; 01139 sscanf(var, "%30d:%30d", offset, length); 01140 return 1; /* offset:length valid */ 01141 } 01142 } 01143 return 0; 01144 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6079 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().
06080 { 06081 struct ast_var_t *vardata; 06082 06083 ast_mutex_lock(&globalslock); 06084 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06085 ast_var_delete(vardata); 06086 ast_mutex_unlock(&globalslock); 06087 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5856 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(), dahdi_r2_answer(), dahdi_r2_get_channel_category(), 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().
05857 { 05858 struct ast_var_t *variables; 05859 const char *ret = NULL; 05860 int i; 05861 struct varshead *places[2] = { NULL, &globals }; 05862 05863 if (!name) 05864 return NULL; 05865 05866 if (chan) { 05867 ast_channel_lock(chan); 05868 places[0] = &chan->varshead; 05869 } 05870 05871 for (i = 0; i < 2; i++) { 05872 if (!places[i]) 05873 continue; 05874 if (places[i] == &globals) 05875 ast_mutex_lock(&globalslock); 05876 AST_LIST_TRAVERSE(places[i], variables, entries) { 05877 if (!strcmp(name, ast_var_name(variables))) { 05878 ret = ast_var_value(variables); 05879 break; 05880 } 05881 } 05882 if (places[i] == &globals) 05883 ast_mutex_unlock(&globalslock); 05884 if (ret) 05885 break; 05886 } 05887 05888 if (chan) 05889 ast_channel_unlock(chan); 05890 05891 return ret; 05892 }
static int pbx_builtin_gotoif | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6099 of file pbx.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_goto(), and pbx_checkcondition().
06100 { 06101 char *condition, *branch1, *branch2, *branch; 06102 int rc; 06103 char *stringp; 06104 06105 if (ast_strlen_zero(data)) { 06106 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06107 return 0; 06108 } 06109 06110 stringp = ast_strdupa(data); 06111 condition = strsep(&stringp,"?"); 06112 branch1 = strsep(&stringp,":"); 06113 branch2 = strsep(&stringp,""); 06114 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06115 06116 if (ast_strlen_zero(branch)) { 06117 if (option_debug) 06118 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06119 return 0; 06120 } 06121 06122 rc = pbx_builtin_goto(chan, branch); 06123 06124 return rc; 06125 }
int pbx_builtin_importvar | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6018 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.
06019 { 06020 char *name; 06021 char *value; 06022 char *channel; 06023 char tmp[VAR_BUF_SIZE]=""; 06024 06025 if (ast_strlen_zero(data)) { 06026 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06027 return 0; 06028 } 06029 06030 value = ast_strdupa(data); 06031 name = strsep(&value,"="); 06032 channel = strsep(&value,"|"); 06033 if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */ 06034 struct ast_channel *chan2 = ast_get_channel_by_name_locked(channel); 06035 if (chan2) { 06036 char *s = alloca(strlen(value) + 4); 06037 if (s) { 06038 sprintf(s, "${%s}", value); 06039 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 06040 } 06041 ast_channel_unlock(chan2); 06042 } 06043 pbx_builtin_setvar_helper(chan, name, tmp); 06044 } 06045 06046 return(0); 06047 }
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 5894 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().
05895 { 05896 struct ast_var_t *newvariable; 05897 struct varshead *headp; 05898 05899 if (name[strlen(name)-1] == ')') { 05900 char *function = ast_strdupa(name); 05901 05902 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05903 ast_func_write(chan, function, value); 05904 return; 05905 } 05906 05907 if (chan) { 05908 ast_channel_lock(chan); 05909 headp = &chan->varshead; 05910 } else { 05911 ast_mutex_lock(&globalslock); 05912 headp = &globals; 05913 } 05914 05915 if (value) { 05916 if ((option_verbose > 1) && (headp == &globals)) 05917 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05918 newvariable = ast_var_assign(name, value); 05919 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05920 } 05921 05922 if (chan) 05923 ast_channel_unlock(chan); 05924 else 05925 ast_mutex_unlock(&globalslock); 05926 }
static int pbx_builtin_saycharacters | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6164 of file pbx.c.
References ast_say_character_str(), and ast_channel::language.
06165 { 06166 int res = 0; 06167 06168 if (data) 06169 res = ast_say_character_str(chan, data, "", chan->language); 06170 return res; 06171 }
static int pbx_builtin_saydate | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6182 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().
06183 { 06184 int res = 0; 06185 char *parse; 06186 int unixdate = 0; 06187 char charascii[2]; 06188 06189 AST_DECLARE_APP_ARGS(args, 06190 AST_APP_ARG(datestr); 06191 AST_APP_ARG(digits); 06192 ); 06193 06194 06195 if (ast_strlen_zero(data)) { 06196 ast_log(LOG_WARNING, "SayDate requires an argument (date)\n"); 06197 return -1; 06198 } 06199 06200 if (!(parse = ast_strdupa(data))) { 06201 ast_log(LOG_WARNING, "Memory Error!\n"); 06202 return -1; 06203 } 06204 06205 AST_STANDARD_APP_ARGS(args, parse); 06206 06207 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06208 ast_log(LOG_WARNING, "SayDate escape digits must be a subset from '0123456789*#'\n"); 06209 args.digits = ""; 06210 } 06211 06212 if (sscanf(args.datestr, "%d", &unixdate) != 1) { 06213 ast_log(LOG_WARNING, "Firt argument to SayDate must be numeric (date)\n"); 06214 return -1; 06215 } 06216 06217 res = ast_say_date(chan, (time_t)unixdate, args.digits, chan->language); 06218 if (res > 0) { 06219 if (isdigit(res) || (res == '*') || (res == '#')) { 06220 snprintf(charascii, 2, "%c", res); 06221 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06222 res = 0; 06223 } else { 06224 ast_log(LOG_WARNING, "SayDate: invalid return value (%d) detected\n", res); 06225 } 06226 } 06227 return res; 06228 }
static int pbx_builtin_saydigits | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6155 of file pbx.c.
References ast_say_digit_str(), and ast_channel::language.
06156 { 06157 int res = 0; 06158 06159 if (data) 06160 res = ast_say_digit_str(chan, data, "", chan->language); 06161 return res; 06162 }
static int pbx_builtin_saynumber | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6127 of file pbx.c.
References ast_copy_string(), ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, and LOG_WARNING.
06128 { 06129 char tmp[256]; 06130 char *number = tmp; 06131 char *options; 06132 06133 if (ast_strlen_zero(data)) { 06134 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06135 return -1; 06136 } 06137 ast_copy_string(tmp, data, sizeof(tmp)); 06138 strsep(&number, "|"); 06139 options = strsep(&number, "|"); 06140 if (options) { 06141 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06142 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06143 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06144 return -1; 06145 } 06146 } 06147 06148 if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) { 06149 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp); 06150 } 06151 06152 return 0; 06153 }
static int pbx_builtin_sayphonetic | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6173 of file pbx.c.
References ast_say_phonetic_str(), and ast_channel::language.
06174 { 06175 int res = 0; 06176 06177 if (data) 06178 res = ast_say_phonetic_str(chan, data, "", chan->language); 06179 return res; 06180 }
static int pbx_builtin_saytime | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6230 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().
06231 { 06232 int res = 0; 06233 char *parse; 06234 int secs = 0; 06235 char charascii[2]; 06236 06237 AST_DECLARE_APP_ARGS(args, 06238 AST_APP_ARG(timestr); 06239 AST_APP_ARG(digits); 06240 ); 06241 06242 if (ast_strlen_zero(data)) { 06243 ast_log(LOG_WARNING, "SayTime requires an argument (time in seconds)\n"); 06244 return -1; 06245 } 06246 06247 if (!(parse = ast_strdupa(data))) { 06248 ast_log(LOG_WARNING, "Memory Error!\n"); 06249 return -1; 06250 } 06251 06252 AST_STANDARD_APP_ARGS(args, parse); 06253 06254 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06255 ast_log(LOG_WARNING, "SayTime escape digits must be a subset from '0123456789*#'\n"); 06256 args.digits = ""; 06257 } 06258 06259 if (sscanf(args.timestr, "%d", &secs) != 1) { 06260 ast_log(LOG_WARNING, "Firt argument to SayTime must be numeric (time in seconds)\n"); 06261 return -1; 06262 } 06263 06264 res = ast_say_time(chan, (time_t)secs, args.digits, chan->language); 06265 if (res > 0) { 06266 if (isdigit(res) || (res == '*') || (res == '#')) { 06267 snprintf(charascii, 2, "%c", res); 06268 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06269 res = 0; 06270 } else { 06271 ast_log(LOG_WARNING, "SayTime: invalid return value (%d) detected\n", res); 06272 } 06273 } 06274 return res; 06275 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5825 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().
05826 { 05827 struct ast_var_t *variables; 05828 const char *var, *val; 05829 int total = 0; 05830 05831 if (!chan) 05832 return 0; 05833 05834 memset(buf, 0, size); 05835 05836 ast_channel_lock(chan); 05837 05838 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05839 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05840 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05841 ) { 05842 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05843 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05844 break; 05845 } else 05846 total++; 05847 } else 05848 break; 05849 } 05850 05851 ast_channel_unlock(chan); 05852 05853 return total; 05854 }
static int pbx_builtin_setglobalvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 6050 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and pbx_builtin_setvar_helper().
06051 { 06052 char *name; 06053 char *stringp = data; 06054 static int dep_warning = 0; 06055 06056 if (ast_strlen_zero(data)) { 06057 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06058 return 0; 06059 } 06060 06061 name = strsep(&stringp, "="); 06062 06063 if (!dep_warning) { 06064 dep_warning = 1; 06065 ast_log(LOG_WARNING, "SetGlobalVar is deprecated. Please use Set(GLOBAL(%s)=%s) instead.\n", name, stringp); 06066 } 06067 06068 /*! \todo XXX watch out, leading whitespace ? */ 06069 pbx_builtin_setvar_helper(NULL, name, stringp); 06070 06071 return(0); 06072 }
int pbx_builtin_setvar | ( | struct ast_channel * | , | |
void * | ||||
) |
Definition at line 5978 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().
05979 { 05980 char *name, *value, *mydata; 05981 int argc; 05982 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 05983 int global = 0; 05984 int x; 05985 05986 if (ast_strlen_zero(data)) { 05987 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 05988 return 0; 05989 } 05990 05991 mydata = ast_strdupa(data); 05992 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 05993 05994 /* check for a trailing flags argument */ 05995 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 05996 argc--; 05997 if (strchr(argv[argc], 'g')) { 05998 ast_log(LOG_WARNING, "The use of the 'g' flag is deprecated. Please use Set(GLOBAL(foo)=bar) instead\n"); 05999 global = 1; 06000 } 06001 } 06002 06003 if (argc > 1) 06004 ast_log(LOG_WARNING, "Setting multiple variables at once within Set is deprecated. Please separate each name/value pair into its own line.\n"); 06005 06006 for (x = 0; x < argc; x++) { 06007 name = argv[x]; 06008 if ((value = strchr(name, '='))) { 06009 *value++ = '\0'; 06010 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 06011 } else 06012 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 06013 } 06014 06015 return(0); 06016 }
void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 5928 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().
05929 { 05930 struct ast_var_t *newvariable; 05931 struct varshead *headp; 05932 const char *nametail = name; 05933 05934 if (name[strlen(name)-1] == ')') { 05935 char *function = ast_strdupa(name); 05936 05937 ast_func_write(chan, function, value); 05938 return; 05939 } 05940 05941 if (chan) { 05942 ast_channel_lock(chan); 05943 headp = &chan->varshead; 05944 } else { 05945 ast_mutex_lock(&globalslock); 05946 headp = &globals; 05947 } 05948 05949 /* For comparison purposes, we have to strip leading underscores */ 05950 if (*nametail == '_') { 05951 nametail++; 05952 if (*nametail == '_') 05953 nametail++; 05954 } 05955 05956 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05957 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05958 /* there is already such a variable, delete it */ 05959 AST_LIST_REMOVE(headp, newvariable, entries); 05960 ast_var_delete(newvariable); 05961 break; 05962 } 05963 } 05964 05965 if (value) { 05966 if ((option_verbose > 1) && (headp == &globals)) 05967 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05968 newvariable = ast_var_assign(name, value); 05969 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05970 } 05971 05972 if (chan) 05973 ast_channel_unlock(chan); 05974 else 05975 ast_mutex_unlock(&globalslock); 05976 }
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 6089 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().
06090 { 06091 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06092 return 0; 06093 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06094 return atoi(condition); 06095 else /* Strings are true */ 06096 return 1; 06097 }
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(), 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 1851 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, S_OR, 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().
01854 { 01855 struct ast_exten *e; 01856 struct ast_app *app; 01857 int res; 01858 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */ 01859 char passdata[EXT_DATA_SIZE]; 01860 01861 int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE); 01862 01863 ast_rdlock_contexts(); 01864 e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action); 01865 if (e) { 01866 if (matching_action) { 01867 ast_unlock_contexts(); 01868 return -1; /* success, we found it */ 01869 } else if (action == E_FINDLABEL) { /* map the label to a priority */ 01870 res = e->priority; 01871 ast_unlock_contexts(); 01872 return res; /* the priority we were looking for */ 01873 } else { /* spawn */ 01874 app = pbx_findapp(e->app); 01875 ast_unlock_contexts(); 01876 if (!app) { 01877 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority); 01878 return -1; 01879 } 01880 if (c->context != context) 01881 ast_copy_string(c->context, context, sizeof(c->context)); 01882 if (c->exten != exten) 01883 ast_copy_string(c->exten, exten, sizeof(c->exten)); 01884 c->priority = priority; 01885 pbx_substitute_variables(passdata, sizeof(passdata), c, e); 01886 if (option_debug) { 01887 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name); 01888 } 01889 if (option_verbose > 2) { 01890 char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE]; 01891 ast_verbose( VERBOSE_PREFIX_3 "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n", 01892 exten, context, priority, 01893 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)), 01894 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 01895 term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)), 01896 "in new stack"); 01897 } 01898 manager_event(EVENT_FLAG_CALL, "Newexten", 01899 "Channel: %s\r\n" 01900 "Context: %s\r\n" 01901 "Extension: %s\r\n" 01902 "Priority: %d\r\n" 01903 "Application: %s\r\n" 01904 "AppData: %s\r\n" 01905 "Uniqueid: %s\r\n", 01906 c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid); 01907 return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */ 01908 } 01909 } else if (q.swo) { /* not found here, but in another switch */ 01910 ast_unlock_contexts(); 01911 if (matching_action) { 01912 return -1; 01913 } else { 01914 if (!q.swo->exec) { 01915 ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name); 01916 res = -1; 01917 } 01918 return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data); 01919 } 01920 } else { /* not found anywhere, see what happened */ 01921 ast_unlock_contexts(); 01922 /* Using S_OR here because Solaris doesn't like NULL being passed to ast_log */ 01923 switch (q.status) { 01924 case STATUS_NO_CONTEXT: 01925 if (!matching_action) 01926 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", S_OR(context, "")); 01927 break; 01928 case STATUS_NO_EXTENSION: 01929 if (!matching_action) 01930 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, S_OR(context, "")); 01931 break; 01932 case STATUS_NO_PRIORITY: 01933 if (!matching_action) 01934 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, S_OR(context, "")); 01935 break; 01936 case STATUS_NO_LABEL: 01937 if (context) 01938 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, S_OR(context, "")); 01939 break; 01940 default: 01941 if (option_debug) 01942 ast_log(LOG_DEBUG, "Shouldn't happen!\n"); 01943 } 01944 01945 return (matching_action) ? 0 : -1; 01946 } 01947 }
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 985 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().
00989 { 00990 int x, res; 00991 struct ast_context *tmp; 00992 struct ast_exten *e, *eroot; 00993 struct ast_include *i; 00994 struct ast_sw *sw; 00995 char *tmpdata = NULL; 00996 00997 /* Initialize status if appropriate */ 00998 if (q->stacklen == 0) { 00999 q->status = STATUS_NO_CONTEXT; 01000 q->swo = NULL; 01001 q->data = NULL; 01002 q->foundcontext = NULL; 01003 } 01004 /* Check for stack overflow */ 01005 if (q->stacklen >= AST_PBX_MAX_STACK) { 01006 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n"); 01007 return NULL; 01008 } 01009 /* Check first to see if we've already been checked */ 01010 for (x = 0; x < q->stacklen; x++) { 01011 if (!strcasecmp(q->incstack[x], context)) 01012 return NULL; 01013 } 01014 if (bypass) /* bypass means we only look there */ 01015 tmp = bypass; 01016 else { /* look in contexts */ 01017 tmp = NULL; 01018 while ((tmp = ast_walk_contexts(tmp)) ) { 01019 if (!strcmp(tmp->name, context)) 01020 break; 01021 } 01022 if (!tmp) 01023 return NULL; 01024 } 01025 if (q->status < STATUS_NO_EXTENSION) 01026 q->status = STATUS_NO_EXTENSION; 01027 01028 /* scan the list trying to match extension and CID */ 01029 eroot = NULL; 01030 while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) { 01031 int match = extension_match_core(eroot->exten, exten, action); 01032 /* 0 on fail, 1 on match, 2 on earlymatch */ 01033 01034 if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid))) 01035 continue; /* keep trying */ 01036 if (match == 2 && action == E_MATCHMORE) { 01037 /* We match an extension ending in '!'. 01038 * The decision in this case is final and is NULL (no match). 01039 */ 01040 return NULL; 01041 } 01042 /* found entry, now look for the right priority */ 01043 if (q->status < STATUS_NO_PRIORITY) 01044 q->status = STATUS_NO_PRIORITY; 01045 e = NULL; 01046 while ( (e = ast_walk_extension_priorities(eroot, e)) ) { 01047 /* Match label or priority */ 01048 if (action == E_FINDLABEL) { 01049 if (q->status < STATUS_NO_LABEL) 01050 q->status = STATUS_NO_LABEL; 01051 if (label && e->label && !strcmp(label, e->label)) 01052 break; /* found it */ 01053 } else if (e->priority == priority) { 01054 break; /* found it */ 01055 } /* else keep searching */ 01056 } 01057 if (e) { /* found a valid match */ 01058 q->status = STATUS_SUCCESS; 01059 q->foundcontext = context; 01060 return e; 01061 } 01062 } 01063 /* Check alternative switches */ 01064 AST_LIST_TRAVERSE(&tmp->alts, sw, list) { 01065 struct ast_switch *asw = pbx_findswitch(sw->name); 01066 ast_switch_f *aswf = NULL; 01067 char *datap; 01068 01069 if (!asw) { 01070 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); 01071 continue; 01072 } 01073 /* Substitute variables now */ 01074 if (sw->eval) { 01075 if (!(tmpdata = ast_threadstorage_get(&switch_data, 512))) { 01076 ast_log(LOG_WARNING, "Can't evaluate switch?!"); 01077 continue; 01078 } 01079 pbx_substitute_variables_helper(chan, sw->data, tmpdata, 512); 01080 } 01081 01082 /* equivalent of extension_match_core() at the switch level */ 01083 if (action == E_CANMATCH) 01084 aswf = asw->canmatch; 01085 else if (action == E_MATCHMORE) 01086 aswf = asw->matchmore; 01087 else /* action == E_MATCH */ 01088 aswf = asw->exists; 01089 datap = sw->eval ? tmpdata : sw->data; 01090 if (!aswf) 01091 res = 0; 01092 else { 01093 if (chan) 01094 ast_autoservice_start(chan); 01095 res = aswf(chan, context, exten, priority, callerid, datap); 01096 if (chan) 01097 ast_autoservice_stop(chan); 01098 } 01099 if (res) { /* Got a match */ 01100 q->swo = asw; 01101 q->data = datap; 01102 q->foundcontext = context; 01103 /* XXX keep status = STATUS_NO_CONTEXT ? */ 01104 return NULL; 01105 } 01106 } 01107 q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */ 01108 /* Now try any includes we have in this context */ 01109 for (i = tmp->includes; i; i = i->next) { 01110 if (include_valid(i)) { 01111 if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) 01112 return e; 01113 if (q->swo) 01114 return NULL; 01115 } 01116 } 01117 return NULL; 01118 }
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(), 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 1192 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().
01193 { 01194 const char not_found = '\0'; 01195 char *tmpvar; 01196 const char *s; /* the result */ 01197 int offset, length; 01198 int i, need_substring; 01199 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 01200 01201 if (c) { 01202 ast_channel_lock(c); 01203 places[0] = &c->varshead; 01204 } 01205 /* 01206 * Make a copy of var because parse_variable_name() modifies the string. 01207 * Then if called directly, we might need to run substring() on the result; 01208 * remember this for later in 'need_substring', 'offset' and 'length' 01209 */ 01210 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 01211 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 01212 01213 /* 01214 * Look first into predefined variables, then into variable lists. 01215 * Variable 's' points to the result, according to the following rules: 01216 * s == ¬_found (set at the beginning) means that we did not find a 01217 * matching variable and need to look into more places. 01218 * If s != ¬_found, s is a valid result string as follows: 01219 * s = NULL if the variable does not have a value; 01220 * you typically do this when looking for an unset predefined variable. 01221 * s = workspace if the result has been assembled there; 01222 * typically done when the result is built e.g. with an snprintf(), 01223 * so we don't need to do an additional copy. 01224 * s != workspace in case we have a string, that needs to be copied 01225 * (the ast_copy_string is done once for all at the end). 01226 * Typically done when the result is already available in some string. 01227 */ 01228 s = ¬_found; /* default value */ 01229 if (c) { /* This group requires a valid channel */ 01230 /* Names with common parts are looked up a piece at a time using strncmp. */ 01231 if (!strncmp(var, "CALL", 4)) { 01232 if (!strncmp(var + 4, "ING", 3)) { 01233 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 01234 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01235 s = workspace; 01236 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 01237 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01238 s = workspace; 01239 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 01240 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01241 s = workspace; 01242 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 01243 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01244 s = workspace; 01245 } 01246 } 01247 } else if (!strcmp(var, "HINT")) { 01248 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 01249 } else if (!strcmp(var, "HINTNAME")) { 01250 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 01251 } else if (!strcmp(var, "EXTEN")) { 01252 s = c->exten; 01253 } else if (!strcmp(var, "CONTEXT")) { 01254 s = c->context; 01255 } else if (!strcmp(var, "PRIORITY")) { 01256 snprintf(workspace, workspacelen, "%d", c->priority); 01257 s = workspace; 01258 } else if (!strcmp(var, "CHANNEL")) { 01259 s = c->name; 01260 } else if (!strcmp(var, "UNIQUEID")) { 01261 s = c->uniqueid; 01262 } else if (!strcmp(var, "HANGUPCAUSE")) { 01263 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01264 s = workspace; 01265 } else if (c && !strcmp(var, "HANGUPCAUSESTR")) { 01266 ast_copy_string(workspace, ast_cause2str(c->hangupcause), workspacelen); 01267 *ret = workspace; 01268 } 01269 } 01270 if (s == ¬_found) { /* look for more */ 01271 if (!strcmp(var, "EPOCH")) { 01272 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01273 s = workspace; 01274 } else if (!strcmp(var, "SYSTEMNAME")) { 01275 s = ast_config_AST_SYSTEM_NAME; 01276 } 01277 } 01278 /* if not found, look into chanvars or global vars */ 01279 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) { 01280 struct ast_var_t *variables; 01281 if (!places[i]) 01282 continue; 01283 if (places[i] == &globals) 01284 ast_mutex_lock(&globalslock); 01285 AST_LIST_TRAVERSE(places[i], variables, entries) { 01286 if (strcasecmp(ast_var_name(variables), var)==0) { 01287 s = ast_var_value(variables); 01288 break; 01289 } 01290 } 01291 if (places[i] == &globals) 01292 ast_mutex_unlock(&globalslock); 01293 } 01294 if (s == ¬_found || s == NULL) 01295 *ret = NULL; 01296 else { 01297 if (s != workspace) 01298 ast_copy_string(workspace, s, workspacelen); 01299 *ret = workspace; 01300 if (need_substring) 01301 *ret = substring(*ret, offset, length, workspace, workspacelen); 01302 } 01303 01304 if (c) 01305 ast_channel_unlock(c); 01306 }
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 2705 of file pbx.c.
References autofallthrough.
Referenced by pbx_load_module().
02706 { 02707 int oldval = autofallthrough; 02708 autofallthrough = newval; 02709 return oldval; 02710 }
static void pbx_substitute_variables | ( | char * | passdata, | |
int | datalen, | |||
struct ast_channel * | c, | |||
struct ast_exten * | e | |||
) | [static] |
Definition at line 1822 of file pbx.c.
References ast_copy_string(), ast_exten::data, and pbx_substitute_variables_helper().
Referenced by pbx_extension_helper().
01823 { 01824 memset(passdata, 0, datalen); 01825 01826 /* No variables or expressions in e->data, so why scan it? */ 01827 if (e->data && !strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) { 01828 ast_copy_string(passdata, e->data, datalen); 01829 return; 01830 } 01831 01832 pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1); 01833 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1812 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().
01813 { 01814 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01815 }
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 1617 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().
01618 { 01619 /* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!! */ 01620 char *cp4; 01621 const char *tmp, *whereweare; 01622 int length, offset, offset2, isfunction; 01623 char *workspace = NULL; 01624 char *ltmp = NULL, *var = NULL; 01625 char *nextvar, *nextexp, *nextthing; 01626 char *vars, *vare; 01627 int pos, brackets, needsub, len; 01628 01629 *cp2 = 0; /* just in case nothing ends up there */ 01630 whereweare=tmp=cp1; 01631 while (!ast_strlen_zero(whereweare) && count) { 01632 /* Assume we're copying the whole remaining string */ 01633 pos = strlen(whereweare); 01634 nextvar = NULL; 01635 nextexp = NULL; 01636 nextthing = strchr(whereweare, '$'); 01637 if (nextthing) { 01638 switch(nextthing[1]) { 01639 case '{': 01640 nextvar = nextthing; 01641 pos = nextvar - whereweare; 01642 break; 01643 case '[': 01644 nextexp = nextthing; 01645 pos = nextexp - whereweare; 01646 break; 01647 default: 01648 pos = 1; 01649 } 01650 } 01651 01652 if (pos) { 01653 /* Can't copy more than 'count' bytes */ 01654 if (pos > count) 01655 pos = count; 01656 01657 /* Copy that many bytes */ 01658 memcpy(cp2, whereweare, pos); 01659 01660 count -= pos; 01661 cp2 += pos; 01662 whereweare += pos; 01663 *cp2 = 0; 01664 } 01665 01666 if (nextvar) { 01667 /* We have a variable. Find the start and end, and determine 01668 if we are going to have to recursively call ourselves on the 01669 contents */ 01670 vars = vare = nextvar + 2; 01671 brackets = 1; 01672 needsub = 0; 01673 01674 /* Find the end of it */ 01675 while (brackets && *vare) { 01676 if ((vare[0] == '$') && (vare[1] == '{')) { 01677 needsub++; 01678 } else if (vare[0] == '{') { 01679 brackets++; 01680 } else if (vare[0] == '}') { 01681 brackets--; 01682 } else if ((vare[0] == '$') && (vare[1] == '[')) 01683 needsub++; 01684 vare++; 01685 } 01686 if (brackets) 01687 ast_log(LOG_WARNING, "Error in extension logic (missing '}')\n"); 01688 len = vare - vars - 1; 01689 01690 /* Skip totally over variable string */ 01691 whereweare += (len + 3); 01692 01693 if (!var) 01694 var = alloca(VAR_BUF_SIZE); 01695 01696 /* Store variable name (and truncate) */ 01697 ast_copy_string(var, vars, len + 1); 01698 01699 /* Substitute if necessary */ 01700 if (needsub) { 01701 if (!ltmp) 01702 ltmp = alloca(VAR_BUF_SIZE); 01703 01704 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01705 vars = ltmp; 01706 } else { 01707 vars = var; 01708 } 01709 01710 if (!workspace) 01711 workspace = alloca(VAR_BUF_SIZE); 01712 01713 workspace[0] = '\0'; 01714 01715 parse_variable_name(vars, &offset, &offset2, &isfunction); 01716 if (isfunction) { 01717 /* Evaluate function */ 01718 if (c || !headp) 01719 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace; 01720 else { 01721 struct varshead old; 01722 struct ast_channel *c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/%p", vars); 01723 if (c) { 01724 memcpy(&old, &c->varshead, sizeof(old)); 01725 memcpy(&c->varshead, headp, sizeof(c->varshead)); 01726 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace; 01727 /* Don't deallocate the varshead that was passed in */ 01728 memcpy(&c->varshead, &old, sizeof(c->varshead)); 01729 ast_channel_free(c); 01730 } else 01731 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 01732 } 01733 01734 if (option_debug) 01735 ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)"); 01736 } else { 01737 /* Retrieve variable value */ 01738 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp); 01739 } 01740 if (cp4) { 01741 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE); 01742 01743 length = strlen(cp4); 01744 if (length > count) 01745 length = count; 01746 memcpy(cp2, cp4, length); 01747 count -= length; 01748 cp2 += length; 01749 *cp2 = 0; 01750 } 01751 } else if (nextexp) { 01752 /* We have an expression. Find the start and end, and determine 01753 if we are going to have to recursively call ourselves on the 01754 contents */ 01755 vars = vare = nextexp + 2; 01756 brackets = 1; 01757 needsub = 0; 01758 01759 /* Find the end of it */ 01760 while (brackets && *vare) { 01761 if ((vare[0] == '$') && (vare[1] == '[')) { 01762 needsub++; 01763 brackets++; 01764 vare++; 01765 } else if (vare[0] == '[') { 01766 brackets++; 01767 } else if (vare[0] == ']') { 01768 brackets--; 01769 } else if ((vare[0] == '$') && (vare[1] == '{')) { 01770 needsub++; 01771 vare++; 01772 } 01773 vare++; 01774 } 01775 if (brackets) 01776 ast_log(LOG_WARNING, "Error in extension logic (missing ']')\n"); 01777 len = vare - vars - 1; 01778 01779 /* Skip totally over expression */ 01780 whereweare += (len + 3); 01781 01782 if (!var) 01783 var = alloca(VAR_BUF_SIZE); 01784 01785 /* Store variable name (and truncate) */ 01786 ast_copy_string(var, vars, len + 1); 01787 01788 /* Substitute if necessary */ 01789 if (needsub) { 01790 if (!ltmp) 01791 ltmp = alloca(VAR_BUF_SIZE); 01792 01793 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01794 vars = ltmp; 01795 } else { 01796 vars = var; 01797 } 01798 01799 length = ast_expr(vars, cp2, count); 01800 01801 if (length) { 01802 if (option_debug) 01803 ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2); 01804 count -= length; 01805 cp2 += length; 01806 *cp2 = 0; 01807 } 01808 } 01809 } 01810 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1817 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_subst().
01818 { 01819 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01820 }
static void* pbx_thread | ( | void * | data | ) | [static] |
Definition at line 2635 of file pbx.c.
References __ast_pbx_run(), and decrease_call_count().
Referenced by ast_pbx_start().
02636 { 02637 /* Oh joyeous kernel, we're a new thread, with nothing to do but 02638 answer this channel and get it going. 02639 */ 02640 /* NOTE: 02641 The launcher of this function _MUST_ increment 'countcalls' 02642 before invoking the function; it will be decremented when the 02643 PBX has finished running on the channel 02644 */ 02645 struct ast_channel *c = data; 02646 02647 __ast_pbx_run(c); 02648 decrease_call_count(); 02649 02650 pthread_exit(NULL); 02651 02652 return NULL; 02653 }
static void print_ext | ( | struct ast_exten * | e, | |
char * | buf, | |||
int | buflen | |||
) | [static] |
helper function to print an extension
Definition at line 3531 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().
03532 { 03533 int prio = ast_get_extension_priority(e); 03534 if (prio == PRIORITY_HINT) { 03535 snprintf(buf, buflen, "hint: %s", 03536 ast_get_extension_app(e)); 03537 } else { 03538 snprintf(buf, buflen, "%d. %s(%s)", 03539 prio, ast_get_extension_app(e), 03540 (!ast_strlen_zero(ast_get_extension_app_data(e)) ? (char *)ast_get_extension_app_data(e) : "")); 03541 } 03542 }
static void set_ext_pri | ( | struct ast_channel * | c, | |
const char * | exten, | |||
int | pri | |||
) | [static] |
Definition at line 2332 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().
02333 { 02334 ast_channel_lock(c); 02335 ast_copy_string(c->exten, exten, sizeof(c->exten)); 02336 c->priority = pri; 02337 ast_channel_unlock(c); 02338 }
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 3545 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().
03546 { 03547 struct ast_context *c = NULL; 03548 int res = 0, old_total_exten = dpc->total_exten; 03549 03550 ast_rdlock_contexts(); 03551 03552 /* walk all contexts ... */ 03553 while ( (c = ast_walk_contexts(c)) ) { 03554 struct ast_exten *e; 03555 struct ast_include *i; 03556 struct ast_ignorepat *ip; 03557 char buf[256], buf2[256]; 03558 int context_info_printed = 0; 03559 03560 if (context && strcmp(ast_get_context_name(c), context)) 03561 continue; /* skip this one, name doesn't match */ 03562 03563 dpc->context_existence = 1; 03564 03565 ast_lock_context(c); 03566 03567 /* are we looking for exten too? if yes, we print context 03568 * only if we find our extension. 03569 * Otherwise print context even if empty ? 03570 * XXX i am not sure how the rinclude is handled. 03571 * I think it ought to go inside. 03572 */ 03573 if (!exten) { 03574 dpc->total_context++; 03575 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03576 ast_get_context_name(c), ast_get_context_registrar(c)); 03577 context_info_printed = 1; 03578 } 03579 03580 /* walk extensions ... */ 03581 e = NULL; 03582 while ( (e = ast_walk_context_extensions(c, e)) ) { 03583 struct ast_exten *p; 03584 03585 if (exten && !ast_extension_match(ast_get_extension_name(e), exten)) 03586 continue; /* skip, extension match failed */ 03587 03588 dpc->extension_existence = 1; 03589 03590 /* may we print context info? */ 03591 if (!context_info_printed) { 03592 dpc->total_context++; 03593 if (rinclude) { /* TODO Print more info about rinclude */ 03594 ast_cli(fd, "[ Included context '%s' created by '%s' ]\n", 03595 ast_get_context_name(c), ast_get_context_registrar(c)); 03596 } else { 03597 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03598 ast_get_context_name(c), ast_get_context_registrar(c)); 03599 } 03600 context_info_printed = 1; 03601 } 03602 dpc->total_prio++; 03603 03604 /* write extension name and first peer */ 03605 if (e->matchcid) 03606 snprintf(buf, sizeof(buf), "'%s' (CID match '%s') => ", ast_get_extension_name(e), e->cidmatch); 03607 else 03608 snprintf(buf, sizeof(buf), "'%s' =>", ast_get_extension_name(e)); 03609 03610 print_ext(e, buf2, sizeof(buf2)); 03611 03612 ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2, 03613 ast_get_extension_registrar(e)); 03614 03615 dpc->total_exten++; 03616 /* walk next extension peers */ 03617 p = e; /* skip the first one, we already got it */ 03618 while ( (p = ast_walk_extension_priorities(e, p)) ) { 03619 const char *el = ast_get_extension_label(p); 03620 dpc->total_prio++; 03621 if (el) 03622 snprintf(buf, sizeof(buf), " [%s]", el); 03623 else 03624 buf[0] = '\0'; 03625 print_ext(p, buf2, sizeof(buf2)); 03626 03627 ast_cli(fd," %-17s %-45s [%s]\n", buf, buf2, 03628 ast_get_extension_registrar(p)); 03629 } 03630 } 03631 03632 /* walk included and write info ... */ 03633 i = NULL; 03634 while ( (i = ast_walk_context_includes(c, i)) ) { 03635 snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i)); 03636 if (exten) { 03637 /* Check all includes for the requested extension */ 03638 if (includecount >= AST_PBX_MAX_STACK) { 03639 ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n"); 03640 } else { 03641 int dupe=0; 03642 int x; 03643 for (x=0;x<includecount;x++) { 03644 if (!strcasecmp(includes[x], ast_get_include_name(i))) { 03645 dupe++; 03646 break; 03647 } 03648 } 03649 if (!dupe) { 03650 includes[includecount] = ast_get_include_name(i); 03651 show_dialplan_helper(fd, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes); 03652 } else { 03653 ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context); 03654 } 03655 } 03656 } else { 03657 ast_cli(fd, " Include => %-45s [%s]\n", 03658 buf, ast_get_include_registrar(i)); 03659 } 03660 } 03661 03662 /* walk ignore patterns and write info ... */ 03663 ip = NULL; 03664 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) { 03665 const char *ipname = ast_get_ignorepat_name(ip); 03666 char ignorepat[AST_MAX_EXTENSION]; 03667 snprintf(buf, sizeof(buf), "'%s'", ipname); 03668 snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname); 03669 if (!exten || ast_extension_match(ignorepat, exten)) { 03670 ast_cli(fd, " Ignore pattern => %-45s [%s]\n", 03671 buf, ast_get_ignorepat_registrar(ip)); 03672 } 03673 } 03674 if (!rinclude) { 03675 struct ast_sw *sw = NULL; 03676 while ( (sw = ast_walk_context_switches(c, sw)) ) { 03677 snprintf(buf, sizeof(buf), "'%s/%s'", 03678 ast_get_switch_name(sw), 03679 ast_get_switch_data(sw)); 03680 ast_cli(fd, " Alt. Switch => %-45s [%s]\n", 03681 buf, ast_get_switch_registrar(sw)); 03682 } 03683 } 03684 03685 ast_unlock_context(c); 03686 03687 /* if we print something in context, make an empty line */ 03688 if (context_info_printed) 03689 ast_cli(fd, "\n"); 03690 } 03691 ast_unlock_contexts(); 03692 03693 return (dpc->total_exten == old_total_exten) ? -1 : res; 03694 }
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 1154 of file pbx.c.
References ast_copy_string().
Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
01155 { 01156 char *ret = workspace; 01157 int lr; /* length of the input string after the copy */ 01158 01159 ast_copy_string(workspace, value, workspace_len); /* always make a copy */ 01160 01161 lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */ 01162 01163 /* Quick check if no need to do anything */ 01164 if (offset == 0 && length >= lr) /* take the whole string */ 01165 return ret; 01166 01167 if (offset < 0) { /* translate negative offset into positive ones */ 01168 offset = lr + offset; 01169 if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */ 01170 offset = 0; 01171 } 01172 01173 /* too large offset result in empty string so we know what to return */ 01174 if (offset >= lr) 01175 return ret + lr; /* the final '\0' */ 01176 01177 ret += offset; /* move to the start position */ 01178 if (length >= 0 && length < lr - offset) /* truncate if necessary */ 01179 ret[length] = '\0'; 01180 else if (length < 0) { 01181 if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */ 01182 ret[lr + length - offset] = '\0'; 01183 else 01184 ret[0] = '\0'; 01185 } 01186 01187 return ret; 01188 }
static void switch_data_init | ( | void | ) | [static] |
static void wait_for_hangup | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5419 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().
05420 { 05421 int res; 05422 struct ast_frame *f; 05423 int waittime; 05424 05425 if (ast_strlen_zero(data) || (sscanf(data, "%30d", &waittime) != 1) || (waittime < 0)) 05426 waittime = -1; 05427 if (waittime > -1) { 05428 ast_safe_sleep(chan, waittime * 1000); 05429 } else do { 05430 res = ast_waitfor(chan, -1); 05431 if (res < 0) 05432 return; 05433 f = ast_read(chan); 05434 if (f) 05435 ast_frfree(f); 05436 } while(f); 05437 }
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] |