#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 2 minute | |
static int | handle_set_global (int fd, int argc, char *argv[]) |
static int | handle_set_global_deprecated (int fd, int argc, char *argv[]) |
CLI support for setting global variables. | |
static int | handle_show_application (int fd, int argc, char *argv[]) |
static int | handle_show_application_deprecated (int fd, int argc, char *argv[]) |
static int | handle_show_applications (int fd, int argc, char *argv[]) |
static int | handle_show_applications_deprecated (int fd, int argc, char *argv[]) |
static int | handle_show_dialplan (int fd, int argc, char *argv[]) |
static int | handle_show_function (int fd, int argc, char *argv[]) |
static int | handle_show_function_deprecated (int fd, int argc, char *argv[]) |
static int | handle_show_functions (int fd, int argc, char *argv[]) |
static int | handle_show_functions_deprecated (int fd, int argc, char *argv[]) |
static int | handle_show_globals (int fd, int argc, char *argv[]) |
CLI support for listing global variables in a parseable way. | |
static int | handle_show_hints (int fd, int argc, char *argv[]) |
handle_show_hints: CLI support for listing registered dial plan hints | |
static int | handle_show_switches (int fd, int argc, char *argv[]) |
handle_show_switches: CLI support for listing registered dial plan switches | |
static int | 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 5440 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().
05441 { 05442 struct ast_context *tmp, *tmpl=NULL; 05443 struct ast_include *tmpi; 05444 struct ast_sw *sw; 05445 struct ast_exten *e, *el, *en; 05446 struct ast_ignorepat *ipi; 05447 05448 for (tmp = contexts; tmp; ) { 05449 struct ast_context *next; /* next starting point */ 05450 for (; tmp; tmpl = tmp, tmp = tmp->next) { 05451 if (option_debug) 05452 ast_log(LOG_DEBUG, "check ctx %s %s\n", tmp->name, tmp->registrar); 05453 if ( (!registrar || !strcasecmp(registrar, tmp->registrar)) && 05454 (!con || !strcasecmp(tmp->name, con->name)) ) 05455 break; /* found it */ 05456 } 05457 if (!tmp) /* not found, we are done */ 05458 break; 05459 ast_mutex_lock(&tmp->lock); 05460 if (option_debug) 05461 ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar); 05462 next = tmp->next; 05463 if (tmpl) 05464 tmpl->next = next; 05465 else 05466 contexts = next; 05467 /* Okay, now we're safe to let it go -- in a sense, we were 05468 ready to let it go as soon as we locked it. */ 05469 ast_mutex_unlock(&tmp->lock); 05470 for (tmpi = tmp->includes; tmpi; ) { /* Free includes */ 05471 struct ast_include *tmpil = tmpi; 05472 tmpi = tmpi->next; 05473 free(tmpil); 05474 } 05475 for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */ 05476 struct ast_ignorepat *ipl = ipi; 05477 ipi = ipi->next; 05478 free(ipl); 05479 } 05480 while ((sw = AST_LIST_REMOVE_HEAD(&tmp->alts, list))) 05481 free(sw); 05482 for (e = tmp->root; e;) { 05483 for (en = e->peer; en;) { 05484 el = en; 05485 en = en->peer; 05486 destroy_exten(el); 05487 } 05488 el = e; 05489 e = e->next; 05490 destroy_exten(el); 05491 } 05492 ast_mutex_destroy(&tmp->lock); 05493 free(tmp); 05494 /* if we have a specific match, we are done, otherwise continue */ 05495 tmp = con ? NULL : next; 05496 } 05497 }
static int __ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
int | async | |||
) | [static] |
Definition at line 6613 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().
06614 { 06615 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06616 06617 if (!chan) 06618 return -2; 06619 06620 if (context == NULL) 06621 context = chan->context; 06622 if (exten == NULL) 06623 exten = chan->exten; 06624 06625 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06626 if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num)) 06627 return goto_func(chan, context, exten, priority); 06628 else 06629 return -3; 06630 }
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 4834 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().
04836 { 04837 struct ast_exten *ep; 04838 04839 for (ep = NULL; e ; ep = e, e = e->peer) { 04840 if (e->priority >= tmp->priority) 04841 break; 04842 } 04843 if (!e) { /* go at the end, and ep is surely set because the list is not empty */ 04844 ep->peer = tmp; 04845 return 0; /* success */ 04846 } 04847 if (e->priority == tmp->priority) { 04848 /* Can't have something exactly the same. Is this a 04849 replacement? If so, replace, otherwise, bonk. */ 04850 if (!replace) { 04851 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04852 if (tmp->datad) 04853 tmp->datad(tmp->data); 04854 free(tmp); 04855 return -1; 04856 } 04857 /* we are replacing e, so copy the link fields and then update 04858 * whoever pointed to e to point to us 04859 */ 04860 tmp->next = e->next; /* not meaningful if we are not first in the peer list */ 04861 tmp->peer = e->peer; /* always meaningful */ 04862 if (ep) /* We're in the peer list, just insert ourselves */ 04863 ep->peer = tmp; 04864 else if (el) /* We're the first extension. Take over e's functions */ 04865 el->next = tmp; 04866 else /* We're the very first extension. */ 04867 con->root = tmp; 04868 if (tmp->priority == PRIORITY_HINT) 04869 ast_change_hint(e,tmp); 04870 /* Destroy the old one */ 04871 if (e->datad) 04872 e->datad(e->data); 04873 free(e); 04874 } else { /* Slip ourselves in just before e */ 04875 tmp->peer = e; 04876 tmp->next = e->next; /* extension chain, or NULL if e is not the first extension */ 04877 if (ep) /* Easy enough, we're just in the peer list */ 04878 ep->peer = tmp; 04879 else { /* we are the first in some peer list, so link in the ext list */ 04880 if (el) 04881 el->next = tmp; /* in the middle... */ 04882 else 04883 con->root = tmp; /* ... or at the head */ 04884 e->next = NULL; /* e is no more at the head, so e->next must be reset */ 04885 } 04886 /* And immediately return success. */ 04887 if (tmp->priority == PRIORITY_HINT) 04888 ast_add_hint(tmp); 04889 } 04890 return 0; 04891 }
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 4703 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().
04706 { 04707 int ret = -1; 04708 struct ast_context *c = find_context_locked(context); 04709 04710 if (c) { 04711 ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04712 application, data, datad, registrar); 04713 ast_unlock_contexts(); 04714 } 04715 return ret; 04716 }
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 4918 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().
04922 { 04923 /* 04924 * Sort extensions (or patterns) according to the rules indicated above. 04925 * These are implemented by the function ext_cmp()). 04926 * All priorities for the same ext/pattern/cid are kept in a list, 04927 * using the 'peer' field as a link field.. 04928 */ 04929 struct ast_exten *tmp, *e, *el = NULL; 04930 int res; 04931 int length; 04932 char *p; 04933 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04934 04935 /* if we are adding a hint, and there are global variables, and the hint 04936 contains variable references, then expand them 04937 */ 04938 ast_mutex_lock(&globalslock); 04939 if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04940 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04941 application = expand_buf; 04942 } 04943 ast_mutex_unlock(&globalslock); 04944 04945 length = sizeof(struct ast_exten); 04946 length += strlen(extension) + 1; 04947 length += strlen(application) + 1; 04948 if (label) 04949 length += strlen(label) + 1; 04950 if (callerid) 04951 length += strlen(callerid) + 1; 04952 else 04953 length ++; /* just the '\0' */ 04954 04955 /* Be optimistic: Build the extension structure first */ 04956 if (!(tmp = ast_calloc(1, length))) 04957 return -1; 04958 04959 /* use p as dst in assignments, as the fields are const char * */ 04960 p = tmp->stuff; 04961 if (label) { 04962 tmp->label = p; 04963 strcpy(p, label); 04964 p += strlen(label) + 1; 04965 } 04966 tmp->exten = p; 04967 p += ext_strncpy(p, extension, strlen(extension) + 1) + 1; 04968 tmp->priority = priority; 04969 tmp->cidmatch = p; /* but use p for assignments below */ 04970 if (callerid) { 04971 p += ext_strncpy(p, callerid, strlen(callerid) + 1) + 1; 04972 tmp->matchcid = 1; 04973 } else { 04974 *p++ = '\0'; 04975 tmp->matchcid = 0; 04976 } 04977 tmp->app = p; 04978 strcpy(p, application); 04979 tmp->parent = con; 04980 tmp->data = data; 04981 tmp->datad = datad; 04982 tmp->registrar = registrar; 04983 04984 ast_mutex_lock(&con->lock); 04985 res = 0; /* some compilers will think it is uninitialized otherwise */ 04986 for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */ 04987 res = ext_cmp(e->exten, tmp->exten); 04988 if (res == 0) { /* extension match, now look at cidmatch */ 04989 if (!e->matchcid && !tmp->matchcid) 04990 res = 0; 04991 else if (tmp->matchcid && !e->matchcid) 04992 res = 1; 04993 else if (e->matchcid && !tmp->matchcid) 04994 res = -1; 04995 else 04996 res = ext_cmp(e->cidmatch, tmp->cidmatch); 04997 } 04998 if (res >= 0) 04999 break; 05000 } 05001 if (e && res == 0) { /* exact match, insert in the pri chain */ 05002 res = add_pri(con, tmp, el, e, replace); 05003 ast_mutex_unlock(&con->lock); 05004 if (res < 0) { 05005 errno = EEXIST; /* XXX do we care ? */ 05006 return 0; /* XXX should we return -1 maybe ? */ 05007 } 05008 } else { 05009 /* 05010 * not an exact match, this is the first entry with this pattern, 05011 * so insert in the main list right before 'e' (if any) 05012 */ 05013 tmp->next = e; 05014 if (el) 05015 el->next = tmp; 05016 else 05017 con->root = tmp; 05018 ast_mutex_unlock(&con->lock); 05019 if (tmp->priority == PRIORITY_HINT) 05020 ast_add_hint(tmp); 05021 } 05022 if (option_debug) { 05023 if (tmp->matchcid) { 05024 if (option_debug) 05025 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", 05026 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 05027 } else { 05028 if (option_debug) 05029 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", 05030 tmp->exten, tmp->priority, con->name); 05031 } 05032 } 05033 if (option_verbose > 2) { 05034 if (tmp->matchcid) { 05035 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", 05036 tmp->exten, tmp->priority, tmp->cidmatch, con->name); 05037 } else { 05038 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", 05039 tmp->exten, tmp->priority, con->name); 05040 } 05041 } 05042 return 0; 05043 }
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 4741 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().
04742 { 04743 int res = 0; 04744 04745 ast_channel_lock(chan); 04746 04747 if (chan->pbx) { /* This channel is currently in the PBX */ 04748 ast_explicit_goto(chan, context, exten, priority); 04749 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04750 } else { 04751 /* In order to do it when the channel doesn't really exist within 04752 the PBX, we have to make a new channel, masquerade, and start the PBX 04753 at the new location */ 04754 struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); 04755 if (!tmpchan) { 04756 res = -1; 04757 } else { 04758 if (chan->cdr) { 04759 ast_cdr_discard(tmpchan->cdr); 04760 tmpchan->cdr = ast_cdr_dup(chan->cdr); /* share the love */ 04761 } 04762 /* Make formats okay */ 04763 tmpchan->readformat = chan->readformat; 04764 tmpchan->writeformat = chan->writeformat; 04765 /* Setup proper location */ 04766 ast_explicit_goto(tmpchan, 04767 S_OR(context, chan->context), S_OR(exten, chan->exten), priority); 04768 04769 /* Masquerade into temp channel */ 04770 if (ast_channel_masquerade(tmpchan, chan)) { 04771 /* Failed to set up the masquerade. It's probably chan_local 04772 * in the middle of optimizing itself out. Sad. :( */ 04773 ast_hangup(tmpchan); 04774 tmpchan = NULL; 04775 res = -1; 04776 } else { 04777 /* Grab the locks and get going */ 04778 ast_channel_lock(tmpchan); 04779 ast_do_masquerade(tmpchan); 04780 ast_channel_unlock(tmpchan); 04781 /* Start the PBX going on our stolen channel */ 04782 if (ast_pbx_start(tmpchan)) { 04783 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04784 ast_hangup(tmpchan); 04785 res = -1; 04786 } 04787 } 04788 } 04789 } 04790 ast_channel_unlock(chan); 04791 return res; 04792 }
int ast_async_goto_by_name | ( | const char * | channame, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 4794 of file pbx.c.
References ast_async_goto(), ast_channel_unlock, and ast_get_channel_by_name_locked().
04795 { 04796 struct ast_channel *chan; 04797 int res = -1; 04798 04799 chan = ast_get_channel_by_name_locked(channame); 04800 if (chan) { 04801 res = ast_async_goto(chan, context, exten, priority); 04802 ast_channel_unlock(chan); 04803 } 04804 return res; 04805 }
int ast_async_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6637 of file pbx.c.
References __ast_goto_if_exists().
Referenced by asyncgoto_exec().
06638 { 06639 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06640 }
int ast_build_timing | ( | struct ast_timing * | i, | |
const char * | info_in | |||
) |
Definition at line 4381 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().
04382 { 04383 char info_save[256]; 04384 char *info; 04385 04386 /* Check for empty just in case */ 04387 if (ast_strlen_zero(info_in)) 04388 return 0; 04389 /* make a copy just in case we were passed a static string */ 04390 ast_copy_string(info_save, info_in, sizeof(info_save)); 04391 info = info_save; 04392 /* Assume everything except time */ 04393 i->monthmask = 0xfff; /* 12 bits */ 04394 i->daymask = 0x7fffffffU; /* 31 bits */ 04395 i->dowmask = 0x7f; /* 7 bits */ 04396 /* on each call, use strsep() to move info to the next argument */ 04397 get_timerange(i, strsep(&info, "|")); 04398 if (info) 04399 i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week"); 04400 if (info) 04401 i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day"); 04402 if (info) 04403 i->monthmask = get_range(strsep(&info, "|"), 12, months, "month"); 04404 return 1; 04405 }
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 4407 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().
04408 { 04409 struct tm tm; 04410 time_t t = time(NULL); 04411 04412 ast_localtime(&t, &tm, NULL); 04413 04414 /* If it's not the right month, return */ 04415 if (!(i->monthmask & (1 << tm.tm_mon))) 04416 return 0; 04417 04418 /* If it's not that time of the month.... */ 04419 /* Warning, tm_mday has range 1..31! */ 04420 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04421 return 0; 04422 04423 /* If it's not the right day of the week */ 04424 if (!(i->dowmask & (1 << tm.tm_wday))) 04425 return 0; 04426 04427 /* Sanity check the hour just to be safe */ 04428 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04429 ast_log(LOG_WARNING, "Insane time...\n"); 04430 return 0; 04431 } 04432 04433 /* Now the tough part, we calculate if it fits 04434 in the right time based on min/hour */ 04435 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04436 return 0; 04437 04438 /* If we got this far, then we're good */ 04439 return 1; 04440 }
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 4634 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().
04635 { 04636 int ret = -1; 04637 struct ast_context *c = find_context_locked(context); 04638 04639 if (c) { 04640 ret = ast_context_add_ignorepat2(c, value, registrar); 04641 ast_unlock_contexts(); 04642 } 04643 return ret; 04644 }
int ast_context_add_ignorepat2 | ( | struct ast_context * | con, | |
const char * | value, | |||
const char * | registrar | |||
) |
Definition at line 4646 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().
04647 { 04648 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04649 int length; 04650 char *pattern; 04651 length = sizeof(struct ast_ignorepat); 04652 length += strlen(value) + 1; 04653 if (!(ignorepat = ast_calloc(1, length))) 04654 return -1; 04655 /* The cast to char * is because we need to write the initial value. 04656 * The field is not supposed to be modified otherwise. Also, gcc 4.2 04657 * sees the cast as dereferencing a type-punned pointer and warns about 04658 * it. This is the workaround (we're telling gcc, yes, that's really 04659 * what we wanted to do). 04660 */ 04661 pattern = (char *) ignorepat->pattern; 04662 strcpy(pattern, value); 04663 ignorepat->next = NULL; 04664 ignorepat->registrar = registrar; 04665 ast_mutex_lock(&con->lock); 04666 for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) { 04667 ignorepatl = ignorepatc; 04668 if (!strcasecmp(ignorepatc->pattern, value)) { 04669 /* Already there */ 04670 ast_mutex_unlock(&con->lock); 04671 errno = EEXIST; 04672 return -1; 04673 } 04674 } 04675 if (ignorepatl) 04676 ignorepatl->next = ignorepat; 04677 else 04678 con->ignorepats = ignorepat; 04679 ast_mutex_unlock(&con->lock); 04680 return 0; 04681 04682 }
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 4449 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().
04451 { 04452 struct ast_include *new_include; 04453 char *c; 04454 struct ast_include *i, *il = NULL; /* include, include_last */ 04455 int length; 04456 char *p; 04457 04458 length = sizeof(struct ast_include); 04459 length += 2 * (strlen(value) + 1); 04460 04461 /* allocate new include structure ... */ 04462 if (!(new_include = ast_calloc(1, length))) 04463 return -1; 04464 /* Fill in this structure. Use 'p' for assignments, as the fields 04465 * in the structure are 'const char *' 04466 */ 04467 p = new_include->stuff; 04468 new_include->name = p; 04469 strcpy(p, value); 04470 p += strlen(value) + 1; 04471 new_include->rname = p; 04472 strcpy(p, value); 04473 /* Strip off timing info, and process if it is there */ 04474 if ( (c = strchr(p, '|')) ) { 04475 *c++ = '\0'; 04476 new_include->hastime = ast_build_timing(&(new_include->timing), c); 04477 } 04478 new_include->next = NULL; 04479 new_include->registrar = registrar; 04480 04481 ast_mutex_lock(&con->lock); 04482 04483 /* ... go to last include and check if context is already included too... */ 04484 for (i = con->includes; i; i = i->next) { 04485 if (!strcasecmp(i->name, new_include->name)) { 04486 free(new_include); 04487 ast_mutex_unlock(&con->lock); 04488 errno = EEXIST; 04489 return -1; 04490 } 04491 il = i; 04492 } 04493 04494 /* ... include new context into context list, unlock, return */ 04495 if (il) 04496 il->next = new_include; 04497 else 04498 con->includes = new_include; 04499 if (option_verbose > 2) 04500 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04501 ast_mutex_unlock(&con->lock); 04502 04503 return 0; 04504 }
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 4511 of file pbx.c.
References ast_context_add_switch2(), ast_unlock_contexts(), and find_context_locked().
04512 { 04513 int ret = -1; 04514 struct ast_context *c = find_context_locked(context); 04515 04516 if (c) { /* found, add switch to this context */ 04517 ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04518 ast_unlock_contexts(); 04519 } 04520 return ret; 04521 }
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 4530 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().
04532 { 04533 struct ast_sw *new_sw; 04534 struct ast_sw *i; 04535 int length; 04536 char *p; 04537 04538 length = sizeof(struct ast_sw); 04539 length += strlen(value) + 1; 04540 if (data) 04541 length += strlen(data); 04542 length++; 04543 04544 /* allocate new sw structure ... */ 04545 if (!(new_sw = ast_calloc(1, length))) 04546 return -1; 04547 /* ... fill in this structure ... */ 04548 p = new_sw->stuff; 04549 new_sw->name = p; 04550 strcpy(new_sw->name, value); 04551 p += strlen(value) + 1; 04552 new_sw->data = p; 04553 if (data) { 04554 strcpy(new_sw->data, data); 04555 p += strlen(data) + 1; 04556 } else { 04557 strcpy(new_sw->data, ""); 04558 p++; 04559 } 04560 new_sw->eval = eval; 04561 new_sw->registrar = registrar; 04562 04563 /* ... try to lock this context ... */ 04564 ast_mutex_lock(&con->lock); 04565 04566 /* ... go to last sw and check if context is already swd too... */ 04567 AST_LIST_TRAVERSE(&con->alts, i, list) { 04568 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04569 free(new_sw); 04570 ast_mutex_unlock(&con->lock); 04571 errno = EEXIST; 04572 return -1; 04573 } 04574 } 04575 04576 /* ... sw new context into context list, unlock, return */ 04577 AST_LIST_INSERT_TAIL(&con->alts, new_sw, list); 04578 04579 if (option_verbose > 2) 04580 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04581 04582 ast_mutex_unlock(&con->lock); 04583 04584 return 0; 04585 }
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 5499 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().
05500 { 05501 ast_wrlock_contexts(); 05502 __ast_context_destroy(con,registrar); 05503 ast_unlock_contexts(); 05504 }
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 4591 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().
04592 { 04593 int ret = -1; 04594 struct ast_context *c = find_context_locked(context); 04595 04596 if (c) { 04597 ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04598 ast_unlock_contexts(); 04599 } 04600 return ret; 04601 }
int ast_context_remove_ignorepat2 | ( | struct ast_context * | con, | |
const char * | ignorepat, | |||
const char * | registrar | |||
) |
Definition at line 4603 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().
04604 { 04605 struct ast_ignorepat *ip, *ipl = NULL; 04606 04607 ast_mutex_lock(&con->lock); 04608 04609 for (ip = con->ignorepats; ip; ip = ip->next) { 04610 if (!strcmp(ip->pattern, ignorepat) && 04611 (!registrar || (registrar == ip->registrar))) { 04612 if (ipl) { 04613 ipl->next = ip->next; 04614 free(ip); 04615 } else { 04616 con->ignorepats = ip->next; 04617 free(ip); 04618 } 04619 ast_mutex_unlock(&con->lock); 04620 return 0; 04621 } 04622 ipl = ip; 04623 } 04624 04625 ast_mutex_unlock(&con->lock); 04626 errno = EINVAL; 04627 return -1; 04628 }
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 6594 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().
06595 { 06596 struct ast_include *inc = NULL; 06597 int res = 0; 06598 06599 while ( (inc = ast_walk_context_includes(con, inc)) ) { 06600 if (ast_context_find(inc->rname)) 06601 continue; 06602 06603 res = -1; 06604 ast_log(LOG_WARNING, "Context '%s' tries to include nonexistent context '%s'\n", 06605 ast_get_context_name(con), inc->rname); 06606 break; 06607 } 06608 06609 return res; 06610 }
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 4718 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().
04719 { 04720 if (!chan) 04721 return -1; 04722 04723 ast_channel_lock(chan); 04724 04725 if (!ast_strlen_zero(context)) 04726 ast_copy_string(chan->context, context, sizeof(chan->context)); 04727 if (!ast_strlen_zero(exten)) 04728 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04729 if (priority > -1) { 04730 chan->priority = priority; 04731 /* see flag description in channel.h for explanation */ 04732 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04733 chan->priority--; 04734 } 04735 04736 ast_channel_unlock(chan); 04737 04738 return 0; 04739 }
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 6451 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().
06452 { 06453 return con ? con->name : NULL; 06454 }
const char* ast_get_context_registrar | ( | struct ast_context * | c | ) |
Definition at line 6489 of file pbx.c.
References ast_context::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06490 { 06491 return c ? c->registrar : NULL; 06492 }
const char* ast_get_extension_app | ( | struct ast_exten * | e | ) |
Definition at line 6519 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().
06520 { 06521 return e ? e->app : NULL; 06522 }
void* ast_get_extension_app_data | ( | struct ast_exten * | e | ) |
Definition at line 6524 of file pbx.c.
References ast_exten::data.
Referenced by _macro_exec(), ast_get_hint(), handle_save_dialplan(), and print_ext().
06525 { 06526 return e ? e->data : NULL; 06527 }
const char* ast_get_extension_cidmatch | ( | struct ast_exten * | e | ) |
Definition at line 6514 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().
06515 { 06516 return e ? e->cidmatch : NULL; 06517 }
struct ast_context* ast_get_extension_context | ( | struct ast_exten * | exten | ) |
const char* ast_get_extension_label | ( | struct ast_exten * | exten | ) |
Definition at line 6466 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 6509 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().
06510 { 06511 return e ? e->matchcid : 0; 06512 }
const char* ast_get_extension_name | ( | struct ast_exten * | exten | ) |
Definition at line 6461 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 6481 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 6494 of file pbx.c.
References ast_exten::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06495 { 06496 return e ? e->registrar : NULL; 06497 }
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 6476 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().
06477 { 06478 return ip ? ip->pattern : NULL; 06479 }
const char* ast_get_ignorepat_registrar | ( | struct ast_ignorepat * | ip | ) |
Definition at line 6504 of file pbx.c.
References ast_ignorepat::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06505 { 06506 return ip ? ip->registrar : NULL; 06507 }
const char* ast_get_include_name | ( | struct ast_include * | inc | ) |
Definition at line 6471 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().
06472 { 06473 return inc ? inc->name : NULL; 06474 }
const char* ast_get_include_registrar | ( | struct ast_include * | i | ) |
Definition at line 6499 of file pbx.c.
References ast_include::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06500 { 06501 return i ? i->registrar : NULL; 06502 }
const char* ast_get_switch_data | ( | struct ast_sw * | sw | ) |
Definition at line 6534 of file pbx.c.
References ast_sw::data.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06535 { 06536 return sw ? sw->data : NULL; 06537 }
const char* ast_get_switch_name | ( | struct ast_sw * | sw | ) |
Definition at line 6529 of file pbx.c.
References ast_sw::name.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06530 { 06531 return sw ? sw->name : NULL; 06532 }
const char* ast_get_switch_registrar | ( | struct ast_sw * | sw | ) |
Definition at line 6539 of file pbx.c.
References ast_sw::registrar.
Referenced by handle_save_dialplan(), and show_dialplan_helper().
06540 { 06541 return sw ? sw->registrar : NULL; 06542 }
int ast_goto_if_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) |
Definition at line 6632 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().
06633 { 06634 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06635 }
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 4684 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().
04685 { 04686 struct ast_context *con = ast_context_find(context); 04687 if (con) { 04688 struct ast_ignorepat *pat; 04689 for (pat = con->ignorepats; pat; pat = pat->next) { 04690 if (ast_extension_match(pat->pattern, pattern)) 04691 return 1; 04692 } 04693 } 04694 04695 return 0; 04696 }
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 6438 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().
06439 { 06440 return ast_mutex_lock(&con->lock); 06441 }
int ast_lock_contexts | ( | void | ) |
Locks the context list.
0 | on success | |
-1 | on error |
Definition at line 6415 of file pbx.c.
References ast_mutex_lock(), and conlock.
Referenced by find_matching_endwhile().
06416 { 06417 return ast_mutex_lock(&conlock); 06418 }
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 6642 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().
06643 { 06644 char *exten, *pri, *context; 06645 char *stringp; 06646 int ipri; 06647 int mode = 0; 06648 06649 if (ast_strlen_zero(goto_string)) { 06650 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06651 return -1; 06652 } 06653 stringp = ast_strdupa(goto_string); 06654 context = strsep(&stringp, "|"); /* guaranteed non-null */ 06655 exten = strsep(&stringp, "|"); 06656 pri = strsep(&stringp, "|"); 06657 if (!exten) { /* Only a priority in this one */ 06658 pri = context; 06659 exten = NULL; 06660 context = NULL; 06661 } else if (!pri) { /* Only an extension and priority in this one */ 06662 pri = exten; 06663 exten = context; 06664 context = NULL; 06665 } 06666 if (*pri == '+') { 06667 mode = 1; 06668 pri++; 06669 } else if (*pri == '-') { 06670 mode = -1; 06671 pri++; 06672 } 06673 if (sscanf(pri, "%30d", &ipri) != 1) { 06674 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten, 06675 pri, chan->cid.cid_num)) < 1) { 06676 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06677 return -1; 06678 } else 06679 mode = 0; 06680 } 06681 /* At this point we have a priority and maybe an extension and a context */ 06682 06683 if (mode) 06684 ipri = chan->priority + (ipri * mode); 06685 06686 ast_explicit_goto(chan, context, exten, ipri); 06687 return 0; 06688 06689 }
int ast_pbx_init | ( | void | ) |
Provided by pbx.c
Definition at line 6705 of file pbx.c.
References ao2_container_alloc(), hint_cmp(), hint_hash(), and hints.
Referenced by main().
06706 { 06707 hints = ao2_container_alloc(1, hint_hash, hint_cmp); 06708 06709 return hints ? 0 : -1; 06710 }
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 5311 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().
05312 { 05313 struct ast_channel *chan; 05314 struct app_tmp *tmp; 05315 int res = -1, cdr_res = -1; 05316 struct outgoing_helper oh; 05317 pthread_attr_t attr; 05318 05319 memset(&oh, 0, sizeof(oh)); 05320 oh.vars = vars; 05321 oh.account = account; 05322 05323 if (locked_channel) 05324 *locked_channel = NULL; 05325 if (ast_strlen_zero(app)) { 05326 res = -1; 05327 goto outgoing_app_cleanup; 05328 } 05329 if (sync) { 05330 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05331 if (chan) { 05332 ast_set_variables(chan, vars); 05333 if (account) 05334 ast_cdr_setaccount(chan, account); 05335 if (chan->_state == AST_STATE_UP) { 05336 res = 0; 05337 if (option_verbose > 3) 05338 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05339 tmp = ast_calloc(1, sizeof(*tmp)); 05340 if (!tmp) 05341 res = -1; 05342 else { 05343 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05344 if (appdata) 05345 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05346 tmp->chan = chan; 05347 if (sync > 1) { 05348 if (locked_channel) 05349 ast_channel_unlock(chan); 05350 ast_pbx_run_app(tmp); 05351 } else { 05352 pthread_attr_init(&attr); 05353 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05354 if (locked_channel) 05355 ast_channel_lock(chan); 05356 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05357 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05358 free(tmp); 05359 if (locked_channel) 05360 ast_channel_unlock(chan); 05361 ast_hangup(chan); 05362 res = -1; 05363 } else { 05364 if (locked_channel) 05365 *locked_channel = chan; 05366 } 05367 pthread_attr_destroy(&attr); 05368 } 05369 } 05370 } else { 05371 if (option_verbose > 3) 05372 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05373 if (chan->cdr) { /* update the cdr */ 05374 /* here we update the status of the call, which sould be busy. 05375 * if that fails then we set the status to failed */ 05376 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05377 ast_cdr_failed(chan->cdr); 05378 } 05379 ast_hangup(chan); 05380 } 05381 } 05382 05383 if (res < 0) { /* the call failed for some reason */ 05384 if (*reason == 0) { /* if the call failed (not busy or no answer) 05385 * update the cdr with the failed message */ 05386 cdr_res = ast_pbx_outgoing_cdr_failed(); 05387 if (cdr_res != 0) { 05388 res = cdr_res; 05389 goto outgoing_app_cleanup; 05390 } 05391 } 05392 } 05393 05394 } else { 05395 struct async_stat *as; 05396 if (!(as = ast_calloc(1, sizeof(*as)))) { 05397 res = -1; 05398 goto outgoing_app_cleanup; 05399 } 05400 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05401 if (!chan) { 05402 free(as); 05403 res = -1; 05404 goto outgoing_app_cleanup; 05405 } 05406 as->chan = chan; 05407 ast_copy_string(as->app, app, sizeof(as->app)); 05408 if (appdata) 05409 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05410 as->timeout = timeout; 05411 ast_set_variables(chan, vars); 05412 if (account) 05413 ast_cdr_setaccount(chan, account); 05414 /* Start a new thread, and get something handling this channel. */ 05415 pthread_attr_init(&attr); 05416 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05417 if (locked_channel) 05418 ast_channel_lock(chan); 05419 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05420 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05421 free(as); 05422 if (locked_channel) 05423 ast_channel_unlock(chan); 05424 ast_hangup(chan); 05425 res = -1; 05426 pthread_attr_destroy(&attr); 05427 goto outgoing_app_cleanup; 05428 } else { 05429 if (locked_channel) 05430 *locked_channel = chan; 05431 } 05432 pthread_attr_destroy(&attr); 05433 res = 0; 05434 } 05435 outgoing_app_cleanup: 05436 ast_variables_destroy(vars); 05437 return res; 05438 }
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 5119 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().
05120 { 05121 /* allocate a channel */ 05122 struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", ""); 05123 05124 if (!chan) 05125 return -1; /* failure */ 05126 05127 if (!chan->cdr) { 05128 /* allocation of the cdr failed */ 05129 ast_channel_free(chan); /* free the channel */ 05130 return -1; /* return failure */ 05131 } 05132 05133 /* allocation of the cdr was successful */ 05134 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05135 ast_cdr_start(chan->cdr); /* record the start and stop time */ 05136 ast_cdr_end(chan->cdr); 05137 ast_cdr_failed(chan->cdr); /* set the status to failed */ 05138 ast_cdr_detach(chan->cdr); /* post and free the record */ 05139 chan->cdr = NULL; 05140 ast_channel_free(chan); /* free the channel */ 05141 05142 return 0; /* success */ 05143 }
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 5145 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().
05146 { 05147 struct ast_channel *chan; 05148 struct async_stat *as; 05149 int res = -1, cdr_res = -1; 05150 struct outgoing_helper oh; 05151 pthread_attr_t attr; 05152 05153 if (sync) { 05154 LOAD_OH(oh); 05155 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05156 if (channel) { 05157 *channel = chan; 05158 if (chan) 05159 ast_channel_lock(chan); 05160 } 05161 if (chan) { 05162 if (chan->_state == AST_STATE_UP) { 05163 res = 0; 05164 if (option_verbose > 3) 05165 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05166 05167 if (sync > 1) { 05168 if (channel) 05169 ast_channel_unlock(chan); 05170 if (ast_pbx_run(chan)) { 05171 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05172 if (channel) 05173 *channel = NULL; 05174 ast_hangup(chan); 05175 chan = NULL; 05176 res = -1; 05177 } 05178 } else { 05179 if (ast_pbx_start(chan)) { 05180 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05181 if (channel) { 05182 *channel = NULL; 05183 ast_channel_unlock(chan); 05184 } 05185 ast_hangup(chan); 05186 res = -1; 05187 } 05188 chan = NULL; 05189 } 05190 } else { 05191 if (option_verbose > 3) 05192 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05193 05194 if (chan->cdr) { /* update the cdr */ 05195 /* here we update the status of the call, which sould be busy. 05196 * if that fails then we set the status to failed */ 05197 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05198 ast_cdr_failed(chan->cdr); 05199 } 05200 05201 if (channel) { 05202 *channel = NULL; 05203 ast_channel_unlock(chan); 05204 } 05205 ast_hangup(chan); 05206 chan = NULL; 05207 } 05208 } 05209 05210 if (res < 0) { /* the call failed for some reason */ 05211 if (*reason == 0) { /* if the call failed (not busy or no answer) 05212 * update the cdr with the failed message */ 05213 cdr_res = ast_pbx_outgoing_cdr_failed(); 05214 if (cdr_res != 0) { 05215 res = cdr_res; 05216 goto outgoing_exten_cleanup; 05217 } 05218 } 05219 05220 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05221 /* check if "failed" exists */ 05222 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05223 chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); 05224 if (chan) { 05225 char failed_reason[4] = ""; 05226 if (!ast_strlen_zero(context)) 05227 ast_copy_string(chan->context, context, sizeof(chan->context)); 05228 set_ext_pri(chan, "failed", 1); 05229 ast_set_variables(chan, vars); 05230 snprintf(failed_reason, sizeof(failed_reason), "%d", *reason); 05231 pbx_builtin_setvar_helper(chan, "REASON", failed_reason); 05232 if (account) 05233 ast_cdr_setaccount(chan, account); 05234 if (ast_pbx_run(chan)) { 05235 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05236 ast_hangup(chan); 05237 } 05238 chan = NULL; 05239 } 05240 } 05241 } 05242 } else { 05243 if (!(as = ast_calloc(1, sizeof(*as)))) { 05244 res = -1; 05245 goto outgoing_exten_cleanup; 05246 } 05247 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05248 if (channel) { 05249 *channel = chan; 05250 if (chan) 05251 ast_channel_lock(chan); 05252 } 05253 if (!chan) { 05254 free(as); 05255 res = -1; 05256 goto outgoing_exten_cleanup; 05257 } 05258 as->chan = chan; 05259 ast_copy_string(as->context, context, sizeof(as->context)); 05260 set_ext_pri(as->chan, exten, priority); 05261 as->timeout = timeout; 05262 ast_set_variables(chan, vars); 05263 if (account) 05264 ast_cdr_setaccount(chan, account); 05265 pthread_attr_init(&attr); 05266 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05267 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05268 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05269 free(as); 05270 if (channel) { 05271 *channel = NULL; 05272 ast_channel_unlock(chan); 05273 } 05274 ast_hangup(chan); 05275 res = -1; 05276 pthread_attr_destroy(&attr); 05277 goto outgoing_exten_cleanup; 05278 } 05279 pthread_attr_destroy(&attr); 05280 res = 0; 05281 } 05282 outgoing_exten_cleanup: 05283 ast_variables_destroy(vars); 05284 return res; 05285 }
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 5295 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().
05296 { 05297 struct app_tmp *tmp = data; 05298 struct ast_app *app; 05299 app = pbx_findapp(tmp->app); 05300 if (app) { 05301 if (option_verbose > 3) 05302 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05303 pbx_exec(tmp->chan, app, tmp->data); 05304 } else 05305 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05306 ast_hangup(tmp->chan); 05307 free(tmp); 05308 return NULL; 05309 }
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 6420 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().
06421 { 06422 return ast_mutex_lock(&conlock); 06423 }
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 6443 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().
06444 { 06445 return ast_mutex_unlock(&con->lock); 06446 }
int ast_unlock_contexts | ( | void | ) |
Unlocks contexts.
0 | on success | |
-1 | on failure |
Definition at line 6430 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().
06431 { 06432 return ast_mutex_unlock(&conlock); 06433 }
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 6552 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().
06554 { 06555 if (!exten) 06556 return con ? con->root : NULL; 06557 else 06558 return exten->next; 06559 }
struct ast_ignorepat* ast_walk_context_ignorepats | ( | struct ast_context * | con, | |
struct ast_ignorepat * | ip | |||
) |
Definition at line 6585 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().
06587 { 06588 if (!ip) 06589 return con ? con->ignorepats : NULL; 06590 else 06591 return ip->next; 06592 }
struct ast_include* ast_walk_context_includes | ( | struct ast_context * | con, | |
struct ast_include * | inc | |||
) |
Definition at line 6576 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().
06578 { 06579 if (!inc) 06580 return con ? con->includes : NULL; 06581 else 06582 return inc->next; 06583 }
struct ast_sw* ast_walk_context_switches | ( | struct ast_context * | con, | |
struct ast_sw * | sw | |||
) |
Definition at line 6561 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().
06563 { 06564 if (!sw) 06565 return con ? AST_LIST_FIRST(&con->alts) : NULL; 06566 else 06567 return AST_LIST_NEXT(sw, list); 06568 }
struct ast_context* ast_walk_contexts | ( | struct ast_context * | con | ) |
Definition at line 6547 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 6570 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 6425 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().
06426 { 06427 return ast_mutex_lock(&conlock); 06428 }
static void* async_wait | ( | void * | data | ) | [static] |
Definition at line 5056 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().
05057 { 05058 struct async_stat *as = data; 05059 struct ast_channel *chan = as->chan; 05060 int timeout = as->timeout; 05061 int res; 05062 struct ast_frame *f; 05063 struct ast_app *app; 05064 05065 while (timeout && (chan->_state != AST_STATE_UP)) { 05066 res = ast_waitfor(chan, timeout); 05067 if (res < 1) 05068 break; 05069 if (timeout > -1) 05070 timeout = res; 05071 f = ast_read(chan); 05072 if (!f) 05073 break; 05074 if (f->frametype == AST_FRAME_CONTROL) { 05075 if ((f->subclass == AST_CONTROL_BUSY) || 05076 (f->subclass == AST_CONTROL_CONGESTION) ) { 05077 ast_frfree(f); 05078 break; 05079 } 05080 } 05081 ast_frfree(f); 05082 } 05083 if (chan->_state == AST_STATE_UP) { 05084 if (!ast_strlen_zero(as->app)) { 05085 app = pbx_findapp(as->app); 05086 if (app) { 05087 if (option_verbose > 2) 05088 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 05089 pbx_exec(chan, app, as->appdata); 05090 } else 05091 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 05092 } else { 05093 if (!ast_strlen_zero(as->context)) 05094 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 05095 if (!ast_strlen_zero(as->exten)) 05096 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 05097 if (as->priority > 0) 05098 chan->priority = as->priority; 05099 /* Run the PBX */ 05100 if (ast_pbx_run(chan)) { 05101 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 05102 } else { 05103 /* PBX will have taken care of this */ 05104 chan = NULL; 05105 } 05106 } 05107 } 05108 free(as); 05109 if (chan) 05110 ast_hangup(chan); 05111 return NULL; 05112 }
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 4808 of file pbx.c.
Referenced by ast_add_extension2().
04809 { 04810 int count=0; 04811 04812 while (*src && (count < len - 1)) { 04813 switch(*src) { 04814 case ' ': 04815 /* otherwise exten => [a-b],1,... doesn't work */ 04816 /* case '-': */ 04817 /* Ignore */ 04818 break; 04819 default: 04820 *dst = *src; 04821 dst++; 04822 } 04823 src++; 04824 count++; 04825 } 04826 *dst = '\0'; 04827 04828 return count; 04829 }
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 4221 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, lookup_name(), and s.
Referenced by ast_build_timing().
04222 { 04223 int s, e; /* start and ending position */ 04224 unsigned int mask = 0; 04225 04226 /* Check for whole range */ 04227 if (ast_strlen_zero(src) || !strcmp(src, "*")) { 04228 s = 0; 04229 e = max - 1; 04230 } else { 04231 /* Get start and ending position */ 04232 char *c = strchr(src, '-'); 04233 if (c) 04234 *c++ = '\0'; 04235 /* Find the start */ 04236 s = lookup_name(src, names, max); 04237 if (!s) { 04238 ast_log(LOG_WARNING, "Invalid %s '%s', assuming none\n", msg, src); 04239 return 0; 04240 } 04241 s--; 04242 if (c) { /* find end of range */ 04243 e = lookup_name(c, names, max); 04244 if (!e) { 04245 ast_log(LOG_WARNING, "Invalid end %s '%s', assuming none\n", msg, c); 04246 return 0; 04247 } 04248 e--; 04249 } else 04250 e = s; 04251 } 04252 /* Fill the mask. Remember that ranges are cyclic */ 04253 mask = 1 << e; /* initialize with last element */ 04254 while (s != e) { 04255 if (s >= max) { 04256 s = 0; 04257 mask |= (1 << s); 04258 } else { 04259 mask |= (1 << s); 04260 s++; 04261 } 04262 } 04263 return mask; 04264 }
static void get_timerange | ( | struct ast_timing * | i, | |
char * | times | |||
) | [static] |
store a bitmask of valid times, one bit each 2 minute
Definition at line 4267 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask.
Referenced by ast_build_timing().
04268 { 04269 char *e; 04270 int x; 04271 int s1, s2; 04272 int e1, e2; 04273 /* int cth, ctm; */ 04274 04275 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 04276 memset(i->minmask, 0, sizeof(i->minmask)); 04277 04278 /* 2-minutes per bit, since the mask has only 32 bits :( */ 04279 /* Star is all times */ 04280 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 04281 for (x=0; x<24; x++) 04282 i->minmask[x] = 0x3fffffff; /* 30 bits */ 04283 return; 04284 } 04285 /* Otherwise expect a range */ 04286 e = strchr(times, '-'); 04287 if (!e) { 04288 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n"); 04289 return; 04290 } 04291 *e++ = '\0'; 04292 /* XXX why skip non digits ? */ 04293 while (*e && !isdigit(*e)) 04294 e++; 04295 if (!*e) { 04296 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n"); 04297 return; 04298 } 04299 if (sscanf(times, "%2d:%2d", &s1, &s2) != 2) { 04300 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times); 04301 return; 04302 } 04303 if (sscanf(e, "%2d:%2d", &e1, &e2) != 2) { 04304 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e); 04305 return; 04306 } 04307 /* XXX this needs to be optimized */ 04308 #if 1 04309 s1 = s1 * 30 + s2/2; 04310 if ((s1 < 0) || (s1 >= 24*30)) { 04311 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times); 04312 return; 04313 } 04314 e1 = e1 * 30 + e2/2; 04315 if ((e1 < 0) || (e1 >= 24*30)) { 04316 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e); 04317 return; 04318 } 04319 /* Go through the time and enable each appropriate bit */ 04320 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) { 04321 i->minmask[x/30] |= (1 << (x % 30)); 04322 } 04323 /* Do the last one */ 04324 i->minmask[x/30] |= (1 << (x % 30)); 04325 #else 04326 for (cth=0; cth<24; cth++) { 04327 /* Initialize masks to blank */ 04328 i->minmask[cth] = 0; 04329 for (ctm=0; ctm<30; ctm++) { 04330 if ( 04331 /* First hour with more than one hour */ 04332 (((cth == s1) && (ctm >= s2)) && 04333 ((cth < e1))) 04334 /* Only one hour */ 04335 || (((cth == s1) && (ctm >= s2)) && 04336 ((cth == e1) && (ctm <= e2))) 04337 /* In between first and last hours (more than 2 hours) */ 04338 || ((cth > s1) && 04339 (cth < e1)) 04340 /* Last hour with more than one hour */ 04341 || ((cth > s1) && 04342 ((cth == e1) && (ctm <= e2))) 04343 ) 04344 i->minmask[cth] |= (1 << (ctm / 2)); 04345 } 04346 } 04347 #endif 04348 /* All done */ 04349 return; 04350 }
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 6697 of file pbx.c.
References exten, and ast_hint::exten.
Referenced by ast_pbx_init().
06698 { 06699 const struct ast_hint *hint = obj; 06700 const struct ast_exten *exten = arg; 06701 06702 return (hint->exten == exten) ? CMP_MATCH | CMP_STOP : 0; 06703 }
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 6389 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().
06390 { 06391 int x; 06392 06393 /* Initialize the PBX */ 06394 if (option_verbose) { 06395 ast_verbose( "Asterisk PBX Core Initializing\n"); 06396 ast_verbose( "Registering builtin applications:\n"); 06397 } 06398 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(struct ast_cli_entry)); 06399 06400 /* Register builtin applications */ 06401 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06402 if (option_verbose) 06403 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06404 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06405 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06406 return -1; 06407 } 06408 } 06409 return 0; 06410 }
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) { 04208 for (i = 0; names[i]; i++) { 04209 if (!strcasecmp(s, names[i])) 04210 return i+1; 04211 } 04212 } else if (sscanf(s, "%30d", &i) == 1 && i >= 1 && i <= max) { 04213 return i; 04214 } 04215 return 0; /* error return */ 04216 }
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 6191 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().
06192 { 06193 struct ast_var_t *vardata; 06194 06195 ast_mutex_lock(&globalslock); 06196 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06197 ast_var_delete(vardata); 06198 ast_mutex_unlock(&globalslock); 06199 }
const char* pbx_builtin_getvar_helper | ( | struct ast_channel * | chan, | |
const char * | name | |||
) |
Definition at line 5967 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().
05968 { 05969 struct ast_var_t *variables; 05970 const char *ret = NULL; 05971 int i; 05972 struct varshead *places[2] = { NULL, &globals }; 05973 05974 if (!name) 05975 return NULL; 05976 05977 if (chan) { 05978 ast_channel_lock(chan); 05979 places[0] = &chan->varshead; 05980 } 05981 05982 for (i = 0; i < 2; i++) { 05983 if (!places[i]) 05984 continue; 05985 if (places[i] == &globals) 05986 ast_mutex_lock(&globalslock); 05987 AST_LIST_TRAVERSE(places[i], variables, entries) { 05988 if (!strcmp(name, ast_var_name(variables))) { 05989 ret = ast_var_value(variables); 05990 break; 05991 } 05992 } 05993 if (places[i] == &globals) 05994 ast_mutex_unlock(&globalslock); 05995 if (ret) 05996 break; 05997 } 05998 05999 if (chan) 06000 ast_channel_unlock(chan); 06001 06002 return ret; 06003 }
static int pbx_builtin_gotoif | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6211 of file pbx.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, pbx_builtin_goto(), and pbx_checkcondition().
06212 { 06213 char *condition, *branch1, *branch2, *branch; 06214 int rc; 06215 char *stringp; 06216 06217 if (ast_strlen_zero(data)) { 06218 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06219 return 0; 06220 } 06221 06222 stringp = ast_strdupa(data); 06223 condition = strsep(&stringp,"?"); 06224 branch1 = strsep(&stringp,":"); 06225 branch2 = strsep(&stringp,""); 06226 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06227 06228 if (ast_strlen_zero(branch)) { 06229 if (option_debug) 06230 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06231 return 0; 06232 } 06233 06234 rc = pbx_builtin_goto(chan, branch); 06235 06236 return rc; 06237 }
int pbx_builtin_importvar | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6130 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.
06131 { 06132 char *name; 06133 char *value; 06134 char *channel; 06135 char tmp[VAR_BUF_SIZE]=""; 06136 06137 if (ast_strlen_zero(data)) { 06138 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06139 return 0; 06140 } 06141 06142 value = ast_strdupa(data); 06143 name = strsep(&value,"="); 06144 channel = strsep(&value,"|"); 06145 if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */ 06146 struct ast_channel *chan2 = ast_get_channel_by_name_locked(channel); 06147 if (chan2) { 06148 char *s = alloca(strlen(value) + 4); 06149 if (s) { 06150 sprintf(s, "${%s}", value); 06151 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 06152 } 06153 ast_channel_unlock(chan2); 06154 } 06155 pbx_builtin_setvar_helper(chan, name, tmp); 06156 } 06157 06158 return(0); 06159 }
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 6005 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().
06006 { 06007 struct ast_var_t *newvariable; 06008 struct varshead *headp; 06009 06010 if (name[strlen(name)-1] == ')') { 06011 char *function = ast_strdupa(name); 06012 06013 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 06014 ast_func_write(chan, function, value); 06015 return; 06016 } 06017 06018 if (chan) { 06019 ast_channel_lock(chan); 06020 headp = &chan->varshead; 06021 } else { 06022 ast_mutex_lock(&globalslock); 06023 headp = &globals; 06024 } 06025 06026 if (value) { 06027 if ((option_verbose > 1) && (headp == &globals)) 06028 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 06029 newvariable = ast_var_assign(name, value); 06030 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 06031 } 06032 06033 if (chan) 06034 ast_channel_unlock(chan); 06035 else 06036 ast_mutex_unlock(&globalslock); 06037 }
static int pbx_builtin_saycharacters | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6276 of file pbx.c.
References ast_say_character_str(), and ast_channel::language.
06277 { 06278 int res = 0; 06279 06280 if (data) 06281 res = ast_say_character_str(chan, data, "", chan->language); 06282 return res; 06283 }
static int pbx_builtin_saydate | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6294 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().
06295 { 06296 int res = 0; 06297 char *parse; 06298 int unixdate = 0; 06299 char charascii[2]; 06300 06301 AST_DECLARE_APP_ARGS(args, 06302 AST_APP_ARG(datestr); 06303 AST_APP_ARG(digits); 06304 ); 06305 06306 06307 if (ast_strlen_zero(data)) { 06308 ast_log(LOG_WARNING, "SayDate requires an argument (date)\n"); 06309 return -1; 06310 } 06311 06312 if (!(parse = ast_strdupa(data))) { 06313 ast_log(LOG_WARNING, "Memory Error!\n"); 06314 return -1; 06315 } 06316 06317 AST_STANDARD_APP_ARGS(args, parse); 06318 06319 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06320 ast_log(LOG_WARNING, "SayDate escape digits must be a subset from '0123456789*#'\n"); 06321 args.digits = ""; 06322 } 06323 06324 if (sscanf(args.datestr, "%d", &unixdate) != 1) { 06325 ast_log(LOG_WARNING, "Firt argument to SayDate must be numeric (date)\n"); 06326 return -1; 06327 } 06328 06329 res = ast_say_date(chan, (time_t)unixdate, args.digits, chan->language); 06330 if (res > 0) { 06331 if (isdigit(res) || (res == '*') || (res == '#')) { 06332 snprintf(charascii, 2, "%c", res); 06333 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06334 res = 0; 06335 } else { 06336 ast_log(LOG_WARNING, "SayDate: invalid return value (%d) detected\n", res); 06337 } 06338 } 06339 return res; 06340 }
static int pbx_builtin_saydigits | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6267 of file pbx.c.
References ast_say_digit_str(), and ast_channel::language.
06268 { 06269 int res = 0; 06270 06271 if (data) 06272 res = ast_say_digit_str(chan, data, "", chan->language); 06273 return res; 06274 }
static int pbx_builtin_saynumber | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6239 of file pbx.c.
References ast_copy_string(), ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, and LOG_WARNING.
06240 { 06241 char tmp[256]; 06242 char *number = tmp; 06243 char *options; 06244 06245 if (ast_strlen_zero(data)) { 06246 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06247 return -1; 06248 } 06249 ast_copy_string(tmp, data, sizeof(tmp)); 06250 strsep(&number, "|"); 06251 options = strsep(&number, "|"); 06252 if (options) { 06253 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06254 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06255 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06256 return -1; 06257 } 06258 } 06259 06260 if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) { 06261 ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp); 06262 } 06263 06264 return 0; 06265 }
static int pbx_builtin_sayphonetic | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6285 of file pbx.c.
References ast_say_phonetic_str(), and ast_channel::language.
06286 { 06287 int res = 0; 06288 06289 if (data) 06290 res = ast_say_phonetic_str(chan, data, "", chan->language); 06291 return res; 06292 }
static int pbx_builtin_saytime | ( | struct ast_channel * | , | |
void * | ||||
) | [static] |
Definition at line 6342 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().
06343 { 06344 int res = 0; 06345 char *parse; 06346 int secs = 0; 06347 char charascii[2]; 06348 06349 AST_DECLARE_APP_ARGS(args, 06350 AST_APP_ARG(timestr); 06351 AST_APP_ARG(digits); 06352 ); 06353 06354 if (ast_strlen_zero(data)) { 06355 ast_log(LOG_WARNING, "SayTime requires an argument (time in seconds)\n"); 06356 return -1; 06357 } 06358 06359 if (!(parse = ast_strdupa(data))) { 06360 ast_log(LOG_WARNING, "Memory Error!\n"); 06361 return -1; 06362 } 06363 06364 AST_STANDARD_APP_ARGS(args, parse); 06365 06366 if (!ast_strlen_zero(args.digits) && (strspn(args.digits, "0123456789*#") != strlen(args.digits))) { 06367 ast_log(LOG_WARNING, "SayTime escape digits must be a subset from '0123456789*#'\n"); 06368 args.digits = ""; 06369 } 06370 06371 if (sscanf(args.timestr, "%d", &secs) != 1) { 06372 ast_log(LOG_WARNING, "Firt argument to SayTime must be numeric (time in seconds)\n"); 06373 return -1; 06374 } 06375 06376 res = ast_say_time(chan, (time_t)secs, args.digits, chan->language); 06377 if (res > 0) { 06378 if (isdigit(res) || (res == '*') || (res == '#')) { 06379 snprintf(charascii, 2, "%c", res); 06380 pbx_builtin_setvar_helper(chan, "USER_INPUT", charascii); 06381 res = 0; 06382 } else { 06383 ast_log(LOG_WARNING, "SayTime: invalid return value (%d) detected\n", res); 06384 } 06385 } 06386 return res; 06387 }
int pbx_builtin_serialize_variables | ( | struct ast_channel * | chan, | |
char * | buf, | |||
size_t | size | |||
) |
Definition at line 5936 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().
05937 { 05938 struct ast_var_t *variables; 05939 const char *var, *val; 05940 int total = 0; 05941 05942 if (!chan) 05943 return 0; 05944 05945 memset(buf, 0, size); 05946 05947 ast_channel_lock(chan); 05948 05949 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05950 if ((var=ast_var_name(variables)) && (val=ast_var_value(variables)) 05951 /* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */ 05952 ) { 05953 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05954 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05955 break; 05956 } else 05957 total++; 05958 } else 05959 break; 05960 } 05961 05962 ast_channel_unlock(chan); 05963 05964 return total; 05965 }
static int pbx_builtin_setglobalvar | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 6162 of file pbx.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and pbx_builtin_setvar_helper().
06163 { 06164 char *name; 06165 char *stringp = data; 06166 static int dep_warning = 0; 06167 06168 if (ast_strlen_zero(data)) { 06169 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06170 return 0; 06171 } 06172 06173 name = strsep(&stringp, "="); 06174 06175 if (!dep_warning) { 06176 dep_warning = 1; 06177 ast_log(LOG_WARNING, "SetGlobalVar is deprecated. Please use Set(GLOBAL(%s)=%s) instead.\n", name, stringp); 06178 } 06179 06180 /*! \todo XXX watch out, leading whitespace ? */ 06181 pbx_builtin_setvar_helper(NULL, name, stringp); 06182 06183 return(0); 06184 }
int pbx_builtin_setvar | ( | struct ast_channel * | , | |
void * | ||||
) |
Definition at line 6090 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().
06091 { 06092 char *name, *value, *mydata; 06093 int argc; 06094 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 06095 int global = 0; 06096 int x; 06097 06098 if (ast_strlen_zero(data)) { 06099 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 06100 return 0; 06101 } 06102 06103 mydata = ast_strdupa(data); 06104 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 06105 06106 /* check for a trailing flags argument */ 06107 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 06108 argc--; 06109 if (strchr(argv[argc], 'g')) { 06110 ast_log(LOG_WARNING, "The use of the 'g' flag is deprecated. Please use Set(GLOBAL(foo)=bar) instead\n"); 06111 global = 1; 06112 } 06113 } 06114 06115 if (argc > 1) 06116 ast_log(LOG_WARNING, "Setting multiple variables at once within Set is deprecated. Please separate each name/value pair into its own line.\n"); 06117 06118 for (x = 0; x < argc; x++) { 06119 name = argv[x]; 06120 if ((value = strchr(name, '='))) { 06121 *value++ = '\0'; 06122 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 06123 } else 06124 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 06125 } 06126 06127 return(0); 06128 }
void pbx_builtin_setvar_helper | ( | struct ast_channel * | chan, | |
const char * | name, | |||
const char * | value | |||
) |
Definition at line 6039 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(), 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().
06040 { 06041 struct ast_var_t *newvariable; 06042 struct varshead *headp; 06043 const char *nametail = name; 06044 06045 if (name[strlen(name)-1] == ')') { 06046 char *function = ast_strdupa(name); 06047 06048 ast_func_write(chan, function, value); 06049 return; 06050 } 06051 06052 if (chan) { 06053 ast_channel_lock(chan); 06054 headp = &chan->varshead; 06055 } else { 06056 ast_mutex_lock(&globalslock); 06057 headp = &globals; 06058 } 06059 06060 /* For comparison purposes, we have to strip leading underscores */ 06061 if (*nametail == '_') { 06062 nametail++; 06063 if (*nametail == '_') 06064 nametail++; 06065 } 06066 06067 AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) { 06068 if (strcmp(ast_var_name(newvariable), nametail) == 0) { 06069 /* there is already such a variable, delete it */ 06070 AST_LIST_REMOVE_CURRENT(headp, entries); 06071 ast_var_delete(newvariable); 06072 break; 06073 } 06074 } 06075 AST_LIST_TRAVERSE_SAFE_END; 06076 06077 if (value) { 06078 if ((option_verbose > 1) && (headp == &globals)) 06079 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 06080 newvariable = ast_var_assign(name, value); 06081 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 06082 } 06083 06084 if (chan) 06085 ast_channel_unlock(chan); 06086 else 06087 ast_mutex_unlock(&globalslock); 06088 }
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 6201 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().
06202 { 06203 if (ast_strlen_zero(condition)) /* NULL or empty strings are false */ 06204 return 0; 06205 else if (*condition >= '0' && *condition <= '9') /* Numbers are evaluated for truth */ 06206 return atoi(condition); 06207 else /* Strings are true */ 06208 return 1; 06209 }
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 5506 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().
05507 { 05508 int res; 05509 struct ast_frame *f; 05510 int waittime; 05511 05512 if (ast_strlen_zero(data) || (sscanf(data, "%30d", &waittime) != 1) || (waittime < 0)) 05513 waittime = -1; 05514 if (waittime > -1) { 05515 ast_safe_sleep(chan, waittime * 1000); 05516 } else do { 05517 res = ast_waitfor(chan, -1); 05518 if (res < 0) 05519 return; 05520 f = ast_read(chan); 05521 if (f) 05522 ast_frfree(f); 05523 } while(f); 05524 }
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] |