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