#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"
#include "asterisk/astobj2.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 | 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 void | ast_hint_destroy (void *obj) |
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_init (void) |
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 int | find_hint_by_cb_id (void *obj, void *arg, int flags) |
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 1 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 | hint_cmp (void *obj, void *arg, int flags) |
static int | hint_hash (const void *hint, const int flags) |
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_proceeding (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_mutex_t | conlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
Lock for the ast_context list This lock MUST be recursive, or a deadlock on reload may result. See https://issues.asterisk.org/view.php?id=17643. | |
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 struct ao2_container * | hints |
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 585 of file pbx.c.
Referenced by handle_show_dialplan(), pbx_find_extension(), and show_dialplan_helper().
#define BACKGROUND_MATCHEXTEN (1 << 2) |
#define BACKGROUND_NOANSWER (1 << 1) |
#define BACKGROUND_PLAYBACK (1 << 3) |
#define BACKGROUND_SKIP (1 << 0) |
#define EXT_DATA_SIZE 8192 |
Definition at line 78 of file pbx.c.
Referenced by pbx_extension_helper(), and realtime_exec().
#define STATUS_NO_CONTEXT 1 |
Definition at line 964 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_EXTENSION 2 |
Definition at line 965 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_LABEL 4 |
Definition at line 967 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_NO_PRIORITY 3 |
Definition at line 966 of file pbx.c.
Referenced by pbx_extension_helper(), and pbx_find_extension().
#define STATUS_SUCCESS 5 |
#define VAR_BUF_SIZE 4096 |
Definition at line 83 of file pbx.c.
Referenced by ast_add_extension2(), pbx_builtin_importvar(), and pbx_substitute_variables_helper_full().
#define WAITEXTEN_MOH (1 << 0) |
enum ext_match_t |
When looking up extensions, we can have different requests identified by the 'action' argument, as follows. Note that the coding is such that the low 4 bits are the third argument to extension_match_core.
Definition at line 807 of file pbx.c.
00807 { 00808 E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */ 00809 E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */ 00810 E_MATCH = 0x02, /* extension is an exact match */ 00811 E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */ 00812 E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */ 00813 E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */ 00814 };
static struct ast_context* __ast_context_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar, | |||
int | existsokay | |||
) | [static] |
Definition at line 3998 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().
03999 { 04000 struct ast_context *tmp, **local_contexts; 04001 int length = sizeof(struct ast_context) + strlen(name) + 1; 04002 04003 if (!extcontexts) { 04004 ast_rdlock_contexts(); 04005 local_contexts = &contexts; 04006 } else 04007 local_contexts = extcontexts; 04008 04009 for (tmp = *local_contexts; tmp; tmp = tmp->next) { 04010 if (!strcasecmp(tmp->name, name)) { 04011 if (!existsokay) { 04012 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 04013 tmp = NULL; 04014 } 04015 if (!extcontexts) 04016 ast_unlock_contexts(); 04017 return tmp; 04018 } 04019 } 04020 04021 if (!extcontexts) 04022 ast_unlock_contexts(); 04023 04024 if ((tmp = ast_calloc(1, length))) { 04025 ast_mutex_init(&tmp->lock); 04026 ast_mutex_init(&tmp->macrolock); 04027 strcpy(tmp->name, name); 04028 tmp->registrar = registrar; 04029 if (!extcontexts) 04030 ast_wrlock_contexts(); 04031 tmp->next = *local_contexts; 04032 *local_contexts = tmp; 04033 if (!extcontexts) 04034 ast_unlock_contexts(); 04035 if (option_debug) 04036 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 04037 if (option_verbose > 2) 04038 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 04039 } 04040 04041 return tmp; 04042 }
void __ast_context_destroy | ( | struct ast_context * | con, | |
const char * | registrar | |||
) |
Definition at line 5416 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().
05417 { 05418 struct ast_context *tmp, *tmpl=NULL; 05419 struct ast_include *tmpi; 05420 struct ast_sw *sw; 05421 struct ast_exten *e, *el, *en; 05422 struct ast_ignorepat *ipi; 05423 05424 for (tmp = contexts; tmp; ) { 05425 struct ast_context *next; /* next starting point */ 05426 for (; tmp; tmpl = tmp, tmp = tmp->next) { 05427 if (option_debug) 05428 ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar); 05429 if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) && 05430 (!con || !strcasecmp(tmp->name, con->name)) ) 05431 break; /* found it */ 05432 } 05433 if (!tmp) /* not found, we are done */ 05434 break; 05435 ast_mutex_lock(&tmp->lock); 05436 if (option_debug) 05437 ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar); 05438 next = tmp->next; 05439 if (tmpl) 05440 tmpl->next = next; 05441 else 05442 contexts = next; 05443 /* Okay, now we're safe to let it go -- in a sense, we were 05444 ready to let it go as soon as we locked it. */ 05445 ast_mutex_unlock(&tmp->lock); 05446 for (tmpi = tmp->includes; tmpi; ) { /* Free includes */ 05447 struct ast_include *tmpil = tmpi; 05448 tmpi = tmpi->next; 05449 free(tmpil); 05450 } 05451 for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */ 05452 struct ast_ignorepat *ipl = ipi; 05453 ipi = ipi->next; 05454 free(ipl); 05455 } 05456 while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list))) 05457 free(sw); 05458 for (e = tmp->root; e;) { 05459 for (en = e->peer; en;) { 05460 el = en; 05461 en = en->peer; 05462 destroy_exten(el); 05463 } 05464 el = e; 05465 e = e->next; 05466 destroy_exten(el); 05467 } 05468 ast_mutex_destroy(&tmp->lock); 05469 free(tmp); 05470 /* if we have a specific match, we are done, otherwise continue */ 05471 tmp = con ? NULL : next; 05472 } 05473 }
static int __ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
int | async | |||
) | [static] |
Definition at line 6589 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().
06590 { 06591 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06592 06593 if (!chan) 06594 return -2; 06595 06596 if (context == NULL) 06597 context = chan->context; 06598 if (exten == NULL) 06599 exten = chan->exten; 06600 06601 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06602 if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num)) 06603 return goto_func(chan, context, exten, priority); 06604 else 06605 return -3; 06606 }
static int __ast_pbx_run | ( | struct ast_channel * | c | ) | [static] |
Definition at line 2435 of file pbx.c.
References ast_channel::_softhangup, ast_calloc, ast_cdr_update(), ast_channel_clear_softhangup(), 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::cdr, 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().
02436 { 02437 int found = 0; /* set if we find at least one match */ 02438 int res = 0; 02439 int autoloopflag; 02440 int error = 0; /* set an error conditions */ 02441 const char *emc; 02442 02443 /* A little initial setup here */ 02444 if (c->pbx) { 02445 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name); 02446 /* XXX and now what ? */ 02447 free(c->pbx); 02448 } 02449 if (!(c->pbx = ast_calloc(1, sizeof(*c->pbx)))) 02450 return -1; 02451 /* Set reasonable defaults */ 02452 c->pbx->rtimeout = 10; 02453 c->pbx->dtimeout = 5; 02454 02455 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */ 02456 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP); 02457 02458 /* Start by trying whatever the channel is set to */ 02459 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02460 /* If not successful fall back to 's' */ 02461 if (option_verbose > 1) 02462 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); 02463 /* XXX the original code used the existing priority in the call to 02464 * ast_exists_extension(), and reset it to 1 afterwards. 02465 * I believe the correct thing is to set it to 1 immediately. 02466 */ 02467 set_ext_pri(c, "s", 1); 02468 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02469 /* JK02: And finally back to default if everything else failed */ 02470 if (option_verbose > 1) 02471 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); 02472 ast_copy_string(c->context, "default", sizeof(c->context)); 02473 } 02474 } 02475 if (c->cdr) { 02476 /* allow CDR variables that have been collected after channel was created to be visible during call */ 02477 ast_cdr_update(c); 02478 } 02479 for (;;) { 02480 char dst_exten[256]; /* buffer to accumulate digits */ 02481 int pos = 0; /* XXX should check bounds */ 02482 int digit = 0; 02483 02484 /* loop on priorities in this context/exten */ 02485 while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02486 found = 1; 02487 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02488 /* Something bad happened, or a hangup has been requested. */ 02489 if (strchr("0123456789ABCDEF*#", res)) { 02490 if (option_debug) 02491 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 02492 pos = 0; 02493 dst_exten[pos++] = digit = res; 02494 dst_exten[pos] = '\0'; 02495 break; 02496 } 02497 if (res == AST_PBX_KEEPALIVE) { 02498 if (option_debug) 02499 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02500 if (option_verbose > 1) 02501 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02502 error = 1; 02503 break; 02504 } 02505 if (option_debug) 02506 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02507 if (option_verbose > 1) 02508 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02509 if (c->_softhangup & AST_SOFTHANGUP_ASYNCGOTO) { 02510 ast_channel_clear_softhangup(c, AST_SOFTHANGUP_ASYNCGOTO); 02511 } else if (c->_softhangup & AST_SOFTHANGUP_TIMEOUT) { 02512 /* atimeout, nothing bad */ 02513 } else { 02514 if (c->cdr) 02515 ast_cdr_update(c); 02516 error = 1; 02517 break; 02518 } 02519 } 02520 if (c->_softhangup & AST_SOFTHANGUP_ASYNCGOTO) { 02521 ast_channel_clear_softhangup(c, AST_SOFTHANGUP_ASYNCGOTO); 02522 } else if (c->_softhangup & AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c,c->context,"T",1,c->cid.cid_num)) { 02523 set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */ 02524 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */ 02525 c->whentohangup = 0; 02526 ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT); 02527 } else if (c->_softhangup) { 02528 if (option_debug) 02529 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", 02530 c->exten, c->priority); 02531 error = 1; 02532 break; 02533 } 02534 c->priority++; 02535 } /* end while - from here on we can use 'break' to go out */ 02536 if (error) 02537 break; 02538 02539 /* XXX we get here on non-existing extension or a keypress or hangup ? */ 02540 02541 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { 02542 /* If there is no match at priority 1, it is not a valid extension anymore. 02543 * Try to continue at "i", 1 or exit if the latter does not exist. 02544 */ 02545 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02546 if (option_verbose > 2) 02547 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name); 02548 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten); 02549 set_ext_pri(c, "i", 1); 02550 } else { 02551 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n", 02552 c->name, c->exten, c->context); 02553 error = 1; /* we know what to do with it */ 02554 break; 02555 } 02556 } else if (c->_softhangup & AST_SOFTHANGUP_TIMEOUT) { 02557 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */ 02558 ast_channel_clear_softhangup(c, AST_SOFTHANGUP_TIMEOUT); 02559 } else { /* keypress received, get more digits for a full extension */ 02560 int waittime = 0; 02561 if (digit) 02562 waittime = c->pbx->dtimeout; 02563 else if (!autofallthrough) 02564 waittime = c->pbx->rtimeout; 02565 if (!waittime) { 02566 const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 02567 if (!status) 02568 status = "UNKNOWN"; 02569 if (option_verbose > 2) 02570 ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status); 02571 if (!strcasecmp(status, "CONGESTION")) 02572 res = pbx_builtin_congestion(c, "10"); 02573 else if (!strcasecmp(status, "CHANUNAVAIL")) 02574 res = pbx_builtin_congestion(c, "10"); 02575 else if (!strcasecmp(status, "BUSY")) 02576 res = pbx_builtin_busy(c, "10"); 02577 error = 1; /* XXX disable message */ 02578 break; /* exit from the 'for' loop */ 02579 } 02580 02581 if (collect_digits(c, waittime, dst_exten, sizeof(dst_exten), pos)) 02582 break; 02583 if (ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */ 02584 set_ext_pri(c, dst_exten, 1); 02585 else { 02586 /* No such extension */ 02587 if (!ast_strlen_zero(dst_exten)) { 02588 /* An invalid extension */ 02589 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02590 if (option_verbose > 2) 02591 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name); 02592 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten); 02593 set_ext_pri(c, "i", 1); 02594 } else { 02595 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context); 02596 found = 1; /* XXX disable message */ 02597 break; 02598 } 02599 } else { 02600 /* A simple timeout */ 02601 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) { 02602 if (option_verbose > 2) 02603 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name); 02604 set_ext_pri(c, "t", 1); 02605 } else { 02606 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context); 02607 found = 1; /* XXX disable message */ 02608 break; 02609 } 02610 } 02611 } 02612 if (c->cdr) { 02613 if (option_verbose > 2) 02614 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name); 02615 ast_cdr_update(c); 02616 } 02617 } 02618 } 02619 if (!found && !error) 02620 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); 02621 if (res != AST_PBX_KEEPALIVE) { 02622 ast_softhangup(c, AST_SOFTHANGUP_APPUNLOAD); 02623 } 02624 ast_channel_lock(c); 02625 if ((emc = pbx_builtin_getvar_helper(c, "EXIT_MACRO_CONTEXT"))) { 02626 emc = ast_strdupa(emc); 02627 } 02628 ast_channel_unlock(c); 02629 if ((res != AST_PBX_KEEPALIVE) && !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) && 02630 ((emc && ast_exists_extension(c, emc, "h", 1, c->cid.cid_num)) || 02631 (ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num) && (emc = c->context)))) { 02632 ast_copy_string(c->context, emc, sizeof(c->context)); 02633 set_ext_pri(c, "h", 1); 02634 if (c->cdr && ast_opt_end_cdr_before_h_exten) { 02635 ast_cdr_end(c->cdr); 02636 } 02637 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02638 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02639 /* Something bad happened, or a hangup has been requested. */ 02640 if (option_debug) 02641 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02642 if (option_verbose > 1) 02643 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02644 break; 02645 } 02646 c->priority++; 02647 } 02648 } 02649 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP); 02650 ast_clear_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */ 02651 pbx_destroy(c->pbx); 02652 c->pbx = NULL; 02653 if (res != AST_PBX_KEEPALIVE) 02654 ast_hangup(c); 02655 return 0; 02656 }
static int _extension_match_core | ( | const char * | pattern, | |
const char * | data, | |||
enum ext_match_t | mode | |||
) | [static] |
Definition at line 825 of file pbx.c.
References ast_log(), E_MATCH, E_MATCH_MASK, E_MATCHMORE, and LOG_WARNING.
Referenced by extension_match_core().
00826 { 00827 mode &= E_MATCH_MASK; /* only consider the relevant bits */ 00828 00829 if ( (mode == E_MATCH) && (pattern[0] == '_') && (strcasecmp(pattern,data)==0) ) /* note: if this test is left out, then _x. will not match _x. !!! */ 00830 return 1; 00831 00832 if (pattern[0] != '_') { /* not a pattern, try exact or partial match */ 00833 int ld = strlen(data), lp = strlen(pattern); 00834 00835 if (lp < ld) /* pattern too short, cannot match */ 00836 return 0; 00837 /* depending on the mode, accept full or partial match or both */ 00838 if (mode == E_MATCH) 00839 return !strcmp(pattern, data); /* 1 on match, 0 on fail */ 00840 if (ld == 0 || !strncasecmp(pattern, data, ld)) /* partial or full match */ 00841 return (mode == E_MATCHMORE) ? lp > ld : 1; /* XXX should consider '!' and '/' ? */ 00842 else 00843 return 0; 00844 } 00845 pattern++; /* skip leading _ */ 00846 /* 00847 * XXX below we stop at '/' which is a separator for the CID info. However we should 00848 * not store '/' in the pattern at all. When we insure it, we can remove the checks. 00849 */ 00850 while (*data && *pattern && *pattern != '/') { 00851 const char *end; 00852 00853 if (*data == '-') { /* skip '-' in data (just a separator) */ 00854 data++; 00855 continue; 00856 } 00857 switch (toupper(*pattern)) { 00858 case '[': /* a range */ 00859 end = strchr(pattern+1, ']'); /* XXX should deal with escapes ? */ 00860 if (end == NULL) { 00861 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n"); 00862 return 0; /* unconditional failure */ 00863 } 00864 for (pattern++; pattern != end; pattern++) { 00865 if (pattern+2 < end && pattern[1] == '-') { /* this is a range */ 00866 if (*data >= pattern[0] && *data <= pattern[2]) 00867 break; /* match found */ 00868 else { 00869 pattern += 2; /* skip a total of 3 chars */ 00870 continue; 00871 } 00872 } else if (*data == pattern[0]) 00873 break; /* match found */ 00874 } 00875 if (pattern == end) 00876 return 0; 00877 pattern = end; /* skip and continue */ 00878 break; 00879 case 'N': 00880 if (*data < '2' || *data > '9') 00881 return 0; 00882 break; 00883 case 'X': 00884 if (*data < '0' || *data > '9') 00885 return 0; 00886 break; 00887 case 'Z': 00888 if (*data < '1' || *data > '9') 00889 return 0; 00890 break; 00891 case '.': /* Must match, even with more digits */ 00892 return 1; 00893 case '!': /* Early match */ 00894 return 2; 00895 case ' ': 00896 case '-': /* Ignore these in patterns */ 00897 data--; /* compensate the final data++ */ 00898 break; 00899 default: 00900 if (*data != *pattern) 00901 return 0; 00902 } 00903 data++; 00904 pattern++; 00905 } 00906 if (*data) /* data longer than pattern, no match */ 00907 return 0; 00908 /* 00909 * match so far, but ran off the end of the data. 00910 * Depending on what is next, determine match or not. 00911 */ 00912 if (*pattern == '\0' || *pattern == '/') /* exact match */ 00913 return (mode == E_MATCHMORE) ? 0 : 1; /* this is a failure for E_MATCHMORE */ 00914 else if (*pattern == '!') /* early match */ 00915 return 2; 00916 else /* partial match */ 00917 return (mode == E_MATCH) ? 0 : 1; /* this is a failure for E_MATCH */ 00918 }
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 4810 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().
04812 { 04813 struct ast_exten *ep; 04814 04815 for (ep = NULL; e ; ep = e, e = e->peer) { 04816 if (e->priority >= tmp->priority) 04817 break; 04818 } 04819 if (!e) { /* go at the end, and ep is surely set because the list is not empty */ 04820 ep->peer = tmp; 04821 return 0; /* success */ 04822 } 04823 if (e->priority == tmp->priority) { 04824 /* Can't have something exactly the same. Is this a 04825 replacement? If so, replace, otherwise, bonk. */ 04826 if (!replace) { 04827 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04828 if (tmp->datad) 04829 tmp->datad(tmp->data); 04830 free(tmp); 04831 return -1; 04832 } 04833 /* we are replacing e, so copy the link fields and then update 04834 * whoever pointed to e to point to us 04835 */ 04836 tmp->next = e->next; /* not meaningful if we are not first in the peer list */ 04837 tmp->peer = e->peer; /* always meaningful */ 04838 if (ep) /* We're in the peer list, just insert ourselves */ 04839 ep->peer = tmp; 04840 else if (el) /* We're the first extension. Take over e's functions */ 04841 el->next = tmp; 04842 else /* We're the very first extension. */ 04843 con->root = tmp; 04844 if (tmp->priority == PRIORITY_HINT) 04845 ast_change_hint(e,tmp); 04846 /* Destroy the old one */ 04847 if (e->datad) 04848 e->datad(e->data); 04849 free(e); 04850 } else { /* Slip ourselves in just before e */ 04851 tmp->peer = e; 04852 tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */ 04853 if (ep) /* Easy enough, we're just in the peer list */ 04854 ep->peer = tmp; 04855 else { /* we are the first in some peer list, so link in the ext list */ 04856 if (el) 04857 el->next = tmp; /* in the middle... */ 04858 else 04859 con->root = tmp; /* ... or at the head */ 04860 e->next = NULL; /* e is no more at the head, so e->next must be reset */ 04861 } 04862 /* And immediately return success. */ 04863 if (tmp->priority == PRIORITY_HINT) 04864 ast_add_hint(tmp); 04865 } 04866 return 0; 04867 }
int ast_active_calls | ( | void | ) |
Retrieve the number of active calls.
Definition at line 2764 of file pbx.c.
Referenced by handle_chanlist(), and handle_chanlist_deprecated().
02765 { 02766 return countcalls; 02767 }
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 4679 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().
04682 { 04683 int ret = -1; 04684 struct ast_context *c = find_context_locked(context); 04685 04686 if (c) { 04687 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04688 application, data, datad, registrar); 04689 ast_unlock_contexts(); 04690 } 04691 return ret; 04692 }
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 4894 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().
04898 { 04899 /* 04900 * Sort extensions (or patterns) according to the rules indicated above. 04901 * These are implemented by the function ext_cmp()). 04902 * All priorities for the same ext/pattern/cid are kept in a list, 04903 * using the 'peer' field as a link field.. 04904 */ 04905 struct ast_exten *tmp, *e, *el = NULL; 04906 int res; 04907 int length; 04908 char *p; 04909 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04910 04911 /* if we are adding a hint, and there are global variables, and the hint 04912 contains variable references, then expand them 04913 */ 04914 ast_mutex_lock(&globalslock); 04915 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04916 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04917 application = expand_buf; 04918 } 04919 ast_mutex_unlock(&globalslock); 04920 04921 length = sizeof(struct ast_exten); 04922 length += strlen(extension) + 1; 04923 length += strlen(application) + 1; 04924 if (label) 04925 length += strlen(label) + 1; 04926 if (callerid) 04927 length += strlen(callerid) + 1; 04928 else 04929 length ++; /* just the '\0' */ 04930 04931 /* Be optimistic: Build the extension structure first */ 04932 if (!(tmp = ast_calloc(1, length))) 04933 return -1; 04934 04935 /* use p as dst in assignments, as the fields are const char * */ 04936 p = tmp->stuff; 04937 if (label) { 04938 tmp->label = p; 04939 strcpy(p, label); 04940 p += strlen(label) + 1; 04941 } 04942 tmp->exten = p; 04943 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04944 tmp->priority = priority; 04945 tmp->cidmatch = p; /* but use p for assignments below */ 04946 if (callerid) { 04947 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04948 tmp->matchcid = 1; 04949 } else { 04950 *p++ = '\0'; 04951 tmp->matchcid = 0; 04952 } 04953 tmp->app = p; 04954 strcpy(p, application); 04955 tmp->parent = con; 04956 tmp->data = data; 04957 tmp->datad = datad; 04958 tmp->registrar = registrar; 04959 04960 ast_mutex_lock(&con->lock); 04961 res = 0; /* some compilers will think it is uninitialized otherwise */ 04962 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04963 res = ext_cmp(e->exten, tmp->exten); 04964 if (res == 0) { /* extension match, now look at cidmatch */ 04965 if (!e->matchcid && !tmp->matchcid) 04966 res = 0; 04967 else if (tmp->matchcid && !e->matchcid) 04968 res = 1; 04969 else if (e->matchcid && !tmp->matchcid) 04970 res = -1; 04971 else 04972 res = ext_cmp(e->cidmatch, tmp->cidmatch); 04973 } 04974 if (res >= 0) 04975 break; 04976 } 04977 if (e && res == 0) { /* exact match, insert in the pri chain */ 04978 res = add_pri(con, tmp, el, e, replace); 04979 ast_mutex_unlock(&con->lock); 04980 if (res < 0) { 04981 errno = EEXIST; /* XXX do we care ? */ 04982 return 0; /* XXX should we return -1 maybe ? */ 04983 } 04984 } else { 04985 /* 04986 * not an exact match, this is the first entry with this pattern, 04987 * so insert in the main list right before 'e' (if any) 04988 */ 04989 tmp->next = e; 04990 if (el) 04991 el->next = tmp; 04992 else 04993 con->root = tmp; 04994 ast_mutex_unlock(&con->lock); 04995 if (tmp->priority == PRIORITY_HINT) 04996 ast_add_hint(tmp); 04997 } 04998 if (option_debug) { 04999 if (tmp->matchcid) { 05000 if (option_debug) 05001 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 05002 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 05003 } else { 05004 if (option_debug) 05005 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 05006 tmp->exten, tmp->priority, con->name); 05007 } 05008 } 05009 if (option_verbose > 2) { 05010 if (tmp->matchcid) { 05011 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 05012 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 05013 } else { 05014 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 05015 tmp->exten, tmp->priority, con->name); 05016 } 05017 } 05018 return 0; 05019 }
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 2258 of file pbx.c.
References ao2_alloc(), ao2_find(), ao2_ref(), ast_extension_state2(), ast_get_extension_app(), ast_get_extension_name(), ast_hint_destroy(), ast_log(), hints, LOG_DEBUG, and option_debug.
Referenced by ast_add_extension2().
02259 { 02260 struct ast_hint *hint; 02261 02262 if (!e) { 02263 return -1; 02264 } 02265 02266 hint = ao2_find(hints, e, 0); 02267 02268 if (hint) { 02269 if (option_debug > 1) 02270 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02271 ao2_ref(hint, -1); 02272 return -1; 02273 } 02274 02275 if (option_debug > 1) 02276 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02277 02278 if (!(hint = ao2_alloc(sizeof(*hint), ast_hint_destroy))) { 02279 return -1; 02280 } 02281 02282 /* Initialize and insert new item at the top */ 02283 hint->exten = e; 02284 hint->laststate = ast_extension_state2(e); 02285 02286 ao2_link(hints, hint); 02287 02288 ao2_ref(hint, -1); 02289 02290 return 0; 02291 }
int ast_async_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4717 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_dtmf(), handle_request_bye(), handle_request_refer(), process_ast_dsp(), and socket_process().
04718 { 04719 int res = 0; 04720 04721 ast_channel_lock(chan); 04722 04723 if (chan->pbx) { /* This channel is currently in the PBX */ 04724 ast_explicit_goto(chan, context, exten, priority); 04725 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04726 } else { 04727 /* In order to do it when the channel doesn't really exist within 04728 the PBX, we have to make a new channel, masquerade, and start the PBX 04729 at the new location */ 04730 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04731 if (!tmpchan) { 04732 res = -1; 04733 } else { 04734 if (chan->cdr) { 04735 ast_cdr_discard(tmpchan->cdr); 04736 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04737 } 04738 /* Make formats okay */ 04739 tmpchan->readformat = chan->readformat; 04740 tmpchan->writeformat = chan->writeformat; 04741 /* Setup proper location */ 04742 ast_explicit_goto(tmpchan, 04743 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04744 04745 /* Masquerade into temp channel */ 04746 if (ast_channel_masquerade(tmpchan, chan)) { 04747 /* Failed to set up the masquerade. It's probably chan_local 04748 * in the middle of optimizing itself out. Sad. :( */ 04749 ast_hangup(tmpchan); 04750 tmpchan = NULL; 04751 res = -1; 04752 } else { 04753 /* Grab the locks and get going */ 04754 ast_channel_lock(tmpchan); 04755 ast_do_masquerade(tmpchan); 04756 ast_channel_unlock(tmpchan); 04757 /* Start the PBX going on our stolen channel */ 04758 if (ast_pbx_start(tmpchan)) { 04759 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04760 ast_hangup(tmpchan); 04761 res = -1; 04762 } 04763 } 04764 } 04765 } 04766 ast_channel_unlock(chan); 04767 return res; 04768 }
int ast_async_goto_by_name | ( | const char * | channame, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4770 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04771 { 04772 struct ast_channel *chan; 04773 int res = -1; 04774 04775 chan = ast_get_channel_by_name_locked(channame); 04776 if (chan) { 04777 res = ast_async_goto(chan, context, exten, priority); 04778 ast_channel_unlock(chan); 04779 } 04780 return res; 04781 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6613 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06614 { 06615 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06616 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info_in | |||
) |
Definition at line 4357 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().
04358 { 04359 char info_save[256]; 04360 char *info; 04361 04362 /* Check for empty just in case */ 04363 if (ast_strlen_zero(info_in)) 04364 return 0; 04365 /* make a copy just in case we were passed a static string */ 04366 ast_copy_string(info_save, info_in, sizeof(info_save)); 04367 info = info_save; 04368 /* Assume everything except time */ 04369 i->monthmask = 0xfff; /* 12 bits */ 04370 i->daymask = 0x7fffffffU; /* 31 bits */ 04371 i->dowmask = 0x7f; /* 7 bits */ 04372 /* on each call, use strsep() to move info to the next argument */ 04373 get_timerange(i, strsep(&info, "|")); 04374 if (info) 04375 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04376 if (info) 04377 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04378 if (info) 04379 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04380 return 1; 04381 }
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 2381 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().
02382 { 02383 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH); 02384 }
ast_change_hint: Change hint for an extension
Definition at line 2294 of file pbx.c.
References ao2_find(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_hint::exten, and hints.
Referenced by add_pri().
02295 { 02296 struct ast_hint *hint; 02297 02298 hint = ao2_find(hints, oe, 0); 02299 02300 if (!hint) { 02301 return -1; 02302 } 02303 02304 ao2_lock(hint); 02305 hint->exten = ne; 02306 ao2_unlock(hint); 02307 ao2_ref(hint, -1); 02308 02309 return 0; 02310 }
int ast_check_timing | ( | const struct ast_timing * | i | ) |
Definition at line 4383 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().
04384 { 04385 struct tm tm; 04386 time_t t = time(NULL); 04387 04388 ast_localtime(&t, &tm, NULL); 04389 04390 /* If it's not the right month, return */ 04391 if (!(i->monthmask & (1 << tm.tm_mon))) 04392 return 0; 04393 04394 /* If it's not that time of the month.... */ 04395 /* Warning, tm_mday has range 1..31! */ 04396 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04397 return 0; 04398 04399 /* If it's not the right day of the week */ 04400 if (!(i->dowmask & (1 << tm.tm_wday))) 04401 return 0; 04402 04403 /* Sanity check the hour just to be safe */ 04404 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04405 ast_log(LOG_WARNING, "Insane time...\n"); 04406 return 0; 04407 } 04408 04409 /* Now the tough part, we calculate if it fits 04410 in the right time based on min/hour */ 04411 if (!(i->minmask[tm.tm_hour * 2 + (tm.tm_min >= 30 ? 1 : 0)] & (1 << (tm.tm_min >= 30 ? tm.tm_min - 30 : tm.tm_min)))) 04412 return 0; 04413 04414 /* If we got this far, then we're good */ 04415 return 1; 04416 }
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 4610 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().
04611 { 04612 int ret = -1; 04613 struct ast_context *c = find_context_locked(context); 04614 04615 if (c) { 04616 ret = ast_context_add_ignorepat2(c, value, registrar); 04617 ast_unlock_contexts(); 04618 } 04619 return ret; 04620 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | value, | |||
const char * | registrar | |||
) |
Definition at line 4622 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().
04623 { 04624 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04625 int length; 04626 char *pattern; 04627 length = sizeof(struct ast_ignorepat); 04628 length += strlen(value) + 1; 04629 if (!(ignorepat = ast_calloc(1, length))) 04630 return -1; 04631 /* The cast to char * is because we need to write the initial value. 04632 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04633 * sees the cast as dereferencing a type-punned pointer and warns about 04634 * it. This is the workaround (we're telling gcc, yes, that's really 04635 * what we wanted to do). 04636 */ 04637 pattern = (char *) ignorepat->pattern; 04638 strcpy(pattern, value); 04639 ignorepat->next = NULL; 04640 ignorepat->registrar = registrar; 04641 ast_mutex_lock(&con->lock); 04642 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04643 ignorepatl = ignorepatc; 04644 if (!strcasecmp(ignorepatc->pattern, value)) { 04645 /* Already there */ 04646 ast_mutex_unlock(&con->lock); 04647 errno = EEXIST; 04648 return -1; 04649 } 04650 } 04651 if (ignorepatl) 04652 ignorepatl->next = ignorepat; 04653 else 04654 con->ignorepats = ignorepat; 04655 ast_mutex_unlock(&con->lock); 04656 return 0; 04657 04658 }
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 4187 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().
04188 { 04189 int ret = -1; 04190 struct ast_context *c = find_context_locked(context); 04191 04192 if (c) { 04193 ret = ast_context_add_include2(c, include, registrar); 04194 ast_unlock_contexts(); 04195 } 04196 return ret; 04197 }
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 4425 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().
04427 { 04428 struct ast_include *new_include; 04429 char *c; 04430 struct ast_include *i, *il = NULL; /* include, include_last */ 04431 int length; 04432 char *p; 04433 04434 length = sizeof(struct ast_include); 04435 length += 2 * (strlen(value) + 1); 04436 04437 /* allocate new include structure ... */ 04438 if (!(new_include = ast_calloc(1, length))) 04439 return -1; 04440 /* Fill in this structure. Use 'p' for assignments, as the fields 04441 * in the structure are 'const char *' 04442 */ 04443 p = new_include->stuff; 04444 new_include->name = p; 04445 strcpy(p, value); 04446 p += strlen(value) + 1; 04447 new_include->rname = p; 04448 strcpy(p, value); 04449 /* Strip off timing info, and process if it is there */ 04450 if ( (c = strchr(p, '|')) ) { 04451 *c++ = '\0'; 04452 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04453 } 04454 new_include->next = NULL; 04455 new_include->registrar = registrar; 04456 04457 ast_mutex_lock(&con->lock); 04458 04459 /* ... go to last include and check if context is already included too... */ 04460 for (i = con->includes; i; i = i->next) { 04461 if (!strcasecmp(i->name, new_include->name)) { 04462 free(new_include); 04463 ast_mutex_unlock(&con->lock); 04464 errno = EEXIST; 04465 return -1; 04466 } 04467 il = i; 04468 } 04469 04470 /* ... include new context into context list, unlock, return */ 04471 if (il) 04472 il->next = new_include; 04473 else 04474 con->includes = new_include; 04475 if (option_verbose > 2) 04476 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04477 ast_mutex_unlock(&con->lock); 04478 04479 return 0; 04480 }
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 4487 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04488 { 04489 int ret = -1; 04490 struct ast_context *c = find_context_locked(context); 04491 04492 if (c) { /* found, add switch to this context */ 04493 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04494 ast_unlock_contexts(); 04495 } 04496 return ret; 04497 }
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 4506 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().
04508 { 04509 struct ast_sw *new_sw; 04510 struct ast_sw *i; 04511 int length; 04512 char *p; 04513 04514 length = sizeof(struct ast_sw); 04515 length += strlen(value) + 1; 04516 if (data) 04517 length += strlen(data); 04518 length++; 04519 04520 /* allocate new sw structure ... */ 04521 if (!(new_sw = ast_calloc(1, length))) 04522 return -1; 04523 /* ... fill in this structure ... */ 04524 p = new_sw->stuff; 04525 new_sw->name = p; 04526 strcpy(new_sw->name, value); 04527 p += strlen(value) + 1; 04528 new_sw->data = p; 04529 if (data) { 04530 strcpy(new_sw->data, data); 04531 p += strlen(data) + 1; 04532 } else { 04533 strcpy(new_sw->data, ""); 04534 p++; 04535 } 04536 new_sw->eval = eval; 04537 new_sw->registrar = registrar; 04538 04539 /* ... try to lock this context ... */ 04540 ast_mutex_lock(&con->lock); 04541 04542 /* ... go to last sw and check if context is already swd too... */ 04543 AST_LIST_TRAVERSE(&con->alts, i, list) { 04544 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04545 free(new_sw); 04546 ast_mutex_unlock(&con->lock); 04547 errno = EEXIST; 04548 return -1; 04549 } 04550 } 04551 04552 /* ... sw new context into context list, unlock, return */ 04553 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04554 04555 if (option_verbose > 2) 04556 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04557 04558 ast_mutex_unlock(&con->lock); 04559 04560 return 0; 04561 }
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 4044 of file pbx.c.
References __ast_context_create().
Referenced by park_call_full(), and set_config().
04045 { 04046 return __ast_context_create(extcontexts, name, registrar, 0); 04047 }
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 5475 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().
05476 { 05477 ast_wrlock_contexts(); 05478 __ast_context_destroy(con,registrar); 05479 ast_unlock_contexts(); 05480 }
struct ast_context* ast_context_find | ( | const char * | name | ) |
Find a context.
name | name of the context to find |
Definition at line 948 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().
00949 { 00950 struct ast_context *tmp = NULL; 00951 00952 ast_rdlock_contexts(); 00953 00954 while ( (tmp = ast_walk_contexts(tmp)) ) { 00955 if (!name || !strcasecmp(name, tmp->name)) 00956 break; 00957 } 00958 00959 ast_unlock_contexts(); 00960 00961 return tmp; 00962 }
struct ast_context* ast_context_find_or_create | ( | struct ast_context ** | extcontexts, | |
const char * | name, | |||
const char * | registrar | |||
) |
Definition at line 4049 of file pbx.c.
References __ast_context_create().
Referenced by do_parking_thread(), pbx_load_config(), and pbx_load_users().
04050 { 04051 return __ast_context_create(extcontexts, name, registrar, 1); 04052 }
int ast_context_lockmacro | ( | const char * | context | ) |
locks the macrolock in the given given context
Definition at line 3006 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().
03007 { 03008 struct ast_context *c = NULL; 03009 int ret = -1; 03010 03011 ast_rdlock_contexts(); 03012 03013 while ((c = ast_walk_contexts(c))) { 03014 if (!strcmp(ast_get_context_name(c), context)) { 03015 ret = 0; 03016 break; 03017 } 03018 } 03019 03020 ast_unlock_contexts(); 03021 03022 /* if we found context, lock macrolock */ 03023 if (ret == 0) 03024 ret = ast_mutex_lock(&c->macrolock); 03025 03026 return ret; 03027 }
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 2907 of file pbx.c.
References ast_context_remove_extension_callerid().
Referenced by destroy_station(), destroy_trunk(), and register_peer_exten().
02908 { 02909 return ast_context_remove_extension_callerid(context, extension, priority, NULL, 0, registrar); 02910 }
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 2934 of file pbx.c.
References ast_context_remove_extension_callerid2().
Referenced by do_parking_thread(), and park_exec().
02935 { 02936 return ast_context_remove_extension_callerid2(con, extension, priority, NULL, 0, registrar); 02937 }
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 2912 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().
02913 { 02914 int ret = -1; /* default error return */ 02915 struct ast_context *c = find_context_locked(context); 02916 02917 if (c) { /* ... remove extension ... */ 02918 ret = ast_context_remove_extension_callerid2(c, extension, priority, callerid, matchcid, registrar); 02919 ast_unlock_contexts(); 02920 } 02921 return ret; 02922 }
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 2939 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().
02940 { 02941 struct ast_exten *exten, *prev_exten = NULL; 02942 struct ast_exten *peer; 02943 struct ast_exten *previous_peer = NULL; 02944 struct ast_exten *next_peer = NULL; 02945 int found = 0; 02946 02947 ast_mutex_lock(&con->lock); 02948 02949 /* scan the extension list to find first matching extension-registrar */ 02950 for (exten = con->root; exten; prev_exten = exten, exten = exten->next) { 02951 if (!strcmp(exten->exten, extension) && 02952 (!registrar || !strcmp(exten->registrar, registrar))) 02953 break; 02954 } 02955 if (!exten) { 02956 /* we can't find right extension */ 02957 ast_mutex_unlock(&con->lock); 02958 return -1; 02959 } 02960 02961 /* scan the priority list to remove extension with exten->priority == priority */ 02962 for (peer = exten, next_peer = exten->peer ? exten->peer : exten->next; 02963 peer && !strcmp(peer->exten, extension); 02964 peer = next_peer, next_peer = next_peer ? (next_peer->peer ? next_peer->peer : next_peer->next) : NULL) { 02965 if ((priority == 0 || peer->priority == priority) && 02966 (!callerid || !matchcid || (matchcid && !strcmp(peer->cidmatch, callerid))) && 02967 (!registrar || !strcmp(peer->registrar, registrar) )) { 02968 found = 1; 02969 02970 /* we are first priority extension? */ 02971 if (!previous_peer) { 02972 /* 02973 * We are first in the priority chain, so must update the extension chain. 02974 * The next node is either the next priority or the next extension 02975 */ 02976 struct ast_exten *next_node = peer->peer ? peer->peer : peer->next; 02977 02978 if (!prev_exten) { /* change the root... */ 02979 con->root = next_node; 02980 } else { 02981 prev_exten->next = next_node; /* unlink */ 02982 } 02983 if (peer->peer) { /* update the new head of the pri list */ 02984 peer->peer->next = peer->next; 02985 } 02986 } else { /* easy, we are not first priority in extension */ 02987 previous_peer->peer = peer->peer; 02988 } 02989 02990 /* now, free whole priority extension */ 02991 destroy_exten(peer); 02992 } else { 02993 previous_peer = peer; 02994 } 02995 } 02996 ast_mutex_unlock(&con->lock); 02997 return found ? 0 : -1; 02998 }
int ast_context_remove_ignorepat | ( | const char * | context, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4567 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().
04568 { 04569 int ret = -1; 04570 struct ast_context *c = find_context_locked(context); 04571 04572 if (c) { 04573 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04574 ast_unlock_contexts(); 04575 } 04576 return ret; 04577 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4579 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().
04580 { 04581 struct ast_ignorepat *ip, *ipl = NULL; 04582 04583 ast_mutex_lock(&con->lock); 04584 04585 for (ip = con->ignorepats; ip; ip = ip->next) { 04586 if (!strcmp(ip->pattern, ignorepat) && 04587 (!registrar || (registrar == ip->registrar))) { 04588 if (ipl) { 04589 ipl->next = ip->next; 04590 free(ip); 04591 } else { 04592 con->ignorepats = ip->next; 04593 free(ip); 04594 } 04595 ast_mutex_unlock(&con->lock); 04596 return 0; 04597 } 04598 ipl = ip; 04599 } 04600 04601 ast_mutex_unlock(&con->lock); 04602 errno = EINVAL; 04603 return -1; 04604 }
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 2803 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().
02804 { 02805 int ret = -1; 02806 struct ast_context *c = find_context_locked(context); 02807 02808 if (c) { 02809 /* found, remove include from this context ... */ 02810 ret = ast_context_remove_include2(c, include, registrar); 02811 ast_unlock_contexts(); 02812 } 02813 return ret; 02814 }
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 2824 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().
02825 { 02826 struct ast_include *i, *pi = NULL; 02827 int ret = -1; 02828 02829 ast_mutex_lock(&con->lock); 02830 02831 /* find our include */ 02832 for (i = con->includes; i; pi = i, i = i->next) { 02833 if (!strcmp(i->name, include) && 02834 (!registrar || !strcmp(i->registrar, registrar))) { 02835 /* remove from list */ 02836 if (pi) 02837 pi->next = i->next; 02838 else 02839 con->includes = i->next; 02840 /* free include and return */ 02841 free(i); 02842 ret = 0; 02843 break; 02844 } 02845 } 02846 02847 ast_mutex_unlock(&con->lock); 02848 return ret; 02849 }
int ast_context_remove_switch | ( | const char * | context, | |
const char * | sw, | |||
const char * | data, | |||
const char * | registrar | |||
) |
Remove a switch.
Definition at line 2856 of file pbx.c.
References ast_context_remove_switch2(), ast_unlock_contexts(), and find_context_locked().
02857 { 02858 int ret = -1; /* default error return */ 02859 struct ast_context *c = find_context_locked(context); 02860 02861 if (c) { 02862 /* remove switch from this context ... */ 02863 ret = ast_context_remove_switch2(c, sw, data, registrar); 02864 ast_unlock_contexts(); 02865 } 02866 return ret; 02867 }
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 2877 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().
02878 { 02879 struct ast_sw *i; 02880 int ret = -1; 02881 02882 ast_mutex_lock(&con->lock); 02883 02884 /* walk switches */ 02885 AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) { 02886 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02887 (!registrar || !strcmp(i->registrar, registrar))) { 02888 /* found, remove from list */ 02889 AST_LIST_REMOVE_CURRENT(&con->alts, list); 02890 free(i); /* free switch and return */ 02891 ret = 0; 02892 break; 02893 } 02894 } 02895 AST_LIST_TRAVERSE_SAFE_END 02896 02897 ast_mutex_unlock(&con->lock); 02898 02899 return ret; 02900 }
int ast_context_unlockmacro | ( | const char * | context | ) |
Unlocks the macrolock in the given context.
Definition at line 3034 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().
03035 { 03036 struct ast_context *c = NULL; 03037 int ret = -1; 03038 03039 ast_rdlock_contexts(); 03040 03041 while ((c = ast_walk_contexts(c))) { 03042 if (!strcmp(ast_get_context_name(c), context)) { 03043 ret = 0; 03044 break; 03045 } 03046 } 03047 03048 ast_unlock_contexts(); 03049 03050 /* if we found context, unlock macrolock */ 03051 if (ret == 0) 03052 ret = ast_mutex_unlock(&c->macrolock); 03053 03054 return ret; 03055 }
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 6570 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().
06571 { 06572 struct ast_include *inc = NULL; 06573 int res = 0; 06574 06575 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06576 if (ast_context_find(inc->rname)) 06577 continue; 06578 06579 res = -1; 06580 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06581 ast_get_context_name(con), inc->rname); 06582 break; 06583 } 06584 06585 return res; 06586 }
struct ast_custom_function* ast_custom_function_find | ( | const char * | name | ) |
Definition at line 1510 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().
01511 { 01512 struct ast_custom_function *acf = NULL; 01513 01514 AST_LIST_LOCK(&acf_root); 01515 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01516 if (!strcmp(name, acf->name)) 01517 break; 01518 } 01519 AST_LIST_UNLOCK(&acf_root); 01520 01521 return acf; 01522 }
int ast_custom_function_register | ( | struct ast_custom_function * | acf | ) |
Reigster a custom function.
Definition at line 1546 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().
01547 { 01548 struct ast_custom_function *cur; 01549 01550 if (!acf) 01551 return -1; 01552 01553 AST_LIST_LOCK(&acf_root); 01554 01555 if (ast_custom_function_find(acf->name)) { 01556 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01557 AST_LIST_UNLOCK(&acf_root); 01558 return -1; 01559 } 01560 01561 /* Store in alphabetical order */ 01562 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01563 if (strcasecmp(acf->name, cur->name) < 0) { 01564 AST_LIST_INSERT_BEFORE_CURRENT(&acf_root, acf, acflist); 01565 break; 01566 } 01567 } 01568 AST_LIST_TRAVERSE_SAFE_END 01569 if (!cur) 01570 AST_LIST_INSERT_TAIL(&acf_root, acf, acflist); 01571 01572 AST_LIST_UNLOCK(&acf_root); 01573 01574 if (option_verbose > 1) 01575 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01576 01577 return 0; 01578 }
int ast_custom_function_unregister | ( | struct ast_custom_function * | acf | ) |
Unregister a custom function.
Definition at line 1524 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().
01525 { 01526 struct ast_custom_function *cur; 01527 01528 if (!acf) 01529 return -1; 01530 01531 AST_LIST_LOCK(&acf_root); 01532 AST_LIST_TRAVERSE_SAFE_BEGIN(&acf_root, cur, acflist) { 01533 if (cur == acf) { 01534 AST_LIST_REMOVE_CURRENT(&acf_root, acflist); 01535 if (option_verbose > 1) 01536 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01537 break; 01538 } 01539 } 01540 AST_LIST_TRAVERSE_SAFE_END 01541 AST_LIST_UNLOCK(&acf_root); 01542 01543 return acf ? 0 : -1; 01544 }
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 1974 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().
01975 { 01976 switch (devstate) { 01977 case AST_DEVICE_ONHOLD: 01978 return AST_EXTENSION_ONHOLD; 01979 case AST_DEVICE_BUSY: 01980 return AST_EXTENSION_BUSY; 01981 case AST_DEVICE_UNKNOWN: 01982 return AST_EXTENSION_NOT_INUSE; 01983 case AST_DEVICE_UNAVAILABLE: 01984 case AST_DEVICE_INVALID: 01985 return AST_EXTENSION_UNAVAILABLE; 01986 case AST_DEVICE_RINGINUSE: 01987 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 01988 case AST_DEVICE_RINGING: 01989 return AST_EXTENSION_RINGING; 01990 case AST_DEVICE_INUSE: 01991 return AST_EXTENSION_INUSE; 01992 case AST_DEVICE_NOT_INUSE: 01993 return AST_EXTENSION_NOT_INUSE; 01994 case AST_DEVICE_TOTAL: /* not a device state, included for completeness */ 01995 break; 01996 } 01997 01998 return AST_EXTENSION_NOT_INUSE; 01999 }
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 2366 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(), cb_events(), conf_run(), console_dial(), console_dial_deprecated(), console_transfer(), console_transfer_deprecated(), dahdi_handle_dtmf(), dahdi_r2_on_call_offered(), dahdi_r2_on_dnis_digit_received(), disa_exec(), dp_lookup(), dundi_lookup_local(), findmeexec(), 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(), sip_new(), skinny_ss(), socket_process(), ss_thread(), and waitstream_core().
02367 { 02368 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH); 02369 }
int ast_explicit_goto | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4694 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(), builtin_atxfer(), disa_exec(), and handle_setpriority().
04695 { 04696 if (!chan) 04697 return -1; 04698 04699 ast_channel_lock(chan); 04700 04701 if (!ast_strlen_zero(context)) 04702 ast_copy_string(chan->context, context, sizeof(chan->context)); 04703 if (!ast_strlen_zero(exten)) 04704 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04705 if (priority > -1) { 04706 chan->priority = priority; 04707 /* see flag description in channel.h for explanation */ 04708 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04709 chan->priority--; 04710 } 04711 04712 ast_channel_unlock(chan); 04713 04714 return 0; 04715 }
int ast_extension_close | ( | const char * | pattern, | |
const char * | data, | |||
int | needmore | |||
) |
Definition at line 941 of file pbx.c.
References ast_log(), E_CANMATCH, E_MATCHMORE, extension_match_core(), and LOG_WARNING.
Referenced by realtime_switch_common().
00942 { 00943 if (needmore != E_MATCHMORE && needmore != E_CANMATCH) 00944 ast_log(LOG_WARNING, "invalid argument %d\n", needmore); 00945 return extension_match_core(pattern, data, needmore); 00946 }
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 936 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().
00937 { 00938 return extension_match_core(pattern, data, E_MATCH); 00939 }
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 2036 of file pbx.c.
References ast_extension_state2(), and ast_hint_extension().
Referenced by action_extensionstate(), and handle_request_subscribe().
02037 { 02038 struct ast_exten *e; 02039 02040 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 02041 if (!e) 02042 return -1; /* No hint, return -1 */ 02043 02044 return ast_extension_state2(e); /* Check all devices in the hint */ 02045 }
static int ast_extension_state2 | ( | struct ast_exten * | e | ) | [static] |
ast_extensions_state2: Check state of extension by using hints
Definition at line 2002 of file pbx.c.
References 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_strdupa.
Referenced by ast_add_hint(), ast_extension_state(), and ast_hint_state_changed().
02003 { 02004 char *hint; 02005 char *cur, *rest; 02006 struct ast_devstate_aggregate agg; 02007 02008 ast_devstate_aggregate_init(&agg); 02009 02010 if (!e) 02011 return -1; 02012 02013 hint = ast_strdupa(ast_get_extension_app(e)); 02014 02015 rest = hint; /* One or more devices separated with a & character */ 02016 while ( (cur = strsep(&rest, "&")) ) { 02017 int res = ast_device_state(cur); 02018 ast_devstate_aggregate_add(&agg, res); 02019 } 02020 return ast_devstate_to_extenstate(ast_devstate_aggregate_result(&agg)); 02021 }
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 2024 of file pbx.c.
References extension_states.
Referenced by handle_request_subscribe(), handle_show_hints(), and notify_extenstate_update().
02025 { 02026 int i; 02027 02028 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 02029 if (extension_states[i].extension_state == extension_state) 02030 return extension_states[i].text; 02031 } 02032 return "Unknown"; 02033 }
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 2118 of file pbx.c.
References ao2_lock(), ao2_unlock(), ast_calloc, ast_state_cb::callback, ast_state_cb::data, hints, ast_state_cb::next, and statecbs.
Referenced by handle_request_subscribe(), and init_manager().
02120 { 02121 struct ast_hint *hint; 02122 struct ast_state_cb *cblist; 02123 struct ast_exten *e; 02124 02125 /* If there's no context and extension: add callback to statecbs list */ 02126 if (!context && !exten) { 02127 ao2_lock(hints); 02128 02129 for (cblist = statecbs; cblist; cblist = cblist->next) { 02130 if (cblist->callback == callback) { 02131 cblist->data = data; 02132 ao2_unlock(hints); 02133 return 0; 02134 } 02135 } 02136 02137 /* Now insert the callback */ 02138 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02139 ao2_unlock(hints); 02140 return -1; 02141 } 02142 cblist->id = 0; 02143 cblist->callback = callback; 02144 cblist->data = data; 02145 02146 cblist->next = statecbs; 02147 statecbs = cblist; 02148 02149 ao2_unlock(hints); 02150 return 0; 02151 } 02152 02153 if (!context || !exten) 02154 return -1; 02155 02156 /* This callback type is for only one hint, so get the hint */ 02157 e = ast_hint_extension(NULL, context, exten); 02158 if (!e) { 02159 return -1; 02160 } 02161 02162 hint = ao2_find(hints, e, 0); 02163 02164 if (!hint) { 02165 return -1; 02166 } 02167 02168 /* Now insert the callback in the callback list */ 02169 if (!(cblist = ast_calloc(1, sizeof(*cblist)))) { 02170 ao2_ref(hint, -1); 02171 return -1; 02172 } 02173 cblist->id = stateid++; /* Unique ID for this callback */ 02174 cblist->callback = callback; /* Pointer to callback routine */ 02175 cblist->data = data; /* Data for the callback */ 02176 02177 ao2_lock(hint); 02178 cblist->next = hint->callbacks; 02179 hint->callbacks = cblist; 02180 ao2_unlock(hint); 02181 02182 ao2_ref(hint, -1); 02183 02184 return cblist->id; 02185 }
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 2203 of file pbx.c.
References ao2_lock(), ao2_unlock(), free, hints, ast_state_cb::next, and statecbs.
Referenced by __sip_destroy(), and handle_request_subscribe().
02204 { 02205 struct ast_state_cb **p_cur = NULL; /* address of pointer to us */ 02206 int ret = -1; 02207 02208 if (!id && !callback) { 02209 return -1; 02210 } 02211 02212 if (!id) { /* id == 0 is a callback without extension */ 02213 ao2_lock(hints); 02214 for (p_cur = &statecbs; *p_cur; p_cur = &(*p_cur)->next) { 02215 if ((*p_cur)->callback == callback) { 02216 break; 02217 } 02218 } 02219 if (p_cur && *p_cur) { 02220 struct ast_state_cb *cur = *p_cur; 02221 *p_cur = cur->next; 02222 free(cur); 02223 ret = 0; 02224 } 02225 ao2_unlock(hints); 02226 } else { /* callback with extension, find the callback based on ID */ 02227 struct ast_hint *hint; 02228 02229 hint = ao2_callback(hints, 0, find_hint_by_cb_id, &id); 02230 02231 if (hint) { 02232 ao2_lock(hint); 02233 for (p_cur = &hint->callbacks; *p_cur; p_cur = &(*p_cur)->next) { 02234 if ((*p_cur)->id == id) { 02235 break; 02236 } 02237 } 02238 if (p_cur && *p_cur) { 02239 struct ast_state_cb *cur = *p_cur; 02240 *p_cur = cur->next; 02241 free(cur); 02242 ret = 0; 02243 } 02244 ao2_unlock(hint); 02245 ao2_ref(hint, -1); 02246 } 02247 } 02248 02249 return ret; 02250 }
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 2371 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().
02372 { 02373 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL); 02374 }
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 2376 of file pbx.c.
References E_FINDLABEL, and pbx_extension_helper().
Referenced by pbx_load_config().
02377 { 02378 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL); 02379 }
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 1600 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().
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->read) 01608 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01609 else 01610 return acfptr->read(chan, function, args, workspace, len); 01611 return -1; 01612 }
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 1614 of file pbx.c.
References ast_custom_function_find(), ast_log(), func_args(), LOG_ERROR, and ast_custom_function::write.
Referenced by action_setvar(), pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper().
01615 { 01616 char *args = func_args(function); 01617 struct ast_custom_function *acfptr = ast_custom_function_find(function); 01618 01619 if (acfptr == NULL) 01620 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01621 else if (!acfptr->write) 01622 ast_log(LOG_ERROR, "Function %s cannot be written to\n", function); 01623 else 01624 return acfptr->write(chan, function, args, value); 01625 01626 return -1; 01627 }
const char* ast_get_context_name | ( | struct ast_context * | con | ) |
Definition at line 6427 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().
06428 { 06429 return con ? con->name : NULL; 06430 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6465 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06466 { 06467 return c ? c->registrar : NULL; 06468 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6495 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().
06496 { 06497 return e ? e->app : NULL; 06498 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6500 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06501 { 06502 return e ? e->data : NULL; 06503 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6490 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().
06491 { 06492 return e ? e->cidmatch : NULL; 06493 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | exten | ) |
Definition at line 6442 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 6485 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().
06486 { 06487 return e ? e->matchcid : 0; 06488 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6437 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 6457 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 6470 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06471 { 06472 return e ? e->registrar : NULL; 06473 }
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 2349 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().
02350 { 02351 struct ast_exten *e = ast_hint_extension(c, context, exten); 02352 02353 if (e) { 02354 if (hint) 02355 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02356 if (name) { 02357 const char *tmp = ast_get_extension_app_data(e); 02358 if (tmp) 02359 ast_copy_string(name, tmp, namesize); 02360 } 02361 return -1; 02362 } 02363 return 0; 02364 }
const char* ast_get_ignorepat_name | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6452 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().
06453 { 06454 return ip ? ip->pattern : NULL; 06455 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6480 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06481 { 06482 return ip ? ip->registrar : NULL; 06483 }
const char* ast_get_include_name | ( | struct ast_include * | inc | ) |
Definition at line 6447 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().
06448 { 06449 return inc ? inc->name : NULL; 06450 }
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6475 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06476 { 06477 return i ? i->registrar : NULL; 06478 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6510 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06511 { 06512 return sw ? sw->data : NULL; 06513 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6505 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06506 { 06507 return sw ? sw->name : NULL; 06508 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6515 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06516 { 06517 return sw ? sw->registrar : NULL; 06518 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6608 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().
06609 { 06610 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06611 }
static void ast_hint_destroy | ( | void * | obj | ) | [static] |
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 1962 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().
01963 { 01964 struct ast_exten *e; 01965 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */ 01966 01967 ast_rdlock_contexts(); 01968 e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH); 01969 ast_unlock_contexts(); 01970 01971 return e; 01972 }
void ast_hint_state_changed | ( | const char * | device | ) |
Definition at line 2047 of file pbx.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_dynamic_str_create(), ast_dynamic_str_set(), ast_extension_state2(), ast_free, ast_get_extension_app(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_hint::callbacks, ast_hint::exten, ast_exten::exten, hints, ast_hint::laststate, ast_context::name, ast_state_cb::next, ast_exten::parent, parse(), statecbs, and ast_dynamic_str::str.
Referenced by do_state_change().
02048 { 02049 struct ast_hint *hint; 02050 struct ast_dynamic_str *str; 02051 struct ao2_iterator i; 02052 02053 if (!(str = ast_dynamic_str_create(1024))) { 02054 return; 02055 } 02056 02057 i = ao2_iterator_init(hints, 0); 02058 for (hint = ao2_iterator_next(&i); hint; ao2_ref(hint, -1), hint = ao2_iterator_next(&i)) { 02059 struct ast_state_cb *cblist; 02060 char *cur, *parse; 02061 int state; 02062 02063 ast_dynamic_str_set(&str, 0, "%s", ast_get_extension_app(hint->exten)); 02064 parse = str->str; 02065 02066 while ( (cur = strsep(&parse, "&")) ) { 02067 if (!strcasecmp(cur, device)) { 02068 break; 02069 } 02070 } 02071 02072 if (!cur) { 02073 continue; 02074 } 02075 02076 /* Get device state for this hint */ 02077 state = ast_extension_state2(hint->exten); 02078 02079 if ((state == -1) || (state == hint->laststate)) { 02080 continue; 02081 } 02082 02083 /* Device state changed since last check - notify the watchers */ 02084 02085 ast_rdlock_contexts(); 02086 ao2_lock(hints); 02087 ao2_lock(hint); 02088 02089 if (hint->exten == NULL) { 02090 /* the extension has been destroyed */ 02091 ao2_unlock(hint); 02092 ao2_unlock(hints); 02093 ast_unlock_contexts(); 02094 continue; 02095 } 02096 02097 /* For general callbacks */ 02098 for (cblist = statecbs; cblist; cblist = cblist->next) { 02099 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02100 } 02101 02102 /* For extension callbacks */ 02103 for (cblist = hint->callbacks; cblist; cblist = cblist->next) { 02104 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 02105 } 02106 02107 hint->laststate = state; /* record we saw the change */ 02108 ao2_unlock(hint); 02109 ao2_unlock(hints); 02110 ast_unlock_contexts(); 02111 } 02112 02113 ao2_iterator_destroy(&i); 02114 ast_free(str); 02115 }
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 4660 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().
04661 { 04662 struct ast_context *con = ast_context_find(context); 04663 if (con) { 04664 struct ast_ignorepat *pat; 04665 for (pat = con->ignorepats; pat; pat = pat->next) { 04666 if (ast_extension_match(pat->pattern, pattern)) 04667 return 1; 04668 } 04669 } 04670 04671 return 0; 04672 }
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 6414 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().
06415 { 06416 return ast_mutex_lock(&con->lock); 06417 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6391 of file pbx.c.
References ast_mutex_lock(), and conlock.
Referenced by find_matching_endwhile().
06392 { 06393 return ast_mutex_lock(&conlock); 06394 }
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 2386 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().
02387 { 02388 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE); 02389 }
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 4067 of file pbx.c.
References __ast_context_destroy(), ao2_find(), AO2_ITERATOR_DONTLOCK, ao2_iterator_init(), ao2_iterator_next(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_calloc, AST_EXTENSION_REMOVED, AST_LIST_HEAD_INIT_VALUE, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, 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, hints, 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().
04068 { 04069 struct ast_context *tmp, *lasttmp = NULL; 04070 struct store_hints store = AST_LIST_HEAD_INIT_VALUE; 04071 struct store_hint *this; 04072 struct ast_hint *hint; 04073 struct ast_exten *exten; 04074 int length; 04075 struct ast_state_cb *thiscb, *prevcb; 04076 struct ao2_iterator i; 04077 04078 /* it is very important that this function hold the hint list lock _and_ the conlock 04079 during its operation; not only do we need to ensure that the list of contexts 04080 and extensions does not change, but also that no hint callbacks (watchers) are 04081 added or removed during the merge/delete process 04082 04083 in addition, the locks _must_ be taken in this order, because there are already 04084 other code paths that use this order 04085 */ 04086 ast_wrlock_contexts(); 04087 ao2_lock(hints); 04088 04089 /* preserve all watchers for hints associated with this registrar */ 04090 i = ao2_iterator_init(hints, AO2_ITERATOR_DONTLOCK); 04091 for (hint = ao2_iterator_next(&i); hint; ao2_ref(hint, -1), hint = ao2_iterator_next(&i)) { 04092 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 04093 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 04094 if (!(this = ast_calloc(1, length))) { 04095 continue; 04096 } 04097 ao2_lock(hint); 04098 04099 if (hint->exten == NULL) { 04100 ao2_unlock(hint); 04101 continue; 04102 } 04103 04104 this->callbacks = hint->callbacks; 04105 hint->callbacks = NULL; 04106 this->laststate = hint->laststate; 04107 ao2_unlock(hint); 04108 this->context = this->data; 04109 strcpy(this->data, hint->exten->parent->name); 04110 this->exten = this->data + strlen(this->context) + 1; 04111 strcpy(this->exten, hint->exten->exten); 04112 AST_LIST_INSERT_HEAD(&store, this, list); 04113 } 04114 } 04115 04116 tmp = *extcontexts; 04117 if (registrar) { 04118 /* XXX remove previous contexts from same registrar */ 04119 if (option_debug) 04120 ast_log(LOG_DEBUG, "must remove any reg %s\n", registrar); 04121 __ast_context_destroy(NULL,registrar); 04122 while (tmp) { 04123 lasttmp = tmp; 04124 tmp = tmp->next; 04125 } 04126 } else { 04127 /* XXX remove contexts with the same name */ 04128 while (tmp) { 04129 ast_log(LOG_WARNING, "must remove %s reg %s\n", tmp->name, tmp->registrar); 04130 __ast_context_destroy(tmp,tmp->registrar); 04131 lasttmp = tmp; 04132 tmp = tmp->next; 04133 } 04134 } 04135 if (lasttmp) { 04136 lasttmp->next = contexts; 04137 contexts = *extcontexts; 04138 *extcontexts = NULL; 04139 } else 04140 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 04141 04142 /* restore the watchers for hints that can be found; notify those that 04143 cannot be restored 04144 */ 04145 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 04146 struct pbx_find_info q = { .stacklen = 0 }; 04147 exten = pbx_find_extension(NULL, NULL, &q, this->context, this->exten, PRIORITY_HINT, NULL, "", E_MATCH); 04148 hint = ao2_find(hints, exten, 0); 04149 if (!exten || !hint) { 04150 /* this hint has been removed, notify the watchers */ 04151 prevcb = NULL; 04152 thiscb = this->callbacks; 04153 while (thiscb) { 04154 prevcb = thiscb; 04155 thiscb = thiscb->next; 04156 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 04157 free(prevcb); 04158 } 04159 } else { 04160 thiscb = this->callbacks; 04161 while (thiscb->next) { 04162 thiscb = thiscb->next; 04163 } 04164 ao2_lock(hint); 04165 thiscb->next = hint->callbacks; 04166 hint->callbacks = this->callbacks; 04167 hint->laststate = this->laststate; 04168 ao2_unlock(hint); 04169 } 04170 if (hint) { 04171 ao2_ref(hint, -1); 04172 } 04173 free(this); 04174 } 04175 04176 ao2_unlock(hints); 04177 ast_unlock_contexts(); 04178 04179 return; 04180 }
int ast_parseable_goto | ( | struct ast_channel * | chan, | |
const char * | goto_string | |||
) |
This function will handle locking the channel as needed.
Definition at line 6618 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().
06619 { 06620 char *exten, *pri, *context; 06621 char *stringp; 06622 int ipri; 06623 int mode = 0; 06624 06625 if (ast_strlen_zero(goto_string)) { 06626 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06627 return -1; 06628 } 06629 stringp = ast_strdupa(goto_string); 06630 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06631 exten = strsep(&stringp, "|"); 06632 pri = strsep(&stringp, "|"); 06633 if (!exten) { /* Only a priority in this one */ 06634 pri = context; 06635 exten = NULL; 06636 context = NULL; 06637 } else if (!pri) { /* Only an extension and priority in this one */ 06638 pri = exten; 06639 exten = context; 06640 context = NULL; 06641 } 06642 if (*pri == '+') { 06643 mode = 1; 06644 pri++; 06645 } else if (*pri == '-') { 06646 mode = -1; 06647 pri++; 06648 } 06649 if (sscanf(pri, "%30d", &ipri) != 1) { 06650 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06651 pri, chan->cid.cid_num)) < 1) { 06652 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06653 return -1; 06654 } else 06655 mode = 0; 06656 } 06657 /* At this point we have a priority and maybe an extension and a context */ 06658 06659 if (mode) 06660 ipri = chan->priority + (ipri * mode); 06661 06662 ast_explicit_goto(chan, context, exten, ipri); 06663 return 0; 06664 06665 }
int ast_pbx_init | ( | void | ) |
Provided by pbx.c
Definition at line 6681 of file pbx.c.
References ao2_container_alloc(), hint_cmp(), hint_hash(), and hints.
Referenced by main().
06682 { 06683 hints = ao2_container_alloc(1, hint_hash, hint_cmp); 06684 06685 return hints ? 0 : -1; 06686 }
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 5287 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().
05288 { 05289 struct ast_channel *chan; 05290 struct app_tmp *tmp; 05291 int res = -1, cdr_res = -1; 05292 struct outgoing_helper oh; 05293 pthread_attr_t attr; 05294 05295 memset(&oh, 0, sizeof(oh)); 05296 oh.vars = vars; 05297 oh.account = account; 05298 05299 if (locked_channel) 05300 *locked_channel = NULL; 05301 if (ast_strlen_zero(app)) { 05302 res = -1; 05303 goto outgoing_app_cleanup; 05304 } 05305 if (sync) { 05306 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05307 if (chan) { 05308 ast_set_variables(chan, vars); 05309 if (account) 05310 ast_cdr_setaccount(chan, account); 05311 if (chan->_state == AST_STATE_UP) { 05312 res = 0; 05313 if (option_verbose > 3) 05314 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05315 tmp = ast_calloc(1, sizeof(*tmp)); 05316 if (!tmp) 05317 res = -1; 05318 else { 05319 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05320 if (appdata) 05321 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05322 tmp->chan = chan; 05323 if (sync > 1) { 05324 if (locked_channel) 05325 ast_channel_unlock(chan); 05326 ast_pbx_run_app(tmp); 05327 } else { 05328 pthread_attr_init(&attr); 05329 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05330 if (locked_channel) 05331 ast_channel_lock(chan); 05332 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05333 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05334 free(tmp); 05335 if (locked_channel) 05336 ast_channel_unlock(chan); 05337 ast_hangup(chan); 05338 res = -1; 05339 } else { 05340 if (locked_channel) 05341 *locked_channel = chan; 05342 } 05343 pthread_attr_destroy(&attr); 05344 } 05345 } 05346 } else { 05347 if (option_verbose > 3) 05348 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05349 if (chan->cdr) { /* update the cdr */ 05350 /* here we update the status of the call, which sould be busy. 05351 * if that fails then we set the status to failed */ 05352 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05353 ast_cdr_failed(chan->cdr); 05354 } 05355 ast_hangup(chan); 05356 } 05357 } 05358 05359 if (res < 0) { /* the call failed for some reason */ 05360 if (*reason == 0) { /* if the call failed (not busy or no answer) 05361 * update the cdr with the failed message */ 05362 cdr_res = ast_pbx_outgoing_cdr_failed(); 05363 if (cdr_res != 0) { 05364 res = cdr_res; 05365 goto outgoing_app_cleanup; 05366 } 05367 } 05368 } 05369 05370 } else { 05371 struct async_stat *as; 05372 if (!(as = ast_calloc(1, sizeof(*as)))) { 05373 res = -1; 05374 goto outgoing_app_cleanup; 05375 } 05376 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05377 if (!chan) { 05378 free(as); 05379 res = -1; 05380 goto outgoing_app_cleanup; 05381 } 05382 as->chan = chan; 05383 ast_copy_string(as->app, app, sizeof(as->app)); 05384 if (appdata) 05385 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05386 as->timeout = timeout; 05387 ast_set_variables(chan, vars); 05388 if (account) 05389 ast_cdr_setaccount(chan, account); 05390 /* Start a new thread, and get something handling this channel. */ 05391 pthread_attr_init(&attr); 05392 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05393 if (locked_channel) 05394 ast_channel_lock(chan); 05395 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05396 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05397 free(as); 05398 if (locked_channel) 05399 ast_channel_unlock(chan); 05400 ast_hangup(chan); 05401 res = -1; 05402 pthread_attr_destroy(&attr); 05403 goto outgoing_app_cleanup; 05404 } else { 05405 if (locked_channel) 05406 *locked_channel = chan; 05407 } 05408 pthread_attr_destroy(&attr); 05409 res = 0; 05410 } 05411 outgoing_app_cleanup: 05412 ast_variables_destroy(vars); 05413 return res; 05414 }
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 5095 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().
05096 { 05097 /* allocate a channel */ 05098 struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", ""); 05099 05100 if (!chan) 05101 return -1; /* failure */ 05102 05103 if (!chan->cdr) { 05104 /* allocation of the cdr failed */ 05105 ast_channel_free(chan); /* free the channel */ 05106 return -1; /* return failure */ 05107 } 05108 05109 /* allocation of the cdr was successful */ 05110 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05111 ast_cdr_start(chan->cdr); /* record the start and stop time */ 05112 ast_cdr_end(chan->cdr); 05113 ast_cdr_failed(chan->cdr); /* set the status to failed */ 05114 ast_cdr_detach(chan->cdr); /* post and free the record */ 05115 chan->cdr = NULL; 05116 ast_channel_free(chan); /* free the channel */ 05117 05118 return 0; /* success */ 05119 }
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 5121 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().
05122 { 05123 struct ast_channel *chan; 05124 struct async_stat *as; 05125 int res = -1, cdr_res = -1; 05126 struct outgoing_helper oh; 05127 pthread_attr_t attr; 05128 05129 if (sync) { 05130 LOAD_OH(oh); 05131 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05132 if (channel) { 05133 *channel = chan; 05134 if (chan) 05135 ast_channel_lock(chan); 05136 } 05137 if (chan) { 05138 if (chan->_state == AST_STATE_UP) { 05139 res = 0; 05140 if (option_verbose > 3) 05141 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05142 05143 if (sync > 1) { 05144 if (channel) 05145 ast_channel_unlock(chan); 05146 if (ast_pbx_run(chan)) { 05147 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05148 if (channel) 05149 *channel = NULL; 05150 ast_hangup(chan); 05151 chan = NULL; 05152 res = -1; 05153 } 05154 } else { 05155 if (ast_pbx_start(chan)) { 05156 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05157 if (channel) { 05158 *channel = NULL; 05159 ast_channel_unlock(chan); 05160 } 05161 ast_hangup(chan); 05162 res = -1; 05163 } 05164 chan = NULL; 05165 } 05166 } else { 05167 if (option_verbose > 3) 05168 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05169 05170 if (chan->cdr) { /* update the cdr */ 05171 /* here we update the status of the call, which sould be busy. 05172 * if that fails then we set the status to failed */ 05173 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05174 ast_cdr_failed(chan->cdr); 05175 } 05176 05177 if (channel) { 05178 *channel = NULL; 05179 ast_channel_unlock(chan); 05180 } 05181 ast_hangup(chan); 05182 chan = NULL; 05183 } 05184 } 05185 05186 if (res < 0) { /* the call failed for some reason */ 05187 if (*reason == 0) { /* if the call failed (not busy or no answer) 05188 * update the cdr with the failed message */ 05189 cdr_res = ast_pbx_outgoing_cdr_failed(); 05190 if (cdr_res != 0) { 05191 res = cdr_res; 05192 goto outgoing_exten_cleanup; 05193 } 05194 } 05195 05196 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05197 /* check if "failed" exists */ 05198 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05199 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05200 if (chan) { 05201 char failed_reason[4] = ""; 05202 if (!ast_strlen_zero(context)) 05203 ast_copy_string(chan->context, context, sizeof(chan->context)); 05204 set_ext_pri(chan, "failed", 1); 05205 ast_set_variables(chan, vars); 05206 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05207 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05208 if (account) 05209 ast_cdr_setaccount(chan, account); 05210 if (ast_pbx_run(chan)) { 05211 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05212 ast_hangup(chan); 05213 } 05214 chan = NULL; 05215 } 05216 } 05217 } 05218 } else { 05219 if (!(as = ast_calloc(1, sizeof(*as)))) { 05220 res = -1; 05221 goto outgoing_exten_cleanup; 05222 } 05223 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05224 if (channel) { 05225 *channel = chan; 05226 if (chan) 05227 ast_channel_lock(chan); 05228 } 05229 if (!chan) { 05230 free(as); 05231 res = -1; 05232 goto outgoing_exten_cleanup; 05233 } 05234 as->chan = chan; 05235 ast_copy_string(as->context, context, sizeof(as->context)); 05236 set_ext_pri(as->chan, exten, priority); 05237 as->timeout = timeout; 05238 ast_set_variables(chan, vars); 05239 if (account) 05240 ast_cdr_setaccount(chan, account); 05241 pthread_attr_init(&attr); 05242 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05243 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05244 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05245 free(as); 05246 if (channel) { 05247 *channel = NULL; 05248 ast_channel_unlock(chan); 05249 } 05250 ast_hangup(chan); 05251 res = -1; 05252 pthread_attr_destroy(&attr); 05253 goto outgoing_exten_cleanup; 05254 } 05255 pthread_attr_destroy(&attr); 05256 res = 0; 05257 } 05258 outgoing_exten_cleanup: 05259 ast_variables_destroy(vars); 05260 return res; 05261 }
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 2751 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().
02752 { 02753 enum ast_pbx_result res = AST_PBX_SUCCESS; 02754 02755 if (increase_call_count(c)) 02756 return AST_PBX_CALL_LIMIT; 02757 02758 res = __ast_pbx_run(c); 02759 decrease_call_count(); 02760 02761 return res; 02762 }
static void* ast_pbx_run_app | ( | void * | data | ) | [static] |
run the application and free the descriptor once done
Definition at line 5271 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().
05272 { 05273 struct app_tmp *tmp = data; 05274 struct ast_app *app; 05275 app = pbx_findapp(tmp->app); 05276 if (app) { 05277 if (option_verbose > 3) 05278 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05279 pbx_exec(tmp->chan, app, tmp->data); 05280 } else 05281 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05282 ast_hangup(tmp->chan); 05283 free(tmp); 05284 return NULL; 05285 }
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 2724 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().
02725 { 02726 pthread_t t; 02727 pthread_attr_t attr; 02728 02729 if (!c) { 02730 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02731 return AST_PBX_FAILED; 02732 } 02733 02734 if (increase_call_count(c)) 02735 return AST_PBX_CALL_LIMIT; 02736 02737 /* Start a new thread, and get something handling this channel. */ 02738 pthread_attr_init(&attr); 02739 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02740 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02741 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02742 pthread_attr_destroy(&attr); 02743 decrease_call_count(); 02744 return AST_PBX_FAILED; 02745 } 02746 pthread_attr_destroy(&attr); 02747 02748 return AST_PBX_SUCCESS; 02749 }
int ast_processed_calls | ( | void | ) |
Retrieve the total number of calls processed through the PBX since last restart.
Definition at line 2769 of file pbx.c.
02770 { 02771 return totalcalls; 02772 }
int ast_rdlock_contexts | ( | void | ) |
Definition at line 6396 of file pbx.c.
References ast_mutex_lock(), 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().
06397 { 06398 return ast_mutex_lock(&conlock); 06399 }
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 3058 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().
03059 { 03060 struct ast_app *tmp, *cur = NULL; 03061 char tmps[80]; 03062 int length; 03063 03064 AST_LIST_LOCK(&apps); 03065 AST_LIST_TRAVERSE(&apps, tmp, list) { 03066 if (!strcasecmp(app, tmp->name)) { 03067 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 03068 AST_LIST_UNLOCK(&apps); 03069 return -1; 03070 } 03071 } 03072 03073 length = sizeof(*tmp) + strlen(app) + 1; 03074 03075 if (!(tmp = ast_calloc(1, length))) { 03076 AST_LIST_UNLOCK(&apps); 03077 return -1; 03078 } 03079 03080 strcpy(tmp->name, app); 03081 tmp->execute = execute; 03082 tmp->synopsis = synopsis; 03083 tmp->description = description; 03084 03085 /* Store in alphabetical order */ 03086 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { 03087 if (strcasecmp(tmp->name, cur->name) < 0) { 03088 AST_LIST_INSERT_BEFORE_CURRENT(&apps, tmp, list); 03089 break; 03090 } 03091 } 03092 AST_LIST_TRAVERSE_SAFE_END 03093 if (!cur) 03094 AST_LIST_INSERT_TAIL(&apps, tmp, list); 03095 03096 if (option_verbose > 1) 03097 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 03098 03099 AST_LIST_UNLOCK(&apps); 03100 03101 return 0; 03102 }
int ast_register_switch | ( | struct ast_switch * | sw | ) |
Register an alternative dialplan switch.
sw | switch to register |
Definition at line 3108 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().
03109 { 03110 struct ast_switch *tmp; 03111 03112 AST_LIST_LOCK(&switches); 03113 AST_LIST_TRAVERSE(&switches, tmp, list) { 03114 if (!strcasecmp(tmp->name, sw->name)) { 03115 AST_LIST_UNLOCK(&switches); 03116 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 03117 return -1; 03118 } 03119 } 03120 AST_LIST_INSERT_TAIL(&switches, sw, list); 03121 AST_LIST_UNLOCK(&switches); 03122 03123 return 0; 03124 }
static int ast_remove_hint | ( | struct ast_exten * | e | ) | [static] |
ast_remove_hint: Remove hint from extension
Definition at line 2313 of file pbx.c.
References ao2_find(), ao2_lock(), ao2_ref(), ao2_unlink(), ao2_unlock(), AST_EXTENSION_DEACTIVATED, ast_free, ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, hints, ast_context::name, ast_state_cb::next, and ast_exten::parent.
Referenced by destroy_exten().
02314 { 02315 /* Cleanup the Notifys if hint is removed */ 02316 struct ast_hint *hint; 02317 struct ast_state_cb *cblist, *cbprev; 02318 02319 if (!e) { 02320 return -1; 02321 } 02322 02323 hint = ao2_find(hints, e, 0); 02324 02325 if (!hint) { 02326 return -1; 02327 } 02328 ao2_lock(hint); 02329 02330 cbprev = NULL; 02331 cblist = hint->callbacks; 02332 while (cblist) { 02333 cbprev = cblist; 02334 cblist = cblist->next; 02335 cbprev->callback(hint->exten->parent->name, hint->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data); 02336 ast_free(cbprev); 02337 } 02338 hint->callbacks = NULL; 02339 hint->exten = NULL; 02340 ao2_unlink(hints, hint); 02341 ao2_unlock(hint); 02342 ao2_ref(hint, -1); 02343 02344 return 0; 02345 }
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 2391 of file pbx.c.
References E_SPAWN, and pbx_extension_helper().
Referenced by __ast_pbx_run(), _macro_exec(), ast_bridge_call(), and loopback_exec().
02392 { 02393 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN); 02394 }
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 6419 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().
06420 { 06421 return ast_mutex_unlock(&con->lock); 06422 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6406 of file pbx.c.
References ast_mutex_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().
06407 { 06408 return ast_mutex_unlock(&conlock); 06409 }
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 3978 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().
03979 { 03980 struct ast_app *tmp; 03981 03982 AST_LIST_LOCK(&apps); 03983 AST_LIST_TRAVERSE_SAFE_BEGIN(&apps, tmp, list) { 03984 if (!strcasecmp(app, tmp->name)) { 03985 AST_LIST_REMOVE_CURRENT(&apps, list); 03986 if (option_verbose > 1) 03987 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03988 free(tmp); 03989 break; 03990 } 03991 } 03992 AST_LIST_TRAVERSE_SAFE_END 03993 AST_LIST_UNLOCK(&apps); 03994 03995 return tmp ? 0 : -1; 03996 }
void ast_unregister_switch | ( | struct ast_switch * | sw | ) |
Unregister an alternative switch.
sw | switch to unregister |
Definition at line 3126 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().
03127 { 03128 AST_LIST_LOCK(&switches); 03129 AST_LIST_REMOVE(&switches, sw, list); 03130 AST_LIST_UNLOCK(&switches); 03131 }
struct ast_exten* ast_walk_context_extensions | ( | struct ast_context * | con, | |
struct ast_exten * | exten | |||
) |
Definition at line 6528 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().
06530 { 06531 if (!exten) 06532 return con ? con->root : NULL; 06533 else 06534 return exten->next; 06535 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6561 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().
06563 { 06564 if (!ip) 06565 return con ? con->ignorepats : NULL; 06566 else 06567 return ip->next; 06568 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6552 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().
06554 { 06555 if (!inc) 06556 return con ? con->includes : NULL; 06557 else 06558 return inc->next; 06559 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6537 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().
06539 { 06540 if (!sw) 06541 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06542 else 06543 return AST_LIST_NEXT(sw, list); 06544 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6523 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 6546 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 6401 of file pbx.c.
References ast_mutex_lock(), and conlock.
Referenced by ast_context_destroy(), ast_merge_contexts_and_delete(), and complete_context_dont_include_deprecated().
06402 { 06403 return ast_mutex_lock(&conlock); 06404 }
static void* async_wait | ( | void * | data | ) | [static] |
Definition at line 5032 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().
05033 { 05034 struct async_stat *as = data; 05035 struct ast_channel *chan = as->chan; 05036 int timeout = as->timeout; 05037 int res; 05038 struct ast_frame *f; 05039 struct ast_app *app; 05040 05041 while (timeout && (chan->_state != AST_STATE_UP)) { 05042 res = ast_waitfor(chan, timeout); 05043 if (res < 1) 05044 break; 05045 if (timeout > -1) 05046 timeout = res; 05047 f = ast_read(chan); 05048 if (!f) 05049 break; 05050 if (f->frametype == AST_FRAME_CONTROL) { 05051 if ((f->subclass == AST_CONTROL_BUSY) || 05052 (f->subclass == AST_CONTROL_CONGESTION) ) { 05053 ast_frfree(f); 05054 break; 05055 } 05056 } 05057 ast_frfree(f); 05058 } 05059 if (chan->_state == AST_STATE_UP) { 05060 if (!ast_strlen_zero(as->app)) { 05061 app = pbx_findapp(as->app); 05062 if (app) { 05063 if (option_verbose > 2) 05064 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 05065 pbx_exec(chan, app, as->appdata); 05066 } else 05067 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 05068 } else { 05069 if (!ast_strlen_zero(as->context)) 05070 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 05071 if (!ast_strlen_zero(as->exten)) 05072 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 05073 if (as->priority > 0) 05074 chan->priority = as->priority; 05075 /* Run the PBX */ 05076 if (ast_pbx_run(chan)) { 05077 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 05078 } else { 05079 /* PBX will have taken care of this */ 05080 chan = NULL; 05081 } 05082 } 05083 } 05084 free(as); 05085 if (chan) 05086 ast_hangup(chan); 05087 return NULL; 05088 }
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 2409 of file pbx.c.
References ast_channel::_softhangup, ast_channel_clear_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.
02410 { 02411 int digit; 02412 02413 buf[pos] = '\0'; /* make sure it is properly terminated */ 02414 while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) { 02415 /* As long as we're willing to wait, and as long as it's not defined, 02416 keep reading digits until we can't possibly get a right answer anymore. */ 02417 digit = ast_waitfordigit(c, waittime * 1000); 02418 if (c->_softhangup & AST_SOFTHANGUP_ASYNCGOTO) { 02419 ast_channel_clear_softhangup(c, AST_SOFTHANGUP_ASYNCGOTO); 02420 } else { 02421 if (!digit) /* No entry */ 02422 break; 02423 if (digit < 0) /* Error, maybe a hangup */ 02424 return -1; 02425 if (pos < buflen - 1) { /* XXX maybe error otherwise ? */ 02426 buf[pos++] = digit; 02427 buf[pos] = '\0'; 02428 } 02429 waittime = c->pbx->dtimeout; 02430 } 02431 } 02432 return 0; 02433 }
static char* complete_show_application | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3191 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_app::list, ast_app::name, and strdup.
03192 { 03193 struct ast_app *a; 03194 char *ret = NULL; 03195 int which = 0; 03196 int wordlen = strlen(word); 03197 03198 /* return the n-th [partial] matching entry */ 03199 AST_LIST_LOCK(&apps); 03200 AST_LIST_TRAVERSE(&apps, a, list) { 03201 if (!strncasecmp(word, a->name, wordlen) && ++which > state) { 03202 ret = strdup(a->name); 03203 break; 03204 } 03205 } 03206 AST_LIST_UNLOCK(&apps); 03207 03208 return ret; 03209 }
static char* complete_show_applications | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3557 of file pbx.c.
References ast_cli_complete().
03558 { 03559 static char* choices[] = { "like", "describing", NULL }; 03560 03561 return (pos != 3) ? NULL : ast_cli_complete(word, choices, state); 03562 }
static char* complete_show_applications_deprecated | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3550 of file pbx.c.
References ast_cli_complete().
03551 { 03552 static char* choices[] = { "like", "describing", NULL }; 03553 03554 return (pos != 2) ? NULL : ast_cli_complete(word, choices, state); 03555 }
static char* complete_show_dialplan_context | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3567 of file pbx.c.
References ast_get_context_name(), ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), and ast_walk_contexts().
03569 { 03570 struct ast_context *c = NULL; 03571 char *ret = NULL; 03572 int which = 0; 03573 int wordlen; 03574 03575 /* we are do completion of [exten@]context on second position only */ 03576 if (pos != 2) 03577 return NULL; 03578 03579 ast_rdlock_contexts(); 03580 03581 wordlen = strlen(word); 03582 03583 /* walk through all contexts and return the n-th match */ 03584 while ( (c = ast_walk_contexts(c)) ) { 03585 if (!strncasecmp(word, ast_get_context_name(c), wordlen) && ++which > state) { 03586 ret = ast_strdup(ast_get_context_name(c)); 03587 break; 03588 } 03589 } 03590 03591 ast_unlock_contexts(); 03592 03593 return ret; 03594 }
static char* complete_show_function | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1490 of file pbx.c.
References ast_custom_function::acflist, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_custom_function::name, and strdup.
01491 { 01492 struct ast_custom_function *acf; 01493 char *ret = NULL; 01494 int which = 0; 01495 int wordlen = strlen(word); 01496 01497 /* case-insensitive for convenience in this 'complete' function */ 01498 AST_LIST_LOCK(&acf_root); 01499 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01500 if (!strncasecmp(word, acf->name, wordlen) && ++which > state) { 01501 ret = strdup(acf->name); 01502 break; 01503 } 01504 } 01505 AST_LIST_UNLOCK(&acf_root); 01506 01507 return ret; 01508 }
static void decrease_call_count | ( | void | ) | [static] |
Definition at line 2686 of file pbx.c.
References ast_mutex_lock(), ast_mutex_unlock(), and maxcalllock.
Referenced by ast_pbx_run(), ast_pbx_start(), and pbx_thread().
02687 { 02688 ast_mutex_lock(&maxcalllock); 02689 if (countcalls > 0) 02690 countcalls--; 02691 ast_mutex_unlock(&maxcalllock); 02692 }
static void destroy_exten | ( | struct ast_exten * | e | ) | [static] |
Definition at line 2694 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().
02695 { 02696 if (e->priority == PRIORITY_HINT) 02697 ast_remove_hint(e); 02698 02699 if (e->datad) 02700 e->datad(e->data); 02701 free(e); 02702 }
static int ext_cmp | ( | const char * | a, | |
const char * | b | |||
) | [static] |
the full routine to compare extensions in rules.
Definition at line 768 of file pbx.c.
References ext_cmp1().
Referenced by ast_add_extension2().
00769 { 00770 /* make sure non-patterns come first. 00771 * If a is not a pattern, it either comes first or 00772 * we do a more complex pattern comparison. 00773 */ 00774 int ret = 0; 00775 00776 if (a[0] != '_') 00777 return (b[0] == '_') ? -1 : strcmp(a, b); 00778 00779 /* Now we know a is a pattern; if b is not, a comes first */ 00780 if (b[0] != '_') 00781 return 1; 00782 00783 /* ok we need full pattern sorting routine. 00784 * skip past the underscores */ 00785 ++a; ++b; 00786 do { 00787 unsigned char bitwise[2][32] = { { 0, } }; 00788 ret = ext_cmp1(&a, bitwise[0]) - ext_cmp1(&b, bitwise[1]); 00789 if (ret == 0) { 00790 /* Are the classes different, even though they score the same? */ 00791 ret = memcmp(bitwise[0], bitwise[1], 32); 00792 } 00793 } while (!ret && a && b); 00794 if (ret == 0) { 00795 return 0; 00796 } else { 00797 return (ret > 0) ? 1 : -1; 00798 } 00799 }
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 687 of file pbx.c.
References ast_log(), and LOG_WARNING.
Referenced by ext_cmp().
00688 { 00689 int c, cmin = 0xff, count = 0; 00690 const char *end; 00691 00692 /* load value and advance pointer */ 00693 while ( (c = *(*p)++) && (c == ' ' || c == '-') ) 00694 ; /* ignore some characters */ 00695 00696 /* always return unless we have a set of chars */ 00697 switch (c) { 00698 default: /* ordinary character */ 00699 bitwise[c / 8] = 1 << (c % 8); 00700 return 0x0100 | (c & 0xff); 00701 00702 case 'N': /* 2..9 */ 00703 bitwise[6] = 0xfc; 00704 bitwise[7] = 0x03; 00705 return 0x0800 | '2'; 00706 00707 case 'X': /* 0..9 */ 00708 bitwise[6] = 0xff; 00709 bitwise[7] = 0x03; 00710 return 0x0A00 | '0'; 00711 00712 case 'Z': /* 1..9 */ 00713 bitwise[6] = 0xfe; 00714 bitwise[7] = 0x03; 00715 return 0x0900 | '1'; 00716 00717 case '.': /* wildcard */ 00718 return 0x10000; 00719 00720 case '!': /* earlymatch */ 00721 return 0x20000; /* less specific than NULL */ 00722 00723 case '\0': /* empty string */ 00724 *p = NULL; 00725 return 0x30000; 00726 00727 case '[': /* pattern */ 00728 break; 00729 } 00730 /* locate end of set */ 00731 end = strchr(*p, ']'); 00732 00733 if (end == NULL) { 00734 ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n"); 00735 return 0x40000; /* XXX make this entry go last... */ 00736 } 00737 00738 for (; *p < end ; (*p)++) { 00739 unsigned char c1, c2; /* first-last char in range */ 00740 c1 = (unsigned char)((*p)[0]); 00741 if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */ 00742 c2 = (unsigned char)((*p)[2]); 00743 *p += 2; /* skip a total of 3 chars */ 00744 } else { /* individual character */ 00745 c2 = c1; 00746 } 00747 if (c1 < cmin) { 00748 cmin = c1; 00749 } 00750 for (; c1 <= c2; c1++) { 00751 unsigned char mask = 1 << (c1 % 8); 00752 /*!\note If two patterns score the same, the one with the lowest 00753 * ascii values will compare as coming first. */ 00754 /* Flag the character as included (used) and count it. */ 00755 if (!(bitwise[ c1 / 8 ] & mask)) { 00756 bitwise[ c1 / 8 ] |= mask; 00757 count += 0x100; 00758 } 00759 } 00760 } 00761 (*p)++; 00762 return count == 0 ? 0x30000 : (count | cmin); 00763 }
static int ext_strncpy | ( | char * | dst, | |
const char * | src, | |||
int | len | |||
) | [static] |
copy a string skipping whitespace
Definition at line 4784 of file pbx.c.
Referenced by ast_add_extension2().
04785 { 04786 int count=0; 04787 04788 while (*src && (count < len - 1)) { 04789 switch(*src) { 04790 case ' ': 04791 /* otherwise exten => [a-b],1,... doesn't work */ 04792 /* case '-': */ 04793 /* Ignore */ 04794 break; 04795 default: 04796 *dst = *src; 04797 dst++; 04798 } 04799 src++; 04800 count++; 04801 } 04802 *dst = '\0'; 04803 04804 return count; 04805 }
static int extension_match_core | ( | const char * | pattern, | |
const char * | data, | |||
enum ext_match_t | mode | |||
) | [static] |
Definition at line 924 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().
00925 { 00926 int i; 00927 static int prof_id = -2; /* marker for 'unallocated' id */ 00928 if (prof_id == -2) 00929 prof_id = ast_add_profile("ext_match", 0); 00930 ast_mark(prof_id, 1); 00931 i = _extension_match_core(pattern, data, mode); 00932 ast_mark(prof_id, 0); 00933 return i; 00934 }
static struct ast_context* find_context_locked | ( | const char * | context | ) | [static] |
Definition at line 2784 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().
02785 { 02786 struct ast_context *c = NULL; 02787 02788 ast_rdlock_contexts(); 02789 while ( (c = ast_walk_contexts(c)) ) { 02790 if (!strcmp(ast_get_context_name(c), context)) 02791 return c; 02792 } 02793 ast_unlock_contexts(); 02794 02795 return NULL; 02796 }
static int find_hint_by_cb_id | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2187 of file pbx.c.
References ast_hint::callbacks, ast_state_cb::id, and ast_state_cb::next.
02188 { 02189 const struct ast_hint *hint = obj; 02190 int *id = arg; 02191 struct ast_state_cb *cb; 02192 02193 for (cb = hint->callbacks; cb; cb = cb->next) { 02194 if (cb->id == *id) { 02195 return CMP_MATCH | CMP_STOP; 02196 } 02197 } 02198 02199 return 0; 02200 }
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 1583 of file pbx.c.
References ast_log(), and LOG_WARNING.
Referenced by ast_func_read(), and ast_func_write().
01584 { 01585 char *args = strchr(function, '('); 01586 01587 if (!args) 01588 ast_log(LOG_WARNING, "Function '%s' doesn't contain parentheses. Assuming null argument.\n", function); 01589 else { 01590 char *p; 01591 *args++ = '\0'; 01592 if ((p = strrchr(args, ')')) ) 01593 *p = '\0'; 01594 else 01595 ast_log(LOG_WARNING, "Can't find trailing parenthesis for function '%s(%s'?\n", function, args); 01596 } 01597 return args; 01598 }
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 4225 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and lookup_name().
Referenced by ast_build_timing().
04226 { 04227 int start, end; /* start and ending position */ 04228 unsigned int mask = 0; 04229 char *part; 04230 04231 /* Check for whole range */ 04232 if (ast_strlen_zero(src) || !strcmp(src, "*")) { 04233 return (1 << max) - 1; 04234 } 04235 04236 while ((part = strsep(&src, "&"))) { 04237 /* Get start and ending position */ 04238 char *endpart = strchr(part, '-'); 04239 if (endpart) { 04240 *endpart++ = '\0'; 04241 } 04242 /* Find the start */ 04243 if ((start = lookup_name(part, names, max)) < 0) { 04244 ast_log(LOG_WARNING, "Invalid %s '%s', skipping element\n", msg, part); 04245 continue; 04246 } 04247 if (endpart) { /* find end of range */ 04248 if ((end = lookup_name(endpart, names, max)) < 0) { 04249 ast_log(LOG_WARNING, "Invalid end %s '%s', skipping element\n", msg, endpart); 04250 continue; 04251 } 04252 } else { 04253 end = start; 04254 } 04255 /* Fill the mask. Remember that ranges are cyclic */ 04256 mask |= (1 << end); /* initialize with last element */ 04257 while (start != end) { 04258 mask |= (1 << start); 04259 if (++start >= max) { 04260 start = 0; 04261 } 04262 } 04263 } 04264 return mask; 04265 }
static void get_timerange | ( | struct ast_timing * | i, | |
char * | times | |||
) | [static] |
store a bitmask of valid times, one bit each 1 minute
Definition at line 4268 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask.
Referenced by ast_build_timing().
04269 { 04270 char *endpart, *part; 04271 int x; 04272 int st_h, st_m; 04273 int endh, endm; 04274 int minute_start, minute_end; 04275 04276 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 04277 memset(i->minmask, 0, sizeof(i->minmask)); 04278 04279 /* 1-minute per bit */ 04280 /* Star is all times */ 04281 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 04282 /* 48, because each hour takes 2 integers; 30 bits each */ 04283 for (x = 0; x < 48; x++) { 04284 i->minmask[x] = 0x3fffffff; /* 30 bits */ 04285 } 04286 return; 04287 } 04288 /* Otherwise expect a range */ 04289 while ((part = strsep(×, "&"))) { 04290 if (!(endpart = strchr(part, '-'))) { 04291 if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) { 04292 ast_log(LOG_WARNING, "%s isn't a valid time.\n", part); 04293 continue; 04294 } 04295 i->minmask[st_h * 2 + (st_m >= 30 ? 1 : 0)] |= (1 << (st_m % 30)); 04296 continue; 04297 } 04298 *endpart++ = '\0'; 04299 /* why skip non digits? Mostly to skip spaces */ 04300 while (*endpart && !isdigit(*endpart)) { 04301 endpart++; 04302 } 04303 if (!*endpart) { 04304 ast_log(LOG_WARNING, "Invalid time range starting with '%s-'.\n", part); 04305 continue; 04306 } 04307 if (sscanf(part, "%2d:%2d", &st_h, &st_m) != 2 || st_h < 0 || st_h > 23 || st_m < 0 || st_m > 59) { 04308 ast_log(LOG_WARNING, "'%s' isn't a valid start time.\n", part); 04309 continue; 04310 } 04311 if (sscanf(endpart, "%2d:%2d", &endh, &endm) != 2 || endh < 0 || endh > 23 || endm < 0 || endm > 59) { 04312 ast_log(LOG_WARNING, "'%s' isn't a valid end time.\n", endpart); 04313 continue; 04314 } 04315 minute_start = st_h * 60 + st_m; 04316 minute_end = endh * 60 + endm; 04317 /* Go through the time and enable each appropriate bit */ 04318 for (x = minute_start; x != minute_end; x = (x + 1) % (24 * 60)) { 04319 i->minmask[x / 30] |= (1 << (x % 30)); 04320 } 04321 /* Do the last one */ 04322 i->minmask[x / 30] |= (1 << (x % 30)); 04323 } 04324 /* All done */ 04325 return; 04326 }
static int handle_set_global | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3855 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03856 { 03857 if (argc != 5) 03858 return RESULT_SHOWUSAGE; 03859 03860 pbx_builtin_setvar_helper(NULL, argv[3], argv[4]); 03861 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[3], argv[4]); 03862 03863 return RESULT_SUCCESS; 03864 }
static int handle_set_global_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI support for setting global variables.
Definition at line 3843 of file pbx.c.
References ast_cli(), pbx_builtin_setvar_helper(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03844 { 03845 if (argc != 4) 03846 return RESULT_SHOWUSAGE; 03847 03848 pbx_builtin_setvar_helper(NULL, argv[2], argv[3]); 03849 ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[2], argv[3]); 03850 03851 return RESULT_SUCCESS; 03852 }
static int handle_show_application | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3281 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().
03282 { 03283 struct ast_app *a; 03284 int app, no_registered_app = 1; 03285 03286 if (argc < 4) 03287 return RESULT_SHOWUSAGE; 03288 03289 /* ... go through all applications ... */ 03290 AST_LIST_LOCK(&apps); 03291 AST_LIST_TRAVERSE(&apps, a, list) { 03292 /* ... compare this application name with all arguments given 03293 * to 'show application' command ... */ 03294 for (app = 3; app < argc; app++) { 03295 if (!strcasecmp(a->name, argv[app])) { 03296 /* Maximum number of characters added by terminal coloring is 22 */ 03297 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03298 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03299 int synopsis_size, description_size; 03300 03301 no_registered_app = 0; 03302 03303 if (a->synopsis) 03304 synopsis_size = strlen(a->synopsis) + 23; 03305 else 03306 synopsis_size = strlen("Not available") + 23; 03307 synopsis = alloca(synopsis_size); 03308 03309 if (a->description) 03310 description_size = strlen(a->description) + 23; 03311 else 03312 description_size = strlen("Not available") + 23; 03313 description = alloca(description_size); 03314 03315 if (synopsis && description) { 03316 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03317 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03318 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03319 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03320 term_color(synopsis, 03321 a->synopsis ? a->synopsis : "Not available", 03322 COLOR_CYAN, 0, synopsis_size); 03323 term_color(description, 03324 a->description ? a->description : "Not available", 03325 COLOR_CYAN, 0, description_size); 03326 03327 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03328 } else { 03329 /* ... one of our applications, show info ...*/ 03330 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03331 "[Synopsis]\n %s\n\n" 03332 "[Description]\n%s\n", 03333 a->name, 03334 a->synopsis ? a->synopsis : "Not available", 03335 a->description ? a->description : "Not available"); 03336 } 03337 } 03338 } 03339 } 03340 AST_LIST_UNLOCK(&apps); 03341 03342 /* we found at least one app? no? */ 03343 if (no_registered_app) { 03344 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03345 return RESULT_FAILURE; 03346 } 03347 03348 return RESULT_SUCCESS; 03349 }
static int handle_show_application_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3211 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().
03212 { 03213 struct ast_app *a; 03214 int app, no_registered_app = 1; 03215 03216 if (argc < 3) 03217 return RESULT_SHOWUSAGE; 03218 03219 /* ... go through all applications ... */ 03220 AST_LIST_LOCK(&apps); 03221 AST_LIST_TRAVERSE(&apps, a, list) { 03222 /* ... compare this application name with all arguments given 03223 * to 'show application' command ... */ 03224 for (app = 2; app < argc; app++) { 03225 if (!strcasecmp(a->name, argv[app])) { 03226 /* Maximum number of characters added by terminal coloring is 22 */ 03227 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03228 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03229 int synopsis_size, description_size; 03230 03231 no_registered_app = 0; 03232 03233 if (a->synopsis) 03234 synopsis_size = strlen(a->synopsis) + 23; 03235 else 03236 synopsis_size = strlen("Not available") + 23; 03237 synopsis = alloca(synopsis_size); 03238 03239 if (a->description) 03240 description_size = strlen(a->description) + 23; 03241 else 03242 description_size = strlen("Not available") + 23; 03243 description = alloca(description_size); 03244 03245 if (synopsis && description) { 03246 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03247 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03248 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03249 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03250 term_color(synopsis, 03251 a->synopsis ? a->synopsis : "Not available", 03252 COLOR_CYAN, 0, synopsis_size); 03253 term_color(description, 03254 a->description ? a->description : "Not available", 03255 COLOR_CYAN, 0, description_size); 03256 03257 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03258 } else { 03259 /* ... one of our applications, show info ...*/ 03260 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03261 "[Synopsis]\n %s\n\n" 03262 "[Description]\n%s\n", 03263 a->name, 03264 a->synopsis ? a->synopsis : "Not available", 03265 a->description ? a->description : "Not available"); 03266 } 03267 } 03268 } 03269 } 03270 AST_LIST_UNLOCK(&apps); 03271 03272 /* we found at least one app? no? */ 03273 if (no_registered_app) { 03274 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03275 return RESULT_FAILURE; 03276 } 03277 03278 return RESULT_SUCCESS; 03279 }
static int handle_show_applications | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3481 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.
03482 { 03483 struct ast_app *a; 03484 int like = 0, describing = 0; 03485 int total_match = 0; /* Number of matches in like clause */ 03486 int total_apps = 0; /* Number of apps registered */ 03487 03488 AST_LIST_LOCK(&apps); 03489 03490 if (AST_LIST_EMPTY(&apps)) { 03491 ast_cli(fd, "There are no registered applications\n"); 03492 AST_LIST_UNLOCK(&apps); 03493 return -1; 03494 } 03495 03496 /* core list applications like <keyword> */ 03497 if ((argc == 5) && (!strcmp(argv[3], "like"))) { 03498 like = 1; 03499 } else if ((argc > 4) && (!strcmp(argv[3], "describing"))) { 03500 describing = 1; 03501 } 03502 03503 /* core list applications describing <keyword1> [<keyword2>] [...] */ 03504 if ((!like) && (!describing)) { 03505 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03506 } else { 03507 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03508 } 03509 03510 AST_LIST_TRAVERSE(&apps, a, list) { 03511 int printapp = 0; 03512 total_apps++; 03513 if (like) { 03514 if (strcasestr(a->name, argv[4])) { 03515 printapp = 1; 03516 total_match++; 03517 } 03518 } else if (describing) { 03519 if (a->description) { 03520 /* Match all words on command line */ 03521 int i; 03522 printapp = 1; 03523 for (i = 4; i < argc; i++) { 03524 if (!strcasestr(a->description, argv[i])) { 03525 printapp = 0; 03526 } else { 03527 total_match++; 03528 } 03529 } 03530 } 03531 } else { 03532 printapp = 1; 03533 } 03534 03535 if (printapp) { 03536 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03537 } 03538 } 03539 if ((!like) && (!describing)) { 03540 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03541 } else { 03542 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03543 } 03544 03545 AST_LIST_UNLOCK(&apps); 03546 03547 return RESULT_SUCCESS; 03548 }
static int handle_show_applications_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3413 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.
03414 { 03415 struct ast_app *a; 03416 int like = 0, describing = 0; 03417 int total_match = 0; /* Number of matches in like clause */ 03418 int total_apps = 0; /* Number of apps registered */ 03419 03420 AST_LIST_LOCK(&apps); 03421 03422 if (AST_LIST_EMPTY(&apps)) { 03423 ast_cli(fd, "There are no registered applications\n"); 03424 AST_LIST_UNLOCK(&apps); 03425 return -1; 03426 } 03427 03428 /* show applications like <keyword> */ 03429 if ((argc == 4) && (!strcmp(argv[2], "like"))) { 03430 like = 1; 03431 } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { 03432 describing = 1; 03433 } 03434 03435 /* show applications describing <keyword1> [<keyword2>] [...] */ 03436 if ((!like) && (!describing)) { 03437 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03438 } else { 03439 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03440 } 03441 03442 AST_LIST_TRAVERSE(&apps, a, list) { 03443 int printapp = 0; 03444 total_apps++; 03445 if (like) { 03446 if (strcasestr(a->name, argv[3])) { 03447 printapp = 1; 03448 total_match++; 03449 } 03450 } else if (describing) { 03451 if (a->description) { 03452 /* Match all words on command line */ 03453 int i; 03454 printapp = 1; 03455 for (i = 3; i < argc; i++) { 03456 if (!strcasestr(a->description, argv[i])) { 03457 printapp = 0; 03458 } else { 03459 total_match++; 03460 } 03461 } 03462 } 03463 } else { 03464 printapp = 1; 03465 } 03466 03467 if (printapp) { 03468 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03469 } 03470 } 03471 if ((!like) && (!describing)) { 03472 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03473 } else { 03474 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03475 } 03476 03477 AST_LIST_UNLOCK(&apps); 03478 03479 return RESULT_SUCCESS; 03480 }
static int handle_show_dialplan | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3770 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().
03771 { 03772 char *exten = NULL, *context = NULL; 03773 /* Variables used for different counters */ 03774 struct dialplan_counters counters; 03775 03776 const char *incstack[AST_PBX_MAX_STACK]; 03777 memset(&counters, 0, sizeof(counters)); 03778 03779 if (argc != 2 && argc != 3) 03780 return RESULT_SHOWUSAGE; 03781 03782 /* we obtain [exten@]context? if yes, split them ... */ 03783 if (argc == 3) { 03784 if (strchr(argv[2], '@')) { /* split into exten & context */ 03785 context = ast_strdupa(argv[2]); 03786 exten = strsep(&context, "@"); 03787 /* change empty strings to NULL */ 03788 if (ast_strlen_zero(exten)) 03789 exten = NULL; 03790 } else { /* no '@' char, only context given */ 03791 context = argv[2]; 03792 } 03793 if (ast_strlen_zero(context)) 03794 context = NULL; 03795 } 03796 /* else Show complete dial plan, context and exten are NULL */ 03797 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03798 03799 /* check for input failure and throw some error messages */ 03800 if (context && !counters.context_existence) { 03801 ast_cli(fd, "There is no existence of '%s' context\n", context); 03802 return RESULT_FAILURE; 03803 } 03804 03805 if (exten && !counters.extension_existence) { 03806 if (context) 03807 ast_cli(fd, "There is no existence of %s@%s extension\n", 03808 exten, context); 03809 else 03810 ast_cli(fd, 03811 "There is no existence of '%s' extension in all contexts\n", 03812 exten); 03813 return RESULT_FAILURE; 03814 } 03815 03816 ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", 03817 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions", 03818 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities", 03819 counters.total_context, counters.total_context == 1 ? "context" : "contexts"); 03820 03821 /* everything ok */ 03822 return RESULT_SUCCESS; 03823 }
static int handle_show_function | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1434 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().
01435 { 01436 struct ast_custom_function *acf; 01437 /* Maximum number of characters added by terminal coloring is 22 */ 01438 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01439 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01440 char stxtitle[40], *syntax = NULL; 01441 int synopsis_size, description_size, syntax_size; 01442 01443 if (argc < 4) 01444 return RESULT_SHOWUSAGE; 01445 01446 if (!(acf = ast_custom_function_find(argv[3]))) { 01447 ast_cli(fd, "No function by that name registered.\n"); 01448 return RESULT_FAILURE; 01449 01450 } 01451 01452 if (acf->synopsis) 01453 synopsis_size = strlen(acf->synopsis) + 23; 01454 else 01455 synopsis_size = strlen("Not available") + 23; 01456 synopsis = alloca(synopsis_size); 01457 01458 if (acf->desc) 01459 description_size = strlen(acf->desc) + 23; 01460 else 01461 description_size = strlen("Not available") + 23; 01462 description = alloca(description_size); 01463 01464 if (acf->syntax) 01465 syntax_size = strlen(acf->syntax) + 23; 01466 else 01467 syntax_size = strlen("Not available") + 23; 01468 syntax = alloca(syntax_size); 01469 01470 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01471 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01472 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01473 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01474 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01475 term_color(syntax, 01476 acf->syntax ? acf->syntax : "Not available", 01477 COLOR_CYAN, 0, syntax_size); 01478 term_color(synopsis, 01479 acf->synopsis ? acf->synopsis : "Not available", 01480 COLOR_CYAN, 0, synopsis_size); 01481 term_color(description, 01482 acf->desc ? acf->desc : "Not available", 01483 COLOR_CYAN, 0, description_size); 01484 01485 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01486 01487 return RESULT_SUCCESS; 01488 }
static int handle_show_function_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1378 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().
01379 { 01380 struct ast_custom_function *acf; 01381 /* Maximum number of characters added by terminal coloring is 22 */ 01382 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01383 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01384 char stxtitle[40], *syntax = NULL; 01385 int synopsis_size, description_size, syntax_size; 01386 01387 if (argc < 3) 01388 return RESULT_SHOWUSAGE; 01389 01390 if (!(acf = ast_custom_function_find(argv[2]))) { 01391 ast_cli(fd, "No function by that name registered.\n"); 01392 return RESULT_FAILURE; 01393 01394 } 01395 01396 if (acf->synopsis) 01397 synopsis_size = strlen(acf->synopsis) + 23; 01398 else 01399 synopsis_size = strlen("Not available") + 23; 01400 synopsis = alloca(synopsis_size); 01401 01402 if (acf->desc) 01403 description_size = strlen(acf->desc) + 23; 01404 else 01405 description_size = strlen("Not available") + 23; 01406 description = alloca(description_size); 01407 01408 if (acf->syntax) 01409 syntax_size = strlen(acf->syntax) + 23; 01410 else 01411 syntax_size = strlen("Not available") + 23; 01412 syntax = alloca(syntax_size); 01413 01414 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01415 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01416 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01417 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01418 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01419 term_color(syntax, 01420 acf->syntax ? acf->syntax : "Not available", 01421 COLOR_CYAN, 0, syntax_size); 01422 term_color(synopsis, 01423 acf->synopsis ? acf->synopsis : "Not available", 01424 COLOR_CYAN, 0, synopsis_size); 01425 term_color(description, 01426 acf->desc ? acf->desc : "Not available", 01427 COLOR_CYAN, 0, description_size); 01428 01429 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01430 01431 return RESULT_SUCCESS; 01432 }
static int handle_show_functions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1350 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.
01351 { 01352 struct ast_custom_function *acf; 01353 int count_acf = 0; 01354 int like = 0; 01355 01356 if (argc == 5 && (!strcmp(argv[3], "like")) ) { 01357 like = 1; 01358 } else if (argc != 3) { 01359 return RESULT_SHOWUSAGE; 01360 } 01361 01362 ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed"); 01363 01364 AST_LIST_LOCK(&acf_root); 01365 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01366 if (!like || strstr(acf->name, argv[4])) { 01367 count_acf++; 01368 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01369 } 01370 } 01371 AST_LIST_UNLOCK(&acf_root); 01372 01373 ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : ""); 01374 01375 return RESULT_SUCCESS; 01376 }
static int handle_show_functions_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1323 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.
01324 { 01325 struct ast_custom_function *acf; 01326 int count_acf = 0; 01327 int like = 0; 01328 01329 if (argc == 4 && (!strcmp(argv[2], "like")) ) { 01330 like = 1; 01331 } else if (argc != 2) { 01332 return RESULT_SHOWUSAGE; 01333 } 01334 01335 ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed"); 01336 01337 AST_LIST_LOCK(&acf_root); 01338 AST_LIST_TRAVERSE(&acf_root, acf, acflist) { 01339 if (!like || strstr(acf->name, argv[3])) { 01340 count_acf++; 01341 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01342 } 01343 } 01344 AST_LIST_UNLOCK(&acf_root); 01345 01346 ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : ""); 01347 01348 return RESULT_SUCCESS; 01349 }
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 3826 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.
03827 { 03828 int i = 0; 03829 struct ast_var_t *newvariable; 03830 03831 ast_mutex_lock(&globalslock); 03832 AST_LIST_TRAVERSE (&globals, newvariable, entries) { 03833 i++; 03834 ast_cli(fd, " %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable)); 03835 } 03836 ast_mutex_unlock(&globalslock); 03837 ast_cli(fd, "\n -- %d variables\n", i); 03838 03839 return RESULT_SUCCESS; 03840 }
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 3352 of file pbx.c.
References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ao2_ref(), ast_cli(), ast_extension_state2str(), ast_get_context_name(), ast_get_extension_app(), ast_get_extension_context(), ast_get_extension_name(), ast_hint::callbacks, ast_hint::exten, hints, ast_hint::laststate, ast_state_cb::next, and RESULT_SUCCESS.
03353 { 03354 struct ast_hint *hint; 03355 int num = 0; 03356 int watchers; 03357 struct ast_state_cb *watcher; 03358 struct ao2_iterator i; 03359 03360 if (ao2_container_count(hints) == 0) { 03361 ast_cli(fd, "There are no registered dialplan hints\n"); 03362 return RESULT_SUCCESS; 03363 } 03364 03365 ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); 03366 03367 i = ao2_iterator_init(hints, 0); 03368 for (hint = ao2_iterator_next(&i); hint; ao2_ref(hint, -1), hint = ao2_iterator_next(&i)) { 03369 watchers = 0; 03370 for (watcher = hint->callbacks; watcher; watcher = watcher->next) { 03371 watchers++; 03372 } 03373 ast_cli(fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", 03374 ast_get_extension_name(hint->exten), 03375 ast_get_context_name(ast_get_extension_context(hint->exten)), 03376 ast_get_extension_app(hint->exten), 03377 ast_extension_state2str(hint->laststate), watchers); 03378 num++; 03379 } 03380 ao2_iterator_destroy(&i); 03381 03382 ast_cli(fd, "----------------\n"); 03383 ast_cli(fd, "- %d hints registered\n", num); 03384 03385 return RESULT_SUCCESS; 03386 }
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 3389 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.
03390 { 03391 struct ast_switch *sw; 03392 03393 AST_LIST_LOCK(&switches); 03394 03395 if (AST_LIST_EMPTY(&switches)) { 03396 AST_LIST_UNLOCK(&switches); 03397 ast_cli(fd, "There are no registered alternative switches\n"); 03398 return RESULT_SUCCESS; 03399 } 03400 03401 ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); 03402 AST_LIST_TRAVERSE(&switches, sw, list) 03403 ast_cli(fd, "%s: %s\n", sw->name, sw->description); 03404 03405 AST_LIST_UNLOCK(&switches); 03406 03407 return RESULT_SUCCESS; 03408 }
static int hint_cmp | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 6673 of file pbx.c.
References exten, and ast_hint::exten.
Referenced by ast_pbx_init().
06674 { 06675 const struct ast_hint *hint = obj; 06676 const struct ast_exten *exten = arg; 06677 06678 return (hint->exten == exten) ? CMP_MATCH | CMP_STOP : 0; 06679 }
static int hint_hash | ( | const void * | hint, | |
const int | flags | |||
) | [static] |
static int include_valid | ( | struct ast_include * | i | ) | [inline, static] |
Definition at line 617 of file pbx.c.
References ast_check_timing(), ast_include::hastime, and ast_include::timing.
00618 { 00619 if (!i->hastime) 00620 return 1; 00621 00622 return ast_check_timing(&(i->timing)); 00623 }
static int increase_call_count | ( | const struct ast_channel * | c | ) | [static] |
Definition at line 2659 of file pbx.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_NOTICE, maxcalllock, ast_channel::name, option_maxcalls, and option_maxload.
Referenced by ast_pbx_run(), and ast_pbx_start().
02660 { 02661 int failed = 0; 02662 double curloadavg; 02663 ast_mutex_lock(&maxcalllock); 02664 if (option_maxcalls) { 02665 if (countcalls >= option_maxcalls) { 02666 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name); 02667 failed = -1; 02668 } 02669 } 02670 if (option_maxload) { 02671 getloadavg(&curloadavg, 1); 02672 if (curloadavg >= option_maxload) { 02673 ast_log(LOG_NOTICE, "Maximum loadavg limit of %f load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg); 02674 failed = -1; 02675 } 02676 } 02677 if (!failed) { 02678 countcalls++; 02679 totalcalls++; 02680 } 02681 ast_mutex_unlock(&maxcalllock); 02682 02683 return failed; 02684 }
int load_pbx | ( | void | ) |
Provided by pbx.c
Definition at line 6365 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().
06366 { 06367 int x; 06368 06369 /* Initialize the PBX */ 06370 if (option_verbose) { 06371 ast_verbose( "Asterisk PBX Core Initializing\n"); 06372 ast_verbose( "Registering builtin applications:\n"); 06373 } 06374 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(struct ast_cli_entry)); 06375 06376 /* Register builtin applications */ 06377 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06378 if (option_verbose) 06379 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06380 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06381 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06382 return -1; 06383 } 06384 } 06385 return 0; 06386 }
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 4203 of file pbx.c.
Referenced by get_range().
04204 { 04205 int i; 04206 04207 if (names && *s > '9') { 04208 for (i = 0; names[i]; i++) { 04209 if (!strcasecmp(s, names[i])) { 04210 return i; 04211 } 04212 } 04213 } 04214 /* Allow months and weekdays to be specified as numbers, as well */ 04215 if (sscanf(s, "%2d", &i) == 1 && i >= 1 && i <= max) { 04216 /* What the array offset would have been: "1" would be at offset 0 */ 04217 return i - 1; 04218 } 04219 return -1; /* error return */ 04220 }
static int matchcid | ( | const char * | cidpattern, | |
const char * | callerid | |||
) | [static] |
Definition at line 970 of file pbx.c.
References ast_extension_match(), and ast_strlen_zero().
Referenced by pbx_find_extension().
00971 { 00972 /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so 00973 failing to get a number should count as a match, otherwise not */ 00974 00975 if (ast_strlen_zero(callerid)) 00976 return ast_strlen_zero(cidpattern) ? 1 : 0; 00977 00978 return ast_extension_match(cidpattern, callerid); 00979 }
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 1136 of file pbx.c.
Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
01137 { 01138 int parens=0; 01139 01140 *offset = 0; 01141 *length = INT_MAX; 01142 *isfunc = 0; 01143 for (; *var; var++) { 01144 if (*var == '(') { 01145 (*isfunc)++; 01146 parens++; 01147 } else if (*var == ')') { 01148 parens--; 01149 } else if (*var == ':' && parens == 0) { 01150 *var++ = '\0'; 01151 sscanf(var, "%30d:%30d", offset, length); 01152 return 1; /* offset:length valid */ 01153 } 01154 } 01155 return 0; 01156 }
void pbx_builtin_clear_globals | ( | void | ) |
Definition at line 6167 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().
06168 { 06169 struct ast_var_t *vardata; 06170 06171 ast_mutex_lock(&globalslock); 06172 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06173 ast_var_delete(vardata); 06174 ast_mutex_unlock(&globalslock); 06175 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5943 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_check(), 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().
05944 { 05945 struct ast_var_t *variables; 05946 const char *ret = NULL; 05947 int i; 05948 struct varshead *places[2] = { NULL, &globals }; 05949 05950 if (!name) 05951 return NULL; 05952 05953 if (chan) { 05954 ast_channel_lock(chan); 05955 places[0] = &chan->varshead; 05956 } 05957 05958 for (i = 0; i < 2; i++) { 05959 if (!places[i]) 05960 continue; 05961 if (places[i] == &globals) 05962 ast_mutex_lock(&globalslock); 05963 AST_LIST_TRAVERSE(places[i], variables, entries) { 05964 if (!strcmp(name, ast_var_name(variables))) { 05965 ret = ast_var_value(variables); 05966 break; 05967 } 05968 } 05969 if (places[i] == &globals) 05970 ast_mutex_unlock(&globalslock); 05971 if (ret) 05972 break; 05973 } 05974 05975 if (chan) 05976 ast_channel_unlock(chan); 05977 05978 return ret; 05979 }
static int pbx_builtin_gotoif | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6187 of file pbx.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_goto(), and pbx_checkcondition().
06188 { 06189 char *condition, *branch1, *branch2, *branch; 06190 int rc; 06191 char *stringp; 06192 06193 if (ast_strlen_zero(data)) { 06194 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06195 return 0; 06196 } 06197 06198 stringp = ast_strdupa(data); 06199 condition = strsep(&stringp,"?"); 06200 branch1 = strsep(&stringp,":"); 06201 branch2 = strsep(&stringp,""); 06202 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06203 06204 if (ast_strlen_zero(branch)) { 06205 if (option_debug) 06206 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06207 return 0; 06208 } 06209 06210 rc = pbx_builtin_goto(chan, branch); 06211 06212 return rc; 06213 }
int pbx_builtin_importvar | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6106 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.
06107 { 06108 char *name; 06109 char *value; 06110 char *channel; 06111 char tmp[VAR_BUF_SIZE]=""; 06112 06113 if (ast_strlen_zero(data)) { 06114 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06115 return 0; 06116 } 06117 06118 value = ast_strdupa(data); 06119 name = strsep(&value,"="); 06120 channel = strsep(&value,"|"); 06121 if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */ 06122 struct ast_channel *chan2 = ast_get_channel_by_name_locked(channel); 06123 if (chan2) { 06124 char *s = alloca(strlen(value) + 4); 06125 if (s) { 06126 sprintf(s, "${%s}", value); 06127 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 06128 } 06129 ast_channel_unlock(chan2); 06130 } 06131 pbx_builtin_setvar_helper(chan, name, tmp); 06132 } 06133 06134 return(0); 06135 }
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 5981 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().
05982 { 05983 struct ast_var_t *newvariable; 05984 struct varshead *headp; 05985 05986 if (name[strlen(name)-1] == ')') { 05987 char *function = ast_strdupa(name); 05988 05989 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05990 ast_func_write(chan, function, value); 05991 return; 05992 } 05993 05994 if (chan) { 05995 ast_channel_lock(chan); 05996 headp = &chan->varshead; 05997 } else { 05998 ast_mutex_lock(&globalslock); 05999 headp = &globals; 06000 } 06001 06002 if (value) { 06003 if ((option_verbose > 1) && (headp == &globals)) 06004 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 06005 newvariable = ast_var_assign(name, value); 06006 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 06007 } 06008 06009 if (chan) 06010 ast_channel_unlock(chan); 06011 else 06012 ast_mutex_unlock(&globalslock); 06013 }
static int pbx_builtin_saycharacters | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6252 of file pbx.c.
References ast_say_character_str(), and ast_channel::language.
06253 { 06254 int res = 0; 06255 06256 if (data) 06257 res = ast_say_character_str(chan, data, "", chan->language); 06258 return res; 06259 }
static int pbx_builtin_saydate | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6270 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().
06271 { 06272 int res = 0; 06273 char *parse; 06274 int unixdate = 0; 06275 char charascii[2]; 06276 06277 AST_DECLARE_APP_ARGS(args, 06278 AST_APP_ARG(datestr); 06279 AST_APP_ARG(digits); 06280 ); 06281 06282 06283 if (ast_strlen_zero(data)) { 06284 ast_log(LOG_WARNING, "SayDate requires an argument (date)\n"); 06285 return -1; 06286 } 06287 06288 if (!(parse = ast_strdupa(data))) { 06289 ast_log(LOG_WARNING, "Memory Error!\n"); 06290 return -1; 06291 } 06292 06293 AST_STANDARD_APP_ARGS(args, parse); 06294 06295 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06296 ast_log(LOG_WARNING, "SayDate escape digits must be a subset from '0123456789*#'\n"); 06297 args.digits = ""; 06298 } 06299 06300 if (sscanf(args.datestr, "%d", &unixdate) != 1) { 06301 ast_log(LOG_WARNING, "Firt argument to SayDate must be numeric (date)\n"); 06302 return -1; 06303 } 06304 06305 res = ast_say_date(chan, (time_t)unixdate, args.digits, chan->language); 06306 if (res > 0) { 06307 if (isdigit(res) || (res == '*') || (res == '#')) { 06308 snprintf(charascii, 2, "%c", res); 06309 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06310 res = 0; 06311 } else { 06312 ast_log(LOG_WARNING, "SayDate: invalid return value (%d) detected\n", res); 06313 } 06314 } 06315 return res; 06316 }
static int pbx_builtin_saydigits | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6243 of file pbx.c.
References ast_say_digit_str(), and ast_channel::language.
06244 { 06245 int res = 0; 06246 06247 if (data) 06248 res = ast_say_digit_str(chan, data, "", chan->language); 06249 return res; 06250 }
static int pbx_builtin_saynumber | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6215 of file pbx.c.
References ast_copy_string(), ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, and LOG_WARNING.
06216 { 06217 char tmp[256]; 06218 char *number = tmp; 06219 char *options; 06220 06221 if (ast_strlen_zero(data)) { 06222 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06223 return -1; 06224 } 06225 ast_copy_string(tmp, data, sizeof(tmp)); 06226 strsep(&number, "|"); 06227 options = strsep(&number, "|"); 06228 if (options) { 06229 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06230 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06231 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06232 return -1; 06233 } 06234 } 06235 06236 if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) { 06237 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp); 06238 } 06239 06240 return 0; 06241 }
static int pbx_builtin_sayphonetic | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6261 of file pbx.c.
References ast_say_phonetic_str(), and ast_channel::language.
06262 { 06263 int res = 0; 06264 06265 if (data) 06266 res = ast_say_phonetic_str(chan, data, "", chan->language); 06267 return res; 06268 }
static int pbx_builtin_saytime | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6318 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().
06319 { 06320 int res = 0; 06321 char *parse; 06322 int secs = 0; 06323 char charascii[2]; 06324 06325 AST_DECLARE_APP_ARGS(args, 06326 AST_APP_ARG(timestr); 06327 AST_APP_ARG(digits); 06328 ); 06329 06330 if (ast_strlen_zero(data)) { 06331 ast_log(LOG_WARNING, "SayTime requires an argument (time in seconds)\n"); 06332 return -1; 06333 } 06334 06335 if (!(parse = ast_strdupa(data))) { 06336 ast_log(LOG_WARNING, "Memory Error!\n"); 06337 return -1; 06338 } 06339 06340 AST_STANDARD_APP_ARGS(args, parse); 06341 06342 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06343 ast_log(LOG_WARNING, "SayTime escape digits must be a subset from '0123456789*#'\n"); 06344 args.digits = ""; 06345 } 06346 06347 if (sscanf(args.timestr, "%d", &secs) != 1) { 06348 ast_log(LOG_WARNING, "Firt argument to SayTime must be numeric (time in seconds)\n"); 06349 return -1; 06350 } 06351 06352 res = ast_say_time(chan, (time_t)secs, args.digits, chan->language); 06353 if (res > 0) { 06354 if (isdigit(res) || (res == '*') || (res == '#')) { 06355 snprintf(charascii, 2, "%c", res); 06356 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06357 res = 0; 06358 } else { 06359 ast_log(LOG_WARNING, "SayTime: invalid return value (%d) detected\n", res); 06360 } 06361 } 06362 return res; 06363 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5912 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().
05913 { 05914 struct ast_var_t *variables; 05915 const char *var, *val; 05916 int total = 0; 05917 05918 if (!chan) 05919 return 0; 05920 05921 memset(buf, 0, size); 05922 05923 ast_channel_lock(chan); 05924 05925 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05926 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05927 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05928 ) { 05929 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05930 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05931 break; 05932 } else 05933 total++; 05934 } else 05935 break; 05936 } 05937 05938 ast_channel_unlock(chan); 05939 05940 return total; 05941 }
static int pbx_builtin_setglobalvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 6138 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and pbx_builtin_setvar_helper().
06139 { 06140 char *name; 06141 char *stringp = data; 06142 static int dep_warning = 0; 06143 06144 if (ast_strlen_zero(data)) { 06145 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06146 return 0; 06147 } 06148 06149 name = strsep(&stringp, "="); 06150 06151 if (!dep_warning) { 06152 dep_warning = 1; 06153 ast_log(LOG_WARNING, "SetGlobalVar is deprecated. Please use Set(GLOBAL(%s)=%s) instead.\n", name, stringp); 06154 } 06155 06156 /*! \todo XXX watch out, leading whitespace ? */ 06157 pbx_builtin_setvar_helper(NULL, name, stringp); 06158 06159 return(0); 06160 }
int pbx_builtin_setvar | ( | struct ast_channel * | , | |
void * | ||||
) |
Definition at line 6066 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().
06067 { 06068 char *name, *value, *mydata; 06069 int argc; 06070 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 06071 int global = 0; 06072 int x; 06073 06074 if (ast_strlen_zero(data)) { 06075 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 06076 return 0; 06077 } 06078 06079 mydata = ast_strdupa(data); 06080 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 06081 06082 /* check for a trailing flags argument */ 06083 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 06084 argc--; 06085 if (strchr(argv[argc], 'g')) { 06086 ast_log(LOG_WARNING, "The use of the 'g' flag is deprecated. Please use Set(GLOBAL(foo)=bar) instead\n"); 06087 global = 1; 06088 } 06089 } 06090 06091 if (argc > 1) 06092 ast_log(LOG_WARNING, "Setting multiple variables at once within Set is deprecated. Please separate each name/value pair into its own line.\n"); 06093 06094 for (x = 0; x < argc; x++) { 06095 name = argv[x]; 06096 if ((value = strchr(name, '='))) { 06097 *value++ = '\0'; 06098 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 06099 } else 06100 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 06101 } 06102 06103 return(0); 06104 }
void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 6015 of file pbx.c.
References ast_channel_lock, ast_channel_unlock, ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, 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_iax2_new(), ast_monitor_start(), ast_monitor_stop(), ast_pbx_outgoing_exten(), ast_set_variables(), background_detect_exec(), builtin_automonitor(), builtin_blindtransfer(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), dahdi_handle_dtmf(), dahdi_new(), disa_exec(), do_waiting(), end_bridge_callback(), export_aoc_vars(), export_ch(), feature_request_and_dial(), 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(), ring_entry(), 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().
06016 { 06017 struct ast_var_t *newvariable; 06018 struct varshead *headp; 06019 const char *nametail = name; 06020 06021 if (name[strlen(name)-1] == ')') { 06022 char *function = ast_strdupa(name); 06023 06024 ast_func_write(chan, function, value); 06025 return; 06026 } 06027 06028 if (chan) { 06029 ast_channel_lock(chan); 06030 headp = &chan->varshead; 06031 } else { 06032 ast_mutex_lock(&globalslock); 06033 headp = &globals; 06034 } 06035 06036 /* For comparison purposes, we have to strip leading underscores */ 06037 if (*nametail == '_') { 06038 nametail++; 06039 if (*nametail == '_') 06040 nametail++; 06041 } 06042 06043 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) { 06044 if (strcmp(ast_var_name(newvariable), nametail) == 0) { 06045 /* there is already such a variable, delete it */ 06046 AST_LIST_REMOVE_CURRENT(headp, entries); 06047 ast_var_delete(newvariable); 06048 break; 06049 } 06050 } 06051 AST_LIST_TRAVERSE_SAFE_END; 06052 06053 if (value) { 06054 if ((option_verbose > 1) && (headp == &globals)) 06055 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 06056 newvariable = ast_var_assign(name, value); 06057 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 06058 } 06059 06060 if (chan) 06061 ast_channel_unlock(chan); 06062 else 06063 ast_mutex_unlock(&globalslock); 06064 }
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 6177 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().
06178 { 06179 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06180 return 0; 06181 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06182 return atoi(condition); 06183 else /* Strings are true */ 06184 return 1; 06185 }
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 551 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 aelsub_exec(), 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().
00554 { 00555 int res; 00556 00557 const char *saved_c_appl; 00558 const char *saved_c_data; 00559 00560 if (c->cdr && !ast_check_hangup(c)) 00561 ast_cdr_setapp(c->cdr, app->name, data); 00562 00563 /* save channel values */ 00564 saved_c_appl= c->appl; 00565 saved_c_data= c->data; 00566 00567 c->appl = app->name; 00568 c->data = data; 00569 /* XXX remember what to to when we have linked apps to modules */ 00570 if (app->module) { 00571 /* XXX LOCAL_USER_ADD(app->module) */ 00572 } 00573 res = app->execute(c, S_OR(data, "")); 00574 if (app->module) { 00575 /* XXX LOCAL_USER_REMOVE(app->module) */ 00576 } 00577 /* restore channel values */ 00578 c->appl = saved_c_appl; 00579 c->data = saved_c_data; 00580 return res; 00581 }
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 1863 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().
01866 { 01867 struct ast_exten *e; 01868 struct ast_app *app; 01869 int res; 01870 struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */ 01871 char passdata[EXT_DATA_SIZE]; 01872 01873 int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE); 01874 01875 ast_rdlock_contexts(); 01876 e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action); 01877 if (e) { 01878 if (matching_action) { 01879 ast_unlock_contexts(); 01880 return -1; /* success, we found it */ 01881 } else if (action == E_FINDLABEL) { /* map the label to a priority */ 01882 res = e->priority; 01883 ast_unlock_contexts(); 01884 return res; /* the priority we were looking for */ 01885 } else { /* spawn */ 01886 app = pbx_findapp(e->app); 01887 ast_unlock_contexts(); 01888 if (!app) { 01889 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority); 01890 return -1; 01891 } 01892 if (c->context != context) 01893 ast_copy_string(c->context, context, sizeof(c->context)); 01894 if (c->exten != exten) 01895 ast_copy_string(c->exten, exten, sizeof(c->exten)); 01896 c->priority = priority; 01897 pbx_substitute_variables(passdata, sizeof(passdata), c, e); 01898 if (option_debug) { 01899 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name); 01900 } 01901 if (option_verbose > 2) { 01902 char tmp[80], tmp2[80], tmp3[EXT_DATA_SIZE]; 01903 ast_verbose( VERBOSE_PREFIX_3 "Executing [%s@%s:%d] %s(\"%s\", \"%s\") %s\n", 01904 exten, context, priority, 01905 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)), 01906 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 01907 term_color(tmp3, passdata, COLOR_BRMAGENTA, 0, sizeof(tmp3)), 01908 "in new stack"); 01909 } 01910 manager_event(EVENT_FLAG_CALL, "Newexten", 01911 "Channel: %s\r\n" 01912 "Context: %s\r\n" 01913 "Extension: %s\r\n" 01914 "Priority: %d\r\n" 01915 "Application: %s\r\n" 01916 "AppData: %s\r\n" 01917 "Uniqueid: %s\r\n", 01918 c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid); 01919 return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */ 01920 } 01921 } else if (q.swo) { /* not found here, but in another switch */ 01922 ast_unlock_contexts(); 01923 if (matching_action) { 01924 return -1; 01925 } else { 01926 if (!q.swo->exec) { 01927 ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name); 01928 res = -1; 01929 } 01930 return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data); 01931 } 01932 } else { /* not found anywhere, see what happened */ 01933 ast_unlock_contexts(); 01934 /* Using S_OR here because Solaris doesn't like NULL being passed to ast_log */ 01935 switch (q.status) { 01936 case STATUS_NO_CONTEXT: 01937 if (!matching_action) 01938 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", S_OR(context, "")); 01939 break; 01940 case STATUS_NO_EXTENSION: 01941 if (!matching_action) 01942 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, S_OR(context, "")); 01943 break; 01944 case STATUS_NO_PRIORITY: 01945 if (!matching_action) 01946 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, S_OR(context, "")); 01947 break; 01948 case STATUS_NO_LABEL: 01949 if (context) 01950 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, S_OR(context, "")); 01951 break; 01952 default: 01953 if (option_debug) 01954 ast_log(LOG_DEBUG, "Shouldn't happen!\n"); 01955 } 01956 01957 return (matching_action) ? 0 : -1; 01958 } 01959 }
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 997 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().
01001 { 01002 int x, res; 01003 struct ast_context *tmp; 01004 struct ast_exten *e, *eroot; 01005 struct ast_include *i; 01006 struct ast_sw *sw; 01007 char *tmpdata = NULL; 01008 01009 /* Initialize status if appropriate */ 01010 if (q->stacklen == 0) { 01011 q->status = STATUS_NO_CONTEXT; 01012 q->swo = NULL; 01013 q->data = NULL; 01014 q->foundcontext = NULL; 01015 } 01016 /* Check for stack overflow */ 01017 if (q->stacklen >= AST_PBX_MAX_STACK) { 01018 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n"); 01019 return NULL; 01020 } 01021 /* Check first to see if we've already been checked */ 01022 for (x = 0; x < q->stacklen; x++) { 01023 if (!strcasecmp(q->incstack[x], context)) 01024 return NULL; 01025 } 01026 if (bypass) /* bypass means we only look there */ 01027 tmp = bypass; 01028 else { /* look in contexts */ 01029 tmp = NULL; 01030 while ((tmp = ast_walk_contexts(tmp)) ) { 01031 if (!strcmp(tmp->name, context)) 01032 break; 01033 } 01034 if (!tmp) 01035 return NULL; 01036 } 01037 if (q->status < STATUS_NO_EXTENSION) 01038 q->status = STATUS_NO_EXTENSION; 01039 01040 /* scan the list trying to match extension and CID */ 01041 eroot = NULL; 01042 while ( (eroot = ast_walk_context_extensions(tmp, eroot)) ) { 01043 int match = extension_match_core(eroot->exten, exten, action); 01044 /* 0 on fail, 1 on match, 2 on earlymatch */ 01045 01046 if (!match || (eroot->matchcid && !matchcid(eroot->cidmatch, callerid))) 01047 continue; /* keep trying */ 01048 if (match == 2 && action == E_MATCHMORE) { 01049 /* We match an extension ending in '!'. 01050 * The decision in this case is final and is NULL (no match). 01051 */ 01052 return NULL; 01053 } 01054 /* found entry, now look for the right priority */ 01055 if (q->status < STATUS_NO_PRIORITY) 01056 q->status = STATUS_NO_PRIORITY; 01057 e = NULL; 01058 while ( (e = ast_walk_extension_priorities(eroot, e)) ) { 01059 /* Match label or priority */ 01060 if (action == E_FINDLABEL) { 01061 if (q->status < STATUS_NO_LABEL) 01062 q->status = STATUS_NO_LABEL; 01063 if (label && e->label && !strcmp(label, e->label)) 01064 break; /* found it */ 01065 } else if (e->priority == priority) { 01066 break; /* found it */ 01067 } /* else keep searching */ 01068 } 01069 if (e) { /* found a valid match */ 01070 q->status = STATUS_SUCCESS; 01071 q->foundcontext = context; 01072 return e; 01073 } 01074 } 01075 /* Check alternative switches */ 01076 AST_LIST_TRAVERSE(&tmp->alts, sw, list) { 01077 struct ast_switch *asw = pbx_findswitch(sw->name); 01078 ast_switch_f *aswf = NULL; 01079 char *datap; 01080 01081 if (!asw) { 01082 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); 01083 continue; 01084 } 01085 /* Substitute variables now */ 01086 if (sw->eval) { 01087 if (!(tmpdata = ast_threadstorage_get(&switch_data, 512))) { 01088 ast_log(LOG_WARNING, "Can't evaluate switch?!"); 01089 continue; 01090 } 01091 pbx_substitute_variables_helper(chan, sw->data, tmpdata, 512); 01092 } 01093 01094 /* equivalent of extension_match_core() at the switch level */ 01095 if (action == E_CANMATCH) 01096 aswf = asw->canmatch; 01097 else if (action == E_MATCHMORE) 01098 aswf = asw->matchmore; 01099 else /* action == E_MATCH */ 01100 aswf = asw->exists; 01101 datap = sw->eval ? tmpdata : sw->data; 01102 if (!aswf) 01103 res = 0; 01104 else { 01105 if (chan) 01106 ast_autoservice_start(chan); 01107 res = aswf(chan, context, exten, priority, callerid, datap); 01108 if (chan) 01109 ast_autoservice_stop(chan); 01110 } 01111 if (res) { /* Got a match */ 01112 q->swo = asw; 01113 q->data = datap; 01114 q->foundcontext = context; 01115 /* XXX keep status = STATUS_NO_CONTEXT ? */ 01116 return NULL; 01117 } 01118 } 01119 q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */ 01120 /* Now try any includes we have in this context */ 01121 for (i = tmp->includes; i; i = i->next) { 01122 if (include_valid(i)) { 01123 if ((e = pbx_find_extension(chan, bypass, q, i->rname, exten, priority, label, callerid, action))) 01124 return e; 01125 if (q->swo) 01126 return NULL; 01127 } 01128 } 01129 return NULL; 01130 }
struct ast_app* pbx_findapp | ( | const char * | app | ) |
Look up an application.
app | name of the app |
Definition at line 589 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sw::list, and ast_app::name.
Referenced by aelsub_exec(), 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().
00590 { 00591 struct ast_app *tmp; 00592 00593 AST_LIST_LOCK(&apps); 00594 AST_LIST_TRAVERSE(&apps, tmp, list) { 00595 if (!strcasecmp(tmp->name, app)) 00596 break; 00597 } 00598 AST_LIST_UNLOCK(&apps); 00599 00600 return tmp; 00601 }
static struct ast_switch* pbx_findswitch | ( | const char * | sw | ) | [static] |
Definition at line 603 of file pbx.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sw::list, and ast_switch::name.
00604 { 00605 struct ast_switch *asw; 00606 00607 AST_LIST_LOCK(&switches); 00608 AST_LIST_TRAVERSE(&switches, asw, list) { 00609 if (!strcasecmp(asw->name, sw)) 00610 break; 00611 } 00612 AST_LIST_UNLOCK(&switches); 00613 00614 return asw; 00615 }
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 1204 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().
01205 { 01206 const char not_found = '\0'; 01207 char *tmpvar; 01208 const char *s; /* the result */ 01209 int offset, length; 01210 int i, need_substring; 01211 struct varshead *places[2] = { headp, &globals }; /* list of places where we may look */ 01212 01213 if (c) { 01214 ast_channel_lock(c); 01215 places[0] = &c->varshead; 01216 } 01217 /* 01218 * Make a copy of var because parse_variable_name() modifies the string. 01219 * Then if called directly, we might need to run substring() on the result; 01220 * remember this for later in 'need_substring', 'offset' and 'length' 01221 */ 01222 tmpvar = ast_strdupa(var); /* parse_variable_name modifies the string */ 01223 need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */); 01224 01225 /* 01226 * Look first into predefined variables, then into variable lists. 01227 * Variable 's' points to the result, according to the following rules: 01228 * s == ¬_found (set at the beginning) means that we did not find a 01229 * matching variable and need to look into more places. 01230 * If s != ¬_found, s is a valid result string as follows: 01231 * s = NULL if the variable does not have a value; 01232 * you typically do this when looking for an unset predefined variable. 01233 * s = workspace if the result has been assembled there; 01234 * typically done when the result is built e.g. with an snprintf(), 01235 * so we don't need to do an additional copy. 01236 * s != workspace in case we have a string, that needs to be copied 01237 * (the ast_copy_string is done once for all at the end). 01238 * Typically done when the result is already available in some string. 01239 */ 01240 s = ¬_found; /* default value */ 01241 if (c) { /* This group requires a valid channel */ 01242 /* Names with common parts are looked up a piece at a time using strncmp. */ 01243 if (!strncmp(var, "CALL", 4)) { 01244 if (!strncmp(var + 4, "ING", 3)) { 01245 if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */ 01246 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01247 s = workspace; 01248 } else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */ 01249 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01250 s = workspace; 01251 } else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */ 01252 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01253 s = workspace; 01254 } else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */ 01255 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01256 s = workspace; 01257 } 01258 } 01259 } else if (!strcmp(var, "HINT")) { 01260 s = ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten) ? workspace : NULL; 01261 } else if (!strcmp(var, "HINTNAME")) { 01262 s = ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten) ? workspace : NULL; 01263 } else if (!strcmp(var, "EXTEN")) { 01264 s = c->exten; 01265 } else if (!strcmp(var, "CONTEXT")) { 01266 s = c->context; 01267 } else if (!strcmp(var, "PRIORITY")) { 01268 snprintf(workspace, workspacelen, "%d", c->priority); 01269 s = workspace; 01270 } else if (!strcmp(var, "CHANNEL")) { 01271 s = c->name; 01272 } else if (!strcmp(var, "UNIQUEID")) { 01273 s = c->uniqueid; 01274 } else if (!strcmp(var, "HANGUPCAUSE")) { 01275 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01276 s = workspace; 01277 } else if (c && !strcmp(var, "HANGUPCAUSESTR")) { 01278 ast_copy_string(workspace, ast_cause2str(c->hangupcause), workspacelen); 01279 *ret = workspace; 01280 } 01281 } 01282 if (s == ¬_found) { /* look for more */ 01283 if (!strcmp(var, "EPOCH")) { 01284 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01285 s = workspace; 01286 } else if (!strcmp(var, "SYSTEMNAME")) { 01287 s = ast_config_AST_SYSTEM_NAME; 01288 } 01289 } 01290 /* if not found, look into chanvars or global vars */ 01291 for (i = 0; s == ¬_found && i < (sizeof(places) / sizeof(places[0])); i++) { 01292 struct ast_var_t *variables; 01293 if (!places[i]) 01294 continue; 01295 if (places[i] == &globals) 01296 ast_mutex_lock(&globalslock); 01297 AST_LIST_TRAVERSE(places[i], variables, entries) { 01298 if (strcasecmp(ast_var_name(variables), var)==0) { 01299 s = ast_var_value(variables); 01300 break; 01301 } 01302 } 01303 if (places[i] == &globals) 01304 ast_mutex_unlock(&globalslock); 01305 } 01306 if (s == ¬_found || s == NULL) 01307 *ret = NULL; 01308 else { 01309 if (s != workspace) 01310 ast_copy_string(workspace, s, workspacelen); 01311 *ret = workspace; 01312 if (need_substring) 01313 *ret = substring(*ret, offset, length, workspace, workspacelen); 01314 } 01315 01316 if (c) 01317 ast_channel_unlock(c); 01318 }
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 2774 of file pbx.c.
Referenced by pbx_load_module().
02775 { 02776 int oldval = autofallthrough; 02777 autofallthrough = newval; 02778 return oldval; 02779 }
static void pbx_substitute_variables | ( | char * | passdata, | |
int | datalen, | |||
struct ast_channel * | c, | |||
struct ast_exten * | e | |||
) | [static] |
Definition at line 1834 of file pbx.c.
References ast_copy_string(), ast_exten::data, and pbx_substitute_variables_helper().
Referenced by pbx_extension_helper().
01835 { 01836 memset(passdata, 0, datalen); 01837 01838 /* No variables or expressions in e->data, so why scan it? */ 01839 if (e->data && !strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) { 01840 ast_copy_string(passdata, e->data, datalen); 01841 return; 01842 } 01843 01844 pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1); 01845 }
void pbx_substitute_variables_helper | ( | struct ast_channel * | c, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1824 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().
01825 { 01826 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01827 }
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 1629 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().
01630 { 01631 /* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!! */ 01632 char *cp4; 01633 const char *tmp, *whereweare; 01634 int length, offset, offset2, isfunction; 01635 char *workspace = NULL; 01636 char *ltmp = NULL, *var = NULL; 01637 char *nextvar, *nextexp, *nextthing; 01638 char *vars, *vare; 01639 int pos, brackets, needsub, len; 01640 01641 *cp2 = 0; /* just in case nothing ends up there */ 01642 whereweare=tmp=cp1; 01643 while (!ast_strlen_zero(whereweare) && count) { 01644 /* Assume we're copying the whole remaining string */ 01645 pos = strlen(whereweare); 01646 nextvar = NULL; 01647 nextexp = NULL; 01648 nextthing = strchr(whereweare, '$'); 01649 if (nextthing) { 01650 switch(nextthing[1]) { 01651 case '{': 01652 nextvar = nextthing; 01653 pos = nextvar - whereweare; 01654 break; 01655 case '[': 01656 nextexp = nextthing; 01657 pos = nextexp - whereweare; 01658 break; 01659 default: 01660 pos = 1; 01661 } 01662 } 01663 01664 if (pos) { 01665 /* Can't copy more than 'count' bytes */ 01666 if (pos > count) 01667 pos = count; 01668 01669 /* Copy that many bytes */ 01670 memcpy(cp2, whereweare, pos); 01671 01672 count -= pos; 01673 cp2 += pos; 01674 whereweare += pos; 01675 *cp2 = 0; 01676 } 01677 01678 if (nextvar) { 01679 /* We have a variable. Find the start and end, and determine 01680 if we are going to have to recursively call ourselves on the 01681 contents */ 01682 vars = vare = nextvar + 2; 01683 brackets = 1; 01684 needsub = 0; 01685 01686 /* Find the end of it */ 01687 while (brackets && *vare) { 01688 if ((vare[0] == '$') && (vare[1] == '{')) { 01689 needsub++; 01690 } else if (vare[0] == '{') { 01691 brackets++; 01692 } else if (vare[0] == '}') { 01693 brackets--; 01694 } else if ((vare[0] == '$') && (vare[1] == '[')) 01695 needsub++; 01696 vare++; 01697 } 01698 if (brackets) 01699 ast_log(LOG_WARNING, "Error in extension logic (missing '}')\n"); 01700 len = vare - vars - 1; 01701 01702 /* Skip totally over variable string */ 01703 whereweare += (len + 3); 01704 01705 if (!var) 01706 var = alloca(VAR_BUF_SIZE); 01707 01708 /* Store variable name (and truncate) */ 01709 ast_copy_string(var, vars, len + 1); 01710 01711 /* Substitute if necessary */ 01712 if (needsub) { 01713 if (!ltmp) 01714 ltmp = alloca(VAR_BUF_SIZE); 01715 01716 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01717 vars = ltmp; 01718 } else { 01719 vars = var; 01720 } 01721 01722 if (!workspace) 01723 workspace = alloca(VAR_BUF_SIZE); 01724 01725 workspace[0] = '\0'; 01726 01727 parse_variable_name(vars, &offset, &offset2, &isfunction); 01728 if (isfunction) { 01729 /* Evaluate function */ 01730 if (c || !headp) 01731 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace; 01732 else { 01733 struct varshead old; 01734 struct ast_channel *c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/%p", vars); 01735 if (c) { 01736 memcpy(&old, &c->varshead, sizeof(old)); 01737 memcpy(&c->varshead, headp, sizeof(c->varshead)); 01738 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace; 01739 /* Don't deallocate the varshead that was passed in */ 01740 memcpy(&c->varshead, &old, sizeof(c->varshead)); 01741 ast_channel_free(c); 01742 } else 01743 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 01744 } 01745 01746 if (option_debug) 01747 ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)"); 01748 } else { 01749 /* Retrieve variable value */ 01750 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp); 01751 } 01752 if (cp4) { 01753 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE); 01754 01755 length = strlen(cp4); 01756 if (length > count) 01757 length = count; 01758 memcpy(cp2, cp4, length); 01759 count -= length; 01760 cp2 += length; 01761 *cp2 = 0; 01762 } 01763 } else if (nextexp) { 01764 /* We have an expression. Find the start and end, and determine 01765 if we are going to have to recursively call ourselves on the 01766 contents */ 01767 vars = vare = nextexp + 2; 01768 brackets = 1; 01769 needsub = 0; 01770 01771 /* Find the end of it */ 01772 while (brackets && *vare) { 01773 if ((vare[0] == '$') && (vare[1] == '[')) { 01774 needsub++; 01775 brackets++; 01776 vare++; 01777 } else if (vare[0] == '[') { 01778 brackets++; 01779 } else if (vare[0] == ']') { 01780 brackets--; 01781 } else if ((vare[0] == '$') && (vare[1] == '{')) { 01782 needsub++; 01783 vare++; 01784 } 01785 vare++; 01786 } 01787 if (brackets) 01788 ast_log(LOG_WARNING, "Error in extension logic (missing ']')\n"); 01789 len = vare - vars - 1; 01790 01791 /* Skip totally over expression */ 01792 whereweare += (len + 3); 01793 01794 if (!var) 01795 var = alloca(VAR_BUF_SIZE); 01796 01797 /* Store variable name (and truncate) */ 01798 ast_copy_string(var, vars, len + 1); 01799 01800 /* Substitute if necessary */ 01801 if (needsub) { 01802 if (!ltmp) 01803 ltmp = alloca(VAR_BUF_SIZE); 01804 01805 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01806 vars = ltmp; 01807 } else { 01808 vars = var; 01809 } 01810 01811 length = ast_expr(vars, cp2, count); 01812 01813 if (length) { 01814 if (option_debug) 01815 ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2); 01816 count -= length; 01817 cp2 += length; 01818 *cp2 = 0; 01819 } 01820 } 01821 } 01822 }
void pbx_substitute_variables_varshead | ( | struct varshead * | headp, | |
const char * | cp1, | |||
char * | cp2, | |||
int | count | |||
) |
Definition at line 1829 of file pbx.c.
References pbx_substitute_variables_helper_full().
Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_subst().
01830 { 01831 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01832 }
static void* pbx_thread | ( | void * | data | ) | [static] |
Definition at line 2704 of file pbx.c.
References __ast_pbx_run(), and decrease_call_count().
Referenced by ast_pbx_start().
02705 { 02706 /* Oh joyeous kernel, we're a new thread, with nothing to do but 02707 answer this channel and get it going. 02708 */ 02709 /* NOTE: 02710 The launcher of this function _MUST_ increment 'countcalls' 02711 before invoking the function; it will be decremented when the 02712 PBX has finished running on the channel 02713 */ 02714 struct ast_channel *c = data; 02715 02716 __ast_pbx_run(c); 02717 decrease_call_count(); 02718 02719 pthread_exit(NULL); 02720 02721 return NULL; 02722 }
static void print_ext | ( | struct ast_exten * | e, | |
char * | buf, | |||
int | buflen | |||
) | [static] |
helper function to print an extension
Definition at line 3605 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().
03606 { 03607 int prio = ast_get_extension_priority(e); 03608 if (prio == PRIORITY_HINT) { 03609 snprintf(buf, buflen, "hint: %s", 03610 ast_get_extension_app(e)); 03611 } else { 03612 snprintf(buf, buflen, "%d. %s(%s)", 03613 prio, ast_get_extension_app(e), 03614 (!ast_strlen_zero(ast_get_extension_app_data(e)) ? (char *)ast_get_extension_app_data(e) : "")); 03615 } 03616 }
static void set_ext_pri | ( | struct ast_channel * | c, | |
const char * | exten, | |||
int | pri | |||
) | [static] |
Definition at line 2397 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().
02398 { 02399 ast_channel_lock(c); 02400 ast_copy_string(c->exten, exten, sizeof(c->exten)); 02401 c->priority = pri; 02402 ast_channel_unlock(c); 02403 }
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 3619 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().
03620 { 03621 struct ast_context *c = NULL; 03622 int res = 0, old_total_exten = dpc->total_exten; 03623 03624 ast_rdlock_contexts(); 03625 03626 /* walk all contexts ... */ 03627 while ( (c = ast_walk_contexts(c)) ) { 03628 struct ast_exten *e; 03629 struct ast_include *i; 03630 struct ast_ignorepat *ip; 03631 char buf[256], buf2[256]; 03632 int context_info_printed = 0; 03633 03634 if (context && strcmp(ast_get_context_name(c), context)) 03635 continue; /* skip this one, name doesn't match */ 03636 03637 dpc->context_existence = 1; 03638 03639 ast_lock_context(c); 03640 03641 /* are we looking for exten too? if yes, we print context 03642 * only if we find our extension. 03643 * Otherwise print context even if empty ? 03644 * XXX i am not sure how the rinclude is handled. 03645 * I think it ought to go inside. 03646 */ 03647 if (!exten) { 03648 dpc->total_context++; 03649 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03650 ast_get_context_name(c), ast_get_context_registrar(c)); 03651 context_info_printed = 1; 03652 } 03653 03654 /* walk extensions ... */ 03655 e = NULL; 03656 while ( (e = ast_walk_context_extensions(c, e)) ) { 03657 struct ast_exten *p; 03658 03659 if (exten && !ast_extension_match(ast_get_extension_name(e), exten)) 03660 continue; /* skip, extension match failed */ 03661 03662 dpc->extension_existence = 1; 03663 03664 /* may we print context info? */ 03665 if (!context_info_printed) { 03666 dpc->total_context++; 03667 if (rinclude) { /* TODO Print more info about rinclude */ 03668 ast_cli(fd, "[ Included context '%s' created by '%s' ]\n", 03669 ast_get_context_name(c), ast_get_context_registrar(c)); 03670 } else { 03671 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03672 ast_get_context_name(c), ast_get_context_registrar(c)); 03673 } 03674 context_info_printed = 1; 03675 } 03676 dpc->total_prio++; 03677 03678 /* write extension name and first peer */ 03679 if (e->matchcid) 03680 snprintf(buf, sizeof(buf), "'%s' (CID match '%s') => ", ast_get_extension_name(e), e->cidmatch); 03681 else 03682 snprintf(buf, sizeof(buf), "'%s' =>", ast_get_extension_name(e)); 03683 03684 print_ext(e, buf2, sizeof(buf2)); 03685 03686 ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2, 03687 ast_get_extension_registrar(e)); 03688 03689 dpc->total_exten++; 03690 /* walk next extension peers */ 03691 p = e; /* skip the first one, we already got it */ 03692 while ( (p = ast_walk_extension_priorities(e, p)) ) { 03693 const char *el = ast_get_extension_label(p); 03694 dpc->total_prio++; 03695 if (el) 03696 snprintf(buf, sizeof(buf), " [%s]", el); 03697 else 03698 buf[0] = '\0'; 03699 print_ext(p, buf2, sizeof(buf2)); 03700 03701 ast_cli(fd," %-17s %-45s [%s]\n", buf, buf2, 03702 ast_get_extension_registrar(p)); 03703 } 03704 } 03705 03706 /* walk included and write info ... */ 03707 i = NULL; 03708 while ( (i = ast_walk_context_includes(c, i)) ) { 03709 snprintf(buf, sizeof(buf), "'%s'", ast_get_include_name(i)); 03710 if (exten) { 03711 /* Check all includes for the requested extension */ 03712 if (includecount >= AST_PBX_MAX_STACK) { 03713 ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n"); 03714 } else { 03715 int dupe=0; 03716 int x; 03717 for (x=0;x<includecount;x++) { 03718 if (!strcasecmp(includes[x], ast_get_include_name(i))) { 03719 dupe++; 03720 break; 03721 } 03722 } 03723 if (!dupe) { 03724 includes[includecount] = ast_get_include_name(i); 03725 show_dialplan_helper(fd, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes); 03726 } else { 03727 ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context); 03728 } 03729 } 03730 } else { 03731 ast_cli(fd, " Include => %-45s [%s]\n", 03732 buf, ast_get_include_registrar(i)); 03733 } 03734 } 03735 03736 /* walk ignore patterns and write info ... */ 03737 ip = NULL; 03738 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) { 03739 const char *ipname = ast_get_ignorepat_name(ip); 03740 char ignorepat[AST_MAX_EXTENSION]; 03741 snprintf(buf, sizeof(buf), "'%s'", ipname); 03742 snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname); 03743 if (!exten || ast_extension_match(ignorepat, exten)) { 03744 ast_cli(fd, " Ignore pattern => %-45s [%s]\n", 03745 buf, ast_get_ignorepat_registrar(ip)); 03746 } 03747 } 03748 if (!rinclude) { 03749 struct ast_sw *sw = NULL; 03750 while ( (sw = ast_walk_context_switches(c, sw)) ) { 03751 snprintf(buf, sizeof(buf), "'%s/%s'", 03752 ast_get_switch_name(sw), 03753 ast_get_switch_data(sw)); 03754 ast_cli(fd, " Alt. Switch => %-45s [%s]\n", 03755 buf, ast_get_switch_registrar(sw)); 03756 } 03757 } 03758 03759 ast_unlock_context(c); 03760 03761 /* if we print something in context, make an empty line */ 03762 if (context_info_printed) 03763 ast_cli(fd, "\n"); 03764 } 03765 ast_unlock_contexts(); 03766 03767 return (dpc->total_exten == old_total_exten) ? -1 : res; 03768 }
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 1166 of file pbx.c.
References ast_copy_string().
Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full().
01167 { 01168 char *ret = workspace; 01169 int lr; /* length of the input string after the copy */ 01170 01171 ast_copy_string(workspace, value, workspace_len); /* always make a copy */ 01172 01173 lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */ 01174 01175 /* Quick check if no need to do anything */ 01176 if (offset == 0 && length >= lr) /* take the whole string */ 01177 return ret; 01178 01179 if (offset < 0) { /* translate negative offset into positive ones */ 01180 offset = lr + offset; 01181 if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */ 01182 offset = 0; 01183 } 01184 01185 /* too large offset result in empty string so we know what to return */ 01186 if (offset >= lr) 01187 return ret + lr; /* the final '\0' */ 01188 01189 ret += offset; /* move to the start position */ 01190 if (length >= 0 && length < lr - offset) /* truncate if necessary */ 01191 ret[length] = '\0'; 01192 else if (length < 0) { 01193 if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */ 01194 ret[lr + length - offset] = '\0'; 01195 else 01196 ret[0] = '\0'; 01197 } 01198 01199 return ret; 01200 }
static void switch_data_init | ( | void | ) | [static] |
static void wait_for_hangup | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5482 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().
05483 { 05484 int res; 05485 struct ast_frame *f; 05486 int waittime; 05487 05488 if (ast_strlen_zero(data) || (sscanf(data, "%30d", &waittime) != 1) || (waittime < 0)) 05489 waittime = -1; 05490 if (waittime > -1) { 05491 ast_safe_sleep(chan, waittime * 1000); 05492 } else do { 05493 res = ast_waitfor(chan, -1); 05494 if (res < 0) 05495 return; 05496 f = ast_read(chan); 05497 if (f) 05498 ast_frfree(f); 05499 } while(f); 05500 }
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_mutex_t conlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Lock for the ast_context list This lock MUST be recursive, or a deadlock on reload may result. See https://issues.asterisk.org/view.php?id=17643.
Definition at line 529 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 524 of file pbx.c.
Referenced by __ast_context_create(), __ast_context_destroy(), ast_merge_contexts_and_delete(), and ast_walk_contexts().
int countcalls [static] |
char* days[] [static] |
struct cfextension_states extension_states[] [static] |
Referenced by ast_extension_state2str().
Definition at line 245 of file pbx.c.
Referenced by ast_add_extension2(), handle_show_globals(), pbx_builtin_clear_globals(), pbx_builtin_getvar_helper(), pbx_builtin_pushvar_helper(), pbx_builtin_setvar_helper(), and pbx_retrieve_variable().
ast_mutex_t globalslock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 244 of file pbx.c.
Referenced by ast_add_extension2(), handle_show_globals(), pbx_builtin_clear_globals(), pbx_builtin_getvar_helper(), pbx_builtin_pushvar_helper(), pbx_builtin_setvar_helper(), and pbx_retrieve_variable().
struct ao2_container* hints [static] |
Definition at line 543 of file pbx.c.
Referenced by ast_add_hint(), ast_change_hint(), ast_extension_state_add(), ast_extension_state_del(), ast_hint_state_changed(), ast_merge_contexts_and_delete(), ast_pbx_init(), ast_remove_hint(), and handle_show_hints().
ast_mutex_t maxcalllock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 249 of file pbx.c.
Referenced by decrease_call_count(), and increase_call_count().
char* months[] [static] |
struct ast_cli_entry pbx_cli[] [static] |
struct ast_app_option resetcdr_opts[128] = { [ 'w' ] = { .flag = (1 << 1) }, [ 'a' ] = { .flag = (1 << 2) }, [ 'v' ] = { .flag = (1 << 0) },} [static] |
char set_global_help[] [static] |
char show_application_help[] [static] |
char show_applications_help[] [static] |
char show_dialplan_help[] [static] |
char show_function_help[] [static] |
char show_functions_help[] [static] |
char show_globals_help[] [static] |
char show_hints_help[] [static] |
char show_switches_help[] [static] |
struct ast_state_cb* statecbs |
Definition at line 546 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] |
struct ast_app_option waitexten_opts[128] = { [ 'm' ] = { .flag = (1 << 0) , .arg_index = 0 + 1 },} [static] |