#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 "asterisk.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/devicestate.h"
#include "asterisk/compat.h"
Include dependency graph for pbx.c:
Go to the source code of this file.
Data Structures | |
struct | app_tmp |
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 | dialplan_counters |
struct | pbx_builtin |
Declaration of builtin applications. More... | |
struct | store_hint |
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 | DONT_HAVE_LENGTH 0x80000000 |
#define | EXT_DATA_SIZE 8192 |
#define | EXTENSION_MATCH_CORE(data, pattern, match) |
#define | FIND_NEXT |
#define | HELPER_CANMATCH 3 |
#define | HELPER_EXEC 2 |
#define | HELPER_EXISTS 0 |
#define | HELPER_FINDLABEL 5 |
#define | HELPER_MATCHMORE 4 |
#define | HELPER_SPAWN 1 |
#define | LOG |
#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) |
Functions | |
void | __ast_context_destroy (struct ast_context *con, const char *registrar) |
static int | __ast_goto_if_exists (struct ast_channel *chan, char *context, char *exten, int priority, int async) |
static int | __ast_pbx_run (struct ast_channel *c) |
int | ast_active_calls (void) |
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) |
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) |
static int | ast_add_hint (struct ast_exten *e) |
ast_add_hint: Add hint to hint list, check initial extension state | |
AST_APP_OPTIONS (resetcdr_opts,{AST_APP_OPTION('w', AST_CDR_FLAG_POSTED), AST_APP_OPTION('a', AST_CDR_FLAG_LOCKED), AST_APP_OPTION('v', AST_CDR_FLAG_KEEP_VARS),}) | |
AST_APP_OPTIONS (waitexten_opts,{AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 1),}) | |
AST_APP_OPTIONS (background_opts,{AST_APP_OPTION('s', BACKGROUND_SKIP), AST_APP_OPTION('n', BACKGROUND_NOANSWER), AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN), AST_APP_OPTION('p', BACKGROUND_PLAYBACK),}) | |
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, char *context, char *exten, int priority) |
int | ast_build_timing (struct ast_timing *i, char *info_in) |
int | ast_canmatch_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
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 (struct ast_timing *i) |
int | ast_context_add_ignorepat (const char *con, const char *value, const char *registrar) |
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) |
int | ast_context_add_include2 (struct ast_context *con, const char *value, const char *registrar) |
int | ast_context_add_switch (const char *context, const char *sw, const char *data, int eval, const char *registrar) |
int | ast_context_add_switch2 (struct ast_context *con, const char *value, const char *data, int eval, const char *registrar) |
ast_context * | ast_context_create (struct ast_context **extcontexts, const char *name, const char *registrar) |
void | ast_context_destroy (struct ast_context *con, const char *registrar) |
ast_context * | ast_context_find (const char *name) |
int | ast_context_remove_extension (const char *context, const char *extension, int priority, const char *registrar) |
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_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) |
int | ast_context_remove_include2 (struct ast_context *con, const char *include, const char *registrar) |
int | ast_context_remove_switch (const char *context, const char *sw, const char *data, const char *registrar) |
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_verify_includes (struct ast_context *con) |
ast_custom_function * | ast_custom_function_find (char *name) |
int | ast_custom_function_register (struct ast_custom_function *acf) |
int | ast_custom_function_unregister (struct ast_custom_function *acf) |
int | ast_exec_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
int | ast_exists_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
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) |
int | ast_extension_state (struct ast_channel *c, char *context, char *exten) |
ast_extension_state: Check extension state for an extension by using hint | |
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) |
ast_extension_state2str: Return extension_state as string | |
int | ast_extension_state_add (const char *context, const char *exten, ast_state_cb_type callback, void *data) |
ast_extension_state_add: Add watcher for extension states | |
int | ast_extension_state_del (int id, ast_state_cb_type callback) |
ast_extension_state_del: Remove a watcher from the callback list | |
int | ast_findlabel_extension (struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) |
int | ast_findlabel_extension2 (struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid) |
char * | ast_func_read (struct ast_channel *chan, const char *in, char *workspace, size_t len) |
void | ast_func_write (struct ast_channel *chan, const char *in, const char *value) |
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) |
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) |
ast_get_hint: Get hint for channel | |
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, char *context, char *exten, int priority) |
static struct ast_exten * | ast_hint_extension (struct ast_channel *c, const char *context, const char *exten) |
ast_hint_extension: Find hint for given extension in context | |
void | ast_hint_state_changed (const char *device) |
int | ast_ignore_pattern (const char *context, const char *pattern) |
AST_LIST_HEAD (store_hints, store_hint) | |
int | ast_lock_context (struct ast_context *con) |
int | ast_lock_contexts () |
int | ast_matchmore_extension (struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) |
void | ast_merge_contexts_and_delete (struct ast_context **extcontexts, const char *registrar) |
AST_MUTEX_DEFINE_STATIC (hintlock) | |
AST_MUTEX_DEFINE_STATIC (switchlock) | |
AST_MUTEX_DEFINE_STATIC (applock) | |
AST_MUTEX_DEFINE_STATIC (conlock) | |
AST_MUTEX_DEFINE_STATIC (acflock) | |
AST_MUTEX_DEFINE_STATIC (maxcalllock) | |
AST_MUTEX_DEFINE_STATIC (globalslock) | |
int | ast_parseable_goto (struct ast_channel *chan, const char *goto_string) |
int | ast_pbx_outgoing_app (const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel) |
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) |
static void * | ast_pbx_run_app (void *data) |
enum ast_pbx_result | ast_pbx_start (struct ast_channel *c) |
int | ast_register_application (const char *app, int(*execute)(struct ast_channel *, void *), const char *synopsis, const char *description) |
Dynamically register a new dial plan application. | |
int | ast_register_switch (struct ast_switch *sw) |
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) |
int | ast_unlock_context (struct ast_context *con) |
int | ast_unlock_contexts () |
int | ast_unregister_application (const char *app) |
void | ast_unregister_switch (struct ast_switch *sw) |
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) |
static void * | async_wait (void *data) |
static char * | complete_show_application (char *line, char *word, int pos, int state) |
static char * | complete_show_applications (char *line, char *word, int pos, int state) |
static char * | complete_show_dialplan_context (char *line, char *word, int pos, int state) |
static char * | complete_show_function (char *line, char *word, int pos, int state) |
static void | decrease_call_count (void) |
static void | destroy_exten (struct ast_exten *e) |
static int | ext_strncpy (char *dst, const char *src, int len) |
static unsigned int | get_day (char *day) |
static unsigned int | get_dow (char *dow) |
get_dow: Get day of week | |
static unsigned int | get_month (char *mon) |
static void | get_timerange (struct ast_timing *i, char *times) |
static int | handle_show_application (int fd, int argc, char *argv[]) |
static int | handle_show_applications (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_functions (int fd, int argc, char *argv[]) |
static int | handle_show_hints (int fd, int argc, char *argv[]) |
handle_show_hints: CLI support for listing registred dial plan hints | |
static int | handle_show_switches (int fd, int argc, char *argv[]) |
handle_show_switches: CLI support for listing registred dial plan switches | |
static int | include_valid (struct ast_include *i) |
static int | increase_call_count (const struct ast_channel *c) |
int | load_pbx (void) |
static int | matchcid (const char *cidpattern, const char *callerid) |
static void | null_datad (void *foo) |
static int | parse_variable_name (char *var, int *offset, int *length, int *isfunc) |
static int | pbx_builtin_answer (struct ast_channel *, void *) |
static int | pbx_builtin_atimeout (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_dtimeout (struct ast_channel *, void *) |
static int | pbx_builtin_execiftime (struct ast_channel *, void *) |
char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
static int | pbx_builtin_goto (struct ast_channel *, void *) |
static int | pbx_builtin_gotoif (struct ast_channel *, void *) |
static int | pbx_builtin_gotoiftime (struct ast_channel *, void *) |
static int | pbx_builtin_hangup (struct ast_channel *, void *) |
static int | pbx_builtin_importvar (struct ast_channel *, void *) |
static int | pbx_builtin_noop (struct ast_channel *, void *) |
static int | pbx_builtin_progress (struct ast_channel *, void *) |
void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
static int | pbx_builtin_resetcdr (struct ast_channel *, void *) |
static int | pbx_builtin_ringing (struct ast_channel *, void *) |
static int | pbx_builtin_rtimeout (struct ast_channel *, void *) |
static int | pbx_builtin_saycharacters (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 *) |
int | pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
static int | pbx_builtin_setaccount (struct ast_channel *, void *) |
static int | pbx_builtin_setamaflags (struct ast_channel *, void *) |
static int | pbx_builtin_setglobalvar (struct ast_channel *, void *) |
static int | pbx_builtin_setlanguage (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_setvar_old (struct ast_channel *, void *) |
static int | pbx_builtin_wait (struct ast_channel *, void *) |
static int | pbx_builtin_waitexten (struct ast_channel *, void *) |
int | pbx_checkcondition (char *condition) |
static void | pbx_destroy (struct ast_pbx *p) |
int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data, int newstack) |
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, int action) |
static struct ast_exten * | pbx_find_extension (struct ast_channel *chan, struct ast_context *bypass, const char *context, const char *exten, int priority, const char *label, const char *callerid, int action, char *incstack[], int *stacklen, int *status, struct ast_switch **swo, char **data, const char **foundcontext) |
ast_app * | pbx_findapp (const char *app) |
Find application handle in linked list. | |
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 and functions in the dialplan --- | |
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 int | show_dialplan_helper (int fd, char *context, char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, 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 | wait_for_hangup (struct ast_channel *chan, void *data) |
Variables | |
static struct ast_custom_function * | acf_root = NULL |
static struct ast_app * | apps = NULL |
static int | autofallthrough = 0 |
static struct pbx_builtin | builtins [] |
Declaration of builtin applications. | |
static struct ast_context * | contexts = NULL |
static int | countcalls = 0 |
static char * | days [] |
static struct varshead | globals |
ast_hint * | hints = NULL |
static char * | months [] |
static struct ast_cli_entry | pbx_cli [] |
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_hints_help [] |
static char | show_switches_help [] |
ast_state_cb * | statecbs = NULL |
static int | stateid = 1 |
ast_switch * | switches = NULL |
Definition in file pbx.c.
|
Go no deeper than this through includes (not counting loops) Definition at line 565 of file pbx.c. Referenced by ast_hint_extension(), handle_show_dialplan(), pbx_extension_helper(), pbx_find_extension(), and show_dialplan_helper(). |
|
Definition at line 87 of file pbx.c. Referenced by pbx_builtin_background(). |
|
Definition at line 86 of file pbx.c. Referenced by pbx_builtin_background(). |
|
Definition at line 88 of file pbx.c. Referenced by pbx_builtin_background(). |
|
Definition at line 85 of file pbx.c. Referenced by pbx_builtin_background(). |
|
Definition at line 903 of file pbx.c. Referenced by parse_variable_name(). |
|
Definition at line 74 of file pbx.c. Referenced by pbx_extension_helper(), and realtime_exec(). |
|
Definition at line 625 of file pbx.c. Referenced by ast_extension_close(), and ast_extension_match(). |
|
Value: do { \ c = info; \ while(*c && (*c != '|')) c++; \ if (*c) { *c = '\0'; c++; } else c = NULL; \ } while(0) Definition at line 3830 of file pbx.c. Referenced by ast_build_timing(). |
|
Definition at line 570 of file pbx.c. Referenced by ast_canmatch_extension(), and pbx_extension_helper(). |
|
Definition at line 569 of file pbx.c. Referenced by ast_exec_extension(), and pbx_extension_helper(). |
|
Definition at line 567 of file pbx.c. Referenced by ast_exists_extension(), ast_hint_extension(), and pbx_extension_helper(). |
|
Definition at line 572 of file pbx.c. Referenced by ast_findlabel_extension(), ast_findlabel_extension2(), and pbx_extension_helper(). |
|
Definition at line 571 of file pbx.c. Referenced by ast_matchmore_extension(), and pbx_extension_helper(). |
|
Definition at line 568 of file pbx.c. Referenced by ast_spawn_extension(), and pbx_extension_helper(). |
|
Referenced by ast_add_extension2(). |
|
Definition at line 753 of file pbx.c. Referenced by pbx_extension_helper(), and pbx_find_extension(). |
|
Definition at line 754 of file pbx.c. Referenced by pbx_extension_helper(). |
|
Definition at line 756 of file pbx.c. Referenced by pbx_extension_helper(). |
|
Definition at line 755 of file pbx.c. Referenced by pbx_extension_helper(). |
|
|
|
Definition at line 77 of file pbx.c. Referenced by ast_context_add_switch2(). |
|
Definition at line 79 of file pbx.c. Referenced by ast_add_extension2(), pbx_builtin_importvar(), and pbx_substitute_variables_helper_full(). |
|
|
|
|
|
|
|
Definition at line 97 of file pbx.c. Referenced by pbx_builtin_waitexten(). |
|
Definition at line 5308 of file pbx.c. References ast_context::alts, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), contexts, destroy_exten(), el, free, ast_context::ignorepats, ast_context::includes, ast_context::lock, LOG_WARNING, ast_context::name, ast_exten::next, ast_sw::next, ast_ignorepat::next, ast_include::next, ast_context::next, ast_exten::peer, ast_context::registrar, and ast_context::root. Referenced by ast_context_destroy(). 05309 { 05310 struct ast_context *tmp, *tmpl=NULL; 05311 struct ast_include *tmpi, *tmpil= NULL; 05312 struct ast_sw *sw, *swl= NULL; 05313 struct ast_exten *e, *el, *en; 05314 struct ast_ignorepat *ipi, *ipl = NULL; 05315 05316 ast_mutex_lock(&conlock); 05317 tmp = contexts; 05318 while(tmp) { 05319 if (((tmp->name && con && con->name && !strcasecmp(tmp->name, con->name)) || !con) && 05320 (!registrar || !strcasecmp(registrar, tmp->registrar))) { 05321 /* Okay, let's lock the structure to be sure nobody else 05322 is searching through it. */ 05323 if (ast_mutex_lock(&tmp->lock)) { 05324 ast_log(LOG_WARNING, "Unable to lock context lock\n"); 05325 return; 05326 } 05327 if (tmpl) 05328 tmpl->next = tmp->next; 05329 else 05330 contexts = tmp->next; 05331 /* Okay, now we're safe to let it go -- in a sense, we were 05332 ready to let it go as soon as we locked it. */ 05333 ast_mutex_unlock(&tmp->lock); 05334 for (tmpi = tmp->includes; tmpi; ) { 05335 /* Free includes */ 05336 tmpil = tmpi; 05337 tmpi = tmpi->next; 05338 free(tmpil); 05339 } 05340 for (ipi = tmp->ignorepats; ipi; ) { 05341 /* Free ignorepats */ 05342 ipl = ipi; 05343 ipi = ipi->next; 05344 free(ipl); 05345 } 05346 for (sw = tmp->alts; sw; ) { 05347 /* Free switches */ 05348 swl = sw; 05349 sw = sw->next; 05350 free(swl); 05351 swl = sw; 05352 } 05353 for (e = tmp->root; e;) { 05354 for (en = e->peer; en;) { 05355 el = en; 05356 en = en->peer; 05357 destroy_exten(el); 05358 } 05359 el = e; 05360 e = e->next; 05361 destroy_exten(el); 05362 } 05363 ast_mutex_destroy(&tmp->lock); 05364 free(tmp); 05365 if (!con) { 05366 /* Might need to get another one -- restart */ 05367 tmp = contexts; 05368 tmpl = NULL; 05369 tmpil = NULL; 05370 continue; 05371 } 05372 ast_mutex_unlock(&conlock); 05373 return; 05374 } 05375 tmpl = tmp; 05376 tmp = tmp->next; 05377 } 05378 ast_mutex_unlock(&conlock); 05379 }
|
|
Definition at line 6445 of file pbx.c. References ast_async_goto(), ast_exists_extension(), ast_explicit_goto(), and ast_channel::context. Referenced by ast_async_goto_if_exists(), and ast_goto_if_exists(). 06446 { 06447 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06448 06449 if (!chan) 06450 return -2; 06451 06452 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06453 if (ast_exists_extension(chan, context ? context : chan->context, 06454 exten ? exten : chan->exten, priority, 06455 chan->cid.cid_num)) 06456 return goto_func(chan, context ? context : chan->context, 06457 exten ? exten : chan->exten, priority); 06458 else 06459 return -3; 06460 }
|
|
Definition at line 2235 of file pbx.c. References ast_channel::amaflags, ast_cdr_alloc(), ast_cdr_init(), ast_cdr_start(), ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, ast_log(), ast_set_flag, 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, exten, free, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, ast_channel::pbx, ast_channel::priority, ast_pbx::rtimeout, ast_cdr::start, and VERBOSE_PREFIX_2. Referenced by ast_pbx_run(), and pbx_thread(). 02236 { 02237 int firstpass = 1; 02238 int digit; 02239 char exten[256]; 02240 int pos; 02241 int waittime; 02242 int res=0; 02243 int autoloopflag; 02244 02245 /* A little initial setup here */ 02246 if (c->pbx) 02247 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name); 02248 c->pbx = malloc(sizeof(struct ast_pbx)); 02249 if (!c->pbx) { 02250 ast_log(LOG_ERROR, "Out of memory\n"); 02251 return -1; 02252 } 02253 if (c->amaflags) { 02254 if (!c->cdr) { 02255 c->cdr = ast_cdr_alloc(); 02256 if (!c->cdr) { 02257 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02258 free(c->pbx); 02259 return -1; 02260 } 02261 ast_cdr_init(c->cdr, c); 02262 } 02263 } 02264 memset(c->pbx, 0, sizeof(struct ast_pbx)); 02265 /* Set reasonable defaults */ 02266 c->pbx->rtimeout = 10; 02267 c->pbx->dtimeout = 5; 02268 02269 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); 02270 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP); 02271 02272 /* Start by trying whatever the channel is set to */ 02273 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02274 /* If not successful fall back to 's' */ 02275 if (option_verbose > 1) 02276 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); 02277 ast_copy_string(c->exten, "s", sizeof(c->exten)); 02278 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02279 /* JK02: And finally back to default if everything else failed */ 02280 if (option_verbose > 1) 02281 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); 02282 ast_copy_string(c->context, "default", sizeof(c->context)); 02283 } 02284 c->priority = 1; 02285 } 02286 if (c->cdr && !c->cdr->start.tv_sec && !c->cdr->start.tv_usec) 02287 ast_cdr_start(c->cdr); 02288 for(;;) { 02289 pos = 0; 02290 digit = 0; 02291 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02292 memset(exten, 0, sizeof(exten)); 02293 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02294 /* Something bad happened, or a hangup has been requested. */ 02295 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) || 02296 (res == '*') || (res == '#')) { 02297 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 02298 memset(exten, 0, sizeof(exten)); 02299 pos = 0; 02300 exten[pos++] = digit = res; 02301 break; 02302 } 02303 switch(res) { 02304 case AST_PBX_KEEPALIVE: 02305 if (option_debug) 02306 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02307 else if (option_verbose > 1) 02308 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02309 goto out; 02310 break; 02311 default: 02312 if (option_debug) 02313 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02314 else if (option_verbose > 1) 02315 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02316 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02317 c->_softhangup =0; 02318 break; 02319 } 02320 /* atimeout */ 02321 if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02322 break; 02323 } 02324 02325 if (c->cdr) { 02326 ast_cdr_update(c); 02327 } 02328 goto out; 02329 } 02330 } 02331 if ((c->_softhangup == AST_SOFTHANGUP_TIMEOUT) && (ast_exists_extension(c,c->context,"T",1,c->cid.cid_num))) { 02332 ast_copy_string(c->exten, "T", sizeof(c->exten)); 02333 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */ 02334 c->whentohangup = 0; 02335 c->priority = 0; 02336 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT; 02337 } else if (c->_softhangup) { 02338 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", 02339 c->exten, c->priority); 02340 goto out; 02341 } 02342 firstpass = 0; 02343 c->priority++; 02344 } 02345 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { 02346 /* It's not a valid extension anymore */ 02347 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02348 if (option_verbose > 2) 02349 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name); 02350 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten); 02351 ast_copy_string(c->exten, "i", sizeof(c->exten)); 02352 c->priority = 1; 02353 } else { 02354 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n", 02355 c->name, c->exten, c->context); 02356 goto out; 02357 } 02358 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02359 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */ 02360 c->_softhangup = 0; 02361 } else { 02362 /* Done, wait for an extension */ 02363 waittime = 0; 02364 if (digit) 02365 waittime = c->pbx->dtimeout; 02366 else if (!autofallthrough) 02367 waittime = c->pbx->rtimeout; 02368 if (waittime) { 02369 while (ast_matchmore_extension(c, c->context, exten, 1, c->cid.cid_num)) { 02370 /* As long as we're willing to wait, and as long as it's not defined, 02371 keep reading digits until we can't possibly get a right answer anymore. */ 02372 digit = ast_waitfordigit(c, waittime * 1000); 02373 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02374 c->_softhangup = 0; 02375 } else { 02376 if (!digit) 02377 /* No entry */ 02378 break; 02379 if (digit < 0) 02380 /* Error, maybe a hangup */ 02381 goto out; 02382 exten[pos++] = digit; 02383 waittime = c->pbx->dtimeout; 02384 } 02385 } 02386 if (ast_exists_extension(c, c->context, exten, 1, c->cid.cid_num)) { 02387 /* Prepare the next cycle */ 02388 ast_copy_string(c->exten, exten, sizeof(c->exten)); 02389 c->priority = 1; 02390 } else { 02391 /* No such extension */ 02392 if (!ast_strlen_zero(exten)) { 02393 /* An invalid extension */ 02394 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02395 if (option_verbose > 2) 02396 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name); 02397 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", exten); 02398 ast_copy_string(c->exten, "i", sizeof(c->exten)); 02399 c->priority = 1; 02400 } else { 02401 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", exten, c->context); 02402 goto out; 02403 } 02404 } else { 02405 /* A simple timeout */ 02406 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) { 02407 if (option_verbose > 2) 02408 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name); 02409 ast_copy_string(c->exten, "t", sizeof(c->exten)); 02410 c->priority = 1; 02411 } else { 02412 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context); 02413 goto out; 02414 } 02415 } 02416 } 02417 if (c->cdr) { 02418 if (option_verbose > 2) 02419 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name); 02420 ast_cdr_update(c); 02421 } 02422 } else { 02423 char *status; 02424 02425 status = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 02426 if (!status) 02427 status = "UNKNOWN"; 02428 if (option_verbose > 2) 02429 ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status); 02430 if (!strcasecmp(status, "CONGESTION")) 02431 res = pbx_builtin_congestion(c, "10"); 02432 else if (!strcasecmp(status, "CHANUNAVAIL")) 02433 res = pbx_builtin_congestion(c, "10"); 02434 else if (!strcasecmp(status, "BUSY")) 02435 res = pbx_builtin_busy(c, "10"); 02436 goto out; 02437 } 02438 } 02439 } 02440 if (firstpass) 02441 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); 02442 out: 02443 if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) { 02444 c->exten[0] = 'h'; 02445 c->exten[1] = '\0'; 02446 c->priority = 1; 02447 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02448 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02449 /* Something bad happened, or a hangup has been requested. */ 02450 if (option_debug) 02451 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02452 else if (option_verbose > 1) 02453 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02454 break; 02455 } 02456 c->priority++; 02457 } 02458 } 02459 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP); 02460 02461 pbx_destroy(c->pbx); 02462 c->pbx = NULL; 02463 if (res != AST_PBX_KEEPALIVE) 02464 ast_hangup(c); 02465 return 0; 02466 }
|
|
Definition at line 2559 of file pbx.c. Referenced by handle_chanlist(). 02560 { 02561 return countcalls; 02562 }
|
|
Definition at line 4502 of file pbx.c. References ast_add_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). Referenced by handle_context_add_extension(), and register_peer_exten(). 04504 { 04505 struct ast_context *c; 04506 04507 if (ast_lock_contexts()) { 04508 errno = EBUSY; 04509 return -1; 04510 } 04511 04512 c = ast_walk_contexts(NULL); 04513 while (c) { 04514 if (!strcmp(context, ast_get_context_name(c))) { 04515 int ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04516 application, data, datad, registrar); 04517 ast_unlock_contexts(); 04518 return ret; 04519 } 04520 c = ast_walk_contexts(c); 04521 } 04522 04523 ast_unlock_contexts(); 04524 errno = ENOENT; 04525 return -1; 04526 }
|
|
For details about the arguements, check ast_add_extension() Definition at line 4641 of file pbx.c. References ast_add_hint(), ast_change_hint(), AST_LIST_FIRST, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_exten::cidmatch, ast_exten::data, ast_exten::datad, el, ext_strncpy(), ast_exten::exten, free, ast_context::lock, LOG, LOG_ERROR, LOG_WARNING, malloc, ast_exten::matchcid, ast_context::name, ast_exten::next, null_datad(), pbx_substitute_variables_varshead(), ast_exten::peer, ast_exten::priority, PRIORITY_HINT, ast_context::registrar, ast_context::root, and VAR_BUF_SIZE. Referenced by __build_step(), ast_add_extension(), do_parking_thread(), fillin_process(), handle_macro(), load_config(), and pbx_load_module(). 04645 { 04646 04647 #define LOG do { if (option_debug) {\ 04648 if (tmp->matchcid) { \ 04649 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \ 04650 } else { \ 04651 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \ 04652 } \ 04653 } else if (option_verbose > 2) { \ 04654 if (tmp->matchcid) { \ 04655 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \ 04656 } else { \ 04657 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \ 04658 } \ 04659 } } while(0) 04660 04661 /* 04662 * This is a fairly complex routine. Different extensions are kept 04663 * in order by the extension number. Then, extensions of different 04664 * priorities (same extension) are kept in a list, according to the 04665 * peer pointer. 04666 */ 04667 struct ast_exten *tmp, *e, *el = NULL, *ep = NULL; 04668 int res; 04669 int length; 04670 char *p; 04671 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04672 04673 /* if we are adding a hint, and there are global variables, and the hint 04674 contains variable references, then expand them 04675 */ 04676 ast_mutex_lock(&globalslock); 04677 if ((priority == PRIORITY_HINT) && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04678 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04679 application = expand_buf; 04680 } 04681 ast_mutex_unlock(&globalslock); 04682 04683 length = sizeof(struct ast_exten); 04684 length += strlen(extension) + 1; 04685 length += strlen(application) + 1; 04686 if (label) 04687 length += strlen(label) + 1; 04688 if (callerid) 04689 length += strlen(callerid) + 1; 04690 else 04691 length ++; 04692 04693 /* Be optimistic: Build the extension structure first */ 04694 if (datad == NULL) 04695 datad = null_datad; 04696 tmp = malloc(length); 04697 if (tmp) { 04698 memset(tmp, 0, length); 04699 p = tmp->stuff; 04700 if (label) { 04701 tmp->label = p; 04702 strcpy(tmp->label, label); 04703 p += strlen(label) + 1; 04704 } 04705 tmp->exten = p; 04706 p += ext_strncpy(tmp->exten, extension, strlen(extension) + 1) + 1; 04707 tmp->priority = priority; 04708 tmp->cidmatch = p; 04709 if (callerid) { 04710 p += ext_strncpy(tmp->cidmatch, callerid, strlen(callerid) + 1) + 1; 04711 tmp->matchcid = 1; 04712 } else { 04713 tmp->cidmatch[0] = '\0'; 04714 tmp->matchcid = 0; 04715 p++; 04716 } 04717 tmp->app = p; 04718 strcpy(tmp->app, application); 04719 tmp->parent = con; 04720 tmp->data = data; 04721 tmp->datad = datad; 04722 tmp->registrar = registrar; 04723 tmp->peer = NULL; 04724 tmp->next = NULL; 04725 } else { 04726 ast_log(LOG_ERROR, "Out of memory\n"); 04727 errno = ENOMEM; 04728 return -1; 04729 } 04730 if (ast_mutex_lock(&con->lock)) { 04731 free(tmp); 04732 /* And properly destroy the data */ 04733 datad(data); 04734 ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name); 04735 errno = EBUSY; 04736 return -1; 04737 } 04738 e = con->root; 04739 while(e) { 04740 /* Make sure patterns are always last! */ 04741 if ((e->exten[0] != '_') && (extension[0] == '_')) 04742 res = -1; 04743 else if ((e->exten[0] == '_') && (extension[0] != '_')) 04744 res = 1; 04745 else 04746 res= strcmp(e->exten, extension); 04747 if (!res) { 04748 if (!e->matchcid && !tmp->matchcid) 04749 res = 0; 04750 else if (tmp->matchcid && !e->matchcid) 04751 res = 1; 04752 else if (e->matchcid && !tmp->matchcid) 04753 res = -1; 04754 else 04755 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04756 } 04757 if (res == 0) { 04758 /* We have an exact match, now we find where we are 04759 and be sure there's no duplicates */ 04760 while(e) { 04761 if (e->priority == tmp->priority) { 04762 /* Can't have something exactly the same. Is this a 04763 replacement? If so, replace, otherwise, bonk. */ 04764 if (replace) { 04765 if (ep) { 04766 /* We're in the peer list, insert ourselves */ 04767 ep->peer = tmp; 04768 tmp->peer = e->peer; 04769 } else if (el) { 04770 /* We're the first extension. Take over e's functions */ 04771 el->next = tmp; 04772 tmp->next = e->next; 04773 tmp->peer = e->peer; 04774 } else { 04775 /* We're the very first extension. */ 04776 con->root = tmp; 04777 tmp->next = e->next; 04778 tmp->peer = e->peer; 04779 } 04780 if (tmp->priority == PRIORITY_HINT) 04781 ast_change_hint(e,tmp); 04782 /* Destroy the old one */ 04783 e->datad(e->data); 04784 free(e); 04785 ast_mutex_unlock(&con->lock); 04786 if (tmp->priority == PRIORITY_HINT) 04787 ast_change_hint(e, tmp); 04788 /* And immediately return success. */ 04789 LOG; 04790 return 0; 04791 } else { 04792 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04793 tmp->datad(tmp->data); 04794 free(tmp); 04795 ast_mutex_unlock(&con->lock); 04796 errno = EEXIST; 04797 return -1; 04798 } 04799 } else if (e->priority > tmp->priority) { 04800 /* Slip ourselves in just before e */ 04801 if (ep) { 04802 /* Easy enough, we're just in the peer list */ 04803 ep->peer = tmp; 04804 tmp->peer = e; 04805 } else if (el) { 04806 /* We're the first extension in this peer list */ 04807 el->next = tmp; 04808 tmp->next = e->next; 04809 e->next = NULL; 04810 tmp->peer = e; 04811 } else { 04812 /* We're the very first extension altogether */ 04813 tmp->next = con->root->next; 04814 /* Con->root must always exist or we couldn't get here */ 04815 tmp->peer = con->root; 04816 con->root = tmp; 04817 } 04818 ast_mutex_unlock(&con->lock); 04819 04820 /* And immediately return success. */ 04821 if (tmp->priority == PRIORITY_HINT) 04822 ast_add_hint(tmp); 04823 04824 LOG; 04825 return 0; 04826 } 04827 ep = e; 04828 e = e->peer; 04829 } 04830 /* If we make it here, then it's time for us to go at the very end. 04831 ep *must* be defined or we couldn't have gotten here. */ 04832 ep->peer = tmp; 04833 ast_mutex_unlock(&con->lock); 04834 if (tmp->priority == PRIORITY_HINT) 04835 ast_add_hint(tmp); 04836 04837 /* And immediately return success. */ 04838 LOG; 04839 return 0; 04840 04841 } else if (res > 0) { 04842 /* Insert ourselves just before 'e'. We're the first extension of 04843 this kind */ 04844 tmp->next = e; 04845 if (el) { 04846 /* We're in the list somewhere */ 04847 el->next = tmp; 04848 } else { 04849 /* We're at the top of the list */ 04850 con->root = tmp; 04851 } 04852 ast_mutex_unlock(&con->lock); 04853 if (tmp->priority == PRIORITY_HINT) 04854 ast_add_hint(tmp); 04855 04856 /* And immediately return success. */ 04857 LOG; 04858 return 0; 04859 } 04860 04861 el = e; 04862 e = e->next; 04863 } 04864 /* If we fall all the way through to here, then we need to be on the end. */ 04865 if (el) 04866 el->next = tmp; 04867 else 04868 con->root = tmp; 04869 ast_mutex_unlock(&con->lock); 04870 if (tmp->priority == PRIORITY_HINT) 04871 ast_add_hint(tmp); 04872 LOG; 04873 return 0; 04874 }
|
|
ast_add_hint: Add hint to hint list, check initial extension state
Definition at line 2072 of file pbx.c. References ast_extension_state2(), ast_get_extension_app(), ast_get_extension_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), hints, list, LOG_DEBUG, malloc, ast_imager::next, and option_debug. Referenced by ast_add_extension2(). 02073 { 02074 struct ast_hint *list; 02075 02076 if (!e) 02077 return -1; 02078 02079 ast_mutex_lock(&hintlock); 02080 list = hints; 02081 02082 /* Search if hint exists, do nothing */ 02083 while (list) { 02084 if (list->exten == e) { 02085 ast_mutex_unlock(&hintlock); 02086 if (option_debug > 1) 02087 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02088 return -1; 02089 } 02090 list = list->next; 02091 } 02092 02093 if (option_debug > 1) 02094 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02095 02096 list = malloc(sizeof(struct ast_hint)); 02097 if (!list) { 02098 ast_mutex_unlock(&hintlock); 02099 if (option_debug > 1) 02100 ast_log(LOG_DEBUG, "HINTS: Out of memory...\n"); 02101 return -1; 02102 } 02103 /* Initialize and insert new item at the top */ 02104 memset(list, 0, sizeof(struct ast_hint)); 02105 list->exten = e; 02106 list->laststate = ast_extension_state2(e); 02107 list->next = hints; 02108 hints = list; 02109 02110 ast_mutex_unlock(&hintlock); 02111 return 0; 02112 }
|
|
|
|
|
|
|
|
Definition at line 4547 of file pbx.c. References ast_channel::_state, ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_explicit_goto(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_strlen_zero(), ast_channel::context, ast_channel::exten, ast_channel::lock, LOG_WARNING, ast_channel::name, ast_channel::pbx, ast_channel::readformat, and ast_channel::writeformat. Referenced by __ast_goto_if_exists(), action_redirect(), ast_async_goto_by_name(), builtin_blindtransfer(), console_transfer(), handle_request_bye(), handle_request_refer(), misdn_tx2ast_frm(), monitor_handle_owned(), socket_read(), and zt_read(). 04548 { 04549 int res = 0; 04550 04551 ast_mutex_lock(&chan->lock); 04552 04553 if (chan->pbx) { 04554 /* This channel is currently in the PBX */ 04555 ast_explicit_goto(chan, context, exten, priority); 04556 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04557 } else { 04558 /* In order to do it when the channel doesn't really exist within 04559 the PBX, we have to make a new channel, masquerade, and start the PBX 04560 at the new location */ 04561 struct ast_channel *tmpchan; 04562 tmpchan = ast_channel_alloc(0); 04563 if (tmpchan) { 04564 snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name); 04565 ast_setstate(tmpchan, chan->_state); 04566 /* Make formats okay */ 04567 tmpchan->readformat = chan->readformat; 04568 tmpchan->writeformat = chan->writeformat; 04569 /* Setup proper location */ 04570 ast_explicit_goto(tmpchan, 04571 (!ast_strlen_zero(context)) ? context : chan->context, 04572 (!ast_strlen_zero(exten)) ? exten : chan->exten, 04573 priority); 04574 04575 /* Masquerade into temp channel */ 04576 ast_channel_masquerade(tmpchan, chan); 04577 04578 /* Grab the locks and get going */ 04579 ast_mutex_lock(&tmpchan->lock); 04580 ast_do_masquerade(tmpchan); 04581 ast_mutex_unlock(&tmpchan->lock); 04582 /* Start the PBX going on our stolen channel */ 04583 if (ast_pbx_start(tmpchan)) { 04584 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04585 ast_hangup(tmpchan); 04586 res = -1; 04587 } 04588 } else { 04589 res = -1; 04590 } 04591 } 04592 ast_mutex_unlock(&chan->lock); 04593 return res; 04594 }
|
|
Definition at line 4596 of file pbx.c. References ast_async_goto(), ast_get_channel_by_name_locked(), ast_mutex_unlock(), and ast_channel::lock. 04597 { 04598 struct ast_channel *chan; 04599 int res = -1; 04600 04601 chan = ast_get_channel_by_name_locked(channame); 04602 if (chan) { 04603 res = ast_async_goto(chan, context, exten, priority); 04604 ast_mutex_unlock(&chan->lock); 04605 } 04606 return res; 04607 }
|
|
Definition at line 6466 of file pbx.c. References __ast_goto_if_exists(). 06466 { 06467 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06468 }
|
|
Definition at line 4080 of file pbx.c. References ast_strlen_zero(), ast_timing::daymask, ast_timing::dowmask, FIND_NEXT, get_day(), get_dow(), get_month(), get_timerange(), and ast_timing::monthmask. Referenced by ast_context_add_include2(), builtin_function_iftime(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime(). 04081 { 04082 char info_save[256]; 04083 char *info; 04084 char *c; 04085 04086 /* Check for empty just in case */ 04087 if (ast_strlen_zero(info_in)) 04088 return 0; 04089 /* make a copy just in case we were passed a static string */ 04090 ast_copy_string(info_save, info_in, sizeof(info_save)); 04091 info = info_save; 04092 /* Assume everything except time */ 04093 i->monthmask = (1 << 12) - 1; 04094 i->daymask = (1 << 30) - 1 + (1 << 30); 04095 i->dowmask = (1 << 7) - 1; 04096 /* Avoid using str tok */ 04097 FIND_NEXT; 04098 /* Info has the time range, start with that */ 04099 get_timerange(i, info); 04100 info = c; 04101 if (!info) 04102 return 1; 04103 FIND_NEXT; 04104 /* Now check for day of week */ 04105 i->dowmask = get_dow(info); 04106 04107 info = c; 04108 if (!info) 04109 return 1; 04110 FIND_NEXT; 04111 /* Now check for the day of the month */ 04112 i->daymask = get_day(info); 04113 info = c; 04114 if (!info) 04115 return 1; 04116 FIND_NEXT; 04117 /* And finally go for the month */ 04118 i->monthmask = get_month(info); 04119 04120 return 1; 04121 }
|
|
Definition at line 2215 of file pbx.c. References HELPER_CANMATCH, and pbx_extension_helper(). Referenced by background_detect_exec(), cb_events(), dp_lookup(), dundi_lookup_local(), get_also_info(), get_destination(), get_refer_info(), handle_link_data(), handle_link_phone_dtmf(), loopback_canmatch(), mgcp_ss(), monitor_handle_notowned(), phone_check_exception(), rpt(), skinny_ss(), ss_thread(), and valid_exit(). 02216 { 02217 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_CANMATCH); 02218 }
|
|
ast_change_hint: Change hint for an extension
Definition at line 2115 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), hints, list, and ast_imager::next. Referenced by ast_add_extension2(). 02116 { 02117 struct ast_hint *list; 02118 02119 ast_mutex_lock(&hintlock); 02120 list = hints; 02121 02122 while(list) { 02123 if (list->exten == oe) { 02124 list->exten = ne; 02125 ast_mutex_unlock(&hintlock); 02126 return 0; 02127 } 02128 list = list->next; 02129 } 02130 ast_mutex_unlock(&hintlock); 02131 02132 return -1; 02133 }
|
|
Definition at line 4123 of file pbx.c. References ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, ast_timing::monthmask, and t. Referenced by builtin_function_iftime(), include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime(). 04124 { 04125 struct tm tm; 04126 time_t t; 04127 04128 time(&t); 04129 localtime_r(&t,&tm); 04130 04131 /* If it's not the right month, return */ 04132 if (!(i->monthmask & (1 << tm.tm_mon))) { 04133 return 0; 04134 } 04135 04136 /* If it's not that time of the month.... */ 04137 /* Warning, tm_mday has range 1..31! */ 04138 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04139 return 0; 04140 04141 /* If it's not the right day of the week */ 04142 if (!(i->dowmask & (1 << tm.tm_wday))) 04143 return 0; 04144 04145 /* Sanity check the hour just to be safe */ 04146 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04147 ast_log(LOG_WARNING, "Insane time...\n"); 04148 return 0; 04149 } 04150 04151 /* Now the tough part, we calculate if it fits 04152 in the right time based on min/hour */ 04153 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04154 return 0; 04155 04156 /* If we got this far, then we're good */ 04157 return 1; 04158 }
|
|
Definition at line 4419 of file pbx.c. References ast_context_add_ignorepat2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). Referenced by handle_context_add_ignorepat(). 04420 { 04421 struct ast_context *c; 04422 04423 if (ast_lock_contexts()) { 04424 errno = EBUSY; 04425 return -1; 04426 } 04427 04428 c = ast_walk_contexts(NULL); 04429 while (c) { 04430 if (!strcmp(ast_get_context_name(c), con)) { 04431 int ret = ast_context_add_ignorepat2(c, value, registrar); 04432 ast_unlock_contexts(); 04433 return ret; 04434 } 04435 c = ast_walk_contexts(c); 04436 } 04437 04438 ast_unlock_contexts(); 04439 errno = ENOENT; 04440 return -1; 04441 }
|
|
Definition at line 4443 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_context::ignorepats, ast_context::lock, LOG_ERROR, malloc, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar. Referenced by ast_context_add_ignorepat(), handle_context(), and pbx_load_module(). 04444 { 04445 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04446 int length; 04447 length = sizeof(struct ast_ignorepat); 04448 length += strlen(value) + 1; 04449 ignorepat = malloc(length); 04450 if (!ignorepat) { 04451 ast_log(LOG_ERROR, "Out of memory\n"); 04452 errno = ENOMEM; 04453 return -1; 04454 } 04455 memset(ignorepat, 0, length); 04456 strcpy(ignorepat->pattern, value); 04457 ignorepat->next = NULL; 04458 ignorepat->registrar = registrar; 04459 ast_mutex_lock(&con->lock); 04460 ignorepatc = con->ignorepats; 04461 while(ignorepatc) { 04462 ignorepatl = ignorepatc; 04463 if (!strcasecmp(ignorepatc->pattern, value)) { 04464 /* Already there */ 04465 ast_mutex_unlock(&con->lock); 04466 errno = EEXIST; 04467 return -1; 04468 } 04469 ignorepatc = ignorepatc->next; 04470 } 04471 if (ignorepatl) 04472 ignorepatl->next = ignorepat; 04473 else 04474 con->ignorepats = ignorepat; 04475 ast_mutex_unlock(&con->lock); 04476 return 0; 04477 04478 }
|
|
Definition at line 3802 of file pbx.c. References ast_context_add_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). Referenced by handle_context_add_include(). 03803 { 03804 struct ast_context *c; 03805 03806 if (ast_lock_contexts()) { 03807 errno = EBUSY; 03808 return -1; 03809 } 03810 03811 /* walk contexts ... */ 03812 c = ast_walk_contexts(NULL); 03813 while (c) { 03814 /* ... search for the right one ... */ 03815 if (!strcmp(ast_get_context_name(c), context)) { 03816 int ret = ast_context_add_include2(c, include, registrar); 03817 /* ... unlock contexts list and return */ 03818 ast_unlock_contexts(); 03819 return ret; 03820 } 03821 c = ast_walk_contexts(c); 03822 } 03823 03824 /* we can't find the right context */ 03825 ast_unlock_contexts(); 03826 errno = ENOENT; 03827 return -1; 03828 }
|
|
Definition at line 4167 of file pbx.c. References ast_build_timing(), ast_get_context_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, ast_include::hastime, ast_context::includes, ast_context::lock, LOG_ERROR, malloc, 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(), handle_context(), and pbx_load_module(). 04169 { 04170 struct ast_include *new_include; 04171 char *c; 04172 struct ast_include *i, *il = NULL; /* include, include_last */ 04173 int length; 04174 char *p; 04175 04176 length = sizeof(struct ast_include); 04177 length += 2 * (strlen(value) + 1); 04178 04179 /* allocate new include structure ... */ 04180 if (!(new_include = malloc(length))) { 04181 ast_log(LOG_ERROR, "Out of memory\n"); 04182 errno = ENOMEM; 04183 return -1; 04184 } 04185 04186 /* ... fill in this structure ... */ 04187 memset(new_include, 0, length); 04188 p = new_include->stuff; 04189 new_include->name = p; 04190 strcpy(new_include->name, value); 04191 p += strlen(value) + 1; 04192 new_include->rname = p; 04193 strcpy(new_include->rname, value); 04194 c = new_include->rname; 04195 /* Strip off timing info */ 04196 while(*c && (*c != '|')) 04197 c++; 04198 /* Process if it's there */ 04199 if (*c) { 04200 new_include->hastime = ast_build_timing(&(new_include->timing), c+1); 04201 *c = '\0'; 04202 } 04203 new_include->next = NULL; 04204 new_include->registrar = registrar; 04205 04206 /* ... try to lock this context ... */ 04207 if (ast_mutex_lock(&con->lock)) { 04208 free(new_include); 04209 errno = EBUSY; 04210 return -1; 04211 } 04212 04213 /* ... go to last include and check if context is already included too... */ 04214 i = con->includes; 04215 while (i) { 04216 if (!strcasecmp(i->name, new_include->name)) { 04217 free(new_include); 04218 ast_mutex_unlock(&con->lock); 04219 errno = EEXIST; 04220 return -1; 04221 } 04222 il = i; 04223 i = i->next; 04224 } 04225 04226 /* ... include new context into context list, unlock, return */ 04227 if (il) 04228 il->next = new_include; 04229 else 04230 con->includes = new_include; 04231 if (option_verbose > 2) 04232 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04233 ast_mutex_unlock(&con->lock); 04234 04235 return 0; 04236 }
|
|
Definition at line 4243 of file pbx.c. References ast_context_add_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). 04244 { 04245 struct ast_context *c; 04246 04247 if (ast_lock_contexts()) { 04248 errno = EBUSY; 04249 return -1; 04250 } 04251 04252 /* walk contexts ... */ 04253 c = ast_walk_contexts(NULL); 04254 while (c) { 04255 /* ... search for the right one ... */ 04256 if (!strcmp(ast_get_context_name(c), context)) { 04257 int ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04258 /* ... unlock contexts list and return */ 04259 ast_unlock_contexts(); 04260 return ret; 04261 } 04262 c = ast_walk_contexts(c); 04263 } 04264 04265 /* we can't find the right context */ 04266 ast_unlock_contexts(); 04267 errno = ENOENT; 04268 return -1; 04269 }
|
|
Definition at line 4278 of file pbx.c. References ast_context::alts, ast_get_context_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_sw::data, ast_sw::eval, free, ast_context::lock, LOG_ERROR, malloc, ast_sw::name, ast_sw::next, option_verbose, ast_sw::registrar, ast_sw::stuff, SWITCH_DATA_LENGTH, ast_sw::tmpdata, and VERBOSE_PREFIX_3. Referenced by ast_context_add_switch(), handle_context(), and pbx_load_module(). 04280 { 04281 struct ast_sw *new_sw; 04282 struct ast_sw *i, *il = NULL; /* sw, sw_last */ 04283 int length; 04284 char *p; 04285 04286 length = sizeof(struct ast_sw); 04287 length += strlen(value) + 1; 04288 if (data) 04289 length += strlen(data); 04290 length++; 04291 if (eval) { 04292 /* Create buffer for evaluation of variables */ 04293 length += SWITCH_DATA_LENGTH; 04294 length++; 04295 } 04296 04297 /* allocate new sw structure ... */ 04298 if (!(new_sw = malloc(length))) { 04299 ast_log(LOG_ERROR, "Out of memory\n"); 04300 errno = ENOMEM; 04301 return -1; 04302 } 04303 04304 /* ... fill in this structure ... */ 04305 memset(new_sw, 0, length); 04306 p = new_sw->stuff; 04307 new_sw->name = p; 04308 strcpy(new_sw->name, value); 04309 p += strlen(value) + 1; 04310 new_sw->data = p; 04311 if (data) { 04312 strcpy(new_sw->data, data); 04313 p += strlen(data) + 1; 04314 } else { 04315 strcpy(new_sw->data, ""); 04316 p++; 04317 } 04318 if (eval) 04319 new_sw->tmpdata = p; 04320 new_sw->next = NULL; 04321 new_sw->eval = eval; 04322 new_sw->registrar = registrar; 04323 04324 /* ... try to lock this context ... */ 04325 if (ast_mutex_lock(&con->lock)) { 04326 free(new_sw); 04327 errno = EBUSY; 04328 return -1; 04329 } 04330 04331 /* ... go to last sw and check if context is already swd too... */ 04332 i = con->alts; 04333 while (i) { 04334 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04335 free(new_sw); 04336 ast_mutex_unlock(&con->lock); 04337 errno = EEXIST; 04338 return -1; 04339 } 04340 il = i; 04341 i = i->next; 04342 } 04343 04344 /* ... sw new context into context list, unlock, return */ 04345 if (il) 04346 il->next = new_sw; 04347 else 04348 con->alts = new_sw; 04349 if (option_verbose > 2) 04350 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04351 ast_mutex_unlock(&con->lock); 04352 04353 return 0; 04354 }
|
|
Definition at line 3637 of file pbx.c. References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), contexts, ast_context::includes, local_contexts, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, ast_context::name, ast_context::next, option_verbose, and VERBOSE_PREFIX_3. Referenced by do_parking_thread(), handle_context(), handle_macro(), load_config(), pbx_load_module(), reload_config(), and set_config(). 03638 { 03639 struct ast_context *tmp, **local_contexts; 03640 int length; 03641 length = sizeof(struct ast_context); 03642 length += strlen(name) + 1; 03643 if (!extcontexts) { 03644 local_contexts = &contexts; 03645 ast_mutex_lock(&conlock); 03646 } else 03647 local_contexts = extcontexts; 03648 03649 tmp = *local_contexts; 03650 while(tmp) { 03651 if (!strcasecmp(tmp->name, name)) { 03652 ast_mutex_unlock(&conlock); 03653 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 03654 if (!extcontexts) 03655 ast_mutex_unlock(&conlock); 03656 return NULL; 03657 } 03658 tmp = tmp->next; 03659 } 03660 tmp = malloc(length); 03661 if (tmp) { 03662 memset(tmp, 0, length); 03663 ast_mutex_init(&tmp->lock); 03664 strcpy(tmp->name, name); 03665 tmp->root = NULL; 03666 tmp->registrar = registrar; 03667 tmp->next = *local_contexts; 03668 tmp->includes = NULL; 03669 tmp->ignorepats = NULL; 03670 *local_contexts = tmp; 03671 if (option_debug) 03672 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 03673 else if (option_verbose > 2) 03674 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 03675 } else 03676 ast_log(LOG_ERROR, "Out of memory\n"); 03677 03678 if (!extcontexts) 03679 ast_mutex_unlock(&conlock); 03680 return tmp; 03681 }
|
|
Definition at line 5381 of file pbx.c. References __ast_context_destroy(). Referenced by ael_reload(), reload(), and unload_module(). 05382 { 05383 __ast_context_destroy(con,registrar); 05384 }
|
|
Definition at line 736 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), contexts, ast_context::name, and ast_context::next. Referenced by ast_context_verify_includes(), ast_ignore_pattern(), do_parking_thread(), load_config(), macro_exec(), park_exec(), reload_config(), and set_config(). 00737 { 00738 struct ast_context *tmp; 00739 ast_mutex_lock(&conlock); 00740 if (name) { 00741 tmp = contexts; 00742 while(tmp) { 00743 if (!strcasecmp(name, tmp->name)) 00744 break; 00745 tmp = tmp->next; 00746 } 00747 } else 00748 tmp = contexts; 00749 ast_mutex_unlock(&conlock); 00750 return tmp; 00751 }
|
|
Definition at line 2722 of file pbx.c. References ast_context_remove_extension2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). Referenced by handle_context_remove_extension(), and register_peer_exten(). 02723 { 02724 struct ast_context *c; 02725 02726 if (ast_lock_contexts()) return -1; 02727 02728 /* walk contexts ... */ 02729 c = ast_walk_contexts(NULL); 02730 while (c) { 02731 /* ... search for the right one ... */ 02732 if (!strcmp(ast_get_context_name(c), context)) { 02733 /* ... remove extension ... */ 02734 int ret = ast_context_remove_extension2(c, extension, priority, 02735 registrar); 02736 /* ... unlock contexts list and return */ 02737 ast_unlock_contexts(); 02738 return ret; 02739 } 02740 c = ast_walk_contexts(c); 02741 } 02742 02743 /* we can't find the right context */ 02744 ast_unlock_contexts(); 02745 return -1; 02746 }
|
|
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 2758 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_remove_hint(), exten, free, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::priority, PRIORITY_HINT, ast_exten::registrar, and ast_context::root. Referenced by ast_context_remove_extension(), do_parking_thread(), load_config(), and park_exec(). 02759 { 02760 struct ast_exten *exten, *prev_exten = NULL; 02761 02762 if (ast_mutex_lock(&con->lock)) return -1; 02763 02764 /* go through all extensions in context and search the right one ... */ 02765 exten = con->root; 02766 while (exten) { 02767 02768 /* look for right extension */ 02769 if (!strcmp(exten->exten, extension) && 02770 (!registrar || !strcmp(exten->registrar, registrar))) { 02771 struct ast_exten *peer; 02772 02773 /* should we free all peers in this extension? (priority == 0)? */ 02774 if (priority == 0) { 02775 /* remove this extension from context list */ 02776 if (prev_exten) 02777 prev_exten->next = exten->next; 02778 else 02779 con->root = exten->next; 02780 02781 /* fire out all peers */ 02782 peer = exten; 02783 while (peer) { 02784 exten = peer->peer; 02785 02786 if (!peer->priority==PRIORITY_HINT) 02787 ast_remove_hint(peer); 02788 02789 peer->datad(peer->data); 02790 free(peer); 02791 02792 peer = exten; 02793 } 02794 02795 ast_mutex_unlock(&con->lock); 02796 return 0; 02797 } else { 02798 /* remove only extension with exten->priority == priority */ 02799 struct ast_exten *previous_peer = NULL; 02800 02801 peer = exten; 02802 while (peer) { 02803 /* is this our extension? */ 02804 if (peer->priority == priority && 02805 (!registrar || !strcmp(peer->registrar, registrar) )) { 02806 /* we are first priority extension? */ 02807 if (!previous_peer) { 02808 /* exists previous extension here? */ 02809 if (prev_exten) { 02810 /* yes, so we must change next pointer in 02811 * previous connection to next peer 02812 */ 02813 if (peer->peer) { 02814 prev_exten->next = peer->peer; 02815 peer->peer->next = exten->next; 02816 } else 02817 prev_exten->next = exten->next; 02818 } else { 02819 /* no previous extension, we are first 02820 * extension, so change con->root ... 02821 */ 02822 if (peer->peer) 02823 con->root = peer->peer; 02824 else 02825 con->root = exten->next; 02826 } 02827 } else { 02828 /* we are not first priority in extension */ 02829 previous_peer->peer = peer->peer; 02830 } 02831 02832 /* now, free whole priority extension */ 02833 if (peer->priority==PRIORITY_HINT) 02834 ast_remove_hint(peer); 02835 peer->datad(peer->data); 02836 free(peer); 02837 02838 ast_mutex_unlock(&con->lock); 02839 return 0; 02840 } else { 02841 /* this is not right extension, skip to next peer */ 02842 previous_peer = peer; 02843 peer = peer->peer; 02844 } 02845 } 02846 02847 ast_mutex_unlock(&con->lock); 02848 return -1; 02849 } 02850 } 02851 02852 prev_exten = exten; 02853 exten = exten->next; 02854 } 02855 02856 /* we can't find right extension */ 02857 ast_mutex_unlock(&con->lock); 02858 return -1; 02859 }
|
|
Definition at line 4360 of file pbx.c. References ast_context_remove_ignorepat2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). Referenced by handle_context_remove_ignorepat(). 04361 { 04362 struct ast_context *c; 04363 04364 if (ast_lock_contexts()) { 04365 errno = EBUSY; 04366 return -1; 04367 } 04368 04369 c = ast_walk_contexts(NULL); 04370 while (c) { 04371 if (!strcmp(ast_get_context_name(c), context)) { 04372 int ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04373 ast_unlock_contexts(); 04374 return ret; 04375 } 04376 c = ast_walk_contexts(c); 04377 } 04378 04379 ast_unlock_contexts(); 04380 errno = ENOENT; 04381 return -1; 04382 }
|
|
Definition at line 4384 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), free, ast_context::ignorepats, ast_context::lock, ast_ignorepat::next, ast_ignorepat::pattern, and ast_ignorepat::registrar. Referenced by ast_context_remove_ignorepat(). 04385 { 04386 struct ast_ignorepat *ip, *ipl = NULL; 04387 04388 if (ast_mutex_lock(&con->lock)) { 04389 errno = EBUSY; 04390 return -1; 04391 } 04392 04393 ip = con->ignorepats; 04394 while (ip) { 04395 if (!strcmp(ip->pattern, ignorepat) && 04396 (!registrar || (registrar == ip->registrar))) { 04397 if (ipl) { 04398 ipl->next = ip->next; 04399 free(ip); 04400 } else { 04401 con->ignorepats = ip->next; 04402 free(ip); 04403 } 04404 ast_mutex_unlock(&con->lock); 04405 return 0; 04406 } 04407 ipl = ip; ip = ip->next; 04408 } 04409 04410 ast_mutex_unlock(&con->lock); 04411 errno = EINVAL; 04412 return -1; 04413 }
|
|
See add_include Definition at line 2578 of file pbx.c. References ast_context_remove_include2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). Referenced by handle_context_dont_include(). 02579 { 02580 struct ast_context *c; 02581 02582 if (ast_lock_contexts()) return -1; 02583 02584 /* walk contexts and search for the right one ...*/ 02585 c = ast_walk_contexts(NULL); 02586 while (c) { 02587 /* we found one ... */ 02588 if (!strcmp(ast_get_context_name(c), context)) { 02589 int ret; 02590 /* remove include from this context ... */ 02591 ret = ast_context_remove_include2(c, include, registrar); 02592 02593 ast_unlock_contexts(); 02594 02595 /* ... return results */ 02596 return ret; 02597 } 02598 c = ast_walk_contexts(c); 02599 } 02600 02601 /* we can't find the right one context */ 02602 ast_unlock_contexts(); 02603 return -1; 02604 }
|
|
See add_include2 Definition at line 2614 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(). 02615 { 02616 struct ast_include *i, *pi = NULL; 02617 02618 if (ast_mutex_lock(&con->lock)) return -1; 02619 02620 /* walk includes */ 02621 i = con->includes; 02622 while (i) { 02623 /* find our include */ 02624 if (!strcmp(i->name, include) && 02625 (!registrar || !strcmp(i->registrar, registrar))) { 02626 /* remove from list */ 02627 if (pi) 02628 pi->next = i->next; 02629 else 02630 con->includes = i->next; 02631 /* free include and return */ 02632 free(i); 02633 ast_mutex_unlock(&con->lock); 02634 return 0; 02635 } 02636 pi = i; 02637 i = i->next; 02638 } 02639 02640 /* we can't find the right include */ 02641 ast_mutex_unlock(&con->lock); 02642 return -1; 02643 }
|
|
Definition at line 2650 of file pbx.c. References ast_context_remove_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). 02651 { 02652 struct ast_context *c; 02653 02654 if (ast_lock_contexts()) return -1; 02655 02656 /* walk contexts and search for the right one ...*/ 02657 c = ast_walk_contexts(NULL); 02658 while (c) { 02659 /* we found one ... */ 02660 if (!strcmp(ast_get_context_name(c), context)) { 02661 int ret; 02662 /* remove switch from this context ... */ 02663 ret = ast_context_remove_switch2(c, sw, data, registrar); 02664 02665 ast_unlock_contexts(); 02666 02667 /* ... return results */ 02668 return ret; 02669 } 02670 c = ast_walk_contexts(c); 02671 } 02672 02673 /* we can't find the right one context */ 02674 ast_unlock_contexts(); 02675 return -1; 02676 }
|
|
This function locks given context, removes switch, unlock context and return.
Definition at line 2686 of file pbx.c. References ast_context::alts, ast_mutex_lock(), ast_mutex_unlock(), ast_sw::data, free, ast_context::lock, ast_sw::name, ast_sw::next, and ast_sw::registrar. Referenced by ast_context_remove_switch(). 02687 { 02688 struct ast_sw *i, *pi = NULL; 02689 02690 if (ast_mutex_lock(&con->lock)) return -1; 02691 02692 /* walk switchs */ 02693 i = con->alts; 02694 while (i) { 02695 /* find our switch */ 02696 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02697 (!registrar || !strcmp(i->registrar, registrar))) { 02698 /* remove from list */ 02699 if (pi) 02700 pi->next = i->next; 02701 else 02702 con->alts = i->next; 02703 /* free switch and return */ 02704 free(i); 02705 ast_mutex_unlock(&con->lock); 02706 return 0; 02707 } 02708 pi = i; 02709 i = i->next; 02710 } 02711 02712 /* we can't find the right switch */ 02713 ast_mutex_unlock(&con->lock); 02714 return -1; 02715 }
|
|
Definition at line 6430 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(). 06431 { 06432 struct ast_include *inc; 06433 int res = 0; 06434 06435 for (inc = ast_walk_context_includes(con, NULL); inc; inc = ast_walk_context_includes(con, inc)) 06436 if (!ast_context_find(inc->rname)) { 06437 res = -1; 06438 ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n", 06439 ast_get_context_name(con), inc->rname); 06440 } 06441 return res; 06442 }
|
|
Definition at line 1265 of file pbx.c. References acf_root, ast_log(), ast_mutex_lock(), LOG_ERROR, ast_custom_function::name, and ast_custom_function::next. Referenced by ast_custom_function_register(), ast_func_read(), ast_func_write(), and handle_show_function(). 01266 { 01267 struct ast_custom_function *acfptr; 01268 01269 /* try to lock functions list ... */ 01270 if (ast_mutex_lock(&acflock)) { 01271 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01272 return NULL; 01273 } 01274 01275 for (acfptr = acf_root; acfptr; acfptr = acfptr->next) { 01276 if (!strcmp(name, acfptr->name)) { 01277 break; 01278 } 01279 } 01280 01281 ast_mutex_unlock(&acflock); 01282 01283 return acfptr; 01284 }
|
|
Definition at line 1321 of file pbx.c. References acf_root, ast_custom_function_find(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), LOG_ERROR, ast_custom_function::name, ast_custom_function::next, option_verbose, and VERBOSE_PREFIX_2. Referenced by load_module(). 01322 { 01323 if (!acf) 01324 return -1; 01325 01326 /* try to lock functions list ... */ 01327 if (ast_mutex_lock(&acflock)) { 01328 ast_log(LOG_ERROR, "Unable to lock function list. Failed registering function %s\n", acf->name); 01329 return -1; 01330 } 01331 01332 if (ast_custom_function_find(acf->name)) { 01333 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01334 ast_mutex_unlock(&acflock); 01335 return -1; 01336 } 01337 01338 acf->next = acf_root; 01339 acf_root = acf; 01340 01341 ast_mutex_unlock(&acflock); 01342 01343 if (option_verbose > 1) 01344 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01345 01346 return 0; 01347 }
|
|
Definition at line 1286 of file pbx.c. References acf_root, ast_log(), ast_mutex_lock(), LOG_ERROR, and ast_custom_function::next. Referenced by unload_module(). 01287 { 01288 struct ast_custom_function *acfptr, *lastacf = NULL; 01289 int res = -1; 01290 01291 if (!acf) 01292 return -1; 01293 01294 /* try to lock functions list ... */ 01295 if (ast_mutex_lock(&acflock)) { 01296 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01297 return -1; 01298 } 01299 01300 for (acfptr = acf_root; acfptr; acfptr = acfptr->next) { 01301 if (acfptr == acf) { 01302 if (lastacf) { 01303 lastacf->next = acf->next; 01304 } else { 01305 acf_root = acf->next; 01306 } 01307 res = 0; 01308 break; 01309 } 01310 lastacf = acfptr; 01311 } 01312 01313 ast_mutex_unlock(&acflock); 01314 01315 if (!res && (option_verbose > 1)) 01316 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01317 01318 return res; 01319 }
|
|
Definition at line 2230 of file pbx.c. References HELPER_EXEC, and pbx_extension_helper(). Referenced by loopback_exec(). 02231 { 02232 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXEC); 02233 }
|
|
|
Definition at line 4528 of file pbx.c. References 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(), and handle_setpriority(). 04529 { 04530 if (!chan) 04531 return -1; 04532 04533 if (!ast_strlen_zero(context)) 04534 ast_copy_string(chan->context, context, sizeof(chan->context)); 04535 if (!ast_strlen_zero(exten)) 04536 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04537 if (priority > -1) { 04538 chan->priority = priority; 04539 /* see flag description in channel.h for explanation */ 04540 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04541 chan->priority--; 04542 } 04543 04544 return 0; 04545 }
|
|
Definition at line 715 of file pbx.c. References ast_strlen_zero(), EXTENSION_MATCH_CORE, and match(). Referenced by realtime_switch_common(). 00716 { 00717 int match; 00718 /* If "data" is longer, it can'be a subset of pattern unless 00719 pattern is a pattern match */ 00720 if ((strlen(pattern) < strlen(data)) && (pattern[0] != '_')) 00721 return 0; 00722 00723 if ((ast_strlen_zero((char *)data) || !strncasecmp(pattern, data, strlen(data))) && 00724 (!needmore || (strlen(pattern) > strlen(data)))) { 00725 return 1; 00726 } 00727 EXTENSION_MATCH_CORE(data,pattern,match); 00728 /* If there's more or we don't care about more, or if it's a possible early match, 00729 return non-zero; otherwise it's a miss */ 00730 if (!needmore || *pattern || match == 2) { 00731 return match; 00732 } else 00733 return 0; 00734 }
|
|
Definition at line 702 of file pbx.c. References EXTENSION_MATCH_CORE, and match(). Referenced by ast_ignore_pattern(), find_matching_priority(), loopback_canmatch(), loopback_exec(), loopback_exists(), loopback_matchmore(), matchcid(), realtime_switch_common(), and show_dialplan_helper(). 00703 { 00704 int match; 00705 /* If they're the same return */ 00706 if (!strcmp(pattern, data)) 00707 return 1; 00708 EXTENSION_MATCH_CORE(data,pattern,match); 00709 /* Must be at the end of both */ 00710 if (*data || (*pattern && (*pattern != '/'))) 00711 match = 0; 00712 return match; 00713 }
|
|
ast_extension_state: Check extension state for an extension by using hint
Definition at line 1872 of file pbx.c. References ast_extension_state2(), and ast_hint_extension(). Referenced by action_extensionstate(), and handle_request_subscribe(). 01873 { 01874 struct ast_exten *e; 01875 01876 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 01877 if (!e) 01878 return -1; /* No hint, return -1 */ 01879 01880 return ast_extension_state2(e); /* Check all devices in the hint */ 01881 }
|
|
ast_extensions_state2: Check state of extension by using hints
Definition at line 1785 of file pbx.c. References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_RINGING, ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_extension_app(), AST_MAX_EXTENSION, busy, inuse, and ring(). Referenced by ast_add_hint(), ast_extension_state(), and ast_hint_state_changed(). 01786 { 01787 char hint[AST_MAX_EXTENSION] = ""; 01788 char *cur, *rest; 01789 int res = -1; 01790 int allunavailable = 1, allbusy = 1, allfree = 1; 01791 int busy = 0, inuse = 0, ring = 0; 01792 01793 if (!e) 01794 return -1; 01795 01796 ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint)); 01797 01798 cur = hint; /* On or more devices separated with a & character */ 01799 do { 01800 rest = strchr(cur, '&'); 01801 if (rest) { 01802 *rest = 0; 01803 rest++; 01804 } 01805 01806 res = ast_device_state(cur); 01807 switch (res) { 01808 case AST_DEVICE_NOT_INUSE: 01809 allunavailable = 0; 01810 allbusy = 0; 01811 break; 01812 case AST_DEVICE_INUSE: 01813 inuse = 1; 01814 allunavailable = 0; 01815 allfree = 0; 01816 break; 01817 case AST_DEVICE_RINGING: 01818 ring = 1; 01819 allunavailable = 0; 01820 allfree = 0; 01821 break; 01822 case AST_DEVICE_BUSY: 01823 allunavailable = 0; 01824 allfree = 0; 01825 busy = 1; 01826 break; 01827 case AST_DEVICE_UNAVAILABLE: 01828 case AST_DEVICE_INVALID: 01829 allbusy = 0; 01830 allfree = 0; 01831 break; 01832 default: 01833 allunavailable = 0; 01834 allbusy = 0; 01835 allfree = 0; 01836 } 01837 cur = rest; 01838 } while (cur); 01839 01840 if (!inuse && ring) 01841 return AST_EXTENSION_RINGING; 01842 if (inuse && ring) 01843 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 01844 if (inuse) 01845 return AST_EXTENSION_INUSE; 01846 if (allfree) 01847 return AST_EXTENSION_NOT_INUSE; 01848 if (allbusy) 01849 return AST_EXTENSION_BUSY; 01850 if (allunavailable) 01851 return AST_EXTENSION_UNAVAILABLE; 01852 if (busy) 01853 return AST_EXTENSION_INUSE; 01854 01855 return AST_EXTENSION_NOT_INUSE; 01856 }
|
|
ast_extension_state2str: Return extension_state as string
Definition at line 1859 of file pbx.c. References extension_states. Referenced by __sip_show_channels(), cb_extensionstate(), handle_request_subscribe(), and handle_show_hints(). 01860 { 01861 int i; 01862 01863 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01864 if (extension_states[i].extension_state == extension_state) { 01865 return extension_states[i].text; 01866 } 01867 } 01868 return "Unknown"; 01869 }
|
|
ast_extension_state_add: Add watcher for extension states
Definition at line 1926 of file pbx.c. References ast_hint_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_state_cb::data, hints, ast_state_cb::id, list, malloc, ast_state_cb::next, ast_imager::next, and statecbs. Referenced by handle_request_subscribe(), and init_manager(). 01928 { 01929 struct ast_hint *list; 01930 struct ast_state_cb *cblist; 01931 struct ast_exten *e; 01932 01933 /* If there's no context and extension: add callback to statecbs list */ 01934 if (!context && !exten) { 01935 ast_mutex_lock(&hintlock); 01936 01937 cblist = statecbs; 01938 while (cblist) { 01939 if (cblist->callback == callback) { 01940 cblist->data = data; 01941 ast_mutex_unlock(&hintlock); 01942 return 0; 01943 } 01944 cblist = cblist->next; 01945 } 01946 01947 /* Now insert the callback */ 01948 cblist = malloc(sizeof(struct ast_state_cb)); 01949 if (!cblist) { 01950 ast_mutex_unlock(&hintlock); 01951 return -1; 01952 } 01953 memset(cblist, 0, sizeof(struct ast_state_cb)); 01954 cblist->id = 0; 01955 cblist->callback = callback; 01956 cblist->data = data; 01957 01958 cblist->next = statecbs; 01959 statecbs = cblist; 01960 01961 ast_mutex_unlock(&hintlock); 01962 return 0; 01963 } 01964 01965 if (!context || !exten) 01966 return -1; 01967 01968 /* This callback type is for only one hint, so get the hint */ 01969 e = ast_hint_extension(NULL, context, exten); 01970 if (!e) { 01971 return -1; 01972 } 01973 01974 /* Find the hint in the list of hints */ 01975 ast_mutex_lock(&hintlock); 01976 list = hints; 01977 01978 while (list) { 01979 if (list->exten == e) 01980 break; 01981 list = list->next; 01982 } 01983 01984 if (!list) { 01985 /* We have no hint, sorry */ 01986 ast_mutex_unlock(&hintlock); 01987 return -1; 01988 } 01989 01990 /* Now insert the callback in the callback list */ 01991 cblist = malloc(sizeof(struct ast_state_cb)); 01992 if (!cblist) { 01993 ast_mutex_unlock(&hintlock); 01994 return -1; 01995 } 01996 memset(cblist, 0, sizeof(struct ast_state_cb)); 01997 cblist->id = stateid++; /* Unique ID for this callback */ 01998 cblist->callback = callback; /* Pointer to callback routine */ 01999 cblist->data = data; /* Data for the callback */ 02000 02001 cblist->next = list->callbacks; 02002 list->callbacks = cblist; 02003 02004 ast_mutex_unlock(&hintlock); 02005 return cblist->id; 02006 }
|
|
ast_extension_state_del: Remove a watcher from the callback list
Definition at line 2009 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, free, hints, ast_state_cb::id, list, ast_state_cb::next, ast_imager::next, and statecbs. Referenced by __sip_destroy(). 02010 { 02011 struct ast_hint *list; 02012 struct ast_state_cb *cblist, *cbprev; 02013 02014 if (!id && !callback) 02015 return -1; 02016 02017 ast_mutex_lock(&hintlock); 02018 02019 /* id is zero is a callback without extension */ 02020 if (!id) { 02021 cbprev = NULL; 02022 cblist = statecbs; 02023 while (cblist) { 02024 if (cblist->callback == callback) { 02025 if (!cbprev) 02026 statecbs = cblist->next; 02027 else 02028 cbprev->next = cblist->next; 02029 02030 free(cblist); 02031 02032 ast_mutex_unlock(&hintlock); 02033 return 0; 02034 } 02035 cbprev = cblist; 02036 cblist = cblist->next; 02037 } 02038 02039 ast_mutex_unlock(&hintlock); 02040 return -1; 02041 } 02042 02043 /* id greater than zero is a callback with extension */ 02044 /* Find the callback based on ID */ 02045 list = hints; 02046 while (list) { 02047 cblist = list->callbacks; 02048 cbprev = NULL; 02049 while (cblist) { 02050 if (cblist->id==id) { 02051 if (!cbprev) 02052 list->callbacks = cblist->next; 02053 else 02054 cbprev->next = cblist->next; 02055 02056 free(cblist); 02057 02058 ast_mutex_unlock(&hintlock); 02059 return 0; 02060 } 02061 cbprev = cblist; 02062 cblist = cblist->next; 02063 } 02064 list = list->next; 02065 } 02066 02067 ast_mutex_unlock(&hintlock); 02068 return -1; 02069 }
|
|
Definition at line 2205 of file pbx.c. References HELPER_FINDLABEL, and pbx_extension_helper(). Referenced by ast_parseable_goto(), and handle_setpriority(). 02206 { 02207 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, HELPER_FINDLABEL); 02208 }
|
|
Definition at line 2210 of file pbx.c. References HELPER_FINDLABEL, and pbx_extension_helper(). Referenced by pbx_load_module(). 02211 { 02212 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, HELPER_FINDLABEL); 02213 }
|
|
Definition at line 1349 of file pbx.c. References ast_custom_function_find(), ast_log(), ast_strdupa, LOG_ERROR, LOG_WARNING, and ast_custom_function::read. Referenced by handle_getvariable(), and pbx_substitute_variables_helper_full(). 01350 { 01351 char *args = NULL, *function, *p; 01352 char *ret = "0"; 01353 struct ast_custom_function *acfptr; 01354 01355 function = ast_strdupa(in); 01356 if (!function) { 01357 ast_log(LOG_ERROR, "Out of memory\n"); 01358 return ret; 01359 } 01360 if ((args = strchr(function, '('))) { 01361 *args = '\0'; 01362 args++; 01363 if ((p = strrchr(args, ')'))) { 01364 *p = '\0'; 01365 } else { 01366 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01367 } 01368 } else { 01369 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01370 } 01371 01372 if ((acfptr = ast_custom_function_find(function))) { 01373 /* run the custom function */ 01374 if (acfptr->read) { 01375 return acfptr->read(chan, function, args, workspace, len); 01376 } else { 01377 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01378 } 01379 } else { 01380 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01381 } 01382 return ret; 01383 }
|
|
Definition at line 1385 of file pbx.c. References ast_custom_function_find(), ast_log(), ast_strdupa, LOG_ERROR, LOG_WARNING, and ast_custom_function::write. Referenced by pbx_builtin_pushvar_helper(), and pbx_builtin_setvar_helper(). 01386 { 01387 char *args = NULL, *function, *p; 01388 struct ast_custom_function *acfptr; 01389 01390 function = ast_strdupa(in); 01391 if (!function) { 01392 ast_log(LOG_ERROR, "Out of memory\n"); 01393 return; 01394 } 01395 if ((args = strchr(function, '('))) { 01396 *args = '\0'; 01397 args++; 01398 if ((p = strrchr(args, ')'))) { 01399 *p = '\0'; 01400 } else { 01401 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01402 } 01403 } else { 01404 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01405 } 01406 01407 if ((acfptr = ast_custom_function_find(function))) { 01408 /* run the custom function */ 01409 if (acfptr->write) { 01410 acfptr->write(chan, function, args, value); 01411 } else { 01412 ast_log(LOG_ERROR, "Function %s is read-only, it cannot be written to\n", function); 01413 } 01414 } else { 01415 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01416 } 01417 }
|
|
Definition at line 6286 of file pbx.c. References ast_context::name. Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_include2(), ast_context_add_switch(), ast_context_add_switch2(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), ast_context_verify_includes(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper(). 06287 { 06288 return con ? con->name : NULL; 06289 }
|
|
Definition at line 6319 of file pbx.c. References ast_context::registrar. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06320 { 06321 return c ? c->registrar : NULL; 06322 }
|
|
Definition at line 6349 of file pbx.c. References ast_exten::app. Referenced by ast_add_hint(), ast_extension_state2(), ast_get_hint(), ast_hint_state_changed(), find_matching_endwhile(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper(). 06350 { 06351 return e ? e->app : NULL; 06352 }
|
|
Definition at line 6354 of file pbx.c. References ast_exten::data. Referenced by ast_get_hint(), handle_save_dialplan(), and show_dialplan_helper(). 06355 { 06356 return e ? e->data : NULL; 06357 }
|
|
Definition at line 6344 of file pbx.c. References ast_exten::cidmatch. Referenced by find_matching_priority(), and handle_save_dialplan(). 06345 { 06346 return e ? e->cidmatch : NULL; 06347 }
|
|
Definition at line 6296 of file pbx.c. References exten. Referenced by show_dialplan_helper().
|
|
Definition at line 6339 of file pbx.c. References ast_exten::matchcid. Referenced by find_matching_priority(), and handle_save_dialplan(). 06340 { 06341 return e ? e->matchcid : 0; 06342 }
|
|
Definition at line 6291 of file pbx.c. References exten. Referenced by ast_add_hint(), complete_context_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), handle_show_hints(), and show_dialplan_helper().
|
|
Definition at line 6311 of file pbx.c. References exten. Referenced by complete_context_remove_extension(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
|
|
Definition at line 6324 of file pbx.c. References ast_exten::registrar. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06325 { 06326 return e ? e->registrar : NULL; 06327 }
|
|
ast_get_hint: Get hint for channel
Definition at line 2181 of file pbx.c. References ast_get_extension_app(), ast_get_extension_app_data(), and ast_hint_extension(). Referenced by action_extensionstate(), get_cid_name(), pbx_retrieve_variable(), and transmit_state_notify(). 02182 { 02183 struct ast_exten *e; 02184 void *tmp; 02185 02186 e = ast_hint_extension(c, context, exten); 02187 if (e) { 02188 if (hint) 02189 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02190 if (name) { 02191 tmp = ast_get_extension_app_data(e); 02192 if (tmp) 02193 ast_copy_string(name, (char *) tmp, namesize); 02194 } 02195 return -1; 02196 } 02197 return 0; 02198 }
|
|
Definition at line 6306 of file pbx.c. References ast_ignorepat::pattern. Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), and handle_save_dialplan(). 06307 { 06308 return ip ? ip->pattern : NULL; 06309 }
|
|
Definition at line 6334 of file pbx.c. References ast_ignorepat::registrar. Referenced by handle_save_dialplan(). 06335 { 06336 return ip ? ip->registrar : NULL; 06337 }
|
|
Definition at line 6301 of file pbx.c. References ast_include::name. Referenced by complete_context_add_include(), complete_context_dont_include(), handle_save_dialplan(), and show_dialplan_helper(). 06302 { 06303 return inc ? inc->name : NULL; 06304 }
|
|
Definition at line 6329 of file pbx.c. References ast_include::registrar. Referenced by handle_save_dialplan(). 06330 { 06331 return i ? i->registrar : NULL; 06332 }
|
|
Definition at line 6364 of file pbx.c. References ast_sw::data. Referenced by handle_save_dialplan(). 06365 { 06366 return sw ? sw->data : NULL; 06367 }
|
|
Definition at line 6359 of file pbx.c. References ast_sw::name. Referenced by handle_save_dialplan(). 06360 { 06361 return sw ? sw->name : NULL; 06362 }
|
|
Definition at line 6369 of file pbx.c. References ast_sw::registrar. Referenced by handle_save_dialplan(). 06370 { 06371 return sw ? sw->registrar : NULL; 06372 }
|
|
Definition at line 6462 of file pbx.c. References __ast_goto_if_exists(). Referenced by aqm_exec(), background_detect_exec(), chanavail_exec(), controlplayback_exec(), dial_exec_full(), do_directory(), enumlookup_exec(), get_exec(), group_check_exec(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), md5check_exec(), onedigit_goto(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), play_mailbox_owner(), playback_exec(), pqm_exec(), privacy_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), sip_getheader(), system_exec_helper(), transfer_exec(), txtcidname_exec(), upqm_exec(), valid_exit(), vm_box_exists(), vm_exec(), and wait_for_answer(). 06462 { 06463 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06464 }
|
|
ast_hint_extension: Find hint for given extension in context
Definition at line 1765 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_MAX_STACK, HELPER_EXISTS, LOG_WARNING, pbx_find_extension(), and PRIORITY_HINT. Referenced by ast_extension_state(), ast_extension_state_add(), and ast_get_hint(). 01766 { 01767 struct ast_exten *e; 01768 struct ast_switch *sw; 01769 char *data; 01770 const char *foundcontext = NULL; 01771 int status = 0; 01772 char *incstack[AST_PBX_MAX_STACK]; 01773 int stacklen = 0; 01774 01775 if (ast_mutex_lock(&conlock)) { 01776 ast_log(LOG_WARNING, "Unable to obtain lock\n"); 01777 return NULL; 01778 } 01779 e = pbx_find_extension(c, NULL, context, exten, PRIORITY_HINT, NULL, "", HELPER_EXISTS, incstack, &stacklen, &status, &sw, &data, &foundcontext); 01780 ast_mutex_unlock(&conlock); 01781 return e; 01782 }
|
|
Definition at line 1883 of file pbx.c. References ast_extension_state2(), ast_get_extension_app(), AST_MAX_EXTENSION, ast_mutex_lock(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_exten::exten, hints, ast_hint::laststate, ast_context::name, ast_hint::next, ast_state_cb::next, ast_exten::parent, parse(), statecbs, and strsep(). Referenced by do_state_change(). 01884 { 01885 struct ast_hint *hint; 01886 struct ast_state_cb *cblist; 01887 char buf[AST_MAX_EXTENSION]; 01888 char *parse; 01889 char *cur; 01890 int state; 01891 01892 ast_mutex_lock(&hintlock); 01893 01894 for (hint = hints; hint; hint = hint->next) { 01895 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 01896 parse = buf; 01897 for (cur = strsep(&parse, "&"); cur; cur = strsep(&parse, "&")) { 01898 if (strcasecmp(cur, device)) 01899 continue; 01900 01901 /* Get device state for this hint */ 01902 state = ast_extension_state2(hint->exten); 01903 01904 if ((state == -1) || (state == hint->laststate)) 01905 continue; 01906 01907 /* Device state changed since last check - notify the watchers */ 01908 01909 /* For general callbacks */ 01910 for (cblist = statecbs; cblist; cblist = cblist->next) 01911 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01912 01913 /* For extension callbacks */ 01914 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 01915 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01916 01917 hint->laststate = state; 01918 break; 01919 } 01920 } 01921 01922 ast_mutex_unlock(&hintlock); 01923 }
|
|
Definition at line 4480 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(), dp_lookup(), dundi_lookup_local(), mgcp_ss(), skinny_ss(), and ss_thread(). 04481 { 04482 struct ast_context *con; 04483 struct ast_ignorepat *pat; 04484 04485 con = ast_context_find(context); 04486 if (con) { 04487 pat = con->ignorepats; 04488 while (pat) { 04489 if (ast_extension_match(pat->pattern, pattern)) 04490 return 1; 04491 pat = pat->next; 04492 } 04493 } 04494 return 0; 04495 }
|
|
|
|
Definition at line 6273 of file pbx.c. References ast_mutex_lock(), and ast_context::lock. Referenced by complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_ignorepat(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper(). 06274 { 06275 return ast_mutex_lock(&con->lock); 06276 }
|
|
Locks the context list Returns 0 on success, -1 on error Definition at line 6260 of file pbx.c. References ast_mutex_lock(). Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper(). 06261 { 06262 return ast_mutex_lock(&conlock); 06263 }
|
|
Definition at line 2220 of file pbx.c. References HELPER_MATCHMORE, and pbx_extension_helper(). Referenced by ast_app_dtget(), dp_lookup(), dundi_lookup_local(), loopback_matchmore(), mgcp_ss(), skinny_ss(), and ss_thread(). 02221 { 02222 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_MATCHMORE); 02223 }
|
|
Definition at line 3696 of file pbx.c. References AST_LIST_HEAD_INIT, ast_log(), ast_mutex_lock(), ast_hint::callbacks, calloc, store_hint::exten, ast_hint::exten, ast_exten::exten, hints, LOG_WARNING, ast_context::name, ast_hint::next, ast_exten::parent, and ast_context::registrar. Referenced by pbx_load_module(). 03697 { 03698 struct ast_context *tmp, *lasttmp = NULL; 03699 struct store_hints store; 03700 struct store_hint *this; 03701 struct ast_hint *hint; 03702 struct ast_exten *exten; 03703 int length; 03704 struct ast_state_cb *thiscb, *prevcb; 03705 03706 AST_LIST_HEAD_INIT(&store); 03707 03708 /* it is very important that this function hold the hintlock _and_ the conlock 03709 during its operation; not only do we need to ensure that the list of contexts 03710 and extensions does not change, but also that no hint callbacks (watchers) are 03711 added or removed during the merge/delete process 03712 03713 in addition, the locks _must_ be taken in this order, because there are already 03714 other code paths that use this order 03715 */ 03716 ast_mutex_lock(&conlock); 03717 ast_mutex_lock(&hintlock); 03718 03719 /* preserve all watchers for hints associated with this registrar */ 03720 for (hint = hints; hint; hint = hint->next) { 03721 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03722 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03723 this = calloc(1, length); 03724 if (!this) { 03725 ast_log(LOG_WARNING, "Could not allocate memory to preserve hint\n"); 03726 continue; 03727 } 03728 this->callbacks = hint->callbacks; 03729 hint->callbacks = NULL; 03730 this->laststate = hint->laststate; 03731 this->context = this->data; 03732 strcpy(this->data, hint->exten->parent->name); 03733 this->exten = this->data + strlen(this->context) + 1; 03734 strcpy(this->exten, hint->exten->exten); 03735 AST_LIST_INSERT_HEAD(&store, this, list); 03736 } 03737 } 03738 03739 tmp = *extcontexts; 03740 if (registrar) { 03741 __ast_context_destroy(NULL,registrar); 03742 while (tmp) { 03743 lasttmp = tmp; 03744 tmp = tmp->next; 03745 } 03746 } else { 03747 while (tmp) { 03748 __ast_context_destroy(tmp,tmp->registrar); 03749 lasttmp = tmp; 03750 tmp = tmp->next; 03751 } 03752 } 03753 if (lasttmp) { 03754 lasttmp->next = contexts; 03755 contexts = *extcontexts; 03756 *extcontexts = NULL; 03757 } else 03758 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 03759 03760 /* restore the watchers for hints that can be found; notify those that 03761 cannot be restored 03762 */ 03763 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 03764 exten = ast_hint_extension(NULL, this->context, this->exten); 03765 /* Find the hint in the list of hints */ 03766 for (hint = hints; hint; hint = hint->next) { 03767 if (hint->exten == exten) 03768 break; 03769 } 03770 if (!exten || !hint) { 03771 /* this hint has been removed, notify the watchers */ 03772 prevcb = NULL; 03773 thiscb = this->callbacks; 03774 while (thiscb) { 03775 prevcb = thiscb; 03776 thiscb = thiscb->next; 03777 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 03778 free(prevcb); 03779 } 03780 } else { 03781 thiscb = this->callbacks; 03782 while (thiscb->next) 03783 thiscb = thiscb->next; 03784 thiscb->next = hint->callbacks; 03785 hint->callbacks = this->callbacks; 03786 hint->laststate = this->laststate; 03787 } 03788 free(this); 03789 } 03790 03791 ast_mutex_unlock(&hintlock); 03792 ast_mutex_unlock(&conlock); 03793 03794 return; 03795 }
|
|
|
|
|
|
|
|
|
|
Lock for the custom function list |
|
|
|
|
|
Definition at line 6470 of file pbx.c. References ast_cdr_update(), ast_explicit_goto(), ast_findlabel_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, exten, ast_channel::exten, LOG_WARNING, ast_channel::priority, s, and strsep(). Referenced by check_goto_on_transfer(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), and return_exec(). 06471 { 06472 char *s; 06473 char *exten, *pri, *context; 06474 char *stringp=NULL; 06475 int ipri; 06476 int mode = 0; 06477 06478 if (ast_strlen_zero(goto_string)) { 06479 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06480 return -1; 06481 } 06482 s = ast_strdupa(goto_string); 06483 stringp=s; 06484 context = strsep(&stringp, "|"); 06485 exten = strsep(&stringp, "|"); 06486 if (!exten) { 06487 /* Only a priority in this one */ 06488 pri = context; 06489 exten = NULL; 06490 context = NULL; 06491 } else { 06492 pri = strsep(&stringp, "|"); 06493 if (!pri) { 06494 /* Only an extension and priority in this one */ 06495 pri = exten; 06496 exten = context; 06497 context = NULL; 06498 } 06499 } 06500 if (*pri == '+') { 06501 mode = 1; 06502 pri++; 06503 } else if (*pri == '-') { 06504 mode = -1; 06505 pri++; 06506 } 06507 if (sscanf(pri, "%d", &ipri) != 1) { 06508 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, (exten && strcasecmp(exten, "BYEXTENSION")) ? exten : chan->exten, 06509 pri, chan->cid.cid_num)) < 1) { 06510 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06511 return -1; 06512 } else 06513 mode = 0; 06514 } 06515 /* At this point we have a priority and maybe an extension and a context */ 06516 06517 if (exten && !strcasecmp(exten, "BYEXTENSION")) 06518 exten = NULL; 06519 06520 if (mode) 06521 ipri = chan->priority + (ipri * mode); 06522 06523 ast_explicit_goto(chan, context, exten, ipri); 06524 ast_cdr_update(chan); 06525 return 0; 06526 06527 }
|
|
Definition at line 5153 of file pbx.c. References __ast_request_and_dial(), async_stat::app, async_stat::appdata, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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(), ast_channel::cdr, async_stat::chan, free, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4. Referenced by action_originate(), attempt_thread(), fast_originate(), and page_thread(). 05154 { 05155 struct ast_channel *chan; 05156 struct async_stat *as; 05157 struct app_tmp *tmp; 05158 int res = -1, cdr_res = -1; 05159 struct outgoing_helper oh; 05160 pthread_attr_t attr; 05161 05162 memset(&oh, 0, sizeof(oh)); 05163 oh.vars = vars; 05164 oh.account = account; 05165 05166 if (locked_channel) 05167 *locked_channel = NULL; 05168 if (ast_strlen_zero(app)) { 05169 res = -1; 05170 goto outgoing_app_cleanup; 05171 } 05172 if (sync) { 05173 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05174 if (chan) { 05175 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05176 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05177 } else { 05178 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05179 if(!chan->cdr) { 05180 /* allocation of the cdr failed */ 05181 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 05182 free(chan->pbx); 05183 res = -1; 05184 goto outgoing_app_cleanup; 05185 } 05186 /* allocation of the cdr was successful */ 05187 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05188 ast_cdr_start(chan->cdr); 05189 } 05190 ast_set_variables(chan, vars); 05191 if (account) 05192 ast_cdr_setaccount(chan, account); 05193 if (chan->_state == AST_STATE_UP) { 05194 res = 0; 05195 if (option_verbose > 3) 05196 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05197 tmp = malloc(sizeof(struct app_tmp)); 05198 if (tmp) { 05199 memset(tmp, 0, sizeof(struct app_tmp)); 05200 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05201 if (appdata) 05202 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05203 tmp->chan = chan; 05204 if (sync > 1) { 05205 if (locked_channel) 05206 ast_mutex_unlock(&chan->lock); 05207 ast_pbx_run_app(tmp); 05208 } else { 05209 pthread_attr_init(&attr); 05210 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05211 if (locked_channel) 05212 ast_mutex_lock(&chan->lock); 05213 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05214 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05215 free(tmp); 05216 if (locked_channel) 05217 ast_mutex_unlock(&chan->lock); 05218 ast_hangup(chan); 05219 res = -1; 05220 } else { 05221 if (locked_channel) 05222 *locked_channel = chan; 05223 } 05224 } 05225 } else { 05226 ast_log(LOG_ERROR, "Out of memory :(\n"); 05227 res = -1; 05228 } 05229 } else { 05230 if (option_verbose > 3) 05231 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05232 if (chan->cdr) { /* update the cdr */ 05233 /* here we update the status of the call, which sould be busy. 05234 * if that fails then we set the status to failed */ 05235 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05236 ast_cdr_failed(chan->cdr); 05237 } 05238 ast_hangup(chan); 05239 } 05240 } 05241 05242 if (res < 0) { /* the call failed for some reason */ 05243 if (*reason == 0) { /* if the call failed (not busy or no answer) 05244 * update the cdr with the failed message */ 05245 cdr_res = ast_pbx_outgoing_cdr_failed(); 05246 if (cdr_res != 0) { 05247 res = cdr_res; 05248 goto outgoing_app_cleanup; 05249 } 05250 } 05251 } 05252 05253 } else { 05254 as = malloc(sizeof(struct async_stat)); 05255 if (!as) { 05256 res = -1; 05257 goto outgoing_app_cleanup; 05258 } 05259 memset(as, 0, sizeof(struct async_stat)); 05260 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05261 if (!chan) { 05262 free(as); 05263 res = -1; 05264 goto outgoing_app_cleanup; 05265 } 05266 as->chan = chan; 05267 ast_copy_string(as->app, app, sizeof(as->app)); 05268 if (appdata) 05269 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05270 as->timeout = timeout; 05271 ast_set_variables(chan, vars); 05272 if (account) 05273 ast_cdr_setaccount(chan, account); 05274 /* Start a new thread, and get something handling this channel. */ 05275 pthread_attr_init(&attr); 05276 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05277 if (locked_channel) 05278 ast_mutex_lock(&chan->lock); 05279 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05280 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05281 free(as); 05282 if (locked_channel) 05283 ast_mutex_unlock(&chan->lock); 05284 ast_hangup(chan); 05285 res = -1; 05286 goto outgoing_app_cleanup; 05287 } else { 05288 if (locked_channel) 05289 *locked_channel = chan; 05290 } 05291 res = 0; 05292 } 05293 outgoing_app_cleanup: 05294 ast_variables_destroy(vars); 05295 return res; 05296 }
|
|
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 4949 of file pbx.c. References ast_cdr_alloc(), ast_cdr_detach(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_start(), ast_channel_alloc(), ast_channel_free(), ast_log(), ast_channel::cdr, and LOG_WARNING. Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten(). 04950 { 04951 /* allocate a channel */ 04952 struct ast_channel *chan = ast_channel_alloc(0); 04953 if(!chan) { 04954 /* allocation of the channel failed, let some peeps know */ 04955 ast_log(LOG_WARNING, "Unable to allocate channel structure for CDR record\n"); 04956 return -1; /* failure */ 04957 } 04958 04959 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 04960 04961 if(!chan->cdr) { 04962 /* allocation of the cdr failed */ 04963 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 04964 ast_channel_free(chan); /* free the channel */ 04965 return -1; /* return failure */ 04966 } 04967 04968 /* allocation of the cdr was successful */ 04969 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 04970 ast_cdr_start(chan->cdr); /* record the start and stop time */ 04971 ast_cdr_end(chan->cdr); 04972 ast_cdr_failed(chan->cdr); /* set the status to failed */ 04973 ast_cdr_detach(chan->cdr); /* post and free the record */ 04974 ast_channel_free(chan); /* free the channel */ 04975 04976 return 0; /* success */ 04977 }
|
|
Definition at line 4979 of file pbx.c. References __ast_request_and_dial(), ast_channel::_state, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_start(), ast_channel_alloc(), ast_exists_extension(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_outgoing_cdr_failed(), ast_pbx_run(), ast_pbx_start(), ast_pthread_create, ast_request_and_dial(), ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, async_stat::chan, ast_channel::context, async_stat::context, ast_channel::exten, async_stat::exten, free, ast_channel::hangupcause, LOAD_OH, ast_channel::lock, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, ast_channel::priority, async_stat::priority, async_stat::timeout, outgoing_helper::vars, and VERBOSE_PREFIX_4. Referenced by action_originate(), attempt_thread(), and fast_originate(). 04980 { 04981 struct ast_channel *chan; 04982 struct async_stat *as; 04983 int res = -1, cdr_res = -1; 04984 struct outgoing_helper oh; 04985 pthread_attr_t attr; 04986 04987 if (sync) { 04988 LOAD_OH(oh); 04989 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 04990 if (channel) { 04991 *channel = chan; 04992 if (chan) 04993 ast_mutex_lock(&chan->lock); 04994 } 04995 if (chan) { 04996 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 04997 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 04998 } else { 04999 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05000 if (!chan->cdr) { 05001 /* allocation of the cdr failed */ 05002 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 05003 free(chan->pbx); 05004 res = -1; 05005 goto outgoing_exten_cleanup; 05006 } 05007 /* allocation of the cdr was successful */ 05008 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05009 ast_cdr_start(chan->cdr); 05010 } 05011 if (chan->_state == AST_STATE_UP) { 05012 res = 0; 05013 if (option_verbose > 3) 05014 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05015 05016 if (sync > 1) { 05017 if (channel) 05018 ast_mutex_unlock(&chan->lock); 05019 if (ast_pbx_run(chan)) { 05020 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05021 if (channel) 05022 *channel = NULL; 05023 ast_hangup(chan); 05024 res = -1; 05025 } 05026 } else { 05027 if (ast_pbx_start(chan)) { 05028 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05029 if (channel) { 05030 *channel = NULL; 05031 ast_mutex_unlock(&chan->lock); 05032 } 05033 ast_hangup(chan); 05034 res = -1; 05035 } 05036 } 05037 } else { 05038 if (option_verbose > 3) 05039 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05040 05041 if(chan->cdr) { /* update the cdr */ 05042 /* here we update the status of the call, which sould be busy. 05043 * if that fails then we set the status to failed */ 05044 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05045 ast_cdr_failed(chan->cdr); 05046 } 05047 05048 if (channel) { 05049 *channel = NULL; 05050 ast_mutex_unlock(&chan->lock); 05051 } 05052 ast_hangup(chan); 05053 } 05054 } 05055 05056 if (res < 0) { /* the call failed for some reason */ 05057 if (*reason == 0) { /* if the call failed (not busy or no answer) 05058 * update the cdr with the failed message */ 05059 cdr_res = ast_pbx_outgoing_cdr_failed(); 05060 if (cdr_res != 0) { 05061 res = cdr_res; 05062 goto outgoing_exten_cleanup; 05063 } 05064 } 05065 05066 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05067 /* check if "failed" exists */ 05068 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05069 chan = ast_channel_alloc(0); 05070 if (chan) { 05071 ast_copy_string(chan->name, "OutgoingSpoolFailed", sizeof(chan->name)); 05072 if (!ast_strlen_zero(context)) 05073 ast_copy_string(chan->context, context, sizeof(chan->context)); 05074 ast_copy_string(chan->exten, "failed", sizeof(chan->exten)); 05075 chan->priority = 1; 05076 ast_set_variables(chan, vars); 05077 if (account) 05078 ast_cdr_setaccount(chan, account); 05079 ast_pbx_run(chan); 05080 } else 05081 ast_log(LOG_WARNING, "Can't allocate the channel structure, skipping execution of extension 'failed'\n"); 05082 } 05083 } 05084 } else { 05085 as = malloc(sizeof(struct async_stat)); 05086 if (!as) { 05087 res = -1; 05088 goto outgoing_exten_cleanup; 05089 } 05090 memset(as, 0, sizeof(struct async_stat)); 05091 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05092 if (channel) { 05093 *channel = chan; 05094 if (chan) 05095 ast_mutex_lock(&chan->lock); 05096 } 05097 if (!chan) { 05098 free(as); 05099 res = -1; 05100 goto outgoing_exten_cleanup; 05101 } 05102 as->chan = chan; 05103 ast_copy_string(as->context, context, sizeof(as->context)); 05104 ast_copy_string(as->exten, exten, sizeof(as->exten)); 05105 as->priority = priority; 05106 as->timeout = timeout; 05107 ast_set_variables(chan, vars); 05108 if (account) 05109 ast_cdr_setaccount(chan, account); 05110 pthread_attr_init(&attr); 05111 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05112 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05113 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05114 free(as); 05115 if (channel) { 05116 *channel = NULL; 05117 ast_mutex_unlock(&chan->lock); 05118 } 05119 ast_hangup(chan); 05120 res = -1; 05121 goto outgoing_exten_cleanup; 05122 } 05123 res = 0; 05124 } 05125 outgoing_exten_cleanup: 05126 ast_variables_destroy(vars); 05127 return res; 05128 }
|
|
Definition at line 2546 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(), mgcp_ss(), skinny_ss(), and ss_thread(). 02547 { 02548 enum ast_pbx_result res = AST_PBX_SUCCESS; 02549 02550 if (increase_call_count(c)) 02551 return AST_PBX_CALL_LIMIT; 02552 02553 res = __ast_pbx_run(c); 02554 decrease_call_count(); 02555 02556 return res; 02557 }
|
|
Definition at line 5137 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(). 05138 { 05139 struct app_tmp *tmp = data; 05140 struct ast_app *app; 05141 app = pbx_findapp(tmp->app); 05142 if (app) { 05143 if (option_verbose > 3) 05144 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05145 pbx_exec(tmp->chan, app, tmp->data, 1); 05146 } else 05147 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05148 ast_hangup(tmp->chan); 05149 free(tmp); 05150 return NULL; 05151 }
|
|
Definition at line 2522 of file pbx.c. References ast_log(), AST_PBX_CALL_LIMIT, AST_PBX_FAILED, AST_PBX_SUCCESS, ast_pthread_create, increase_call_count(), LOG_WARNING, pbx_thread(), and t. Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_modem_new(), ast_pbx_outgoing_exten(), cb_events(), check_goto_on_transfer(), do_immediate_setup(), do_parking_thread(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), phone_new(), rpt_call(), sip_new(), skinny_new(), vpb_new(), and zt_new(). 02523 { 02524 pthread_t t; 02525 pthread_attr_t attr; 02526 02527 if (!c) { 02528 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02529 return AST_PBX_FAILED; 02530 } 02531 02532 if (increase_call_count(c)) 02533 return AST_PBX_CALL_LIMIT; 02534 02535 /* Start a new thread, and get something handling this channel. */ 02536 pthread_attr_init(&attr); 02537 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02538 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02539 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02540 return AST_PBX_FAILED; 02541 } 02542 02543 return AST_PBX_SUCCESS; 02544 }
|
|
Dynamically register a new dial plan application.
Definition at line 2863 of file pbx.c. References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), COLOR_BRCYAN, LOG_ERROR, LOG_WARNING, malloc, ast_app::name, ast_app::next, option_verbose, term_color(), and VERBOSE_PREFIX_2. Referenced by load_module(), and load_pbx(). 02864 { 02865 struct ast_app *tmp, *prev, *cur; 02866 char tmps[80]; 02867 int length; 02868 length = sizeof(struct ast_app); 02869 length += strlen(app) + 1; 02870 if (ast_mutex_lock(&applock)) { 02871 ast_log(LOG_ERROR, "Unable to lock application list\n"); 02872 return -1; 02873 } 02874 tmp = apps; 02875 while(tmp) { 02876 if (!strcasecmp(app, tmp->name)) { 02877 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02878 ast_mutex_unlock(&applock); 02879 return -1; 02880 } 02881 tmp = tmp->next; 02882 } 02883 tmp = malloc(length); 02884 if (tmp) { 02885 memset(tmp, 0, length); 02886 strcpy(tmp->name, app); 02887 tmp->execute = execute; 02888 tmp->synopsis = synopsis; 02889 tmp->description = description; 02890 /* Store in alphabetical order */ 02891 cur = apps; 02892 prev = NULL; 02893 while(cur) { 02894 if (strcasecmp(tmp->name, cur->name) < 0) 02895 break; 02896 prev = cur; 02897 cur = cur->next; 02898 } 02899 if (prev) { 02900 tmp->next = prev->next; 02901 prev->next = tmp; 02902 } else { 02903 tmp->next = apps; 02904 apps = tmp; 02905 } 02906 } else { 02907 ast_log(LOG_ERROR, "Out of memory\n"); 02908 ast_mutex_unlock(&applock); 02909 return -1; 02910 } 02911 if (option_verbose > 1) 02912 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02913 ast_mutex_unlock(&applock); 02914 return 0; 02915 }
|
|
Definition at line 2917 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, LOG_WARNING, ast_switch::name, ast_switch::next, and switches. Referenced by load_module(). 02918 { 02919 struct ast_switch *tmp, *prev=NULL; 02920 if (ast_mutex_lock(&switchlock)) { 02921 ast_log(LOG_ERROR, "Unable to lock switch lock\n"); 02922 return -1; 02923 } 02924 tmp = switches; 02925 while(tmp) { 02926 if (!strcasecmp(tmp->name, sw->name)) 02927 break; 02928 prev = tmp; 02929 tmp = tmp->next; 02930 } 02931 if (tmp) { 02932 ast_mutex_unlock(&switchlock); 02933 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 02934 return -1; 02935 } 02936 sw->next = NULL; 02937 if (prev) 02938 prev->next = sw; 02939 else 02940 switches = sw; 02941 ast_mutex_unlock(&switchlock); 02942 return 0; 02943 }
|
|
ast_remove_hint: Remove hint from extension
Definition at line 2136 of file pbx.c. References AST_EXTENSION_DEACTIVATED, ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_state_cb::data, free, hints, list, ast_imager::name, ast_hint::next, ast_imager::next, and ast_state_cb::next. Referenced by ast_context_remove_extension2(), and destroy_exten(). 02137 { 02138 /* Cleanup the Notifys if hint is removed */ 02139 struct ast_hint *list, *prev = NULL; 02140 struct ast_state_cb *cblist, *cbprev; 02141 02142 if (!e) 02143 return -1; 02144 02145 ast_mutex_lock(&hintlock); 02146 02147 list = hints; 02148 while(list) { 02149 if (list->exten==e) { 02150 cbprev = NULL; 02151 cblist = list->callbacks; 02152 while (cblist) { 02153 /* Notify with -1 and remove all callbacks */ 02154 cbprev = cblist; 02155 cblist = cblist->next; 02156 cbprev->callback(list->exten->parent->name, list->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data); 02157 free(cbprev); 02158 } 02159 list->callbacks = NULL; 02160 02161 if (!prev) 02162 hints = list->next; 02163 else 02164 prev->next = list->next; 02165 free(list); 02166 02167 ast_mutex_unlock(&hintlock); 02168 return 0; 02169 } else { 02170 prev = list; 02171 list = list->next; 02172 } 02173 } 02174 02175 ast_mutex_unlock(&hintlock); 02176 return -1; 02177 }
|
|
Definition at line 2225 of file pbx.c. References HELPER_SPAWN, and pbx_extension_helper(). Referenced by __ast_pbx_run(), loopback_exec(), and macro_exec(). 02226 { 02227 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_SPAWN); 02228 }
|
|
Definition at line 6278 of file pbx.c. References ast_mutex_unlock(), and ast_context::lock. Referenced by complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_ignorepat(), dundi_precache_full(), find_matching_endwhile(), and handle_save_dialplan(). 06279 { 06280 return ast_mutex_unlock(&con->lock); 06281 }
|
|
Returns 0 on success, -1 on failure Definition at line 6265 of file pbx.c. References ast_mutex_unlock(). Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), and handle_save_dialplan(). 06266 { 06267 return ast_mutex_unlock(&conlock); 06268 }
|
|
Definition at line 3610 of file pbx.c. References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, LOG_ERROR, ast_app::name, ast_app::next, option_verbose, and VERBOSE_PREFIX_2. Referenced by __unload_module(), and unload_module(). 03611 { 03612 struct ast_app *tmp, *tmpl = NULL; 03613 if (ast_mutex_lock(&applock)) { 03614 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03615 return -1; 03616 } 03617 tmp = apps; 03618 while(tmp) { 03619 if (!strcasecmp(app, tmp->name)) { 03620 if (tmpl) 03621 tmpl->next = tmp->next; 03622 else 03623 apps = tmp->next; 03624 if (option_verbose > 1) 03625 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03626 free(tmp); 03627 ast_mutex_unlock(&applock); 03628 return 0; 03629 } 03630 tmpl = tmp; 03631 tmp = tmp->next; 03632 } 03633 ast_mutex_unlock(&applock); 03634 return -1; 03635 }
|
|
Definition at line 2945 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_switch::next, and switches. Referenced by __unload_module(), and unload_module(). 02946 { 02947 struct ast_switch *tmp, *prev=NULL; 02948 if (ast_mutex_lock(&switchlock)) { 02949 ast_log(LOG_ERROR, "Unable to lock switch lock\n"); 02950 return; 02951 } 02952 tmp = switches; 02953 while(tmp) { 02954 if (tmp == sw) { 02955 if (prev) 02956 prev->next = tmp->next; 02957 else 02958 switches = tmp->next; 02959 tmp->next = NULL; 02960 break; 02961 } 02962 prev = tmp; 02963 tmp = tmp->next; 02964 } 02965 ast_mutex_unlock(&switchlock); 02966 }
|
|
Definition at line 6385 of file pbx.c. References exten, and ast_context::root. Referenced by complete_context_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper(). 06387 { 06388 if (!exten) 06389 return con ? con->root : NULL; 06390 else 06391 return exten->next; 06392 }
|
|
Definition at line 6421 of file pbx.c. References ast_context::ignorepats, and ast_ignorepat::next. Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), and handle_save_dialplan(). 06423 { 06424 if (!ip) 06425 return con ? con->ignorepats : NULL; 06426 else 06427 return ip->next; 06428 }
|
|
Definition at line 6412 of file pbx.c. References ast_context::includes, and ast_include::next. Referenced by ast_context_verify_includes(), complete_context_add_include(), complete_context_dont_include(), handle_save_dialplan(), and show_dialplan_helper(). 06414 { 06415 if (!inc) 06416 return con ? con->includes : NULL; 06417 else 06418 return inc->next; 06419 }
|
|
Definition at line 6394 of file pbx.c. References ast_context::alts, and ast_sw::next. Referenced by handle_save_dialplan(). 06396 { 06397 if (!sw) 06398 return con ? con->alts : NULL; 06399 else 06400 return sw->next; 06401 }
|
|
Definition at line 6377 of file pbx.c. References contexts, and ast_context::next. Referenced by ast_add_extension(), ast_context_add_ignorepat(), ast_context_add_include(), ast_context_add_switch(), ast_context_remove_extension(), ast_context_remove_ignorepat(), ast_context_remove_include(), ast_context_remove_switch(), complete_context_add_extension(), complete_context_add_ignorepat(), complete_context_add_include(), complete_context_dont_include(), complete_context_remove_extension(), complete_context_remove_ignorepat(), complete_show_dialplan_context(), dundi_precache_full(), find_matching_endwhile(), handle_save_dialplan(), pbx_load_module(), and show_dialplan_helper().
|
|
Definition at line 6403 of file pbx.c. References exten, and ast_exten::priority. Referenced by complete_context_remove_extension(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper().
|
|
Definition at line 4887 of file pbx.c. References ast_channel::_state, async_stat::app, app, async_stat::appdata, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, 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, ast_frame::frametype, free, LOG_ERROR, LOG_WARNING, ast_channel::name, option_verbose, pbx_exec(), pbx_findapp(), ast_channel::priority, async_stat::priority, ast_frame::subclass, async_stat::timeout, and VERBOSE_PREFIX_3. Referenced by ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten(). 04888 { 04889 struct async_stat *as = data; 04890 struct ast_channel *chan = as->chan; 04891 int timeout = as->timeout; 04892 int res; 04893 struct ast_frame *f; 04894 struct ast_app *app; 04895 04896 while(timeout && (chan->_state != AST_STATE_UP)) { 04897 res = ast_waitfor(chan, timeout); 04898 if (res < 1) 04899 break; 04900 if (timeout > -1) 04901 timeout = res; 04902 f = ast_read(chan); 04903 if (!f) 04904 break; 04905 if (f->frametype == AST_FRAME_CONTROL) { 04906 if ((f->subclass == AST_CONTROL_BUSY) || 04907 (f->subclass == AST_CONTROL_CONGESTION) ) 04908 break; 04909 } 04910 ast_frfree(f); 04911 } 04912 if (chan->_state == AST_STATE_UP) { 04913 if (!ast_strlen_zero(as->app)) { 04914 app = pbx_findapp(as->app); 04915 if (app) { 04916 if (option_verbose > 2) 04917 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 04918 pbx_exec(chan, app, as->appdata, 1); 04919 } else 04920 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 04921 } else { 04922 if (!ast_strlen_zero(as->context)) 04923 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 04924 if (!ast_strlen_zero(as->exten)) 04925 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 04926 if (as->priority > 0) 04927 chan->priority = as->priority; 04928 /* Run the PBX */ 04929 if (ast_pbx_run(chan)) { 04930 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 04931 } else { 04932 /* PBX will have taken care of this */ 04933 chan = NULL; 04934 } 04935 } 04936 04937 } 04938 free(as); 04939 if (chan) 04940 ast_hangup(chan); 04941 return NULL; 04942 }
|
|
Definition at line 3016 of file pbx.c. References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_app::name, ast_app::next, and strdup. 03018 { 03019 struct ast_app *a; 03020 int which = 0; 03021 03022 /* try to lock applications list ... */ 03023 if (ast_mutex_lock(&applock)) { 03024 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03025 return NULL; 03026 } 03027 03028 /* ... walk all applications ... */ 03029 a = apps; 03030 while (a) { 03031 /* ... check if word matches this application ... */ 03032 if (!strncasecmp(word, a->name, strlen(word))) { 03033 /* ... if this is right app serve it ... */ 03034 if (++which > state) { 03035 char *ret = strdup(a->name); 03036 ast_mutex_unlock(&applock); 03037 return ret; 03038 } 03039 } 03040 a = a->next; 03041 } 03042 03043 /* no application match */ 03044 ast_mutex_unlock(&applock); 03045 return NULL; 03046 }
|
|
Definition at line 3263 of file pbx.c. References ast_strlen_zero(), and strdup. 03264 { 03265 if (pos == 2) { 03266 if (ast_strlen_zero(word)) { 03267 switch (state) { 03268 case 0: 03269 return strdup("like"); 03270 case 1: 03271 return strdup("describing"); 03272 default: 03273 return NULL; 03274 } 03275 } else if (! strncasecmp(word, "like", strlen(word))) { 03276 if (state == 0) { 03277 return strdup("like"); 03278 } else { 03279 return NULL; 03280 } 03281 } else if (! strncasecmp(word, "describing", strlen(word))) { 03282 if (state == 0) { 03283 return strdup("describing"); 03284 } else { 03285 return NULL; 03286 } 03287 } 03288 } 03289 return NULL; 03290 }
|
|
Definition at line 3295 of file pbx.c. References ast_get_context_name(), ast_lock_contexts(), ast_log(), ast_unlock_contexts(), ast_walk_contexts(), LOG_ERROR, and strdup. 03297 { 03298 struct ast_context *c; 03299 int which = 0; 03300 03301 /* we are do completion of [exten@]context on second position only */ 03302 if (pos != 2) return NULL; 03303 03304 /* try to lock contexts list ... */ 03305 if (ast_lock_contexts()) { 03306 ast_log(LOG_ERROR, "Unable to lock context list\n"); 03307 return NULL; 03308 } 03309 03310 /* ... walk through all contexts ... */ 03311 c = ast_walk_contexts(NULL); 03312 while(c) { 03313 /* ... word matches context name? yes? ... */ 03314 if (!strncasecmp(word, ast_get_context_name(c), strlen(word))) { 03315 /* ... for serve? ... */ 03316 if (++which > state) { 03317 /* ... yes, serve this context name ... */ 03318 char *ret = strdup(ast_get_context_name(c)); 03319 ast_unlock_contexts(); 03320 return ret; 03321 } 03322 } 03323 c = ast_walk_contexts(c); 03324 } 03325 03326 /* ... unlock and return */ 03327 ast_unlock_contexts(); 03328 return NULL; 03329 }
|
|
Definition at line 1238 of file pbx.c. References acf_root, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_custom_function::name, ast_custom_function::next, and strdup. 01239 { 01240 struct ast_custom_function *acf; 01241 int which = 0; 01242 01243 /* try to lock functions list ... */ 01244 if (ast_mutex_lock(&acflock)) { 01245 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01246 return NULL; 01247 } 01248 01249 acf = acf_root; 01250 while (acf) { 01251 if (!strncasecmp(word, acf->name, strlen(word))) { 01252 if (++which > state) { 01253 char *ret = strdup(acf->name); 01254 ast_mutex_unlock(&acflock); 01255 return ret; 01256 } 01257 } 01258 acf = acf->next; 01259 } 01260 01261 ast_mutex_unlock(&acflock); 01262 return NULL; 01263 }
|
|
Definition at line 2494 of file pbx.c. References ast_mutex_lock(), and ast_mutex_unlock(). Referenced by ast_pbx_run(), and pbx_thread(). 02495 { 02496 ast_mutex_lock(&maxcalllock); 02497 if (countcalls > 0) 02498 countcalls--; 02499 ast_mutex_unlock(&maxcalllock); 02500 }
|
|
Definition at line 5298 of file pbx.c. References ast_remove_hint(), free, ast_exten::priority, and PRIORITY_HINT. Referenced by __ast_context_destroy(). 05299 { 05300 if (e->priority == PRIORITY_HINT) 05301 ast_remove_hint(e); 05302 05303 if (e->datad) 05304 e->datad(e->data); 05305 free(e); 05306 }
|
|
Definition at line 4609 of file pbx.c. Referenced by ast_add_extension2(). 04610 { 04611 int count=0; 04612 04613 while(*src && (count < len - 1)) { 04614 switch(*src) { 04615 case ' ': 04616 /* otherwise exten => [a-b],1,... doesn't work */ 04617 /* case '-': */ 04618 /* Ignore */ 04619 break; 04620 default: 04621 *dst = *src; 04622 dst++; 04623 } 04624 src++; 04625 count++; 04626 } 04627 *dst = '\0'; 04628 04629 return count; 04630 }
|
|
Definition at line 3975 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and s. Referenced by ast_build_timing(). 03976 { 03977 char *c; 03978 /* The following line is coincidence, really! */ 03979 int s, e, x; 03980 unsigned int mask; 03981 03982 /* Check for all days */ 03983 if (ast_strlen_zero(day) || !strcmp(day, "*")) { 03984 mask = (1 << 30) + ((1 << 30) - 1); 03985 return mask; 03986 } 03987 /* Get start and ending days */ 03988 c = strchr(day, '-'); 03989 if (c) { 03990 *c = '\0'; 03991 c++; 03992 } 03993 /* Find the start */ 03994 if (sscanf(day, "%d", &s) != 1) { 03995 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day); 03996 return 0; 03997 } 03998 if ((s < 1) || (s > 31)) { 03999 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day); 04000 return 0; 04001 } 04002 s--; 04003 if (c) { 04004 if (sscanf(c, "%d", &e) != 1) { 04005 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 04006 return 0; 04007 } 04008 if ((e < 1) || (e > 31)) { 04009 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 04010 return 0; 04011 } 04012 e--; 04013 } else 04014 e = s; 04015 mask = 0; 04016 for (x=s; x!=e; x = (x + 1) % 31) { 04017 mask |= (1 << x); 04018 } 04019 mask |= (1 << x); 04020 return mask; 04021 }
|
|
get_dow: Get day of week
Definition at line 3933 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and s. Referenced by ast_build_timing(). 03934 { 03935 char *c; 03936 /* The following line is coincidence, really! */ 03937 int s, e, x; 03938 unsigned int mask; 03939 03940 /* Check for all days */ 03941 if (ast_strlen_zero(dow) || !strcmp(dow, "*")) 03942 return (1 << 7) - 1; 03943 /* Get start and ending days */ 03944 c = strchr(dow, '-'); 03945 if (c) { 03946 *c = '\0'; 03947 c++; 03948 } else 03949 c = NULL; 03950 /* Find the start */ 03951 s = 0; 03952 while((s < 7) && strcasecmp(dow, days[s])) s++; 03953 if (s >= 7) { 03954 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", dow); 03955 return 0; 03956 } 03957 if (c) { 03958 e = 0; 03959 while((e < 7) && strcasecmp(c, days[e])) e++; 03960 if (e >= 7) { 03961 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 03962 return 0; 03963 } 03964 } else 03965 e = s; 03966 mask = 0; 03967 for (x=s; x != e; x = (x + 1) % 7) { 03968 mask |= (1 << x); 03969 } 03970 /* One last one */ 03971 mask |= (1 << x); 03972 return mask; 03973 }
|
|
Definition at line 4039 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and s. Referenced by ast_build_timing(). 04040 { 04041 char *c; 04042 /* The following line is coincidence, really! */ 04043 int s, e, x; 04044 unsigned int mask; 04045 04046 /* Check for all days */ 04047 if (ast_strlen_zero(mon) || !strcmp(mon, "*")) 04048 return (1 << 12) - 1; 04049 /* Get start and ending days */ 04050 c = strchr(mon, '-'); 04051 if (c) { 04052 *c = '\0'; 04053 c++; 04054 } 04055 /* Find the start */ 04056 s = 0; 04057 while((s < 12) && strcasecmp(mon, months[s])) s++; 04058 if (s >= 12) { 04059 ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", mon); 04060 return 0; 04061 } 04062 if (c) { 04063 e = 0; 04064 while((e < 12) && strcasecmp(mon, months[e])) e++; 04065 if (e >= 12) { 04066 ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", c); 04067 return 0; 04068 } 04069 } else 04070 e = s; 04071 mask = 0; 04072 for (x=s; x!=e; x = (x + 1) % 12) { 04073 mask |= (1 << x); 04074 } 04075 /* One last one */ 04076 mask |= (1 << x); 04077 return mask; 04078 }
|
|
Definition at line 3837 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask. Referenced by ast_build_timing(). 03838 { 03839 char *e; 03840 int x; 03841 int s1, s2; 03842 int e1, e2; 03843 /* int cth, ctm; */ 03844 03845 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 03846 memset(i->minmask, 0, sizeof(i->minmask)); 03847 03848 /* Star is all times */ 03849 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 03850 for (x=0; x<24; x++) 03851 i->minmask[x] = (1 << 30) - 1; 03852 return; 03853 } 03854 /* Otherwise expect a range */ 03855 e = strchr(times, '-'); 03856 if (!e) { 03857 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n"); 03858 return; 03859 } 03860 *e = '\0'; 03861 e++; 03862 while(*e && !isdigit(*e)) 03863 e++; 03864 if (!*e) { 03865 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n"); 03866 return; 03867 } 03868 if (sscanf(times, "%d:%d", &s1, &s2) != 2) { 03869 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times); 03870 return; 03871 } 03872 if (sscanf(e, "%d:%d", &e1, &e2) != 2) { 03873 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e); 03874 return; 03875 } 03876 03877 #if 1 03878 s1 = s1 * 30 + s2/2; 03879 if ((s1 < 0) || (s1 >= 24*30)) { 03880 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times); 03881 return; 03882 } 03883 e1 = e1 * 30 + e2/2; 03884 if ((e1 < 0) || (e1 >= 24*30)) { 03885 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e); 03886 return; 03887 } 03888 /* Go through the time and enable each appropriate bit */ 03889 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) { 03890 i->minmask[x/30] |= (1 << (x % 30)); 03891 } 03892 /* Do the last one */ 03893 i->minmask[x/30] |= (1 << (x % 30)); 03894 #else 03895 for (cth=0; cth<24; cth++) { 03896 /* Initialize masks to blank */ 03897 i->minmask[cth] = 0; 03898 for (ctm=0; ctm<30; ctm++) { 03899 if ( 03900 /* First hour with more than one hour */ 03901 (((cth == s1) && (ctm >= s2)) && 03902 ((cth < e1))) 03903 /* Only one hour */ 03904 || (((cth == s1) && (ctm >= s2)) && 03905 ((cth == e1) && (ctm <= e2))) 03906 /* In between first and last hours (more than 2 hours) */ 03907 || ((cth > s1) && 03908 (cth < e1)) 03909 /* Last hour with more than one hour */ 03910 || ((cth > s1) && 03911 ((cth == e1) && (ctm <= e2))) 03912 ) 03913 i->minmask[cth] |= (1 << (ctm / 2)); 03914 } 03915 } 03916 #endif 03917 /* All done */ 03918 return; 03919 }
|
|
Definition at line 3048 of file pbx.c. References apps, ast_cli(), ast_log(), AST_MAX_APP, ast_mutex_lock(), COLOR_CYAN, COLOR_MAGENTA, ast_app::description, description, LOG_ERROR, ast_app::name, RESULT_SHOWUSAGE, ast_app::synopsis, synopsis, and term_color(). 03049 { 03050 struct ast_app *a; 03051 int app, no_registered_app = 1; 03052 03053 if (argc < 3) return RESULT_SHOWUSAGE; 03054 03055 /* try to lock applications list ... */ 03056 if (ast_mutex_lock(&applock)) { 03057 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03058 return -1; 03059 } 03060 03061 /* ... go through all applications ... */ 03062 a = apps; 03063 while (a) { 03064 /* ... compare this application name with all arguments given 03065 * to 'show application' command ... */ 03066 for (app = 2; app < argc; app++) { 03067 if (!strcasecmp(a->name, argv[app])) { 03068 /* Maximum number of characters added by terminal coloring is 22 */ 03069 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03070 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03071 int synopsis_size, description_size; 03072 03073 no_registered_app = 0; 03074 03075 if (a->synopsis) 03076 synopsis_size = strlen(a->synopsis) + 23; 03077 else 03078 synopsis_size = strlen("Not available") + 23; 03079 synopsis = alloca(synopsis_size); 03080 03081 if (a->description) 03082 description_size = strlen(a->description) + 23; 03083 else 03084 description_size = strlen("Not available") + 23; 03085 description = alloca(description_size); 03086 03087 if (synopsis && description) { 03088 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03089 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03090 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03091 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03092 term_color(synopsis, 03093 a->synopsis ? a->synopsis : "Not available", 03094 COLOR_CYAN, 0, synopsis_size); 03095 term_color(description, 03096 a->description ? a->description : "Not available", 03097 COLOR_CYAN, 0, description_size); 03098 03099 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03100 } else { 03101 /* ... one of our applications, show info ...*/ 03102 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03103 "[Synopsis]\n %s\n\n" 03104 "[Description]\n%s\n", 03105 a->name, 03106 a->synopsis ? a->synopsis : "Not available", 03107 a->description ? a->description : "Not available"); 03108 } 03109 } 03110 } 03111 a = a->next; 03112 } 03113 03114 ast_mutex_unlock(&applock); 03115 03116 /* we found at least one app? no? */ 03117 if (no_registered_app) { 03118 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03119 return RESULT_FAILURE; 03120 } 03121 03122 return RESULT_SUCCESS; 03123 }
|
|
Definition at line 3186 of file pbx.c. References apps, ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_app::name, ast_app::next, and strcasestr(). 03187 { 03188 struct ast_app *a; 03189 int like=0, describing=0; 03190 int total_match = 0; /* Number of matches in like clause */ 03191 int total_apps = 0; /* Number of apps registered */ 03192 03193 /* try to lock applications list ... */ 03194 if (ast_mutex_lock(&applock)) { 03195 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03196 return -1; 03197 } 03198 03199 /* ... have we got at least one application (first)? no? */ 03200 if (!apps) { 03201 ast_cli(fd, "There are no registered applications\n"); 03202 ast_mutex_unlock(&applock); 03203 return -1; 03204 } 03205 03206 /* show applications like <keyword> */ 03207 if ((argc == 4) && (!strcmp(argv[2], "like"))) { 03208 like = 1; 03209 } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { 03210 describing = 1; 03211 } 03212 03213 /* show applications describing <keyword1> [<keyword2>] [...] */ 03214 if ((!like) && (!describing)) { 03215 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03216 } else { 03217 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03218 } 03219 03220 /* ... go through all applications ... */ 03221 for (a = apps; a; a = a->next) { 03222 /* ... show informations about applications ... */ 03223 int printapp=0; 03224 total_apps++; 03225 if (like) { 03226 if (strcasestr(a->name, argv[3])) { 03227 printapp = 1; 03228 total_match++; 03229 } 03230 } else if (describing) { 03231 if (a->description) { 03232 /* Match all words on command line */ 03233 int i; 03234 printapp = 1; 03235 for (i=3; i<argc; i++) { 03236 if (!strcasestr(a->description, argv[i])) { 03237 printapp = 0; 03238 } else { 03239 total_match++; 03240 } 03241 } 03242 } 03243 } else { 03244 printapp = 1; 03245 } 03246 03247 if (printapp) { 03248 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03249 } 03250 } 03251 if ((!like) && (!describing)) { 03252 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03253 } else { 03254 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03255 } 03256 03257 /* ... unlock and return */ 03258 ast_mutex_unlock(&applock); 03259 03260 return RESULT_SUCCESS; 03261 }
|
|
Definition at line 3526 of file pbx.c. References ast_cli(), AST_PBX_MAX_STACK, ast_strdupa, ast_strlen_zero(), context, exten, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, show_dialplan_helper(), and strsep(). 03527 { 03528 char *exten = NULL, *context = NULL; 03529 /* Variables used for different counters */ 03530 struct dialplan_counters counters; 03531 char *incstack[AST_PBX_MAX_STACK]; 03532 memset(&counters, 0, sizeof(counters)); 03533 03534 if (argc != 2 && argc != 3) 03535 return RESULT_SHOWUSAGE; 03536 03537 /* we obtain [exten@]context? if yes, split them ... */ 03538 if (argc == 3) { 03539 char *splitter = ast_strdupa(argv[2]); 03540 /* is there a '@' character? */ 03541 if (splitter && strchr(argv[2], '@')) { 03542 /* yes, split into exten & context ... */ 03543 exten = strsep(&splitter, "@"); 03544 context = splitter; 03545 03546 /* check for length and change to NULL if ast_strlen_zero() */ 03547 if (ast_strlen_zero(exten)) 03548 exten = NULL; 03549 if (ast_strlen_zero(context)) 03550 context = NULL; 03551 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03552 } else { 03553 /* no '@' char, only context given */ 03554 context = argv[2]; 03555 if (ast_strlen_zero(context)) 03556 context = NULL; 03557 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03558 } 03559 } else { 03560 /* Show complete dial plan */ 03561 show_dialplan_helper(fd, NULL, NULL, &counters, NULL, 0, incstack); 03562 } 03563 03564 /* check for input failure and throw some error messages */ 03565 if (context && !counters.context_existence) { 03566 ast_cli(fd, "There is no existence of '%s' context\n", context); 03567 return RESULT_FAILURE; 03568 } 03569 03570 if (exten && !counters.extension_existence) { 03571 if (context) 03572 ast_cli(fd, "There is no existence of %s@%s extension\n", 03573 exten, context); 03574 else 03575 ast_cli(fd, 03576 "There is no existence of '%s' extension in all contexts\n", 03577 exten); 03578 return RESULT_FAILURE; 03579 } 03580 03581 ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", 03582 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions", 03583 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities", 03584 counters.total_context, counters.total_context == 1 ? "context" : "contexts"); 03585 03586 /* everything ok */ 03587 return RESULT_SUCCESS; 03588 }
|
|
Definition at line 1183 of file pbx.c. References ast_cli(), ast_custom_function_find(), AST_MAX_APP, COLOR_CYAN, COLOR_MAGENTA, ast_custom_function::desc, description, ast_custom_function::name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_custom_function::synopsis, synopsis, ast_custom_function::syntax, and term_color(). 01184 { 01185 struct ast_custom_function *acf; 01186 /* Maximum number of characters added by terminal coloring is 22 */ 01187 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01188 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01189 char stxtitle[40], *syntax = NULL; 01190 int synopsis_size, description_size, syntax_size; 01191 01192 if (argc < 3) return RESULT_SHOWUSAGE; 01193 01194 if (!(acf = ast_custom_function_find(argv[2]))) { 01195 ast_cli(fd, "No function by that name registered.\n"); 01196 return RESULT_FAILURE; 01197 01198 } 01199 01200 if (acf->synopsis) 01201 synopsis_size = strlen(acf->synopsis) + 23; 01202 else 01203 synopsis_size = strlen("Not available") + 23; 01204 synopsis = alloca(synopsis_size); 01205 01206 if (acf->desc) 01207 description_size = strlen(acf->desc) + 23; 01208 else 01209 description_size = strlen("Not available") + 23; 01210 description = alloca(description_size); 01211 01212 if (acf->syntax) 01213 syntax_size = strlen(acf->syntax) + 23; 01214 else 01215 syntax_size = strlen("Not available") + 23; 01216 syntax = alloca(syntax_size); 01217 01218 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01219 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01220 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01221 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01222 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01223 term_color(syntax, 01224 acf->syntax ? acf->syntax : "Not available", 01225 COLOR_CYAN, 0, syntax_size); 01226 term_color(synopsis, 01227 acf->synopsis ? acf->synopsis : "Not available", 01228 COLOR_CYAN, 0, synopsis_size); 01229 term_color(description, 01230 acf->desc ? acf->desc : "Not available", 01231 COLOR_CYAN, 0, description_size); 01232 01233 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01234 01235 return RESULT_SUCCESS; 01236 }
|
|
Definition at line 1169 of file pbx.c. References acf_root, ast_cli(), ast_custom_function::name, ast_custom_function::next, ast_custom_function::synopsis, and ast_custom_function::syntax. 01170 { 01171 struct ast_custom_function *acf; 01172 int count_acf = 0; 01173 01174 ast_cli(fd, "Installed Custom Functions:\n--------------------------------------------------------------------------------\n"); 01175 for (acf = acf_root ; acf; acf = acf->next) { 01176 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01177 count_acf++; 01178 } 01179 ast_cli(fd, "%d custom functions installed.\n", count_acf); 01180 return 0; 01181 }
|
|
handle_show_hints: CLI support for listing registred dial plan hints
Definition at line 3126 of file pbx.c. References ast_cli(), ast_extension_state2str(), ast_get_extension_app(), ast_get_extension_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_hint::callbacks, ast_hint::exten, hints, ast_hint::laststate, LOG_ERROR, ast_hint::next, ast_state_cb::next, and RESULT_SUCCESS. 03127 { 03128 struct ast_hint *hint; 03129 int num = 0; 03130 int watchers; 03131 struct ast_state_cb *watcher; 03132 03133 if (!hints) { 03134 ast_cli(fd, "There are no registered dialplan hints\n"); 03135 return RESULT_SUCCESS; 03136 } 03137 /* ... we have hints ... */ 03138 ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); 03139 if (ast_mutex_lock(&hintlock)) { 03140 ast_log(LOG_ERROR, "Unable to lock hints\n"); 03141 return -1; 03142 } 03143 hint = hints; 03144 while (hint) { 03145 watchers = 0; 03146 for (watcher = hint->callbacks; watcher; watcher = watcher->next) 03147 watchers++; 03148 ast_cli(fd, " %-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", 03149 ast_get_extension_name(hint->exten), ast_get_extension_app(hint->exten), 03150 ast_extension_state2str(hint->laststate), watchers); 03151 num++; 03152 hint = hint->next; 03153 } 03154 ast_cli(fd, "----------------\n"); 03155 ast_cli(fd, "- %d hints registered\n", num); 03156 ast_mutex_unlock(&hintlock); 03157 return RESULT_SUCCESS; 03158 }
|
|
handle_show_switches: CLI support for listing registred dial plan switches
Definition at line 3161 of file pbx.c. References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_switch::description, LOG_ERROR, ast_switch::name, ast_switch::next, RESULT_SUCCESS, and switches. 03162 { 03163 struct ast_switch *sw; 03164 if (!switches) { 03165 ast_cli(fd, "There are no registered alternative switches\n"); 03166 return RESULT_SUCCESS; 03167 } 03168 /* ... we have applications ... */ 03169 ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); 03170 if (ast_mutex_lock(&switchlock)) { 03171 ast_log(LOG_ERROR, "Unable to lock switches\n"); 03172 return -1; 03173 } 03174 sw = switches; 03175 while (sw) { 03176 ast_cli(fd, "%s: %s\n", sw->name, sw->description); 03177 sw = sw->next; 03178 } 03179 ast_mutex_unlock(&switchlock); 03180 return RESULT_SUCCESS; 03181 }
|
|
Definition at line 612 of file pbx.c. References ast_check_timing(), ast_include::hastime, and ast_include::timing. 00613 { 00614 if (!i->hastime) 00615 return 1; 00616 00617 return ast_check_timing(&(i->timing)); 00618 }
|
|
Definition at line 2469 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), getloadavg(), LOG_NOTICE, ast_channel::name, option_maxcalls, and option_maxload. Referenced by ast_pbx_run(), and ast_pbx_start(). 02470 { 02471 int failed = 0; 02472 double curloadavg; 02473 ast_mutex_lock(&maxcalllock); 02474 if (option_maxcalls) { 02475 if (countcalls >= option_maxcalls) { 02476 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name); 02477 failed = -1; 02478 } 02479 } 02480 if (option_maxload) { 02481 getloadavg(&curloadavg, 1); 02482 if (curloadavg >= option_maxload) { 02483 ast_log(LOG_NOTICE, "Maximum loadavg limit of %lf load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg); 02484 failed = -1; 02485 } 02486 } 02487 if (!failed) 02488 countcalls++; 02489 ast_mutex_unlock(&maxcalllock); 02490 02491 return failed; 02492 }
|
|
Definition at line 6233 of file pbx.c. References ast_cli_register_multiple(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_register_application(), ast_verbose(), builtins, description, LOG_ERROR, name, option_verbose, pbx_cli, synopsis, and VERBOSE_PREFIX_1. 06234 { 06235 int x; 06236 06237 /* Initialize the PBX */ 06238 if (option_verbose) { 06239 ast_verbose( "Asterisk PBX Core Initializing\n"); 06240 ast_verbose( "Registering builtin applications:\n"); 06241 } 06242 AST_LIST_HEAD_INIT_NOLOCK(&globals); 06243 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(pbx_cli[0])); 06244 06245 /* Register builtin applications */ 06246 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06247 if (option_verbose) 06248 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06249 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06250 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06251 return -1; 06252 } 06253 } 06254 return 0; 06255 }
|
|
Definition at line 759 of file pbx.c. References ast_extension_match(), and ast_strlen_zero(). 00760 { 00761 int failresult; 00762 00763 /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so 00764 failing to get a number should count as a match, otherwise not */ 00765 00766 if (!ast_strlen_zero(cidpattern)) 00767 failresult = 0; 00768 else 00769 failresult = 1; 00770 00771 if (!callerid) 00772 return failresult; 00773 00774 return ast_extension_match(cidpattern, callerid); 00775 }
|
|
Definition at line 4632 of file pbx.c. Referenced by ast_add_extension2().
|
|
Definition at line 905 of file pbx.c. References DONT_HAVE_LENGTH. Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full(). 00906 { 00907 char *varchar, *offsetchar = NULL; 00908 int parens=0; 00909 00910 *offset = 0; 00911 *length = DONT_HAVE_LENGTH; 00912 *isfunc = 0; 00913 for (varchar=var; *varchar; varchar++) { 00914 switch (*varchar) { 00915 case '(': 00916 (*isfunc)++; 00917 parens++; 00918 break; 00919 case ')': 00920 parens--; 00921 break; 00922 case ':': 00923 if (parens == 0) { 00924 offsetchar = varchar + 1; 00925 *varchar = '\0'; 00926 goto pvn_endfor; 00927 } 00928 } 00929 } 00930 pvn_endfor: 00931 if (offsetchar) { 00932 sscanf(offsetchar, "%d:%d", offset, length); 00933 return 1; 00934 } else { 00935 return 0; 00936 } 00937 }
|
|
Definition at line 6122 of file pbx.c. References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), and ast_var_delete(). Referenced by reload(). 06123 { 06124 struct ast_var_t *vardata; 06125 06126 ast_mutex_lock(&globalslock); 06127 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06128 ast_var_delete(vardata); 06129 ast_mutex_unlock(&globalslock); 06130 }
|
|
Definition at line 5917 of file pbx.c. References AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), and ast_channel::varshead. Referenced by __login_exec(), action_getvar(), agentmonitoroutgoing_exec(), ast_app_group_get_count(), ast_app_group_match_get_count(), ast_bridge_call(), ast_feature_interpret(), ast_monitor_stop(), ast_osp_lookup(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), check_goto_on_transfer(), conf_exec(), conf_run(), dial_exec_full(), do_chanreads(), dundi_exec(), dundi_helper(), get_index(), group_check_exec(), group_count_exec(), group_count_function_read(), group_function_read(), iax2_exec(), leave_voicemail(), macro_exec(), misdn_answer(), misdn_hangup(), oh323_hangup(), ospfinished_exec(), ospnext_exec(), queue_exec(), retrydial_exec(), return_exec(), sip_addheader(), try_suggested_sip_codec(), wait_for_answer(), zt_call(), and zt_hangup(). 05918 { 05919 struct ast_var_t *variables; 05920 char *ret = NULL; 05921 int i; 05922 struct varshead *places[2] = { NULL, &globals }; 05923 05924 if (!name) 05925 return NULL; 05926 if (chan) 05927 places[0] = &chan->varshead; 05928 05929 for (i = 0; i < 2; i++) { 05930 if (!places[i]) 05931 continue; 05932 if (places[i] == &globals) 05933 ast_mutex_lock(&globalslock); 05934 AST_LIST_TRAVERSE(places[i], variables, entries) { 05935 if (!strcmp(name, ast_var_name(variables))) { 05936 ret = ast_var_value(variables); 05937 break; 05938 } 05939 } 05940 if (places[i] == &globals) 05941 ast_mutex_unlock(&globalslock); 05942 if (ret) 05943 break; 05944 } 05945 05946 return ret; 05947 }
|
|
Definition at line 6151 of file pbx.c. References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_DEBUG, LOG_WARNING, pbx_builtin_goto(), pbx_checkcondition(), s, and strsep(). 06152 { 06153 char *condition, *branch1, *branch2, *branch; 06154 char *s; 06155 int rc; 06156 char *stringp=NULL; 06157 06158 if (ast_strlen_zero(data)) { 06159 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06160 return 0; 06161 } 06162 06163 s = ast_strdupa(data); 06164 stringp = s; 06165 condition = strsep(&stringp,"?"); 06166 branch1 = strsep(&stringp,":"); 06167 branch2 = strsep(&stringp,""); 06168 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06169 06170 if (ast_strlen_zero(branch)) { 06171 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06172 return 0; 06173 } 06174 06175 rc = pbx_builtin_goto(chan, branch); 06176 06177 return rc; 06178 }
|
|
Definition at line 6061 of file pbx.c. References ast_get_channel_by_name_locked(), ast_log(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), ast_channel::lock, LOG_WARNING, name, pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), s, strsep(), and VAR_BUF_SIZE. 06062 { 06063 char *name; 06064 char *value; 06065 char *stringp=NULL; 06066 char *channel; 06067 struct ast_channel *chan2; 06068 char tmp[VAR_BUF_SIZE]=""; 06069 char *s; 06070 06071 if (ast_strlen_zero(data)) { 06072 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06073 return 0; 06074 } 06075 06076 stringp = ast_strdupa(data); 06077 name = strsep(&stringp,"="); 06078 channel = strsep(&stringp,"|"); 06079 value = strsep(&stringp,"\0"); 06080 if (channel && value && name) { 06081 chan2 = ast_get_channel_by_name_locked(channel); 06082 if (chan2) { 06083 s = alloca(strlen(value) + 4); 06084 if (s) { 06085 sprintf(s, "${%s}", value); 06086 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 06087 } 06088 ast_mutex_unlock(&chan2->lock); 06089 } 06090 pbx_builtin_setvar_helper(chan, name, tmp); 06091 } 06092 06093 return(0); 06094 }
|
|
Definition at line 6116 of file pbx.c.
|
|
Definition at line 5949 of file pbx.c. References ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_var_assign(), ast_verbose(), LOG_WARNING, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2. Referenced by gosub_exec(). 05950 { 05951 struct ast_var_t *newvariable; 05952 struct varshead *headp; 05953 05954 if (name[strlen(name)-1] == ')') { 05955 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05956 return ast_func_write(chan, name, value); 05957 } 05958 05959 headp = (chan) ? &chan->varshead : &globals; 05960 05961 if (value) { 05962 if ((option_verbose > 1) && (headp == &globals)) 05963 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05964 newvariable = ast_var_assign(name, value); 05965 if (headp == &globals) 05966 ast_mutex_lock(&globalslock); 05967 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05968 if (headp == &globals) 05969 ast_mutex_unlock(&globalslock); 05970 } 05971 }
|
|
Definition at line 6215 of file pbx.c. References ast_say_character_str(), and ast_channel::language. 06216 { 06217 int res = 0; 06218 06219 if (data) 06220 res = ast_say_character_str(chan, (char *)data, "", chan->language); 06221 return res; 06222 }
|
|
Definition at line 6206 of file pbx.c. References ast_say_digit_str(), and ast_channel::language. 06207 { 06208 int res = 0; 06209 06210 if (data) 06211 res = ast_say_digit_str(chan, (char *)data, "", chan->language); 06212 return res; 06213 }
|
|
Definition at line 6180 of file pbx.c. References ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, LOG_WARNING, and strsep(). 06181 { 06182 int res = 0; 06183 char tmp[256]; 06184 char *number = (char *) NULL; 06185 char *options = (char *) NULL; 06186 06187 06188 if (ast_strlen_zero(data)) { 06189 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06190 return -1; 06191 } 06192 ast_copy_string(tmp, (char *) data, sizeof(tmp)); 06193 number=tmp; 06194 strsep(&number, "|"); 06195 options = strsep(&number, "|"); 06196 if (options) { 06197 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06198 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06199 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06200 return -1; 06201 } 06202 } 06203 return res = ast_say_number(chan, atoi((char *) tmp), "", chan->language, options); 06204 }
|
|
Definition at line 6224 of file pbx.c. References ast_say_phonetic_str(), and ast_channel::language. 06225 { 06226 int res = 0; 06227 06228 if (data) 06229 res = ast_say_phonetic_str(chan, (char *)data, "", chan->language); 06230 return res; 06231 }
|
|
Definition at line 5890 of file pbx.c. References ast_build_string(), AST_LIST_TRAVERSE, ast_log(), ast_strlen_zero(), ast_var_name(), ast_var_value(), LOG_ERROR, total, var, and ast_channel::varshead. Referenced by dumpchan_exec(), and handle_showchan(). 05891 { 05892 struct ast_var_t *variables; 05893 char *var, *val; 05894 int total = 0; 05895 05896 if (!chan) 05897 return 0; 05898 05899 memset(buf, 0, size); 05900 05901 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05902 if(variables && 05903 (var=ast_var_name(variables)) && (val=ast_var_value(variables)) && 05904 !ast_strlen_zero(var) && !ast_strlen_zero(val)) { 05905 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05906 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05907 break; 05908 } else 05909 total++; 05910 } else 05911 break; 05912 } 05913 05914 return total; 05915 }
|
|
Definition at line 6096 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, name, pbx_builtin_setvar_helper(), and strsep(). 06097 { 06098 char *name; 06099 char *value; 06100 char *stringp = NULL; 06101 06102 if (ast_strlen_zero(data)) { 06103 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06104 return 0; 06105 } 06106 06107 stringp = data; 06108 name = strsep(&stringp, "="); 06109 value = strsep(&stringp, "\0"); 06110 06111 pbx_builtin_setvar_helper(NULL, name, value); 06112 06113 return(0); 06114 }
|
|
Definition at line 6025 of file pbx.c. References ast_app_separate_args(), ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, name, and pbx_builtin_setvar_helper(). Referenced by handle_globals(), and pbx_builtin_setvar_old(). 06026 { 06027 char *name, *value, *mydata; 06028 int argc; 06029 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 06030 int global = 0; 06031 int x; 06032 06033 if (ast_strlen_zero(data)) { 06034 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 06035 return 0; 06036 } 06037 06038 mydata = ast_strdupa(data); 06039 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 06040 06041 /* check for a trailing flags argument */ 06042 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 06043 argc--; 06044 if (strchr(argv[argc], 'g')) 06045 global = 1; 06046 } 06047 06048 for (x = 0; x < argc; x++) { 06049 name = argv[x]; 06050 if ((value = strchr(name, '='))) { 06051 *value = '\0'; 06052 value++; 06053 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 06054 } else 06055 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 06056 } 06057 06058 return(0); 06059 }
|
|
Definition at line 5973 of file pbx.c. References ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_mutex_lock(), ast_mutex_unlock(), ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2. Referenced by action_setvar(), aPGSQL_connect(), aPGSQL_fetch(), aPGSQL_query(), aqm_exec(), ast_app_group_set_channel(), ast_bridge_call(), ast_iax2_new(), ast_monitor_start(), ast_set_variables(), background_detect_exec(), builtin_blindtransfer(), builtin_function_set(), cb_events(), chanavail_exec(), controlplayback_exec(), count_exec(), curl_exec(), cut_exec(), dundi_lookup_exec(), enumlookup_exec(), eval_exec(), function_db_exists(), function_db_read(), get_exec(), get_refer_info(), group_check_exec(), group_count_exec(), group_match_count_exec(), handle_setvariable(), hasvoicemail_exec(), leave_voicemail(), lookupblacklist_exec(), macro_exec(), math_exec(), md5_exec(), md5check_exec(), misdn_call(), misdn_tx2ast_frm(), mixmonitor_exec(), monitor_handle_owned(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_importvar(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_extension_helper(), pbx_load_module(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), read_exec(), readfile_exec(), realtime_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_getheader(), sip_new(), sort_exec(), start_monitor_exec(), system_exec_helper(), transfer_exec(), txtcidname_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_new(), and zt_read(). 05974 { 05975 struct ast_var_t *newvariable; 05976 struct varshead *headp; 05977 const char *nametail = name; 05978 05979 if (name[strlen(name)-1] == ')') 05980 return ast_func_write(chan, name, value); 05981 05982 headp = (chan) ? &chan->varshead : &globals; 05983 05984 /* For comparison purposes, we have to strip leading underscores */ 05985 if (*nametail == '_') { 05986 nametail++; 05987 if (*nametail == '_') 05988 nametail++; 05989 } 05990 05991 if (headp == &globals) 05992 ast_mutex_lock(&globalslock); 05993 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05994 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05995 /* there is already such a variable, delete it */ 05996 AST_LIST_REMOVE(headp, newvariable, entries); 05997 ast_var_delete(newvariable); 05998 break; 05999 } 06000 } 06001 06002 if (value) { 06003 if ((option_verbose > 1) && (headp == &globals)) 06004 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 06005 newvariable = ast_var_assign(name, value); 06006 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 06007 } 06008 06009 if (headp == &globals) 06010 ast_mutex_unlock(&globalslock); 06011 }
|
|
Definition at line 6013 of file pbx.c. References ast_log(), LOG_WARNING, and pbx_builtin_setvar(). 06014 { 06015 static int deprecation_warning = 0; 06016 06017 if (!deprecation_warning) { 06018 ast_log(LOG_WARNING, "SetVar is deprecated, please use Set instead.\n"); 06019 deprecation_warning = 1; 06020 } 06021 06022 return pbx_builtin_setvar(chan, data); 06023 }
|
|
Definition at line 6132 of file pbx.c. Referenced by gosubif_exec(), and pbx_builtin_gotoif(). 06133 { 06134 if (condition) { 06135 if (*condition == '\0') { 06136 /* Empty strings are false */ 06137 return 0; 06138 } else if (*condition >= '0' && *condition <= '9') { 06139 /* Numbers are evaluated for truth */ 06140 return atoi(condition); 06141 } else { 06142 /* Strings are true */ 06143 return 1; 06144 } 06145 } else { 06146 /* NULL is also false */ 06147 return 0; 06148 } 06149 }
|
|
Definition at line 620 of file pbx.c. References free. 00621 { 00622 free(p); 00623 }
|
|
Definition at line 531 of file pbx.c. References app, ast_channel::appl, ast_cdr_setapp(), ast_log(), ast_channel::cdr, ast_channel::data, and LOG_WARNING. Referenced by ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and realtime_exec(). 00535 { 00536 int res; 00537 00538 char *saved_c_appl; 00539 char *saved_c_data; 00540 00541 int (*execute)(struct ast_channel *chan, void *data) = app->execute; 00542 00543 if (newstack) { 00544 if (c->cdr) 00545 ast_cdr_setapp(c->cdr, app->name, data); 00546 00547 /* save channel values */ 00548 saved_c_appl= c->appl; 00549 saved_c_data= c->data; 00550 00551 c->appl = app->name; 00552 c->data = data; 00553 res = execute(c, data); 00554 /* restore channel values */ 00555 c->appl= saved_c_appl; 00556 c->data= saved_c_data; 00557 return res; 00558 } else 00559 ast_log(LOG_WARNING, "You really didn't want to call this function with newstack set to 0\n"); 00560 return -1; 00561 }
|
|
Definition at line 1618 of file pbx.c. References ast_exten::app, app, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_MAX_STACK, ast_strlen_zero(), ast_verbose(), COLOR_BRCYAN, COLOR_BRMAGENTA, ast_channel::context, EVENT_FLAG_CALL, ast_switch::exec, EXT_DATA_SIZE, ast_channel::exten, HELPER_CANMATCH, HELPER_EXEC, HELPER_EXISTS, HELPER_FINDLABEL, HELPER_MATCHMORE, HELPER_SPAWN, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), ast_switch::name, ast_channel::name, option_debug, option_verbose, pbx_builtin_setvar_helper(), pbx_exec(), pbx_find_extension(), pbx_findapp(), pbx_substitute_variables(), ast_channel::priority, ast_exten::priority, STATUS_NO_CONTEXT, STATUS_NO_EXTENSION, STATUS_NO_LABEL, STATUS_NO_PRIORITY, term_color(), ast_channel::uniqueid, and VERBOSE_PREFIX_3. Referenced by ast_canmatch_extension(), ast_exec_extension(), ast_exists_extension(), ast_findlabel_extension(), ast_findlabel_extension2(), ast_matchmore_extension(), and ast_spawn_extension(). 01619 { 01620 struct ast_exten *e; 01621 struct ast_app *app; 01622 struct ast_switch *sw; 01623 char *data; 01624 const char *foundcontext=NULL; 01625 int newstack = 0; 01626 int res; 01627 int status = 0; 01628 char *incstack[AST_PBX_MAX_STACK]; 01629 char passdata[EXT_DATA_SIZE]; 01630 int stacklen = 0; 01631 char tmp[80]; 01632 char tmp2[80]; 01633 char tmp3[EXT_DATA_SIZE]; 01634 char atmp[80]; 01635 char atmp2[EXT_DATA_SIZE+100]; 01636 01637 if (ast_mutex_lock(&conlock)) { 01638 ast_log(LOG_WARNING, "Unable to obtain lock\n"); 01639 if ((action == HELPER_EXISTS) || (action == HELPER_CANMATCH) || (action == HELPER_MATCHMORE)) 01640 return 0; 01641 else 01642 return -1; 01643 } 01644 e = pbx_find_extension(c, con, context, exten, priority, label, callerid, action, incstack, &stacklen, &status, &sw, &data, &foundcontext); 01645 if (e) { 01646 switch(action) { 01647 case HELPER_CANMATCH: 01648 ast_mutex_unlock(&conlock); 01649 return -1; 01650 case HELPER_EXISTS: 01651 ast_mutex_unlock(&conlock); 01652 return -1; 01653 case HELPER_FINDLABEL: 01654 res = e->priority; 01655 ast_mutex_unlock(&conlock); 01656 return res; 01657 case HELPER_MATCHMORE: 01658 ast_mutex_unlock(&conlock); 01659 return -1; 01660 case HELPER_SPAWN: 01661 newstack++; 01662 /* Fall through */ 01663 case HELPER_EXEC: 01664 app = pbx_findapp(e->app); 01665 ast_mutex_unlock(&conlock); 01666 if (app) { 01667 if (c->context != context) 01668 ast_copy_string(c->context, context, sizeof(c->context)); 01669 if (c->exten != exten) 01670 ast_copy_string(c->exten, exten, sizeof(c->exten)); 01671 c->priority = priority; 01672 pbx_substitute_variables(passdata, sizeof(passdata), c, e); 01673 if (option_debug) { 01674 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name); 01675 snprintf(atmp, 80, "STACK-%s-%s-%d", context, exten, priority); 01676 snprintf(atmp2, EXT_DATA_SIZE+100, "%s(\"%s\", \"%s\") %s", app->name, c->name, (!ast_strlen_zero(passdata) ? (char *)passdata : ""), (newstack ? "in new stack" : "in same stack")); 01677 pbx_builtin_setvar_helper(c, atmp, atmp2); 01678 } 01679 if (option_verbose > 2) 01680 ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n", 01681 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)), 01682 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 01683 term_color(tmp3, (!ast_strlen_zero(passdata) ? (char *)passdata : ""), COLOR_BRMAGENTA, 0, sizeof(tmp3)), 01684 (newstack ? "in new stack" : "in same stack")); 01685 manager_event(EVENT_FLAG_CALL, "Newexten", 01686 "Channel: %s\r\n" 01687 "Context: %s\r\n" 01688 "Extension: %s\r\n" 01689 "Priority: %d\r\n" 01690 "Application: %s\r\n" 01691 "AppData: %s\r\n" 01692 "Uniqueid: %s\r\n", 01693 c->name, c->context, c->exten, c->priority, app->name, passdata ? passdata : "(NULL)", c->uniqueid); 01694 res = pbx_exec(c, app, passdata, newstack); 01695 return res; 01696 } else { 01697 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority); 01698 return -1; 01699 } 01700 default: 01701 ast_log(LOG_WARNING, "Huh (%d)?\n", action); return -1; 01702 } 01703 } else if (sw) { 01704 switch(action) { 01705 case HELPER_CANMATCH: 01706 ast_mutex_unlock(&conlock); 01707 return -1; 01708 case HELPER_EXISTS: 01709 ast_mutex_unlock(&conlock); 01710 return -1; 01711 case HELPER_MATCHMORE: 01712 ast_mutex_unlock(&conlock); 01713 return -1; 01714 case HELPER_FINDLABEL: 01715 ast_mutex_unlock(&conlock); 01716 return -1; 01717 case HELPER_SPAWN: 01718 newstack++; 01719 /* Fall through */ 01720 case HELPER_EXEC: 01721 ast_mutex_unlock(&conlock); 01722 if (sw->exec) 01723 res = sw->exec(c, foundcontext ? foundcontext : context, exten, priority, callerid, newstack, data); 01724 else { 01725 ast_log(LOG_WARNING, "No execution engine for switch %s\n", sw->name); 01726 res = -1; 01727 } 01728 return res; 01729 default: 01730 ast_log(LOG_WARNING, "Huh (%d)?\n", action); 01731 return -1; 01732 } 01733 } else { 01734 ast_mutex_unlock(&conlock); 01735 switch(status) { 01736 case STATUS_NO_CONTEXT: 01737 if ((action != HELPER_EXISTS) && (action != HELPER_MATCHMORE)) 01738 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context); 01739 break; 01740 case STATUS_NO_EXTENSION: 01741 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01742 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context); 01743 break; 01744 case STATUS_NO_PRIORITY: 01745 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01746 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context); 01747 break; 01748 case STATUS_NO_LABEL: 01749 if (context) 01750 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context); 01751 break; 01752 default: 01753 ast_log(LOG_DEBUG, "Shouldn't happen!\n"); 01754 } 01755 01756 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01757 return -1; 01758 else 01759 return 0; 01760 } 01761 01762 }
|
|
Definition at line 777 of file pbx.c. References ast_log(), AST_PBX_MAX_STACK, LOG_WARNING, and STATUS_NO_CONTEXT. Referenced by ast_hint_extension(), and pbx_extension_helper(). 00778 { 00779 int x, res; 00780 struct ast_context *tmp; 00781 struct ast_exten *e, *eroot; 00782 struct ast_include *i; 00783 struct ast_sw *sw; 00784 struct ast_switch *asw; 00785 00786 /* Initialize status if appropriate */ 00787 if (!*stacklen) { 00788 *status = STATUS_NO_CONTEXT; 00789 *swo = NULL; 00790 *data = NULL; 00791 } 00792 /* Check for stack overflow */ 00793 if (*stacklen >= AST_PBX_MAX_STACK) { 00794 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n"); 00795 return NULL; 00796 } 00797 /* Check first to see if we've already been checked */ 00798 for (x=0; x<*stacklen; x++) { 00799 if (!strcasecmp(incstack[x], context)) 00800 return NULL; 00801 } 00802 if (bypass) 00803 tmp = bypass; 00804 else 00805 tmp = contexts; 00806 while(tmp) { 00807 /* Match context */ 00808 if (bypass || !strcmp(tmp->name, context)) { 00809 struct ast_exten *earlymatch = NULL; 00810 00811 if (*status < STATUS_NO_EXTENSION) 00812 *status = STATUS_NO_EXTENSION; 00813 for (eroot = tmp->root; eroot; eroot=eroot->next) { 00814 int match = 0; 00815 /* Match extension */ 00816 if ((((action != HELPER_MATCHMORE) && ast_extension_match(eroot->exten, exten)) || 00817 ((action == HELPER_CANMATCH) && (ast_extension_close(eroot->exten, exten, 0))) || 00818 ((action == HELPER_MATCHMORE) && (match = ast_extension_close(eroot->exten, exten, 1)))) && 00819 (!eroot->matchcid || matchcid(eroot->cidmatch, callerid))) { 00820 00821 if (action == HELPER_MATCHMORE && match == 2 && !earlymatch) { 00822 /* It matched an extension ending in a '!' wildcard 00823 So ignore it for now, unless there's a better match */ 00824 earlymatch = eroot; 00825 } else { 00826 e = eroot; 00827 if (*status < STATUS_NO_PRIORITY) 00828 *status = STATUS_NO_PRIORITY; 00829 while(e) { 00830 /* Match priority */ 00831 if (action == HELPER_FINDLABEL) { 00832 if (*status < STATUS_NO_LABEL) 00833 *status = STATUS_NO_LABEL; 00834 if (label && e->label && !strcmp(label, e->label)) { 00835 *status = STATUS_SUCCESS; 00836 *foundcontext = context; 00837 return e; 00838 } 00839 } else if (e->priority == priority) { 00840 *status = STATUS_SUCCESS; 00841 *foundcontext = context; 00842 return e; 00843 } 00844 e = e->peer; 00845 } 00846 } 00847 } 00848 } 00849 if (earlymatch) { 00850 /* Bizarre logic for HELPER_MATCHMORE. We return zero to break out 00851 of the loop waiting for more digits, and _then_ match (normally) 00852 the extension we ended up with. We got an early-matching wildcard 00853 pattern, so return NULL to break out of the loop. */ 00854 return NULL; 00855 } 00856 /* Check alternative switches */ 00857 sw = tmp->alts; 00858 while(sw) { 00859 if ((asw = pbx_findswitch(sw->name))) { 00860 /* Substitute variables now */ 00861 if (sw->eval) 00862 pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1); 00863 if (action == HELPER_CANMATCH) 00864 res = asw->canmatch ? asw->canmatch(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; 00865 else if (action == HELPER_MATCHMORE) 00866 res = asw->matchmore ? asw->matchmore(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; 00867 else 00868 res = asw->exists ? asw->exists(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; 00869 if (res) { 00870 /* Got a match */ 00871 *swo = asw; 00872 *data = sw->eval ? sw->tmpdata : sw->data; 00873 *foundcontext = context; 00874 return NULL; 00875 } 00876 } else { 00877 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); 00878 } 00879 sw = sw->next; 00880 } 00881 /* Setup the stack */ 00882 incstack[*stacklen] = tmp->name; 00883 (*stacklen)++; 00884 /* Now try any includes we have in this context */ 00885 i = tmp->includes; 00886 while(i) { 00887 if (include_valid(i)) { 00888 if ((e = pbx_find_extension(chan, bypass, i->rname, exten, priority, label, callerid, action, incstack, stacklen, status, swo, data, foundcontext))) 00889 return e; 00890 if (*swo) 00891 return NULL; 00892 } 00893 i = i->next; 00894 } 00895 break; 00896 } 00897 tmp = tmp->next; 00898 } 00899 return NULL; 00900 }
|
|
Find application handle in linked list.
Definition at line 576 of file pbx.c. References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, ast_app::name, and ast_app::next. Referenced by ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and realtime_exec(). 00577 { 00578 struct ast_app *tmp; 00579 00580 if (ast_mutex_lock(&applock)) { 00581 ast_log(LOG_WARNING, "Unable to obtain application lock\n"); 00582 return NULL; 00583 } 00584 tmp = apps; 00585 while(tmp) { 00586 if (!strcasecmp(tmp->name, app)) 00587 break; 00588 tmp = tmp->next; 00589 } 00590 ast_mutex_unlock(&applock); 00591 return tmp; 00592 }
|
|
Definition at line 594 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, ast_switch::name, ast_switch::next, and switches. 00595 { 00596 struct ast_switch *asw; 00597 00598 if (ast_mutex_lock(&switchlock)) { 00599 ast_log(LOG_WARNING, "Unable to obtain application lock\n"); 00600 return NULL; 00601 } 00602 asw = switches; 00603 while(asw) { 00604 if (!strcasecmp(asw->name, sw)) 00605 break; 00606 asw = asw->next; 00607 } 00608 ast_mutex_unlock(&switchlock); 00609 return asw; 00610 }
|
|
pbx_retrieve_variable: Support for Asterisk built-in variables and functions in the dialplan ---
Definition at line 979 of file pbx.c. References ast_channel::accountcode, ast_get_hint(), AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_var_name(), ast_var_value(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, ast_channel::hangupcause, ast_channel::language, LOG_WARNING, ast_channel::name, offset, parse_variable_name(), pbx_retrieve_variable(), ast_channel::priority, substring(), ast_channel::uniqueid, and ast_channel::varshead. Referenced by function_fieldqty(), handle_getvariable(), pbx_retrieve_variable(), and pbx_substitute_variables_helper_full(). 00980 { 00981 char tmpvar[80]; 00982 time_t thistime; 00983 struct tm brokentime; 00984 int offset, offset2, isfunc; 00985 struct ast_var_t *variables; 00986 00987 if (c) 00988 headp=&c->varshead; 00989 *ret=NULL; 00990 ast_copy_string(tmpvar, var, sizeof(tmpvar)); 00991 if (parse_variable_name(tmpvar, &offset, &offset2, &isfunc)) { 00992 pbx_retrieve_variable(c, tmpvar, ret, workspace, workspacelen, headp); 00993 if (!(*ret)) 00994 return; 00995 *ret = substring(*ret, offset, offset2, workspace, workspacelen); 00996 } else if (c && !strncmp(var, "CALL", 4)) { 00997 if (!strncmp(var + 4, "ER", 2)) { 00998 if (!strncmp(var + 6, "ID", 2)) { 00999 if (!var[8]) { /* CALLERID */ 01000 if (c->cid.cid_num) { 01001 if (c->cid.cid_name) { 01002 snprintf(workspace, workspacelen, "\"%s\" <%s>", c->cid.cid_name, c->cid.cid_num); 01003 } else { 01004 ast_copy_string(workspace, c->cid.cid_num, workspacelen); 01005 } 01006 *ret = workspace; 01007 } else if (c->cid.cid_name) { 01008 ast_copy_string(workspace, c->cid.cid_name, workspacelen); 01009 *ret = workspace; 01010 } else 01011 *ret = NULL; 01012 } else if (!strcmp(var + 8, "NUM")) { 01013 /* CALLERIDNUM */ 01014 if (c->cid.cid_num) { 01015 ast_copy_string(workspace, c->cid.cid_num, workspacelen); 01016 *ret = workspace; 01017 } else 01018 *ret = NULL; 01019 } else if (!strcmp(var + 8, "NAME")) { 01020 /* CALLERIDNAME */ 01021 if (c->cid.cid_name) { 01022 ast_copy_string(workspace, c->cid.cid_name, workspacelen); 01023 *ret = workspace; 01024 } else 01025 *ret = NULL; 01026 } else 01027 goto icky; 01028 } else if (!strcmp(var + 6, "ANI")) { 01029 /* CALLERANI */ 01030 if (c->cid.cid_ani) { 01031 ast_copy_string(workspace, c->cid.cid_ani, workspacelen); 01032 *ret = workspace; 01033 } else 01034 *ret = NULL; 01035 } else 01036 goto icky; 01037 } else if (!strncmp(var + 4, "ING", 3)) { 01038 if (!strcmp(var + 7, "PRES")) { 01039 /* CALLINGPRES */ 01040 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01041 *ret = workspace; 01042 } else if (!strcmp(var + 7, "ANI2")) { 01043 /* CALLINGANI2 */ 01044 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01045 *ret = workspace; 01046 } else if (!strcmp(var + 7, "TON")) { 01047 /* CALLINGTON */ 01048 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01049 *ret = workspace; 01050 } else if (!strcmp(var + 7, "TNS")) { 01051 /* CALLINGTNS */ 01052 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01053 *ret = workspace; 01054 } else 01055 goto icky; 01056 } else 01057 goto icky; 01058 } else if (c && !strcmp(var, "DNID")) { 01059 if (c->cid.cid_dnid) { 01060 ast_copy_string(workspace, c->cid.cid_dnid, workspacelen); 01061 *ret = workspace; 01062 } else 01063 *ret = NULL; 01064 } else if (c && !strcmp(var, "HINT")) { 01065 if (!ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten)) 01066 *ret = NULL; 01067 else 01068 *ret = workspace; 01069 } else if (c && !strcmp(var, "HINTNAME")) { 01070 if (!ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten)) 01071 *ret = NULL; 01072 else 01073 *ret = workspace; 01074 } else if (c && !strcmp(var, "EXTEN")) { 01075 ast_copy_string(workspace, c->exten, workspacelen); 01076 *ret = workspace; 01077 } else if (c && !strcmp(var, "RDNIS")) { 01078 if (c->cid.cid_rdnis) { 01079 ast_copy_string(workspace, c->cid.cid_rdnis, workspacelen); 01080 *ret = workspace; 01081 } else 01082 *ret = NULL; 01083 } else if (c && !strcmp(var, "CONTEXT")) { 01084 ast_copy_string(workspace, c->context, workspacelen); 01085 *ret = workspace; 01086 } else if (c && !strcmp(var, "PRIORITY")) { 01087 snprintf(workspace, workspacelen, "%d", c->priority); 01088 *ret = workspace; 01089 } else if (c && !strcmp(var, "CHANNEL")) { 01090 ast_copy_string(workspace, c->name, workspacelen); 01091 *ret = workspace; 01092 } else if (!strcmp(var, "EPOCH")) { 01093 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01094 *ret = workspace; 01095 } else if (!strcmp(var, "DATETIME")) { 01096 thistime=time(NULL); 01097 localtime_r(&thistime, &brokentime); 01098 snprintf(workspace, workspacelen, "%02d%02d%04d-%02d:%02d:%02d", 01099 brokentime.tm_mday, 01100 brokentime.tm_mon+1, 01101 brokentime.tm_year+1900, 01102 brokentime.tm_hour, 01103 brokentime.tm_min, 01104 brokentime.tm_sec 01105 ); 01106 *ret = workspace; 01107 } else if (!strcmp(var, "TIMESTAMP")) { 01108 thistime=time(NULL); 01109 localtime_r(&thistime, &brokentime); 01110 /* 20031130-150612 */ 01111 snprintf(workspace, workspacelen, "%04d%02d%02d-%02d%02d%02d", 01112 brokentime.tm_year+1900, 01113 brokentime.tm_mon+1, 01114 brokentime.tm_mday, 01115 brokentime.tm_hour, 01116 brokentime.tm_min, 01117 brokentime.tm_sec 01118 ); 01119 *ret = workspace; 01120 } else if (c && !strcmp(var, "UNIQUEID")) { 01121 snprintf(workspace, workspacelen, "%s", c->uniqueid); 01122 *ret = workspace; 01123 } else if (c && !strcmp(var, "HANGUPCAUSE")) { 01124 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01125 *ret = workspace; 01126 } else if (c && !strcmp(var, "ACCOUNTCODE")) { 01127 ast_copy_string(workspace, c->accountcode, workspacelen); 01128 *ret = workspace; 01129 } else if (c && !strcmp(var, "LANGUAGE")) { 01130 ast_copy_string(workspace, c->language, workspacelen); 01131 *ret = workspace; 01132 } else { 01133 icky: 01134 if (headp) { 01135 AST_LIST_TRAVERSE(headp,variables,entries) { 01136 #if 0 01137 ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",var,ast_var_name(variables)); 01138 #endif 01139 if (strcasecmp(ast_var_name(variables),var)==0) { 01140 *ret=ast_var_value(variables); 01141 if (*ret) { 01142 ast_copy_string(workspace, *ret, workspacelen); 01143 *ret = workspace; 01144 } 01145 break; 01146 } 01147 } 01148 } 01149 if (!(*ret)) { 01150 /* Try globals */ 01151 ast_mutex_lock(&globalslock); 01152 AST_LIST_TRAVERSE(&globals,variables,entries) { 01153 if (strcasecmp(ast_var_name(variables),var)==0) { 01154 *ret = ast_var_value(variables); 01155 if (*ret) { 01156 ast_copy_string(workspace, *ret, workspacelen); 01157 *ret = workspace; 01158 } 01159 } 01160 } 01161 ast_mutex_unlock(&globalslock); 01162 } 01163 } 01164 }
|
|
Definition at line 2564 of file pbx.c. Referenced by pbx_load_module(). 02565 { 02566 int oldval; 02567 oldval = autofallthrough; 02568 if (oldval != newval) 02569 autofallthrough = newval; 02570 return oldval; 02571 }
|
|
Definition at line 1605 of file pbx.c. References ast_exten::data, and pbx_substitute_variables_helper(). Referenced by pbx_extension_helper(). 01606 { 01607 memset(passdata, 0, datalen); 01608 01609 /* No variables or expressions in e->data, so why scan it? */ 01610 if (!strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) { 01611 ast_copy_string(passdata, e->data, datalen); 01612 return; 01613 } 01614 01615 pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1); 01616 }
|
|
Definition at line 1595 of file pbx.c. References pbx_substitute_variables_helper_full(), and ast_channel::varshead. Referenced by custom_log(), cut_internal(), eval_exec(), exec_exec(), function_eval(), handle_getvariablefull(), mixmonitor_thread(), pbx_builtin_importvar(), pbx_load_module(), pbx_substitute_variables(), realtime_exec(), sendmail(), and sendpage(). 01596 { 01597 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01598 }
|
|
Definition at line 1419 of file pbx.c. References ast_expr(), ast_func_read(), ast_log(), ast_strlen_zero(), LOG_DEBUG, LOG_NOTICE, offset, parse_variable_name(), pbx_retrieve_variable(), substring(), var, and VAR_BUF_SIZE. Referenced by pbx_substitute_variables_helper(), and pbx_substitute_variables_varshead(). 01420 { 01421 char *cp4; 01422 const char *tmp, *whereweare; 01423 int length, offset, offset2, isfunction; 01424 char *workspace = NULL; 01425 char *ltmp = NULL, *var = NULL; 01426 char *nextvar, *nextexp, *nextthing; 01427 char *vars, *vare; 01428 int pos, brackets, needsub, len; 01429 01430 /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be 01431 zero-filled */ 01432 whereweare=tmp=cp1; 01433 while(!ast_strlen_zero(whereweare) && count) { 01434 /* Assume we're copying the whole remaining string */ 01435 pos = strlen(whereweare); 01436 nextvar = NULL; 01437 nextexp = NULL; 01438 nextthing = strchr(whereweare, '$'); 01439 if (nextthing) { 01440 switch(nextthing[1]) { 01441 case '{': 01442 nextvar = nextthing; 01443 pos = nextvar - whereweare; 01444 break; 01445 case '[': 01446 nextexp = nextthing; 01447 pos = nextexp - whereweare; 01448 break; 01449 } 01450 } 01451 01452 if (pos) { 01453 /* Can't copy more than 'count' bytes */ 01454 if (pos > count) 01455 pos = count; 01456 01457 /* Copy that many bytes */ 01458 memcpy(cp2, whereweare, pos); 01459 01460 count -= pos; 01461 cp2 += pos; 01462 whereweare += pos; 01463 } 01464 01465 if (nextvar) { 01466 /* We have a variable. Find the start and end, and determine 01467 if we are going to have to recursively call ourselves on the 01468 contents */ 01469 vars = vare = nextvar + 2; 01470 brackets = 1; 01471 needsub = 0; 01472 01473 /* Find the end of it */ 01474 while(brackets && *vare) { 01475 if ((vare[0] == '$') && (vare[1] == '{')) { 01476 needsub++; 01477 brackets++; 01478 } else if (vare[0] == '}') { 01479 brackets--; 01480 } else if ((vare[0] == '$') && (vare[1] == '[')) 01481 needsub++; 01482 vare++; 01483 } 01484 if (brackets) 01485 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n"); 01486 len = vare - vars - 1; 01487 01488 /* Skip totally over variable string */ 01489 whereweare += (len + 3); 01490 01491 if (!var) 01492 var = alloca(VAR_BUF_SIZE); 01493 01494 /* Store variable name (and truncate) */ 01495 ast_copy_string(var, vars, len + 1); 01496 01497 /* Substitute if necessary */ 01498 if (needsub) { 01499 if (!ltmp) 01500 ltmp = alloca(VAR_BUF_SIZE); 01501 01502 memset(ltmp, 0, VAR_BUF_SIZE); 01503 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01504 vars = ltmp; 01505 } else { 01506 vars = var; 01507 } 01508 01509 if (!workspace) 01510 workspace = alloca(VAR_BUF_SIZE); 01511 01512 workspace[0] = '\0'; 01513 01514 parse_variable_name(vars, &offset, &offset2, &isfunction); 01515 if (isfunction) { 01516 /* Evaluate function */ 01517 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE); 01518 01519 ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)"); 01520 } else { 01521 /* Retrieve variable value */ 01522 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp); 01523 } 01524 if (cp4) { 01525 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE); 01526 01527 length = strlen(cp4); 01528 if (length > count) 01529 length = count; 01530 memcpy(cp2, cp4, length); 01531 count -= length; 01532 cp2 += length; 01533 } 01534 } else if (nextexp) { 01535 /* We have an expression. Find the start and end, and determine 01536 if we are going to have to recursively call ourselves on the 01537 contents */ 01538 vars = vare = nextexp + 2; 01539 brackets = 1; 01540 needsub = 0; 01541 01542 /* Find the end of it */ 01543 while(brackets && *vare) { 01544 if ((vare[0] == '$') && (vare[1] == '[')) { 01545 needsub++; 01546 brackets++; 01547 vare++; 01548 } else if (vare[0] == '[') { 01549 brackets++; 01550 } else if (vare[0] == ']') { 01551 brackets--; 01552 } else if ((vare[0] == '$') && (vare[1] == '{')) { 01553 needsub++; 01554 vare++; 01555 } 01556 vare++; 01557 } 01558 if (brackets) 01559 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n"); 01560 len = vare - vars - 1; 01561 01562 /* Skip totally over expression */ 01563 whereweare += (len + 3); 01564 01565 if (!var) 01566 var = alloca(VAR_BUF_SIZE); 01567 01568 /* Store variable name (and truncate) */ 01569 ast_copy_string(var, vars, len + 1); 01570 01571 /* Substitute if necessary */ 01572 if (needsub) { 01573 if (!ltmp) 01574 ltmp = alloca(VAR_BUF_SIZE); 01575 01576 memset(ltmp, 0, VAR_BUF_SIZE); 01577 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01578 vars = ltmp; 01579 } else { 01580 vars = var; 01581 } 01582 01583 length = ast_expr(vars, cp2, count); 01584 01585 if (length) { 01586 ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2); 01587 count -= length; 01588 cp2 += length; 01589 } 01590 } else 01591 break; 01592 } 01593 }
|
|
Definition at line 1600 of file pbx.c. References pbx_substitute_variables_helper_full(). Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_helper(). 01601 { 01602 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01603 }
|
|
Definition at line 2502 of file pbx.c. References __ast_pbx_run(), and decrease_call_count(). Referenced by ast_pbx_start(). 02503 { 02504 /* Oh joyeous kernel, we're a new thread, with nothing to do but 02505 answer this channel and get it going. 02506 */ 02507 /* NOTE: 02508 The launcher of this function _MUST_ increment 'countcalls' 02509 before invoking the function; it will be decremented when the 02510 PBX has finished running on the channel 02511 */ 02512 struct ast_channel *c = data; 02513 02514 __ast_pbx_run(c); 02515 decrease_call_count(); 02516 02517 pthread_exit(NULL); 02518 02519 return NULL; 02520 }
|
|
Definition at line 3339 of file pbx.c. References ast_cli(), ast_extension_match(), ast_get_context_name(), ast_get_context_registrar(), ast_get_extension_app(), ast_get_extension_app_data(), ast_get_extension_label(), ast_get_extension_name(), ast_get_extension_priority(), ast_get_extension_registrar(), ast_get_include_name(), ast_lock_context(), ast_lock_contexts(), ast_log(), AST_PBX_MAX_STACK, ast_walk_context_extensions(), ast_walk_context_includes(), ast_walk_contexts(), ast_walk_extension_priorities(), dialplan_counters::context_existence, dialplan_counters::extension_existence, LOG_NOTICE, LOG_WARNING, PRIORITY_HINT, dialplan_counters::total_context, dialplan_counters::total_exten, and dialplan_counters::total_prio. Referenced by handle_show_dialplan(). 03340 { 03341 struct ast_context *c; 03342 int res=0, old_total_exten = dpc->total_exten; 03343 03344 /* try to lock contexts */ 03345 if (ast_lock_contexts()) { 03346 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 03347 return -1; 03348 } 03349 03350 /* walk all contexts ... */ 03351 for (c = ast_walk_contexts(NULL); c ; c = ast_walk_contexts(c)) { 03352 /* show this context? */ 03353 if (!context || 03354 !strcmp(ast_get_context_name(c), context)) { 03355 dpc->context_existence = 1; 03356 03357 /* try to lock context before walking in ... */ 03358 if (!ast_lock_context(c)) { 03359 struct ast_exten *e; 03360 struct ast_include *i; 03361 struct ast_ignorepat *ip; 03362 struct ast_sw *sw; 03363 char buf[256], buf2[256]; 03364 int context_info_printed = 0; 03365 03366 /* are we looking for exten too? if yes, we print context 03367 * if we our extension only 03368 */ 03369 if (!exten) { 03370 dpc->total_context++; 03371 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03372 ast_get_context_name(c), ast_get_context_registrar(c)); 03373 context_info_printed = 1; 03374 } 03375 03376 /* walk extensions ... */ 03377 for (e = ast_walk_context_extensions(c, NULL); e; e = ast_walk_context_extensions(c, e)) { 03378 struct ast_exten *p; 03379 int prio; 03380 03381 /* looking for extension? is this our extension? */ 03382 if (exten && 03383 !ast_extension_match(ast_get_extension_name(e), exten)) 03384 { 03385 /* we are looking for extension and it's not our 03386 * extension, so skip to next extension */ 03387 continue; 03388 } 03389 03390 dpc->extension_existence = 1; 03391 03392 /* may we print context info? */ 03393 if (!context_info_printed) { 03394 dpc->total_context++; 03395 if (rinclude) { 03396 /* TODO Print more info about rinclude */ 03397 ast_cli(fd, "[ Included context '%s' created by '%s' ]\n", 03398 ast_get_context_name(c), 03399 ast_get_context_registrar(c)); 03400 } else { 03401 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03402 ast_get_context_name(c), 03403 ast_get_context_registrar(c)); 03404 } 03405 context_info_printed = 1; 03406 } 03407 dpc->total_prio++; 03408 03409 /* write extension name and first peer */ 03410 bzero(buf, sizeof(buf)); 03411 snprintf(buf, sizeof(buf), "'%s' =>", 03412 ast_get_extension_name(e)); 03413 03414 prio = ast_get_extension_priority(e); 03415 if (prio == PRIORITY_HINT) { 03416 snprintf(buf2, sizeof(buf2), 03417 "hint: %s", 03418 ast_get_extension_app(e)); 03419 } else { 03420 snprintf(buf2, sizeof(buf2), 03421 "%d. %s(%s)", 03422 prio, 03423 ast_get_extension_app(e), 03424 (char *)ast_get_extension_app_data(e)); 03425 } 03426 03427 ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2, 03428 ast_get_extension_registrar(e)); 03429 03430 dpc->total_exten++; 03431 /* walk next extension peers */ 03432 for (p=ast_walk_extension_priorities(e, e); p; p=ast_walk_extension_priorities(e, p)) { 03433 dpc->total_prio++; 03434 bzero((void *)buf2, sizeof(buf2)); 03435 bzero((void *)buf, sizeof(buf)); 03436 if (ast_get_extension_label(p)) 03437 snprintf(buf, sizeof(buf), " [%s]", ast_get_extension_label(p)); 03438 prio = ast_get_extension_priority(p); 03439 if (prio == PRIORITY_HINT) { 03440 snprintf(buf2, sizeof(buf2), 03441 "hint: %s", 03442 ast_get_extension_app(p)); 03443 } else { 03444 snprintf(buf2, sizeof(buf2), 03445 "%d. %s(%s)", 03446 prio, 03447 ast_get_extension_app(p), 03448 (char *)ast_get_extension_app_data(p)); 03449 } 03450 03451 ast_cli(fd," %-17s %-45s [%s]\n", 03452 buf, buf2, 03453 ast_get_extension_registrar(p)); 03454 } 03455 } 03456 03457 /* walk included and write info ... */ 03458 for (i = ast_walk_context_includes(c, NULL); i; i = ast_walk_context_includes(c, i)) { 03459 bzero(buf, sizeof(buf)); 03460 snprintf(buf, sizeof(buf), "'%s'", 03461 ast_get_include_name(i)); 03462 if (exten) { 03463 /* Check all includes for the requested extension */ 03464 if (includecount >= AST_PBX_MAX_STACK) { 03465 ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n"); 03466 } else { 03467 int dupe=0; 03468 int x; 03469 for (x=0;x<includecount;x++) { 03470 if (!strcasecmp(includes[x], ast_get_include_name(i))) { 03471 dupe++; 03472 break; 03473 } 03474 } 03475 if (!dupe) { 03476 includes[includecount] = (char *)ast_get_include_name(i); 03477 show_dialplan_helper(fd, (char *)ast_get_include_name(i), exten, dpc, i, includecount + 1, includes); 03478 } else { 03479 ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context); 03480 } 03481 } 03482 } else { 03483 ast_cli(fd, " Include => %-45s [%s]\n", 03484 buf, ast_get_include_registrar(i)); 03485 } 03486 } 03487 03488 /* walk ignore patterns and write info ... */ 03489 for (ip=ast_walk_context_ignorepats(c, NULL); ip; ip=ast_walk_context_ignorepats(c, ip)) { 03490 const char *ipname = ast_get_ignorepat_name(ip); 03491 char ignorepat[AST_MAX_EXTENSION]; 03492 snprintf(buf, sizeof(buf), "'%s'", ipname); 03493 snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname); 03494 if ((!exten) || ast_extension_match(ignorepat, exten)) { 03495 ast_cli(fd, " Ignore pattern => %-45s [%s]\n", 03496 buf, ast_get_ignorepat_registrar(ip)); 03497 } 03498 } 03499 if (!rinclude) { 03500 for (sw = ast_walk_context_switches(c, NULL); sw; sw = ast_walk_context_switches(c, sw)) { 03501 snprintf(buf, sizeof(buf), "'%s/%s'", 03502 ast_get_switch_name(sw), 03503 ast_get_switch_data(sw)); 03504 ast_cli(fd, " Alt. Switch => %-45s [%s]\n", 03505 buf, ast_get_switch_registrar(sw)); 03506 } 03507 } 03508 03509 ast_unlock_context(c); 03510 03511 /* if we print something in context, make an empty line */ 03512 if (context_info_printed) ast_cli(fd, "\r\n"); 03513 } 03514 } 03515 } 03516 ast_unlock_contexts(); 03517 03518 if (dpc->total_exten == old_total_exten) { 03519 /* Nothing new under the sun */ 03520 return -1; 03521 } else { 03522 return res; 03523 } 03524 }
|
|
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, -1 means unlimited (we take any negative value). Always return a copy in workspace. Definition at line 947 of file pbx.c. Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full(). 00948 { 00949 char *ret = workspace; 00950 int lr; /* length of the input string after the copy */ 00951 00952 ast_copy_string(workspace, value, workspace_len); /* always make a copy */ 00953 00954 if (offset == 0 && length < 0) /* take the whole string */ 00955 return ret; 00956 00957 lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */ 00958 00959 if (offset < 0) { /* translate negative offset into positive ones */ 00960 offset = lr + offset; 00961 if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */ 00962 offset = 0; 00963 } 00964 00965 /* too large offset result in empty string so we know what to return */ 00966 if (offset >= lr) 00967 return ret + lr; /* the final '\0' */ 00968 00969 ret += offset; /* move to the start position */ 00970 if (length >= 0 && length < lr - offset) /* truncate if necessary */ 00971 ret[length] = '\0'; 00972 00973 return ret; 00974 }
|
|
Definition at line 5386 of file pbx.c. References ast_frfree(), ast_read(), ast_safe_sleep(), ast_strlen_zero(), and ast_waitfor(). Referenced by pbx_builtin_busy(), and pbx_builtin_congestion(). 05387 { 05388 int res; 05389 struct ast_frame *f; 05390 int waittime; 05391 05392 if (ast_strlen_zero(data) || (sscanf(data, "%d", &waittime) != 1) || (waittime < 0)) 05393 waittime = -1; 05394 if (waittime > -1) { 05395 ast_safe_sleep(chan, waittime * 1000); 05396 } else do { 05397 res = ast_waitfor(chan, -1); 05398 if (res < 0) 05399 return; 05400 f = ast_read(chan); 05401 if (f) 05402 ast_frfree(f); 05403 } while(f); 05404 }
|
|
Definition at line 237 of file pbx.c. Referenced by ast_custom_function_find(), ast_custom_function_register(), ast_custom_function_unregister(), complete_show_function(), and handle_show_functions(). |
|
Definition at line 511 of file pbx.c. Referenced by ast_register_application(), ast_unregister_application(), complete_show_application(), handle_show_application(), handle_show_applications(), and pbx_findapp(). |
|
|
|
Declaration of builtin applications.
|
|
Definition at line 509 of file pbx.c. Referenced by __ast_context_destroy(), ast_context_create(), ast_context_find(), and ast_walk_contexts(). |
|
|
|
Definition at line 3921 of file pbx.c. Referenced by format_uptimestr(), and timesub(). |
|
|
|
Definition at line 525 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_remove_hint(), and handle_show_hints(). |
|
|
|
Definition at line 3593 of file pbx.c. Referenced by load_pbx(). |
|
Initial value: "Usage: show application <application> [<application> [<application> [...]]]\n" " Describes a particular application.\n" |
|
Initial value: "Usage: show applications [{like|describing} <text>]\n" " List applications which are currently available.\n" " If 'like', <text> will be a substring of the app name\n" " If 'describing', <text> will be a substring of the description\n" |
|
Initial value: "Usage: show dialplan [exten@][context]\n" " Show dialplan\n" |
|
Initial value: "Usage: show function <function>\n" " Describe a particular dialplan function.\n" |
|
Initial value: "Usage: show functions\n" " List builtin functions accessable as $(function args)\n" |
|
Initial value: "Usage: show hints\n" " Show registered hints\n" |
|
Initial value: "Usage: show switches\n" " Show registered switches\n" |
|
Definition at line 526 of file pbx.c. Referenced by ast_extension_state_add(), ast_extension_state_del(), and ast_hint_state_changed(). |
|
|
|
Definition at line 514 of file pbx.c. Referenced by ast_register_switch(), ast_unregister_switch(), handle_show_switches(), and pbx_findswitch(). |