#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"
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 3833 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 5314 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(). 05315 { 05316 struct ast_context *tmp, *tmpl=NULL; 05317 struct ast_include *tmpi, *tmpil= NULL; 05318 struct ast_sw *sw, *swl= NULL; 05319 struct ast_exten *e, *el, *en; 05320 struct ast_ignorepat *ipi, *ipl = NULL; 05321 05322 ast_mutex_lock(&conlock); 05323 tmp = contexts; 05324 while(tmp) { 05325 if (((tmp->name && con && con->name && !strcasecmp(tmp->name, con->name)) || !con) && 05326 (!registrar || !strcasecmp(registrar, tmp->registrar))) { 05327 /* Okay, let's lock the structure to be sure nobody else 05328 is searching through it. */ 05329 if (ast_mutex_lock(&tmp->lock)) { 05330 ast_log(LOG_WARNING, "Unable to lock context lock\n"); 05331 return; 05332 } 05333 if (tmpl) 05334 tmpl->next = tmp->next; 05335 else 05336 contexts = tmp->next; 05337 /* Okay, now we're safe to let it go -- in a sense, we were 05338 ready to let it go as soon as we locked it. */ 05339 ast_mutex_unlock(&tmp->lock); 05340 for (tmpi = tmp->includes; tmpi; ) { 05341 /* Free includes */ 05342 tmpil = tmpi; 05343 tmpi = tmpi->next; 05344 free(tmpil); 05345 } 05346 for (ipi = tmp->ignorepats; ipi; ) { 05347 /* Free ignorepats */ 05348 ipl = ipi; 05349 ipi = ipi->next; 05350 free(ipl); 05351 } 05352 for (sw = tmp->alts; sw; ) { 05353 /* Free switches */ 05354 swl = sw; 05355 sw = sw->next; 05356 free(swl); 05357 swl = sw; 05358 } 05359 for (e = tmp->root; e;) { 05360 for (en = e->peer; en;) { 05361 el = en; 05362 en = en->peer; 05363 destroy_exten(el); 05364 } 05365 el = e; 05366 e = e->next; 05367 destroy_exten(el); 05368 } 05369 ast_mutex_destroy(&tmp->lock); 05370 free(tmp); 05371 if (!con) { 05372 /* Might need to get another one -- restart */ 05373 tmp = contexts; 05374 tmpl = NULL; 05375 tmpil = NULL; 05376 continue; 05377 } 05378 ast_mutex_unlock(&conlock); 05379 return; 05380 } 05381 tmpl = tmp; 05382 tmp = tmp->next; 05383 } 05384 ast_mutex_unlock(&conlock); 05385 }
|
|
Definition at line 6451 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(). 06452 { 06453 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06454 06455 if (!chan) 06456 return -2; 06457 06458 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06459 if (ast_exists_extension(chan, context ? context : chan->context, 06460 exten ? exten : chan->exten, priority, 06461 chan->cid.cid_num)) 06462 return goto_func(chan, context ? context : chan->context, 06463 exten ? exten : chan->exten, priority); 06464 else 06465 return -3; 06466 }
|
|
Definition at line 2238 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(). 02239 { 02240 int firstpass = 1; 02241 int digit; 02242 char exten[256]; 02243 int pos; 02244 int waittime; 02245 int res=0; 02246 int autoloopflag; 02247 02248 /* A little initial setup here */ 02249 if (c->pbx) 02250 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name); 02251 c->pbx = malloc(sizeof(struct ast_pbx)); 02252 if (!c->pbx) { 02253 ast_log(LOG_ERROR, "Out of memory\n"); 02254 return -1; 02255 } 02256 if (c->amaflags) { 02257 if (!c->cdr) { 02258 c->cdr = ast_cdr_alloc(); 02259 if (!c->cdr) { 02260 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02261 free(c->pbx); 02262 return -1; 02263 } 02264 ast_cdr_init(c->cdr, c); 02265 } 02266 } 02267 memset(c->pbx, 0, sizeof(struct ast_pbx)); 02268 /* Set reasonable defaults */ 02269 c->pbx->rtimeout = 10; 02270 c->pbx->dtimeout = 5; 02271 02272 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); 02273 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP); 02274 02275 /* Start by trying whatever the channel is set to */ 02276 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02277 /* If not successful fall back to 's' */ 02278 if (option_verbose > 1) 02279 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); 02280 ast_copy_string(c->exten, "s", sizeof(c->exten)); 02281 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02282 /* JK02: And finally back to default if everything else failed */ 02283 if (option_verbose > 1) 02284 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); 02285 ast_copy_string(c->context, "default", sizeof(c->context)); 02286 } 02287 c->priority = 1; 02288 } 02289 if (c->cdr && !c->cdr->start.tv_sec && !c->cdr->start.tv_usec) 02290 ast_cdr_start(c->cdr); 02291 for(;;) { 02292 pos = 0; 02293 digit = 0; 02294 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02295 memset(exten, 0, sizeof(exten)); 02296 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02297 /* Something bad happened, or a hangup has been requested. */ 02298 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) || 02299 (res == '*') || (res == '#')) { 02300 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 02301 memset(exten, 0, sizeof(exten)); 02302 pos = 0; 02303 exten[pos++] = digit = res; 02304 break; 02305 } 02306 switch(res) { 02307 case AST_PBX_KEEPALIVE: 02308 if (option_debug) 02309 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02310 if (option_verbose > 1) 02311 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02312 goto out; 02313 break; 02314 default: 02315 if (option_debug) 02316 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02317 if (option_verbose > 1) 02318 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02319 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02320 c->_softhangup =0; 02321 break; 02322 } 02323 /* atimeout */ 02324 if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02325 break; 02326 } 02327 02328 if (c->cdr) { 02329 ast_cdr_update(c); 02330 } 02331 goto out; 02332 } 02333 } 02334 if ((c->_softhangup == AST_SOFTHANGUP_TIMEOUT) && (ast_exists_extension(c,c->context,"T",1,c->cid.cid_num))) { 02335 ast_copy_string(c->exten, "T", sizeof(c->exten)); 02336 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */ 02337 c->whentohangup = 0; 02338 c->priority = 0; 02339 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT; 02340 } else if (c->_softhangup) { 02341 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", 02342 c->exten, c->priority); 02343 goto out; 02344 } 02345 firstpass = 0; 02346 c->priority++; 02347 } 02348 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { 02349 /* It's not a valid extension anymore */ 02350 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02351 if (option_verbose > 2) 02352 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name); 02353 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten); 02354 ast_copy_string(c->exten, "i", sizeof(c->exten)); 02355 c->priority = 1; 02356 } else { 02357 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n", 02358 c->name, c->exten, c->context); 02359 goto out; 02360 } 02361 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02362 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */ 02363 c->_softhangup = 0; 02364 } else { 02365 /* Done, wait for an extension */ 02366 waittime = 0; 02367 if (digit) 02368 waittime = c->pbx->dtimeout; 02369 else if (!autofallthrough) 02370 waittime = c->pbx->rtimeout; 02371 if (waittime) { 02372 while (ast_matchmore_extension(c, c->context, exten, 1, c->cid.cid_num)) { 02373 /* As long as we're willing to wait, and as long as it's not defined, 02374 keep reading digits until we can't possibly get a right answer anymore. */ 02375 digit = ast_waitfordigit(c, waittime * 1000); 02376 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02377 c->_softhangup = 0; 02378 } else { 02379 if (!digit) 02380 /* No entry */ 02381 break; 02382 if (digit < 0) 02383 /* Error, maybe a hangup */ 02384 goto out; 02385 exten[pos++] = digit; 02386 waittime = c->pbx->dtimeout; 02387 } 02388 } 02389 if (ast_exists_extension(c, c->context, exten, 1, c->cid.cid_num)) { 02390 /* Prepare the next cycle */ 02391 ast_copy_string(c->exten, exten, sizeof(c->exten)); 02392 c->priority = 1; 02393 } else { 02394 /* No such extension */ 02395 if (!ast_strlen_zero(exten)) { 02396 /* An invalid extension */ 02397 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02398 if (option_verbose > 2) 02399 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name); 02400 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", exten); 02401 ast_copy_string(c->exten, "i", sizeof(c->exten)); 02402 c->priority = 1; 02403 } else { 02404 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", exten, c->context); 02405 goto out; 02406 } 02407 } else { 02408 /* A simple timeout */ 02409 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) { 02410 if (option_verbose > 2) 02411 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name); 02412 ast_copy_string(c->exten, "t", sizeof(c->exten)); 02413 c->priority = 1; 02414 } else { 02415 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context); 02416 goto out; 02417 } 02418 } 02419 } 02420 if (c->cdr) { 02421 if (option_verbose > 2) 02422 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name); 02423 ast_cdr_update(c); 02424 } 02425 } else { 02426 char *status; 02427 02428 status = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 02429 if (!status) 02430 status = "UNKNOWN"; 02431 if (option_verbose > 2) 02432 ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status); 02433 if (!strcasecmp(status, "CONGESTION")) 02434 res = pbx_builtin_congestion(c, "10"); 02435 else if (!strcasecmp(status, "CHANUNAVAIL")) 02436 res = pbx_builtin_congestion(c, "10"); 02437 else if (!strcasecmp(status, "BUSY")) 02438 res = pbx_builtin_busy(c, "10"); 02439 goto out; 02440 } 02441 } 02442 } 02443 if (firstpass) 02444 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); 02445 out: 02446 if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) { 02447 c->exten[0] = 'h'; 02448 c->exten[1] = '\0'; 02449 c->priority = 1; 02450 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02451 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02452 /* Something bad happened, or a hangup has been requested. */ 02453 if (option_debug) 02454 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02455 if (option_verbose > 1) 02456 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02457 break; 02458 } 02459 c->priority++; 02460 } 02461 } 02462 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP); 02463 02464 pbx_destroy(c->pbx); 02465 c->pbx = NULL; 02466 if (res != AST_PBX_KEEPALIVE) 02467 ast_hangup(c); 02468 return 0; 02469 }
|
|
Definition at line 2562 of file pbx.c. Referenced by handle_chanlist(). 02563 { 02564 return countcalls; 02565 }
|
|
Definition at line 4505 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(). 04507 { 04508 struct ast_context *c; 04509 04510 if (ast_lock_contexts()) { 04511 errno = EBUSY; 04512 return -1; 04513 } 04514 04515 c = ast_walk_contexts(NULL); 04516 while (c) { 04517 if (!strcmp(context, ast_get_context_name(c))) { 04518 int ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04519 application, data, datad, registrar); 04520 ast_unlock_contexts(); 04521 return ret; 04522 } 04523 c = ast_walk_contexts(c); 04524 } 04525 04526 ast_unlock_contexts(); 04527 errno = ENOENT; 04528 return -1; 04529 }
|
|
For details about the arguements, check ast_add_extension() Definition at line 4644 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(). 04648 { 04649 04650 #define LOG do { if (option_debug) {\ 04651 if (tmp->matchcid) { \ 04652 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \ 04653 } else { \ 04654 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \ 04655 } \ 04656 } \ 04657 if (option_verbose > 2) { \ 04658 if (tmp->matchcid) { \ 04659 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \ 04660 } else { \ 04661 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \ 04662 } \ 04663 } } while(0) 04664 04665 /* 04666 * This is a fairly complex routine. Different extensions are kept 04667 * in order by the extension number. Then, extensions of different 04668 * priorities (same extension) are kept in a list, according to the 04669 * peer pointer. 04670 */ 04671 struct ast_exten *tmp, *e, *el = NULL, *ep = NULL; 04672 int res; 04673 int length; 04674 char *p; 04675 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04676 04677 /* if we are adding a hint, and there are global variables, and the hint 04678 contains variable references, then expand them 04679 */ 04680 ast_mutex_lock(&globalslock); 04681 if ((priority == PRIORITY_HINT) && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04682 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04683 application = expand_buf; 04684 } 04685 ast_mutex_unlock(&globalslock); 04686 04687 length = sizeof(struct ast_exten); 04688 length += strlen(extension) + 1; 04689 length += strlen(application) + 1; 04690 if (label) 04691 length += strlen(label) + 1; 04692 if (callerid) 04693 length += strlen(callerid) + 1; 04694 else 04695 length ++; 04696 04697 /* Be optimistic: Build the extension structure first */ 04698 if (datad == NULL) 04699 datad = null_datad; 04700 tmp = malloc(length); 04701 if (tmp) { 04702 memset(tmp, 0, length); 04703 p = tmp->stuff; 04704 if (label) { 04705 tmp->label = p; 04706 strcpy(tmp->label, label); 04707 p += strlen(label) + 1; 04708 } 04709 tmp->exten = p; 04710 p += ext_strncpy(tmp->exten, extension, strlen(extension) + 1) + 1; 04711 tmp->priority = priority; 04712 tmp->cidmatch = p; 04713 if (callerid) { 04714 p += ext_strncpy(tmp->cidmatch, callerid, strlen(callerid) + 1) + 1; 04715 tmp->matchcid = 1; 04716 } else { 04717 tmp->cidmatch[0] = '\0'; 04718 tmp->matchcid = 0; 04719 p++; 04720 } 04721 tmp->app = p; 04722 strcpy(tmp->app, application); 04723 tmp->parent = con; 04724 tmp->data = data; 04725 tmp->datad = datad; 04726 tmp->registrar = registrar; 04727 tmp->peer = NULL; 04728 tmp->next = NULL; 04729 } else { 04730 ast_log(LOG_ERROR, "Out of memory\n"); 04731 errno = ENOMEM; 04732 return -1; 04733 } 04734 if (ast_mutex_lock(&con->lock)) { 04735 free(tmp); 04736 /* And properly destroy the data */ 04737 datad(data); 04738 ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name); 04739 errno = EBUSY; 04740 return -1; 04741 } 04742 e = con->root; 04743 while(e) { 04744 /* Make sure patterns are always last! */ 04745 if ((e->exten[0] != '_') && (extension[0] == '_')) 04746 res = -1; 04747 else if ((e->exten[0] == '_') && (extension[0] != '_')) 04748 res = 1; 04749 else 04750 res= strcmp(e->exten, extension); 04751 if (!res) { 04752 if (!e->matchcid && !tmp->matchcid) 04753 res = 0; 04754 else if (tmp->matchcid && !e->matchcid) 04755 res = 1; 04756 else if (e->matchcid && !tmp->matchcid) 04757 res = -1; 04758 else 04759 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04760 } 04761 if (res == 0) { 04762 /* We have an exact match, now we find where we are 04763 and be sure there's no duplicates */ 04764 while(e) { 04765 if (e->priority == tmp->priority) { 04766 /* Can't have something exactly the same. Is this a 04767 replacement? If so, replace, otherwise, bonk. */ 04768 if (replace) { 04769 if (ep) { 04770 /* We're in the peer list, insert ourselves */ 04771 ep->peer = tmp; 04772 tmp->peer = e->peer; 04773 } else if (el) { 04774 /* We're the first extension. Take over e's functions */ 04775 el->next = tmp; 04776 tmp->next = e->next; 04777 tmp->peer = e->peer; 04778 } else { 04779 /* We're the very first extension. */ 04780 con->root = tmp; 04781 tmp->next = e->next; 04782 tmp->peer = e->peer; 04783 } 04784 if (tmp->priority == PRIORITY_HINT) 04785 ast_change_hint(e,tmp); 04786 /* Destroy the old one */ 04787 e->datad(e->data); 04788 free(e); 04789 ast_mutex_unlock(&con->lock); 04790 if (tmp->priority == PRIORITY_HINT) 04791 ast_change_hint(e, tmp); 04792 /* And immediately return success. */ 04793 LOG; 04794 return 0; 04795 } else { 04796 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04797 tmp->datad(tmp->data); 04798 free(tmp); 04799 ast_mutex_unlock(&con->lock); 04800 errno = EEXIST; 04801 return -1; 04802 } 04803 } else if (e->priority > tmp->priority) { 04804 /* Slip ourselves in just before e */ 04805 if (ep) { 04806 /* Easy enough, we're just in the peer list */ 04807 ep->peer = tmp; 04808 tmp->peer = e; 04809 } else if (el) { 04810 /* We're the first extension in this peer list */ 04811 el->next = tmp; 04812 tmp->next = e->next; 04813 e->next = NULL; 04814 tmp->peer = e; 04815 } else { 04816 /* We're the very first extension altogether */ 04817 tmp->next = con->root->next; 04818 /* Con->root must always exist or we couldn't get here */ 04819 tmp->peer = con->root; 04820 con->root = tmp; 04821 } 04822 ast_mutex_unlock(&con->lock); 04823 04824 /* And immediately return success. */ 04825 if (tmp->priority == PRIORITY_HINT) 04826 ast_add_hint(tmp); 04827 04828 LOG; 04829 return 0; 04830 } 04831 ep = e; 04832 e = e->peer; 04833 } 04834 /* If we make it here, then it's time for us to go at the very end. 04835 ep *must* be defined or we couldn't have gotten here. */ 04836 ep->peer = tmp; 04837 ast_mutex_unlock(&con->lock); 04838 if (tmp->priority == PRIORITY_HINT) 04839 ast_add_hint(tmp); 04840 04841 /* And immediately return success. */ 04842 LOG; 04843 return 0; 04844 04845 } else if (res > 0) { 04846 /* Insert ourselves just before 'e'. We're the first extension of 04847 this kind */ 04848 tmp->next = e; 04849 if (el) { 04850 /* We're in the list somewhere */ 04851 el->next = tmp; 04852 } else { 04853 /* We're at the top of the list */ 04854 con->root = tmp; 04855 } 04856 ast_mutex_unlock(&con->lock); 04857 if (tmp->priority == PRIORITY_HINT) 04858 ast_add_hint(tmp); 04859 04860 /* And immediately return success. */ 04861 LOG; 04862 return 0; 04863 } 04864 04865 el = e; 04866 e = e->next; 04867 } 04868 /* If we fall all the way through to here, then we need to be on the end. */ 04869 if (el) 04870 el->next = tmp; 04871 else 04872 con->root = tmp; 04873 ast_mutex_unlock(&con->lock); 04874 if (tmp->priority == PRIORITY_HINT) 04875 ast_add_hint(tmp); 04876 LOG; 04877 return 0; 04878 }
|
|
ast_add_hint: Add hint to hint list, check initial extension state
Definition at line 2075 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(). 02076 { 02077 struct ast_hint *list; 02078 02079 if (!e) 02080 return -1; 02081 02082 ast_mutex_lock(&hintlock); 02083 list = hints; 02084 02085 /* Search if hint exists, do nothing */ 02086 while (list) { 02087 if (list->exten == e) { 02088 ast_mutex_unlock(&hintlock); 02089 if (option_debug > 1) 02090 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02091 return -1; 02092 } 02093 list = list->next; 02094 } 02095 02096 if (option_debug > 1) 02097 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02098 02099 list = malloc(sizeof(struct ast_hint)); 02100 if (!list) { 02101 ast_mutex_unlock(&hintlock); 02102 if (option_debug > 1) 02103 ast_log(LOG_DEBUG, "HINTS: Out of memory...\n"); 02104 return -1; 02105 } 02106 /* Initialize and insert new item at the top */ 02107 memset(list, 0, sizeof(struct ast_hint)); 02108 list->exten = e; 02109 list->laststate = ast_extension_state2(e); 02110 list->next = hints; 02111 hints = list; 02112 02113 ast_mutex_unlock(&hintlock); 02114 return 0; 02115 }
|
|
|
|
|
|
|
|
Definition at line 4550 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(), monitor_handle_owned(), process_ast_dsp(), socket_read(), and zt_read(). 04551 { 04552 int res = 0; 04553 04554 ast_mutex_lock(&chan->lock); 04555 04556 if (chan->pbx) { 04557 /* This channel is currently in the PBX */ 04558 ast_explicit_goto(chan, context, exten, priority); 04559 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04560 } else { 04561 /* In order to do it when the channel doesn't really exist within 04562 the PBX, we have to make a new channel, masquerade, and start the PBX 04563 at the new location */ 04564 struct ast_channel *tmpchan; 04565 tmpchan = ast_channel_alloc(0); 04566 if (tmpchan) { 04567 snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name); 04568 ast_setstate(tmpchan, chan->_state); 04569 /* Make formats okay */ 04570 tmpchan->readformat = chan->readformat; 04571 tmpchan->writeformat = chan->writeformat; 04572 /* Setup proper location */ 04573 ast_explicit_goto(tmpchan, 04574 (!ast_strlen_zero(context)) ? context : chan->context, 04575 (!ast_strlen_zero(exten)) ? exten : chan->exten, 04576 priority); 04577 04578 /* Masquerade into temp channel */ 04579 ast_channel_masquerade(tmpchan, chan); 04580 04581 /* Grab the locks and get going */ 04582 ast_mutex_lock(&tmpchan->lock); 04583 ast_do_masquerade(tmpchan); 04584 ast_mutex_unlock(&tmpchan->lock); 04585 /* Start the PBX going on our stolen channel */ 04586 if (ast_pbx_start(tmpchan)) { 04587 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04588 ast_hangup(tmpchan); 04589 res = -1; 04590 } 04591 } else { 04592 res = -1; 04593 } 04594 } 04595 ast_mutex_unlock(&chan->lock); 04596 return res; 04597 }
|
|
Definition at line 4599 of file pbx.c. References ast_async_goto(), ast_get_channel_by_name_locked(), ast_mutex_unlock(), and ast_channel::lock. 04600 { 04601 struct ast_channel *chan; 04602 int res = -1; 04603 04604 chan = ast_get_channel_by_name_locked(channame); 04605 if (chan) { 04606 res = ast_async_goto(chan, context, exten, priority); 04607 ast_mutex_unlock(&chan->lock); 04608 } 04609 return res; 04610 }
|
|
Definition at line 6472 of file pbx.c. References __ast_goto_if_exists(). 06472 { 06473 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06474 }
|
|
Definition at line 4083 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(). 04084 { 04085 char info_save[256]; 04086 char *info; 04087 char *c; 04088 04089 /* Check for empty just in case */ 04090 if (ast_strlen_zero(info_in)) 04091 return 0; 04092 /* make a copy just in case we were passed a static string */ 04093 ast_copy_string(info_save, info_in, sizeof(info_save)); 04094 info = info_save; 04095 /* Assume everything except time */ 04096 i->monthmask = (1 << 12) - 1; 04097 i->daymask = (1 << 30) - 1 + (1 << 30); 04098 i->dowmask = (1 << 7) - 1; 04099 /* Avoid using str tok */ 04100 FIND_NEXT; 04101 /* Info has the time range, start with that */ 04102 get_timerange(i, info); 04103 info = c; 04104 if (!info) 04105 return 1; 04106 FIND_NEXT; 04107 /* Now check for day of week */ 04108 i->dowmask = get_dow(info); 04109 04110 info = c; 04111 if (!info) 04112 return 1; 04113 FIND_NEXT; 04114 /* Now check for the day of the month */ 04115 i->daymask = get_day(info); 04116 info = c; 04117 if (!info) 04118 return 1; 04119 FIND_NEXT; 04120 /* And finally go for the month */ 04121 i->monthmask = get_month(info); 04122 04123 return 1; 04124 }
|
|
Definition at line 2218 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(). 02219 { 02220 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_CANMATCH); 02221 }
|
|
ast_change_hint: Change hint for an extension
Definition at line 2118 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), hints, list, and ast_imager::next. Referenced by ast_add_extension2(). 02119 { 02120 struct ast_hint *list; 02121 02122 ast_mutex_lock(&hintlock); 02123 list = hints; 02124 02125 while(list) { 02126 if (list->exten == oe) { 02127 list->exten = ne; 02128 ast_mutex_unlock(&hintlock); 02129 return 0; 02130 } 02131 list = list->next; 02132 } 02133 ast_mutex_unlock(&hintlock); 02134 02135 return -1; 02136 }
|
|
Definition at line 4126 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(). 04127 { 04128 struct tm tm; 04129 time_t t; 04130 04131 time(&t); 04132 localtime_r(&t,&tm); 04133 04134 /* If it's not the right month, return */ 04135 if (!(i->monthmask & (1 << tm.tm_mon))) { 04136 return 0; 04137 } 04138 04139 /* If it's not that time of the month.... */ 04140 /* Warning, tm_mday has range 1..31! */ 04141 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04142 return 0; 04143 04144 /* If it's not the right day of the week */ 04145 if (!(i->dowmask & (1 << tm.tm_wday))) 04146 return 0; 04147 04148 /* Sanity check the hour just to be safe */ 04149 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04150 ast_log(LOG_WARNING, "Insane time...\n"); 04151 return 0; 04152 } 04153 04154 /* Now the tough part, we calculate if it fits 04155 in the right time based on min/hour */ 04156 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04157 return 0; 04158 04159 /* If we got this far, then we're good */ 04160 return 1; 04161 }
|
|
Definition at line 4422 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(). 04423 { 04424 struct ast_context *c; 04425 04426 if (ast_lock_contexts()) { 04427 errno = EBUSY; 04428 return -1; 04429 } 04430 04431 c = ast_walk_contexts(NULL); 04432 while (c) { 04433 if (!strcmp(ast_get_context_name(c), con)) { 04434 int ret = ast_context_add_ignorepat2(c, value, registrar); 04435 ast_unlock_contexts(); 04436 return ret; 04437 } 04438 c = ast_walk_contexts(c); 04439 } 04440 04441 ast_unlock_contexts(); 04442 errno = ENOENT; 04443 return -1; 04444 }
|
|
Definition at line 4446 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(). 04447 { 04448 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04449 int length; 04450 length = sizeof(struct ast_ignorepat); 04451 length += strlen(value) + 1; 04452 ignorepat = malloc(length); 04453 if (!ignorepat) { 04454 ast_log(LOG_ERROR, "Out of memory\n"); 04455 errno = ENOMEM; 04456 return -1; 04457 } 04458 memset(ignorepat, 0, length); 04459 strcpy(ignorepat->pattern, value); 04460 ignorepat->next = NULL; 04461 ignorepat->registrar = registrar; 04462 ast_mutex_lock(&con->lock); 04463 ignorepatc = con->ignorepats; 04464 while(ignorepatc) { 04465 ignorepatl = ignorepatc; 04466 if (!strcasecmp(ignorepatc->pattern, value)) { 04467 /* Already there */ 04468 ast_mutex_unlock(&con->lock); 04469 errno = EEXIST; 04470 return -1; 04471 } 04472 ignorepatc = ignorepatc->next; 04473 } 04474 if (ignorepatl) 04475 ignorepatl->next = ignorepat; 04476 else 04477 con->ignorepats = ignorepat; 04478 ast_mutex_unlock(&con->lock); 04479 return 0; 04480 04481 }
|
|
Definition at line 3805 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(). 03806 { 03807 struct ast_context *c; 03808 03809 if (ast_lock_contexts()) { 03810 errno = EBUSY; 03811 return -1; 03812 } 03813 03814 /* walk contexts ... */ 03815 c = ast_walk_contexts(NULL); 03816 while (c) { 03817 /* ... search for the right one ... */ 03818 if (!strcmp(ast_get_context_name(c), context)) { 03819 int ret = ast_context_add_include2(c, include, registrar); 03820 /* ... unlock contexts list and return */ 03821 ast_unlock_contexts(); 03822 return ret; 03823 } 03824 c = ast_walk_contexts(c); 03825 } 03826 03827 /* we can't find the right context */ 03828 ast_unlock_contexts(); 03829 errno = ENOENT; 03830 return -1; 03831 }
|
|
Definition at line 4170 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(). 04172 { 04173 struct ast_include *new_include; 04174 char *c; 04175 struct ast_include *i, *il = NULL; /* include, include_last */ 04176 int length; 04177 char *p; 04178 04179 length = sizeof(struct ast_include); 04180 length += 2 * (strlen(value) + 1); 04181 04182 /* allocate new include structure ... */ 04183 if (!(new_include = malloc(length))) { 04184 ast_log(LOG_ERROR, "Out of memory\n"); 04185 errno = ENOMEM; 04186 return -1; 04187 } 04188 04189 /* ... fill in this structure ... */ 04190 memset(new_include, 0, length); 04191 p = new_include->stuff; 04192 new_include->name = p; 04193 strcpy(new_include->name, value); 04194 p += strlen(value) + 1; 04195 new_include->rname = p; 04196 strcpy(new_include->rname, value); 04197 c = new_include->rname; 04198 /* Strip off timing info */ 04199 while(*c && (*c != '|')) 04200 c++; 04201 /* Process if it's there */ 04202 if (*c) { 04203 new_include->hastime = ast_build_timing(&(new_include->timing), c+1); 04204 *c = '\0'; 04205 } 04206 new_include->next = NULL; 04207 new_include->registrar = registrar; 04208 04209 /* ... try to lock this context ... */ 04210 if (ast_mutex_lock(&con->lock)) { 04211 free(new_include); 04212 errno = EBUSY; 04213 return -1; 04214 } 04215 04216 /* ... go to last include and check if context is already included too... */ 04217 i = con->includes; 04218 while (i) { 04219 if (!strcasecmp(i->name, new_include->name)) { 04220 free(new_include); 04221 ast_mutex_unlock(&con->lock); 04222 errno = EEXIST; 04223 return -1; 04224 } 04225 il = i; 04226 i = i->next; 04227 } 04228 04229 /* ... include new context into context list, unlock, return */ 04230 if (il) 04231 il->next = new_include; 04232 else 04233 con->includes = new_include; 04234 if (option_verbose > 2) 04235 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04236 ast_mutex_unlock(&con->lock); 04237 04238 return 0; 04239 }
|
|
Definition at line 4246 of file pbx.c. References ast_context_add_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). 04247 { 04248 struct ast_context *c; 04249 04250 if (ast_lock_contexts()) { 04251 errno = EBUSY; 04252 return -1; 04253 } 04254 04255 /* walk contexts ... */ 04256 c = ast_walk_contexts(NULL); 04257 while (c) { 04258 /* ... search for the right one ... */ 04259 if (!strcmp(ast_get_context_name(c), context)) { 04260 int ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04261 /* ... unlock contexts list and return */ 04262 ast_unlock_contexts(); 04263 return ret; 04264 } 04265 c = ast_walk_contexts(c); 04266 } 04267 04268 /* we can't find the right context */ 04269 ast_unlock_contexts(); 04270 errno = ENOENT; 04271 return -1; 04272 }
|
|
Definition at line 4281 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(). 04283 { 04284 struct ast_sw *new_sw; 04285 struct ast_sw *i, *il = NULL; /* sw, sw_last */ 04286 int length; 04287 char *p; 04288 04289 length = sizeof(struct ast_sw); 04290 length += strlen(value) + 1; 04291 if (data) 04292 length += strlen(data); 04293 length++; 04294 if (eval) { 04295 /* Create buffer for evaluation of variables */ 04296 length += SWITCH_DATA_LENGTH; 04297 length++; 04298 } 04299 04300 /* allocate new sw structure ... */ 04301 if (!(new_sw = malloc(length))) { 04302 ast_log(LOG_ERROR, "Out of memory\n"); 04303 errno = ENOMEM; 04304 return -1; 04305 } 04306 04307 /* ... fill in this structure ... */ 04308 memset(new_sw, 0, length); 04309 p = new_sw->stuff; 04310 new_sw->name = p; 04311 strcpy(new_sw->name, value); 04312 p += strlen(value) + 1; 04313 new_sw->data = p; 04314 if (data) { 04315 strcpy(new_sw->data, data); 04316 p += strlen(data) + 1; 04317 } else { 04318 strcpy(new_sw->data, ""); 04319 p++; 04320 } 04321 if (eval) 04322 new_sw->tmpdata = p; 04323 new_sw->next = NULL; 04324 new_sw->eval = eval; 04325 new_sw->registrar = registrar; 04326 04327 /* ... try to lock this context ... */ 04328 if (ast_mutex_lock(&con->lock)) { 04329 free(new_sw); 04330 errno = EBUSY; 04331 return -1; 04332 } 04333 04334 /* ... go to last sw and check if context is already swd too... */ 04335 i = con->alts; 04336 while (i) { 04337 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04338 free(new_sw); 04339 ast_mutex_unlock(&con->lock); 04340 errno = EEXIST; 04341 return -1; 04342 } 04343 il = i; 04344 i = i->next; 04345 } 04346 04347 /* ... sw new context into context list, unlock, return */ 04348 if (il) 04349 il->next = new_sw; 04350 else 04351 con->alts = new_sw; 04352 if (option_verbose > 2) 04353 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04354 ast_mutex_unlock(&con->lock); 04355 04356 return 0; 04357 }
|
|
Definition at line 3640 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(). 03641 { 03642 struct ast_context *tmp, **local_contexts; 03643 int length; 03644 length = sizeof(struct ast_context); 03645 length += strlen(name) + 1; 03646 if (!extcontexts) { 03647 local_contexts = &contexts; 03648 ast_mutex_lock(&conlock); 03649 } else 03650 local_contexts = extcontexts; 03651 03652 tmp = *local_contexts; 03653 while(tmp) { 03654 if (!strcasecmp(tmp->name, name)) { 03655 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 03656 if (!extcontexts) 03657 ast_mutex_unlock(&conlock); 03658 return NULL; 03659 } 03660 tmp = tmp->next; 03661 } 03662 tmp = malloc(length); 03663 if (tmp) { 03664 memset(tmp, 0, length); 03665 ast_mutex_init(&tmp->lock); 03666 strcpy(tmp->name, name); 03667 tmp->root = NULL; 03668 tmp->registrar = registrar; 03669 tmp->next = *local_contexts; 03670 tmp->includes = NULL; 03671 tmp->ignorepats = NULL; 03672 *local_contexts = tmp; 03673 if (option_debug) 03674 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 03675 if (option_verbose > 2) 03676 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 03677 } else 03678 ast_log(LOG_ERROR, "Out of memory\n"); 03679 03680 if (!extcontexts) 03681 ast_mutex_unlock(&conlock); 03682 return tmp; 03683 }
|
|
Definition at line 5387 of file pbx.c. References __ast_context_destroy(). Referenced by ael_reload(), reload(), and unload_module(). 05388 { 05389 __ast_context_destroy(con,registrar); 05390 }
|
|
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 2725 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(). 02726 { 02727 struct ast_context *c; 02728 02729 if (ast_lock_contexts()) return -1; 02730 02731 /* walk contexts ... */ 02732 c = ast_walk_contexts(NULL); 02733 while (c) { 02734 /* ... search for the right one ... */ 02735 if (!strcmp(ast_get_context_name(c), context)) { 02736 /* ... remove extension ... */ 02737 int ret = ast_context_remove_extension2(c, extension, priority, 02738 registrar); 02739 /* ... unlock contexts list and return */ 02740 ast_unlock_contexts(); 02741 return ret; 02742 } 02743 c = ast_walk_contexts(c); 02744 } 02745 02746 /* we can't find the right context */ 02747 ast_unlock_contexts(); 02748 return -1; 02749 }
|
|
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 2761 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(). 02762 { 02763 struct ast_exten *exten, *prev_exten = NULL; 02764 02765 if (ast_mutex_lock(&con->lock)) return -1; 02766 02767 /* go through all extensions in context and search the right one ... */ 02768 exten = con->root; 02769 while (exten) { 02770 02771 /* look for right extension */ 02772 if (!strcmp(exten->exten, extension) && 02773 (!registrar || !strcmp(exten->registrar, registrar))) { 02774 struct ast_exten *peer; 02775 02776 /* should we free all peers in this extension? (priority == 0)? */ 02777 if (priority == 0) { 02778 /* remove this extension from context list */ 02779 if (prev_exten) 02780 prev_exten->next = exten->next; 02781 else 02782 con->root = exten->next; 02783 02784 /* fire out all peers */ 02785 peer = exten; 02786 while (peer) { 02787 exten = peer->peer; 02788 02789 if (!peer->priority==PRIORITY_HINT) 02790 ast_remove_hint(peer); 02791 02792 peer->datad(peer->data); 02793 free(peer); 02794 02795 peer = exten; 02796 } 02797 02798 ast_mutex_unlock(&con->lock); 02799 return 0; 02800 } else { 02801 /* remove only extension with exten->priority == priority */ 02802 struct ast_exten *previous_peer = NULL; 02803 02804 peer = exten; 02805 while (peer) { 02806 /* is this our extension? */ 02807 if (peer->priority == priority && 02808 (!registrar || !strcmp(peer->registrar, registrar) )) { 02809 /* we are first priority extension? */ 02810 if (!previous_peer) { 02811 /* exists previous extension here? */ 02812 if (prev_exten) { 02813 /* yes, so we must change next pointer in 02814 * previous connection to next peer 02815 */ 02816 if (peer->peer) { 02817 prev_exten->next = peer->peer; 02818 peer->peer->next = exten->next; 02819 } else 02820 prev_exten->next = exten->next; 02821 } else { 02822 /* no previous extension, we are first 02823 * extension, so change con->root ... 02824 */ 02825 if (peer->peer) 02826 con->root = peer->peer; 02827 else 02828 con->root = exten->next; 02829 } 02830 } else { 02831 /* we are not first priority in extension */ 02832 previous_peer->peer = peer->peer; 02833 } 02834 02835 /* now, free whole priority extension */ 02836 if (peer->priority==PRIORITY_HINT) 02837 ast_remove_hint(peer); 02838 peer->datad(peer->data); 02839 free(peer); 02840 02841 ast_mutex_unlock(&con->lock); 02842 return 0; 02843 } else { 02844 /* this is not right extension, skip to next peer */ 02845 previous_peer = peer; 02846 peer = peer->peer; 02847 } 02848 } 02849 02850 ast_mutex_unlock(&con->lock); 02851 return -1; 02852 } 02853 } 02854 02855 prev_exten = exten; 02856 exten = exten->next; 02857 } 02858 02859 /* we can't find right extension */ 02860 ast_mutex_unlock(&con->lock); 02861 return -1; 02862 }
|
|
Definition at line 4363 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(). 04364 { 04365 struct ast_context *c; 04366 04367 if (ast_lock_contexts()) { 04368 errno = EBUSY; 04369 return -1; 04370 } 04371 04372 c = ast_walk_contexts(NULL); 04373 while (c) { 04374 if (!strcmp(ast_get_context_name(c), context)) { 04375 int ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04376 ast_unlock_contexts(); 04377 return ret; 04378 } 04379 c = ast_walk_contexts(c); 04380 } 04381 04382 ast_unlock_contexts(); 04383 errno = ENOENT; 04384 return -1; 04385 }
|
|
Definition at line 4387 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(). 04388 { 04389 struct ast_ignorepat *ip, *ipl = NULL; 04390 04391 if (ast_mutex_lock(&con->lock)) { 04392 errno = EBUSY; 04393 return -1; 04394 } 04395 04396 ip = con->ignorepats; 04397 while (ip) { 04398 if (!strcmp(ip->pattern, ignorepat) && 04399 (!registrar || (registrar == ip->registrar))) { 04400 if (ipl) { 04401 ipl->next = ip->next; 04402 free(ip); 04403 } else { 04404 con->ignorepats = ip->next; 04405 free(ip); 04406 } 04407 ast_mutex_unlock(&con->lock); 04408 return 0; 04409 } 04410 ipl = ip; ip = ip->next; 04411 } 04412 04413 ast_mutex_unlock(&con->lock); 04414 errno = EINVAL; 04415 return -1; 04416 }
|
|
See add_include Definition at line 2581 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(). 02582 { 02583 struct ast_context *c; 02584 02585 if (ast_lock_contexts()) return -1; 02586 02587 /* walk contexts and search for the right one ...*/ 02588 c = ast_walk_contexts(NULL); 02589 while (c) { 02590 /* we found one ... */ 02591 if (!strcmp(ast_get_context_name(c), context)) { 02592 int ret; 02593 /* remove include from this context ... */ 02594 ret = ast_context_remove_include2(c, include, registrar); 02595 02596 ast_unlock_contexts(); 02597 02598 /* ... return results */ 02599 return ret; 02600 } 02601 c = ast_walk_contexts(c); 02602 } 02603 02604 /* we can't find the right one context */ 02605 ast_unlock_contexts(); 02606 return -1; 02607 }
|
|
See add_include2 Definition at line 2617 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(). 02618 { 02619 struct ast_include *i, *pi = NULL; 02620 02621 if (ast_mutex_lock(&con->lock)) return -1; 02622 02623 /* walk includes */ 02624 i = con->includes; 02625 while (i) { 02626 /* find our include */ 02627 if (!strcmp(i->name, include) && 02628 (!registrar || !strcmp(i->registrar, registrar))) { 02629 /* remove from list */ 02630 if (pi) 02631 pi->next = i->next; 02632 else 02633 con->includes = i->next; 02634 /* free include and return */ 02635 free(i); 02636 ast_mutex_unlock(&con->lock); 02637 return 0; 02638 } 02639 pi = i; 02640 i = i->next; 02641 } 02642 02643 /* we can't find the right include */ 02644 ast_mutex_unlock(&con->lock); 02645 return -1; 02646 }
|
|
Definition at line 2653 of file pbx.c. References ast_context_remove_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). 02654 { 02655 struct ast_context *c; 02656 02657 if (ast_lock_contexts()) return -1; 02658 02659 /* walk contexts and search for the right one ...*/ 02660 c = ast_walk_contexts(NULL); 02661 while (c) { 02662 /* we found one ... */ 02663 if (!strcmp(ast_get_context_name(c), context)) { 02664 int ret; 02665 /* remove switch from this context ... */ 02666 ret = ast_context_remove_switch2(c, sw, data, registrar); 02667 02668 ast_unlock_contexts(); 02669 02670 /* ... return results */ 02671 return ret; 02672 } 02673 c = ast_walk_contexts(c); 02674 } 02675 02676 /* we can't find the right one context */ 02677 ast_unlock_contexts(); 02678 return -1; 02679 }
|
|
This function locks given context, removes switch, unlock context and return.
Definition at line 2689 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(). 02690 { 02691 struct ast_sw *i, *pi = NULL; 02692 02693 if (ast_mutex_lock(&con->lock)) return -1; 02694 02695 /* walk switchs */ 02696 i = con->alts; 02697 while (i) { 02698 /* find our switch */ 02699 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02700 (!registrar || !strcmp(i->registrar, registrar))) { 02701 /* remove from list */ 02702 if (pi) 02703 pi->next = i->next; 02704 else 02705 con->alts = i->next; 02706 /* free switch and return */ 02707 free(i); 02708 ast_mutex_unlock(&con->lock); 02709 return 0; 02710 } 02711 pi = i; 02712 i = i->next; 02713 } 02714 02715 /* we can't find the right switch */ 02716 ast_mutex_unlock(&con->lock); 02717 return -1; 02718 }
|
|
Definition at line 6436 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(). 06437 { 06438 struct ast_include *inc; 06439 int res = 0; 06440 06441 for (inc = ast_walk_context_includes(con, NULL); inc; inc = ast_walk_context_includes(con, inc)) 06442 if (!ast_context_find(inc->rname)) { 06443 res = -1; 06444 ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n", 06445 ast_get_context_name(con), inc->rname); 06446 } 06447 return res; 06448 }
|
|
Definition at line 1267 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(). 01268 { 01269 struct ast_custom_function *acfptr; 01270 01271 /* try to lock functions list ... */ 01272 if (ast_mutex_lock(&acflock)) { 01273 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01274 return NULL; 01275 } 01276 01277 for (acfptr = acf_root; acfptr; acfptr = acfptr->next) { 01278 if (!strcmp(name, acfptr->name)) { 01279 break; 01280 } 01281 } 01282 01283 ast_mutex_unlock(&acflock); 01284 01285 return acfptr; 01286 }
|
|
Definition at line 1323 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(). 01324 { 01325 if (!acf) 01326 return -1; 01327 01328 /* try to lock functions list ... */ 01329 if (ast_mutex_lock(&acflock)) { 01330 ast_log(LOG_ERROR, "Unable to lock function list. Failed registering function %s\n", acf->name); 01331 return -1; 01332 } 01333 01334 if (ast_custom_function_find(acf->name)) { 01335 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01336 ast_mutex_unlock(&acflock); 01337 return -1; 01338 } 01339 01340 acf->next = acf_root; 01341 acf_root = acf; 01342 01343 ast_mutex_unlock(&acflock); 01344 01345 if (option_verbose > 1) 01346 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01347 01348 return 0; 01349 }
|
|
Definition at line 1288 of file pbx.c. References acf_root, ast_log(), ast_mutex_lock(), LOG_ERROR, and ast_custom_function::next. Referenced by unload_module(). 01289 { 01290 struct ast_custom_function *acfptr, *lastacf = NULL; 01291 int res = -1; 01292 01293 if (!acf) 01294 return -1; 01295 01296 /* try to lock functions list ... */ 01297 if (ast_mutex_lock(&acflock)) { 01298 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01299 return -1; 01300 } 01301 01302 for (acfptr = acf_root; acfptr; acfptr = acfptr->next) { 01303 if (acfptr == acf) { 01304 if (lastacf) { 01305 lastacf->next = acf->next; 01306 } else { 01307 acf_root = acf->next; 01308 } 01309 res = 0; 01310 break; 01311 } 01312 lastacf = acfptr; 01313 } 01314 01315 ast_mutex_unlock(&acflock); 01316 01317 if (!res && (option_verbose > 1)) 01318 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01319 01320 return res; 01321 }
|
|
Definition at line 2233 of file pbx.c. References HELPER_EXEC, and pbx_extension_helper(). Referenced by loopback_exec(). 02234 { 02235 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXEC); 02236 }
|
|
|
Definition at line 4531 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(). 04532 { 04533 if (!chan) 04534 return -1; 04535 04536 if (!ast_strlen_zero(context)) 04537 ast_copy_string(chan->context, context, sizeof(chan->context)); 04538 if (!ast_strlen_zero(exten)) 04539 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04540 if (priority > -1) { 04541 chan->priority = priority; 04542 /* see flag description in channel.h for explanation */ 04543 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04544 chan->priority--; 04545 } 04546 04547 return 0; 04548 }
|
|
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(), misdn_cfg_is_msn_valid(), 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 1875 of file pbx.c. References ast_extension_state2(), and ast_hint_extension(). Referenced by action_extensionstate(), and handle_request_subscribe(). 01876 { 01877 struct ast_exten *e; 01878 01879 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 01880 if (!e) 01881 return -1; /* No hint, return -1 */ 01882 01883 return ast_extension_state2(e); /* Check all devices in the hint */ 01884 }
|
|
ast_extensions_state2: Check state of extension by using hints
Definition at line 1788 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(). 01789 { 01790 char hint[AST_MAX_EXTENSION] = ""; 01791 char *cur, *rest; 01792 int res = -1; 01793 int allunavailable = 1, allbusy = 1, allfree = 1; 01794 int busy = 0, inuse = 0, ring = 0; 01795 01796 if (!e) 01797 return -1; 01798 01799 ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint)); 01800 01801 cur = hint; /* On or more devices separated with a & character */ 01802 do { 01803 rest = strchr(cur, '&'); 01804 if (rest) { 01805 *rest = 0; 01806 rest++; 01807 } 01808 01809 res = ast_device_state(cur); 01810 switch (res) { 01811 case AST_DEVICE_NOT_INUSE: 01812 allunavailable = 0; 01813 allbusy = 0; 01814 break; 01815 case AST_DEVICE_INUSE: 01816 inuse = 1; 01817 allunavailable = 0; 01818 allfree = 0; 01819 break; 01820 case AST_DEVICE_RINGING: 01821 ring = 1; 01822 allunavailable = 0; 01823 allfree = 0; 01824 break; 01825 case AST_DEVICE_BUSY: 01826 allunavailable = 0; 01827 allfree = 0; 01828 busy = 1; 01829 break; 01830 case AST_DEVICE_UNAVAILABLE: 01831 case AST_DEVICE_INVALID: 01832 allbusy = 0; 01833 allfree = 0; 01834 break; 01835 default: 01836 allunavailable = 0; 01837 allbusy = 0; 01838 allfree = 0; 01839 } 01840 cur = rest; 01841 } while (cur); 01842 01843 if (!inuse && ring) 01844 return AST_EXTENSION_RINGING; 01845 if (inuse && ring) 01846 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 01847 if (inuse) 01848 return AST_EXTENSION_INUSE; 01849 if (allfree) 01850 return AST_EXTENSION_NOT_INUSE; 01851 if (allbusy) 01852 return AST_EXTENSION_BUSY; 01853 if (allunavailable) 01854 return AST_EXTENSION_UNAVAILABLE; 01855 if (busy) 01856 return AST_EXTENSION_INUSE; 01857 01858 return AST_EXTENSION_NOT_INUSE; 01859 }
|
|
ast_extension_state2str: Return extension_state as string
Definition at line 1862 of file pbx.c. References extension_states. Referenced by __sip_show_channels(), cb_extensionstate(), handle_request_subscribe(), and handle_show_hints(). 01863 { 01864 int i; 01865 01866 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01867 if (extension_states[i].extension_state == extension_state) { 01868 return extension_states[i].text; 01869 } 01870 } 01871 return "Unknown"; 01872 }
|
|
ast_extension_state_add: Add watcher for extension states
Definition at line 1929 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(). 01931 { 01932 struct ast_hint *list; 01933 struct ast_state_cb *cblist; 01934 struct ast_exten *e; 01935 01936 /* If there's no context and extension: add callback to statecbs list */ 01937 if (!context && !exten) { 01938 ast_mutex_lock(&hintlock); 01939 01940 cblist = statecbs; 01941 while (cblist) { 01942 if (cblist->callback == callback) { 01943 cblist->data = data; 01944 ast_mutex_unlock(&hintlock); 01945 return 0; 01946 } 01947 cblist = cblist->next; 01948 } 01949 01950 /* Now insert the callback */ 01951 cblist = malloc(sizeof(struct ast_state_cb)); 01952 if (!cblist) { 01953 ast_mutex_unlock(&hintlock); 01954 return -1; 01955 } 01956 memset(cblist, 0, sizeof(struct ast_state_cb)); 01957 cblist->id = 0; 01958 cblist->callback = callback; 01959 cblist->data = data; 01960 01961 cblist->next = statecbs; 01962 statecbs = cblist; 01963 01964 ast_mutex_unlock(&hintlock); 01965 return 0; 01966 } 01967 01968 if (!context || !exten) 01969 return -1; 01970 01971 /* This callback type is for only one hint, so get the hint */ 01972 e = ast_hint_extension(NULL, context, exten); 01973 if (!e) { 01974 return -1; 01975 } 01976 01977 /* Find the hint in the list of hints */ 01978 ast_mutex_lock(&hintlock); 01979 list = hints; 01980 01981 while (list) { 01982 if (list->exten == e) 01983 break; 01984 list = list->next; 01985 } 01986 01987 if (!list) { 01988 /* We have no hint, sorry */ 01989 ast_mutex_unlock(&hintlock); 01990 return -1; 01991 } 01992 01993 /* Now insert the callback in the callback list */ 01994 cblist = malloc(sizeof(struct ast_state_cb)); 01995 if (!cblist) { 01996 ast_mutex_unlock(&hintlock); 01997 return -1; 01998 } 01999 memset(cblist, 0, sizeof(struct ast_state_cb)); 02000 cblist->id = stateid++; /* Unique ID for this callback */ 02001 cblist->callback = callback; /* Pointer to callback routine */ 02002 cblist->data = data; /* Data for the callback */ 02003 02004 cblist->next = list->callbacks; 02005 list->callbacks = cblist; 02006 02007 ast_mutex_unlock(&hintlock); 02008 return cblist->id; 02009 }
|
|
ast_extension_state_del: Remove a watcher from the callback list
Definition at line 2012 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(). 02013 { 02014 struct ast_hint *list; 02015 struct ast_state_cb *cblist, *cbprev; 02016 02017 if (!id && !callback) 02018 return -1; 02019 02020 ast_mutex_lock(&hintlock); 02021 02022 /* id is zero is a callback without extension */ 02023 if (!id) { 02024 cbprev = NULL; 02025 cblist = statecbs; 02026 while (cblist) { 02027 if (cblist->callback == callback) { 02028 if (!cbprev) 02029 statecbs = cblist->next; 02030 else 02031 cbprev->next = cblist->next; 02032 02033 free(cblist); 02034 02035 ast_mutex_unlock(&hintlock); 02036 return 0; 02037 } 02038 cbprev = cblist; 02039 cblist = cblist->next; 02040 } 02041 02042 ast_mutex_unlock(&hintlock); 02043 return -1; 02044 } 02045 02046 /* id greater than zero is a callback with extension */ 02047 /* Find the callback based on ID */ 02048 list = hints; 02049 while (list) { 02050 cblist = list->callbacks; 02051 cbprev = NULL; 02052 while (cblist) { 02053 if (cblist->id==id) { 02054 if (!cbprev) 02055 list->callbacks = cblist->next; 02056 else 02057 cbprev->next = cblist->next; 02058 02059 free(cblist); 02060 02061 ast_mutex_unlock(&hintlock); 02062 return 0; 02063 } 02064 cbprev = cblist; 02065 cblist = cblist->next; 02066 } 02067 list = list->next; 02068 } 02069 02070 ast_mutex_unlock(&hintlock); 02071 return -1; 02072 }
|
|
Definition at line 2208 of file pbx.c. References HELPER_FINDLABEL, and pbx_extension_helper(). Referenced by ast_parseable_goto(), and handle_setpriority(). 02209 { 02210 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, HELPER_FINDLABEL); 02211 }
|
|
Definition at line 2213 of file pbx.c. References HELPER_FINDLABEL, and pbx_extension_helper(). Referenced by pbx_load_module(). 02214 { 02215 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, HELPER_FINDLABEL); 02216 }
|
|
Definition at line 1351 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(). 01352 { 01353 char *args = NULL, *function, *p; 01354 char *ret = "0"; 01355 struct ast_custom_function *acfptr; 01356 01357 function = ast_strdupa(in); 01358 if (!function) { 01359 ast_log(LOG_ERROR, "Out of memory\n"); 01360 return ret; 01361 } 01362 if ((args = strchr(function, '('))) { 01363 *args = '\0'; 01364 args++; 01365 if ((p = strrchr(args, ')'))) { 01366 *p = '\0'; 01367 } else { 01368 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01369 } 01370 } else { 01371 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01372 } 01373 01374 if ((acfptr = ast_custom_function_find(function))) { 01375 /* run the custom function */ 01376 if (acfptr->read) { 01377 return acfptr->read(chan, function, args, workspace, len); 01378 } else { 01379 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01380 } 01381 } else { 01382 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01383 } 01384 return ret; 01385 }
|
|
Definition at line 1387 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(). 01388 { 01389 char *args = NULL, *function, *p; 01390 struct ast_custom_function *acfptr; 01391 01392 function = ast_strdupa(in); 01393 if (!function) { 01394 ast_log(LOG_ERROR, "Out of memory\n"); 01395 return; 01396 } 01397 if ((args = strchr(function, '('))) { 01398 *args = '\0'; 01399 args++; 01400 if ((p = strrchr(args, ')'))) { 01401 *p = '\0'; 01402 } else { 01403 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01404 } 01405 } else { 01406 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01407 } 01408 01409 if ((acfptr = ast_custom_function_find(function))) { 01410 /* run the custom function */ 01411 if (acfptr->write) { 01412 acfptr->write(chan, function, args, value); 01413 } else { 01414 ast_log(LOG_ERROR, "Function %s is read-only, it cannot be written to\n", function); 01415 } 01416 } else { 01417 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01418 } 01419 }
|
|
Definition at line 6292 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(). 06293 { 06294 return con ? con->name : NULL; 06295 }
|
|
Definition at line 6325 of file pbx.c. References ast_context::registrar. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06326 { 06327 return c ? c->registrar : NULL; 06328 }
|
|
Definition at line 6355 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(). 06356 { 06357 return e ? e->app : NULL; 06358 }
|
|
Definition at line 6360 of file pbx.c. References ast_exten::data. Referenced by ast_get_hint(), handle_save_dialplan(), and show_dialplan_helper(). 06361 { 06362 return e ? e->data : NULL; 06363 }
|
|
Definition at line 6350 of file pbx.c. References ast_exten::cidmatch. Referenced by find_matching_priority(), and handle_save_dialplan(). 06351 { 06352 return e ? e->cidmatch : NULL; 06353 }
|
|
Definition at line 6302 of file pbx.c. References exten. Referenced by handle_save_dialplan(), and show_dialplan_helper().
|
|
Definition at line 6345 of file pbx.c. References ast_exten::matchcid. Referenced by find_matching_priority(), and handle_save_dialplan(). 06346 { 06347 return e ? e->matchcid : 0; 06348 }
|
|
Definition at line 6297 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 6317 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 6330 of file pbx.c. References ast_exten::registrar. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06331 { 06332 return e ? e->registrar : NULL; 06333 }
|
|
ast_get_hint: Get hint for channel
Definition at line 2184 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(). 02185 { 02186 struct ast_exten *e; 02187 void *tmp; 02188 02189 e = ast_hint_extension(c, context, exten); 02190 if (e) { 02191 if (hint) 02192 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02193 if (name) { 02194 tmp = ast_get_extension_app_data(e); 02195 if (tmp) 02196 ast_copy_string(name, (char *) tmp, namesize); 02197 } 02198 return -1; 02199 } 02200 return 0; 02201 }
|
|
Definition at line 6312 of file pbx.c. References ast_ignorepat::pattern. Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), and handle_save_dialplan(). 06313 { 06314 return ip ? ip->pattern : NULL; 06315 }
|
|
Definition at line 6340 of file pbx.c. References ast_ignorepat::registrar. Referenced by handle_save_dialplan(). 06341 { 06342 return ip ? ip->registrar : NULL; 06343 }
|
|
Definition at line 6307 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(). 06308 { 06309 return inc ? inc->name : NULL; 06310 }
|
|
Definition at line 6335 of file pbx.c. References ast_include::registrar. Referenced by handle_save_dialplan(). 06336 { 06337 return i ? i->registrar : NULL; 06338 }
|
|
Definition at line 6370 of file pbx.c. References ast_sw::data. Referenced by handle_save_dialplan(). 06371 { 06372 return sw ? sw->data : NULL; 06373 }
|
|
Definition at line 6365 of file pbx.c. References ast_sw::name. Referenced by handle_save_dialplan(). 06366 { 06367 return sw ? sw->name : NULL; 06368 }
|
|
Definition at line 6375 of file pbx.c. References ast_sw::registrar. Referenced by handle_save_dialplan(). 06376 { 06377 return sw ? sw->registrar : NULL; 06378 }
|
|
Definition at line 6468 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(). 06468 { 06469 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06470 }
|
|
ast_hint_extension: Find hint for given extension in context
Definition at line 1768 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(). 01769 { 01770 struct ast_exten *e; 01771 struct ast_switch *sw; 01772 char *data; 01773 const char *foundcontext = NULL; 01774 int status = 0; 01775 char *incstack[AST_PBX_MAX_STACK]; 01776 int stacklen = 0; 01777 01778 if (ast_mutex_lock(&conlock)) { 01779 ast_log(LOG_WARNING, "Unable to obtain lock\n"); 01780 return NULL; 01781 } 01782 e = pbx_find_extension(c, NULL, context, exten, PRIORITY_HINT, NULL, "", HELPER_EXISTS, incstack, &stacklen, &status, &sw, &data, &foundcontext); 01783 ast_mutex_unlock(&conlock); 01784 return e; 01785 }
|
|
Definition at line 1886 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(). 01887 { 01888 struct ast_hint *hint; 01889 struct ast_state_cb *cblist; 01890 char buf[AST_MAX_EXTENSION]; 01891 char *parse; 01892 char *cur; 01893 int state; 01894 01895 ast_mutex_lock(&hintlock); 01896 01897 for (hint = hints; hint; hint = hint->next) { 01898 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 01899 parse = buf; 01900 for (cur = strsep(&parse, "&"); cur; cur = strsep(&parse, "&")) { 01901 if (strcasecmp(cur, device)) 01902 continue; 01903 01904 /* Get device state for this hint */ 01905 state = ast_extension_state2(hint->exten); 01906 01907 if ((state == -1) || (state == hint->laststate)) 01908 continue; 01909 01910 /* Device state changed since last check - notify the watchers */ 01911 01912 /* For general callbacks */ 01913 for (cblist = statecbs; cblist; cblist = cblist->next) 01914 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01915 01916 /* For extension callbacks */ 01917 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 01918 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01919 01920 hint->laststate = state; 01921 break; 01922 } 01923 } 01924 01925 ast_mutex_unlock(&hintlock); 01926 }
|
|
Definition at line 4483 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(). 04484 { 04485 struct ast_context *con; 04486 struct ast_ignorepat *pat; 04487 04488 con = ast_context_find(context); 04489 if (con) { 04490 pat = con->ignorepats; 04491 while (pat) { 04492 if (ast_extension_match(pat->pattern, pattern)) 04493 return 1; 04494 pat = pat->next; 04495 } 04496 } 04497 return 0; 04498 }
|
|
|
|
Definition at line 6279 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(). 06280 { 06281 return ast_mutex_lock(&con->lock); 06282 }
|
|
Locks the context list Returns 0 on success, -1 on error Definition at line 6266 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(). 06267 { 06268 return ast_mutex_lock(&conlock); 06269 }
|
|
Definition at line 2223 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(). 02224 { 02225 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_MATCHMORE); 02226 }
|
|
Definition at line 3698 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(). 03699 { 03700 struct ast_context *tmp, *lasttmp = NULL; 03701 struct store_hints store; 03702 struct store_hint *this; 03703 struct ast_hint *hint; 03704 struct ast_exten *exten; 03705 int length; 03706 struct ast_state_cb *thiscb, *prevcb; 03707 03708 memset(&store, 0, sizeof(store)); 03709 AST_LIST_HEAD_INIT(&store); 03710 03711 /* it is very important that this function hold the hintlock _and_ the conlock 03712 during its operation; not only do we need to ensure that the list of contexts 03713 and extensions does not change, but also that no hint callbacks (watchers) are 03714 added or removed during the merge/delete process 03715 03716 in addition, the locks _must_ be taken in this order, because there are already 03717 other code paths that use this order 03718 */ 03719 ast_mutex_lock(&conlock); 03720 ast_mutex_lock(&hintlock); 03721 03722 /* preserve all watchers for hints associated with this registrar */ 03723 for (hint = hints; hint; hint = hint->next) { 03724 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03725 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03726 this = calloc(1, length); 03727 if (!this) { 03728 ast_log(LOG_WARNING, "Could not allocate memory to preserve hint\n"); 03729 continue; 03730 } 03731 this->callbacks = hint->callbacks; 03732 hint->callbacks = NULL; 03733 this->laststate = hint->laststate; 03734 this->context = this->data; 03735 strcpy(this->data, hint->exten->parent->name); 03736 this->exten = this->data + strlen(this->context) + 1; 03737 strcpy(this->exten, hint->exten->exten); 03738 AST_LIST_INSERT_HEAD(&store, this, list); 03739 } 03740 } 03741 03742 tmp = *extcontexts; 03743 if (registrar) { 03744 __ast_context_destroy(NULL,registrar); 03745 while (tmp) { 03746 lasttmp = tmp; 03747 tmp = tmp->next; 03748 } 03749 } else { 03750 while (tmp) { 03751 __ast_context_destroy(tmp,tmp->registrar); 03752 lasttmp = tmp; 03753 tmp = tmp->next; 03754 } 03755 } 03756 if (lasttmp) { 03757 lasttmp->next = contexts; 03758 contexts = *extcontexts; 03759 *extcontexts = NULL; 03760 } else 03761 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 03762 03763 /* restore the watchers for hints that can be found; notify those that 03764 cannot be restored 03765 */ 03766 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 03767 exten = ast_hint_extension(NULL, this->context, this->exten); 03768 /* Find the hint in the list of hints */ 03769 for (hint = hints; hint; hint = hint->next) { 03770 if (hint->exten == exten) 03771 break; 03772 } 03773 if (!exten || !hint) { 03774 /* this hint has been removed, notify the watchers */ 03775 prevcb = NULL; 03776 thiscb = this->callbacks; 03777 while (thiscb) { 03778 prevcb = thiscb; 03779 thiscb = thiscb->next; 03780 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 03781 free(prevcb); 03782 } 03783 } else { 03784 thiscb = this->callbacks; 03785 while (thiscb->next) 03786 thiscb = thiscb->next; 03787 thiscb->next = hint->callbacks; 03788 hint->callbacks = this->callbacks; 03789 hint->laststate = this->laststate; 03790 } 03791 free(this); 03792 } 03793 03794 ast_mutex_unlock(&hintlock); 03795 ast_mutex_unlock(&conlock); 03796 03797 return; 03798 }
|
|
|
|
|
|
|
|
|
|
Lock for the custom function list |
|
|
|
|
|
Definition at line 6476 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(). 06477 { 06478 char *s; 06479 char *exten, *pri, *context; 06480 char *stringp=NULL; 06481 int ipri; 06482 int mode = 0; 06483 06484 if (ast_strlen_zero(goto_string)) { 06485 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06486 return -1; 06487 } 06488 s = ast_strdupa(goto_string); 06489 stringp=s; 06490 context = strsep(&stringp, "|"); 06491 exten = strsep(&stringp, "|"); 06492 if (!exten) { 06493 /* Only a priority in this one */ 06494 pri = context; 06495 exten = NULL; 06496 context = NULL; 06497 } else { 06498 pri = strsep(&stringp, "|"); 06499 if (!pri) { 06500 /* Only an extension and priority in this one */ 06501 pri = exten; 06502 exten = context; 06503 context = NULL; 06504 } 06505 } 06506 if (*pri == '+') { 06507 mode = 1; 06508 pri++; 06509 } else if (*pri == '-') { 06510 mode = -1; 06511 pri++; 06512 } 06513 if (sscanf(pri, "%d", &ipri) != 1) { 06514 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, (exten && strcasecmp(exten, "BYEXTENSION")) ? exten : chan->exten, 06515 pri, chan->cid.cid_num)) < 1) { 06516 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06517 return -1; 06518 } else 06519 mode = 0; 06520 } 06521 /* At this point we have a priority and maybe an extension and a context */ 06522 06523 if (exten && !strcasecmp(exten, "BYEXTENSION")) 06524 exten = NULL; 06525 06526 if (mode) 06527 ipri = chan->priority + (ipri * mode); 06528 06529 ast_explicit_goto(chan, context, exten, ipri); 06530 ast_cdr_update(chan); 06531 return 0; 06532 06533 }
|
|
Definition at line 5159 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(). 05160 { 05161 struct ast_channel *chan; 05162 struct async_stat *as; 05163 struct app_tmp *tmp; 05164 int res = -1, cdr_res = -1; 05165 struct outgoing_helper oh; 05166 pthread_attr_t attr; 05167 05168 memset(&oh, 0, sizeof(oh)); 05169 oh.vars = vars; 05170 oh.account = account; 05171 05172 if (locked_channel) 05173 *locked_channel = NULL; 05174 if (ast_strlen_zero(app)) { 05175 res = -1; 05176 goto outgoing_app_cleanup; 05177 } 05178 if (sync) { 05179 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05180 if (chan) { 05181 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05182 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05183 } else { 05184 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05185 if(!chan->cdr) { 05186 /* allocation of the cdr failed */ 05187 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 05188 free(chan->pbx); 05189 res = -1; 05190 goto outgoing_app_cleanup; 05191 } 05192 /* allocation of the cdr was successful */ 05193 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05194 ast_cdr_start(chan->cdr); 05195 } 05196 ast_set_variables(chan, vars); 05197 if (account) 05198 ast_cdr_setaccount(chan, account); 05199 if (chan->_state == AST_STATE_UP) { 05200 res = 0; 05201 if (option_verbose > 3) 05202 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05203 tmp = malloc(sizeof(struct app_tmp)); 05204 if (tmp) { 05205 memset(tmp, 0, sizeof(struct app_tmp)); 05206 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05207 if (appdata) 05208 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05209 tmp->chan = chan; 05210 if (sync > 1) { 05211 if (locked_channel) 05212 ast_mutex_unlock(&chan->lock); 05213 ast_pbx_run_app(tmp); 05214 } else { 05215 pthread_attr_init(&attr); 05216 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05217 if (locked_channel) 05218 ast_mutex_lock(&chan->lock); 05219 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05220 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05221 free(tmp); 05222 if (locked_channel) 05223 ast_mutex_unlock(&chan->lock); 05224 ast_hangup(chan); 05225 res = -1; 05226 } else { 05227 if (locked_channel) 05228 *locked_channel = chan; 05229 } 05230 } 05231 } else { 05232 ast_log(LOG_ERROR, "Out of memory :(\n"); 05233 res = -1; 05234 } 05235 } else { 05236 if (option_verbose > 3) 05237 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05238 if (chan->cdr) { /* update the cdr */ 05239 /* here we update the status of the call, which sould be busy. 05240 * if that fails then we set the status to failed */ 05241 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05242 ast_cdr_failed(chan->cdr); 05243 } 05244 ast_hangup(chan); 05245 } 05246 } 05247 05248 if (res < 0) { /* the call failed for some reason */ 05249 if (*reason == 0) { /* if the call failed (not busy or no answer) 05250 * update the cdr with the failed message */ 05251 cdr_res = ast_pbx_outgoing_cdr_failed(); 05252 if (cdr_res != 0) { 05253 res = cdr_res; 05254 goto outgoing_app_cleanup; 05255 } 05256 } 05257 } 05258 05259 } else { 05260 as = malloc(sizeof(struct async_stat)); 05261 if (!as) { 05262 res = -1; 05263 goto outgoing_app_cleanup; 05264 } 05265 memset(as, 0, sizeof(struct async_stat)); 05266 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05267 if (!chan) { 05268 free(as); 05269 res = -1; 05270 goto outgoing_app_cleanup; 05271 } 05272 as->chan = chan; 05273 ast_copy_string(as->app, app, sizeof(as->app)); 05274 if (appdata) 05275 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05276 as->timeout = timeout; 05277 ast_set_variables(chan, vars); 05278 if (account) 05279 ast_cdr_setaccount(chan, account); 05280 /* Start a new thread, and get something handling this channel. */ 05281 pthread_attr_init(&attr); 05282 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05283 if (locked_channel) 05284 ast_mutex_lock(&chan->lock); 05285 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05286 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05287 free(as); 05288 if (locked_channel) 05289 ast_mutex_unlock(&chan->lock); 05290 ast_hangup(chan); 05291 res = -1; 05292 goto outgoing_app_cleanup; 05293 } else { 05294 if (locked_channel) 05295 *locked_channel = chan; 05296 } 05297 res = 0; 05298 } 05299 outgoing_app_cleanup: 05300 ast_variables_destroy(vars); 05301 return res; 05302 }
|
|
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 4955 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(). 04956 { 04957 /* allocate a channel */ 04958 struct ast_channel *chan = ast_channel_alloc(0); 04959 if(!chan) { 04960 /* allocation of the channel failed, let some peeps know */ 04961 ast_log(LOG_WARNING, "Unable to allocate channel structure for CDR record\n"); 04962 return -1; /* failure */ 04963 } 04964 04965 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 04966 04967 if(!chan->cdr) { 04968 /* allocation of the cdr failed */ 04969 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 04970 ast_channel_free(chan); /* free the channel */ 04971 return -1; /* return failure */ 04972 } 04973 04974 /* allocation of the cdr was successful */ 04975 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 04976 ast_cdr_start(chan->cdr); /* record the start and stop time */ 04977 ast_cdr_end(chan->cdr); 04978 ast_cdr_failed(chan->cdr); /* set the status to failed */ 04979 ast_cdr_detach(chan->cdr); /* post and free the record */ 04980 ast_channel_free(chan); /* free the channel */ 04981 04982 return 0; /* success */ 04983 }
|
|
Definition at line 4985 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(). 04986 { 04987 struct ast_channel *chan; 04988 struct async_stat *as; 04989 int res = -1, cdr_res = -1; 04990 struct outgoing_helper oh; 04991 pthread_attr_t attr; 04992 04993 if (sync) { 04994 LOAD_OH(oh); 04995 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 04996 if (channel) { 04997 *channel = chan; 04998 if (chan) 04999 ast_mutex_lock(&chan->lock); 05000 } 05001 if (chan) { 05002 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05003 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05004 } else { 05005 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05006 if (!chan->cdr) { 05007 /* allocation of the cdr failed */ 05008 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 05009 free(chan->pbx); 05010 res = -1; 05011 goto outgoing_exten_cleanup; 05012 } 05013 /* allocation of the cdr was successful */ 05014 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05015 ast_cdr_start(chan->cdr); 05016 } 05017 if (chan->_state == AST_STATE_UP) { 05018 res = 0; 05019 if (option_verbose > 3) 05020 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05021 05022 if (sync > 1) { 05023 if (channel) 05024 ast_mutex_unlock(&chan->lock); 05025 if (ast_pbx_run(chan)) { 05026 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05027 if (channel) 05028 *channel = NULL; 05029 ast_hangup(chan); 05030 res = -1; 05031 } 05032 } else { 05033 if (ast_pbx_start(chan)) { 05034 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05035 if (channel) { 05036 *channel = NULL; 05037 ast_mutex_unlock(&chan->lock); 05038 } 05039 ast_hangup(chan); 05040 res = -1; 05041 } 05042 } 05043 } else { 05044 if (option_verbose > 3) 05045 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05046 05047 if(chan->cdr) { /* update the cdr */ 05048 /* here we update the status of the call, which sould be busy. 05049 * if that fails then we set the status to failed */ 05050 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05051 ast_cdr_failed(chan->cdr); 05052 } 05053 05054 if (channel) { 05055 *channel = NULL; 05056 ast_mutex_unlock(&chan->lock); 05057 } 05058 ast_hangup(chan); 05059 } 05060 } 05061 05062 if (res < 0) { /* the call failed for some reason */ 05063 if (*reason == 0) { /* if the call failed (not busy or no answer) 05064 * update the cdr with the failed message */ 05065 cdr_res = ast_pbx_outgoing_cdr_failed(); 05066 if (cdr_res != 0) { 05067 res = cdr_res; 05068 goto outgoing_exten_cleanup; 05069 } 05070 } 05071 05072 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05073 /* check if "failed" exists */ 05074 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05075 chan = ast_channel_alloc(0); 05076 if (chan) { 05077 ast_copy_string(chan->name, "OutgoingSpoolFailed", sizeof(chan->name)); 05078 if (!ast_strlen_zero(context)) 05079 ast_copy_string(chan->context, context, sizeof(chan->context)); 05080 ast_copy_string(chan->exten, "failed", sizeof(chan->exten)); 05081 chan->priority = 1; 05082 ast_set_variables(chan, vars); 05083 if (account) 05084 ast_cdr_setaccount(chan, account); 05085 ast_pbx_run(chan); 05086 } else 05087 ast_log(LOG_WARNING, "Can't allocate the channel structure, skipping execution of extension 'failed'\n"); 05088 } 05089 } 05090 } else { 05091 as = malloc(sizeof(struct async_stat)); 05092 if (!as) { 05093 res = -1; 05094 goto outgoing_exten_cleanup; 05095 } 05096 memset(as, 0, sizeof(struct async_stat)); 05097 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05098 if (channel) { 05099 *channel = chan; 05100 if (chan) 05101 ast_mutex_lock(&chan->lock); 05102 } 05103 if (!chan) { 05104 free(as); 05105 res = -1; 05106 goto outgoing_exten_cleanup; 05107 } 05108 as->chan = chan; 05109 ast_copy_string(as->context, context, sizeof(as->context)); 05110 ast_copy_string(as->exten, exten, sizeof(as->exten)); 05111 as->priority = priority; 05112 as->timeout = timeout; 05113 ast_set_variables(chan, vars); 05114 if (account) 05115 ast_cdr_setaccount(chan, account); 05116 pthread_attr_init(&attr); 05117 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05118 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05119 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05120 free(as); 05121 if (channel) { 05122 *channel = NULL; 05123 ast_mutex_unlock(&chan->lock); 05124 } 05125 ast_hangup(chan); 05126 res = -1; 05127 goto outgoing_exten_cleanup; 05128 } 05129 res = 0; 05130 } 05131 outgoing_exten_cleanup: 05132 ast_variables_destroy(vars); 05133 return res; 05134 }
|
|
Definition at line 2549 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(). 02550 { 02551 enum ast_pbx_result res = AST_PBX_SUCCESS; 02552 02553 if (increase_call_count(c)) 02554 return AST_PBX_CALL_LIMIT; 02555 02556 res = __ast_pbx_run(c); 02557 decrease_call_count(); 02558 02559 return res; 02560 }
|
|
Definition at line 5143 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(). 05144 { 05145 struct app_tmp *tmp = data; 05146 struct ast_app *app; 05147 app = pbx_findapp(tmp->app); 05148 if (app) { 05149 if (option_verbose > 3) 05150 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05151 pbx_exec(tmp->chan, app, tmp->data, 1); 05152 } else 05153 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05154 ast_hangup(tmp->chan); 05155 free(tmp); 05156 return NULL; 05157 }
|
|
Definition at line 2525 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(), check_goto_on_transfer(), do_parking_thread(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), pbx_start_chan(), phone_new(), rpt_call(), sip_new(), skinny_new(), vpb_new(), and zt_new(). 02526 { 02527 pthread_t t; 02528 pthread_attr_t attr; 02529 02530 if (!c) { 02531 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02532 return AST_PBX_FAILED; 02533 } 02534 02535 if (increase_call_count(c)) 02536 return AST_PBX_CALL_LIMIT; 02537 02538 /* Start a new thread, and get something handling this channel. */ 02539 pthread_attr_init(&attr); 02540 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02541 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02542 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02543 return AST_PBX_FAILED; 02544 } 02545 02546 return AST_PBX_SUCCESS; 02547 }
|
|
Dynamically register a new dial plan application.
Definition at line 2866 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(). 02867 { 02868 struct ast_app *tmp, *prev, *cur; 02869 char tmps[80]; 02870 int length; 02871 length = sizeof(struct ast_app); 02872 length += strlen(app) + 1; 02873 if (ast_mutex_lock(&applock)) { 02874 ast_log(LOG_ERROR, "Unable to lock application list\n"); 02875 return -1; 02876 } 02877 tmp = apps; 02878 while(tmp) { 02879 if (!strcasecmp(app, tmp->name)) { 02880 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02881 ast_mutex_unlock(&applock); 02882 return -1; 02883 } 02884 tmp = tmp->next; 02885 } 02886 tmp = malloc(length); 02887 if (tmp) { 02888 memset(tmp, 0, length); 02889 strcpy(tmp->name, app); 02890 tmp->execute = execute; 02891 tmp->synopsis = synopsis; 02892 tmp->description = description; 02893 /* Store in alphabetical order */ 02894 cur = apps; 02895 prev = NULL; 02896 while(cur) { 02897 if (strcasecmp(tmp->name, cur->name) < 0) 02898 break; 02899 prev = cur; 02900 cur = cur->next; 02901 } 02902 if (prev) { 02903 tmp->next = prev->next; 02904 prev->next = tmp; 02905 } else { 02906 tmp->next = apps; 02907 apps = tmp; 02908 } 02909 } else { 02910 ast_log(LOG_ERROR, "Out of memory\n"); 02911 ast_mutex_unlock(&applock); 02912 return -1; 02913 } 02914 if (option_verbose > 1) 02915 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02916 ast_mutex_unlock(&applock); 02917 return 0; 02918 }
|
|
Definition at line 2920 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(). 02921 { 02922 struct ast_switch *tmp, *prev=NULL; 02923 if (ast_mutex_lock(&switchlock)) { 02924 ast_log(LOG_ERROR, "Unable to lock switch lock\n"); 02925 return -1; 02926 } 02927 tmp = switches; 02928 while(tmp) { 02929 if (!strcasecmp(tmp->name, sw->name)) 02930 break; 02931 prev = tmp; 02932 tmp = tmp->next; 02933 } 02934 if (tmp) { 02935 ast_mutex_unlock(&switchlock); 02936 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 02937 return -1; 02938 } 02939 sw->next = NULL; 02940 if (prev) 02941 prev->next = sw; 02942 else 02943 switches = sw; 02944 ast_mutex_unlock(&switchlock); 02945 return 0; 02946 }
|
|
ast_remove_hint: Remove hint from extension
Definition at line 2139 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(). 02140 { 02141 /* Cleanup the Notifys if hint is removed */ 02142 struct ast_hint *list, *prev = NULL; 02143 struct ast_state_cb *cblist, *cbprev; 02144 02145 if (!e) 02146 return -1; 02147 02148 ast_mutex_lock(&hintlock); 02149 02150 list = hints; 02151 while(list) { 02152 if (list->exten==e) { 02153 cbprev = NULL; 02154 cblist = list->callbacks; 02155 while (cblist) { 02156 /* Notify with -1 and remove all callbacks */ 02157 cbprev = cblist; 02158 cblist = cblist->next; 02159 cbprev->callback(list->exten->parent->name, list->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data); 02160 free(cbprev); 02161 } 02162 list->callbacks = NULL; 02163 02164 if (!prev) 02165 hints = list->next; 02166 else 02167 prev->next = list->next; 02168 free(list); 02169 02170 ast_mutex_unlock(&hintlock); 02171 return 0; 02172 } else { 02173 prev = list; 02174 list = list->next; 02175 } 02176 } 02177 02178 ast_mutex_unlock(&hintlock); 02179 return -1; 02180 }
|
|
Definition at line 2228 of file pbx.c. References HELPER_SPAWN, and pbx_extension_helper(). Referenced by __ast_pbx_run(), loopback_exec(), and macro_exec(). 02229 { 02230 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_SPAWN); 02231 }
|
|
Definition at line 6284 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(). 06285 { 06286 return ast_mutex_unlock(&con->lock); 06287 }
|
|
Returns 0 on success, -1 on failure Definition at line 6271 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(). 06272 { 06273 return ast_mutex_unlock(&conlock); 06274 }
|
|
Definition at line 3613 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(). 03614 { 03615 struct ast_app *tmp, *tmpl = NULL; 03616 if (ast_mutex_lock(&applock)) { 03617 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03618 return -1; 03619 } 03620 tmp = apps; 03621 while(tmp) { 03622 if (!strcasecmp(app, tmp->name)) { 03623 if (tmpl) 03624 tmpl->next = tmp->next; 03625 else 03626 apps = tmp->next; 03627 if (option_verbose > 1) 03628 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03629 free(tmp); 03630 ast_mutex_unlock(&applock); 03631 return 0; 03632 } 03633 tmpl = tmp; 03634 tmp = tmp->next; 03635 } 03636 ast_mutex_unlock(&applock); 03637 return -1; 03638 }
|
|
Definition at line 2948 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(). 02949 { 02950 struct ast_switch *tmp, *prev=NULL; 02951 if (ast_mutex_lock(&switchlock)) { 02952 ast_log(LOG_ERROR, "Unable to lock switch lock\n"); 02953 return; 02954 } 02955 tmp = switches; 02956 while(tmp) { 02957 if (tmp == sw) { 02958 if (prev) 02959 prev->next = tmp->next; 02960 else 02961 switches = tmp->next; 02962 tmp->next = NULL; 02963 break; 02964 } 02965 prev = tmp; 02966 tmp = tmp->next; 02967 } 02968 ast_mutex_unlock(&switchlock); 02969 }
|
|
Definition at line 6391 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(). 06393 { 06394 if (!exten) 06395 return con ? con->root : NULL; 06396 else 06397 return exten->next; 06398 }
|
|
Definition at line 6427 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(). 06429 { 06430 if (!ip) 06431 return con ? con->ignorepats : NULL; 06432 else 06433 return ip->next; 06434 }
|
|
Definition at line 6418 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(). 06420 { 06421 if (!inc) 06422 return con ? con->includes : NULL; 06423 else 06424 return inc->next; 06425 }
|
|
Definition at line 6400 of file pbx.c. References ast_context::alts, and ast_sw::next. Referenced by handle_save_dialplan(). 06402 { 06403 if (!sw) 06404 return con ? con->alts : NULL; 06405 else 06406 return sw->next; 06407 }
|
|
Definition at line 6383 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 6409 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 4891 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(). 04892 { 04893 struct async_stat *as = data; 04894 struct ast_channel *chan = as->chan; 04895 int timeout = as->timeout; 04896 int res; 04897 struct ast_frame *f; 04898 struct ast_app *app; 04899 04900 while(timeout && (chan->_state != AST_STATE_UP)) { 04901 res = ast_waitfor(chan, timeout); 04902 if (res < 1) 04903 break; 04904 if (timeout > -1) 04905 timeout = res; 04906 f = ast_read(chan); 04907 if (!f) 04908 break; 04909 if (f->frametype == AST_FRAME_CONTROL) { 04910 if ((f->subclass == AST_CONTROL_BUSY) || 04911 (f->subclass == AST_CONTROL_CONGESTION) ) { 04912 ast_frfree(f); 04913 break; 04914 } 04915 } 04916 ast_frfree(f); 04917 } 04918 if (chan->_state == AST_STATE_UP) { 04919 if (!ast_strlen_zero(as->app)) { 04920 app = pbx_findapp(as->app); 04921 if (app) { 04922 if (option_verbose > 2) 04923 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 04924 pbx_exec(chan, app, as->appdata, 1); 04925 } else 04926 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 04927 } else { 04928 if (!ast_strlen_zero(as->context)) 04929 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 04930 if (!ast_strlen_zero(as->exten)) 04931 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 04932 if (as->priority > 0) 04933 chan->priority = as->priority; 04934 /* Run the PBX */ 04935 if (ast_pbx_run(chan)) { 04936 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 04937 } else { 04938 /* PBX will have taken care of this */ 04939 chan = NULL; 04940 } 04941 } 04942 04943 } 04944 free(as); 04945 if (chan) 04946 ast_hangup(chan); 04947 return NULL; 04948 }
|
|
Definition at line 3019 of file pbx.c. References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_app::name, ast_app::next, and strdup. 03021 { 03022 struct ast_app *a; 03023 int which = 0; 03024 03025 /* try to lock applications list ... */ 03026 if (ast_mutex_lock(&applock)) { 03027 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03028 return NULL; 03029 } 03030 03031 /* ... walk all applications ... */ 03032 a = apps; 03033 while (a) { 03034 /* ... check if word matches this application ... */ 03035 if (!strncasecmp(word, a->name, strlen(word))) { 03036 /* ... if this is right app serve it ... */ 03037 if (++which > state) { 03038 char *ret = strdup(a->name); 03039 ast_mutex_unlock(&applock); 03040 return ret; 03041 } 03042 } 03043 a = a->next; 03044 } 03045 03046 /* no application match */ 03047 ast_mutex_unlock(&applock); 03048 return NULL; 03049 }
|
|
Definition at line 3266 of file pbx.c. References ast_strlen_zero(), and strdup. 03267 { 03268 if (pos == 2) { 03269 if (ast_strlen_zero(word)) { 03270 switch (state) { 03271 case 0: 03272 return strdup("like"); 03273 case 1: 03274 return strdup("describing"); 03275 default: 03276 return NULL; 03277 } 03278 } else if (! strncasecmp(word, "like", strlen(word))) { 03279 if (state == 0) { 03280 return strdup("like"); 03281 } else { 03282 return NULL; 03283 } 03284 } else if (! strncasecmp(word, "describing", strlen(word))) { 03285 if (state == 0) { 03286 return strdup("describing"); 03287 } else { 03288 return NULL; 03289 } 03290 } 03291 } 03292 return NULL; 03293 }
|
|
Definition at line 3298 of file pbx.c. References ast_get_context_name(), ast_lock_contexts(), ast_log(), ast_unlock_contexts(), ast_walk_contexts(), LOG_ERROR, and strdup. 03300 { 03301 struct ast_context *c; 03302 int which = 0; 03303 03304 /* we are do completion of [exten@]context on second position only */ 03305 if (pos != 2) return NULL; 03306 03307 /* try to lock contexts list ... */ 03308 if (ast_lock_contexts()) { 03309 ast_log(LOG_ERROR, "Unable to lock context list\n"); 03310 return NULL; 03311 } 03312 03313 /* ... walk through all contexts ... */ 03314 c = ast_walk_contexts(NULL); 03315 while(c) { 03316 /* ... word matches context name? yes? ... */ 03317 if (!strncasecmp(word, ast_get_context_name(c), strlen(word))) { 03318 /* ... for serve? ... */ 03319 if (++which > state) { 03320 /* ... yes, serve this context name ... */ 03321 char *ret = strdup(ast_get_context_name(c)); 03322 ast_unlock_contexts(); 03323 return ret; 03324 } 03325 } 03326 c = ast_walk_contexts(c); 03327 } 03328 03329 /* ... unlock and return */ 03330 ast_unlock_contexts(); 03331 return NULL; 03332 }
|
|
Definition at line 1240 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. 01241 { 01242 struct ast_custom_function *acf; 01243 int which = 0; 01244 01245 /* try to lock functions list ... */ 01246 if (ast_mutex_lock(&acflock)) { 01247 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01248 return NULL; 01249 } 01250 01251 acf = acf_root; 01252 while (acf) { 01253 if (!strncasecmp(word, acf->name, strlen(word))) { 01254 if (++which > state) { 01255 char *ret = strdup(acf->name); 01256 ast_mutex_unlock(&acflock); 01257 return ret; 01258 } 01259 } 01260 acf = acf->next; 01261 } 01262 01263 ast_mutex_unlock(&acflock); 01264 return NULL; 01265 }
|
|
Definition at line 2497 of file pbx.c. References ast_mutex_lock(), and ast_mutex_unlock(). Referenced by ast_pbx_run(), and pbx_thread(). 02498 { 02499 ast_mutex_lock(&maxcalllock); 02500 if (countcalls > 0) 02501 countcalls--; 02502 ast_mutex_unlock(&maxcalllock); 02503 }
|
|
Definition at line 5304 of file pbx.c. References ast_remove_hint(), free, ast_exten::priority, and PRIORITY_HINT. Referenced by __ast_context_destroy(). 05305 { 05306 if (e->priority == PRIORITY_HINT) 05307 ast_remove_hint(e); 05308 05309 if (e->datad) 05310 e->datad(e->data); 05311 free(e); 05312 }
|
|
Definition at line 4612 of file pbx.c. Referenced by ast_add_extension2(). 04613 { 04614 int count=0; 04615 04616 while(*src && (count < len - 1)) { 04617 switch(*src) { 04618 case ' ': 04619 /* otherwise exten => [a-b],1,... doesn't work */ 04620 /* case '-': */ 04621 /* Ignore */ 04622 break; 04623 default: 04624 *dst = *src; 04625 dst++; 04626 } 04627 src++; 04628 count++; 04629 } 04630 *dst = '\0'; 04631 04632 return count; 04633 }
|
|
Definition at line 3978 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and s. Referenced by ast_build_timing(). 03979 { 03980 char *c; 03981 /* The following line is coincidence, really! */ 03982 int s, e, x; 03983 unsigned int mask; 03984 03985 /* Check for all days */ 03986 if (ast_strlen_zero(day) || !strcmp(day, "*")) { 03987 mask = (1 << 30) + ((1 << 30) - 1); 03988 return mask; 03989 } 03990 /* Get start and ending days */ 03991 c = strchr(day, '-'); 03992 if (c) { 03993 *c = '\0'; 03994 c++; 03995 } 03996 /* Find the start */ 03997 if (sscanf(day, "%d", &s) != 1) { 03998 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day); 03999 return 0; 04000 } 04001 if ((s < 1) || (s > 31)) { 04002 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day); 04003 return 0; 04004 } 04005 s--; 04006 if (c) { 04007 if (sscanf(c, "%d", &e) != 1) { 04008 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 04009 return 0; 04010 } 04011 if ((e < 1) || (e > 31)) { 04012 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 04013 return 0; 04014 } 04015 e--; 04016 } else 04017 e = s; 04018 mask = 0; 04019 for (x=s; x!=e; x = (x + 1) % 31) { 04020 mask |= (1 << x); 04021 } 04022 mask |= (1 << x); 04023 return mask; 04024 }
|
|
get_dow: Get day of week
Definition at line 3936 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and s. Referenced by ast_build_timing(). 03937 { 03938 char *c; 03939 /* The following line is coincidence, really! */ 03940 int s, e, x; 03941 unsigned int mask; 03942 03943 /* Check for all days */ 03944 if (ast_strlen_zero(dow) || !strcmp(dow, "*")) 03945 return (1 << 7) - 1; 03946 /* Get start and ending days */ 03947 c = strchr(dow, '-'); 03948 if (c) { 03949 *c = '\0'; 03950 c++; 03951 } else 03952 c = NULL; 03953 /* Find the start */ 03954 s = 0; 03955 while((s < 7) && strcasecmp(dow, days[s])) s++; 03956 if (s >= 7) { 03957 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", dow); 03958 return 0; 03959 } 03960 if (c) { 03961 e = 0; 03962 while((e < 7) && strcasecmp(c, days[e])) e++; 03963 if (e >= 7) { 03964 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 03965 return 0; 03966 } 03967 } else 03968 e = s; 03969 mask = 0; 03970 for (x=s; x != e; x = (x + 1) % 7) { 03971 mask |= (1 << x); 03972 } 03973 /* One last one */ 03974 mask |= (1 << x); 03975 return mask; 03976 }
|
|
Definition at line 4042 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and s. Referenced by ast_build_timing(). 04043 { 04044 char *c; 04045 /* The following line is coincidence, really! */ 04046 int s, e, x; 04047 unsigned int mask; 04048 04049 /* Check for all days */ 04050 if (ast_strlen_zero(mon) || !strcmp(mon, "*")) 04051 return (1 << 12) - 1; 04052 /* Get start and ending days */ 04053 c = strchr(mon, '-'); 04054 if (c) { 04055 *c = '\0'; 04056 c++; 04057 } 04058 /* Find the start */ 04059 s = 0; 04060 while((s < 12) && strcasecmp(mon, months[s])) s++; 04061 if (s >= 12) { 04062 ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", mon); 04063 return 0; 04064 } 04065 if (c) { 04066 e = 0; 04067 while((e < 12) && strcasecmp(c, months[e])) e++; 04068 if (e >= 12) { 04069 ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", c); 04070 return 0; 04071 } 04072 } else 04073 e = s; 04074 mask = 0; 04075 for (x=s; x!=e; x = (x + 1) % 12) { 04076 mask |= (1 << x); 04077 } 04078 /* One last one */ 04079 mask |= (1 << x); 04080 return mask; 04081 }
|
|
Definition at line 3840 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask. Referenced by ast_build_timing(). 03841 { 03842 char *e; 03843 int x; 03844 int s1, s2; 03845 int e1, e2; 03846 /* int cth, ctm; */ 03847 03848 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 03849 memset(i->minmask, 0, sizeof(i->minmask)); 03850 03851 /* Star is all times */ 03852 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 03853 for (x=0; x<24; x++) 03854 i->minmask[x] = (1 << 30) - 1; 03855 return; 03856 } 03857 /* Otherwise expect a range */ 03858 e = strchr(times, '-'); 03859 if (!e) { 03860 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n"); 03861 return; 03862 } 03863 *e = '\0'; 03864 e++; 03865 while(*e && !isdigit(*e)) 03866 e++; 03867 if (!*e) { 03868 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n"); 03869 return; 03870 } 03871 if (sscanf(times, "%d:%d", &s1, &s2) != 2) { 03872 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times); 03873 return; 03874 } 03875 if (sscanf(e, "%d:%d", &e1, &e2) != 2) { 03876 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e); 03877 return; 03878 } 03879 03880 #if 1 03881 s1 = s1 * 30 + s2/2; 03882 if ((s1 < 0) || (s1 >= 24*30)) { 03883 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times); 03884 return; 03885 } 03886 e1 = e1 * 30 + e2/2; 03887 if ((e1 < 0) || (e1 >= 24*30)) { 03888 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e); 03889 return; 03890 } 03891 /* Go through the time and enable each appropriate bit */ 03892 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) { 03893 i->minmask[x/30] |= (1 << (x % 30)); 03894 } 03895 /* Do the last one */ 03896 i->minmask[x/30] |= (1 << (x % 30)); 03897 #else 03898 for (cth=0; cth<24; cth++) { 03899 /* Initialize masks to blank */ 03900 i->minmask[cth] = 0; 03901 for (ctm=0; ctm<30; ctm++) { 03902 if ( 03903 /* First hour with more than one hour */ 03904 (((cth == s1) && (ctm >= s2)) && 03905 ((cth < e1))) 03906 /* Only one hour */ 03907 || (((cth == s1) && (ctm >= s2)) && 03908 ((cth == e1) && (ctm <= e2))) 03909 /* In between first and last hours (more than 2 hours) */ 03910 || ((cth > s1) && 03911 (cth < e1)) 03912 /* Last hour with more than one hour */ 03913 || ((cth > s1) && 03914 ((cth == e1) && (ctm <= e2))) 03915 ) 03916 i->minmask[cth] |= (1 << (ctm / 2)); 03917 } 03918 } 03919 #endif 03920 /* All done */ 03921 return; 03922 }
|
|
Definition at line 3051 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(). 03052 { 03053 struct ast_app *a; 03054 int app, no_registered_app = 1; 03055 03056 if (argc < 3) return RESULT_SHOWUSAGE; 03057 03058 /* try to lock applications list ... */ 03059 if (ast_mutex_lock(&applock)) { 03060 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03061 return -1; 03062 } 03063 03064 /* ... go through all applications ... */ 03065 a = apps; 03066 while (a) { 03067 /* ... compare this application name with all arguments given 03068 * to 'show application' command ... */ 03069 for (app = 2; app < argc; app++) { 03070 if (!strcasecmp(a->name, argv[app])) { 03071 /* Maximum number of characters added by terminal coloring is 22 */ 03072 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03073 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03074 int synopsis_size, description_size; 03075 03076 no_registered_app = 0; 03077 03078 if (a->synopsis) 03079 synopsis_size = strlen(a->synopsis) + 23; 03080 else 03081 synopsis_size = strlen("Not available") + 23; 03082 synopsis = alloca(synopsis_size); 03083 03084 if (a->description) 03085 description_size = strlen(a->description) + 23; 03086 else 03087 description_size = strlen("Not available") + 23; 03088 description = alloca(description_size); 03089 03090 if (synopsis && description) { 03091 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03092 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03093 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03094 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03095 term_color(synopsis, 03096 a->synopsis ? a->synopsis : "Not available", 03097 COLOR_CYAN, 0, synopsis_size); 03098 term_color(description, 03099 a->description ? a->description : "Not available", 03100 COLOR_CYAN, 0, description_size); 03101 03102 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03103 } else { 03104 /* ... one of our applications, show info ...*/ 03105 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03106 "[Synopsis]\n %s\n\n" 03107 "[Description]\n%s\n", 03108 a->name, 03109 a->synopsis ? a->synopsis : "Not available", 03110 a->description ? a->description : "Not available"); 03111 } 03112 } 03113 } 03114 a = a->next; 03115 } 03116 03117 ast_mutex_unlock(&applock); 03118 03119 /* we found at least one app? no? */ 03120 if (no_registered_app) { 03121 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03122 return RESULT_FAILURE; 03123 } 03124 03125 return RESULT_SUCCESS; 03126 }
|
|
Definition at line 3189 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(). 03190 { 03191 struct ast_app *a; 03192 int like=0, describing=0; 03193 int total_match = 0; /* Number of matches in like clause */ 03194 int total_apps = 0; /* Number of apps registered */ 03195 03196 /* try to lock applications list ... */ 03197 if (ast_mutex_lock(&applock)) { 03198 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03199 return -1; 03200 } 03201 03202 /* ... have we got at least one application (first)? no? */ 03203 if (!apps) { 03204 ast_cli(fd, "There are no registered applications\n"); 03205 ast_mutex_unlock(&applock); 03206 return -1; 03207 } 03208 03209 /* show applications like <keyword> */ 03210 if ((argc == 4) && (!strcmp(argv[2], "like"))) { 03211 like = 1; 03212 } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { 03213 describing = 1; 03214 } 03215 03216 /* show applications describing <keyword1> [<keyword2>] [...] */ 03217 if ((!like) && (!describing)) { 03218 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03219 } else { 03220 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03221 } 03222 03223 /* ... go through all applications ... */ 03224 for (a = apps; a; a = a->next) { 03225 /* ... show informations about applications ... */ 03226 int printapp=0; 03227 total_apps++; 03228 if (like) { 03229 if (strcasestr(a->name, argv[3])) { 03230 printapp = 1; 03231 total_match++; 03232 } 03233 } else if (describing) { 03234 if (a->description) { 03235 /* Match all words on command line */ 03236 int i; 03237 printapp = 1; 03238 for (i=3; i<argc; i++) { 03239 if (!strcasestr(a->description, argv[i])) { 03240 printapp = 0; 03241 } else { 03242 total_match++; 03243 } 03244 } 03245 } 03246 } else { 03247 printapp = 1; 03248 } 03249 03250 if (printapp) { 03251 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03252 } 03253 } 03254 if ((!like) && (!describing)) { 03255 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03256 } else { 03257 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03258 } 03259 03260 /* ... unlock and return */ 03261 ast_mutex_unlock(&applock); 03262 03263 return RESULT_SUCCESS; 03264 }
|
|
Definition at line 3529 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(). 03530 { 03531 char *exten = NULL, *context = NULL; 03532 /* Variables used for different counters */ 03533 struct dialplan_counters counters; 03534 char *incstack[AST_PBX_MAX_STACK]; 03535 memset(&counters, 0, sizeof(counters)); 03536 03537 if (argc != 2 && argc != 3) 03538 return RESULT_SHOWUSAGE; 03539 03540 /* we obtain [exten@]context? if yes, split them ... */ 03541 if (argc == 3) { 03542 char *splitter = ast_strdupa(argv[2]); 03543 /* is there a '@' character? */ 03544 if (splitter && strchr(argv[2], '@')) { 03545 /* yes, split into exten & context ... */ 03546 exten = strsep(&splitter, "@"); 03547 context = splitter; 03548 03549 /* check for length and change to NULL if ast_strlen_zero() */ 03550 if (ast_strlen_zero(exten)) 03551 exten = NULL; 03552 if (ast_strlen_zero(context)) 03553 context = NULL; 03554 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03555 } else { 03556 /* no '@' char, only context given */ 03557 context = argv[2]; 03558 if (ast_strlen_zero(context)) 03559 context = NULL; 03560 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03561 } 03562 } else { 03563 /* Show complete dial plan */ 03564 show_dialplan_helper(fd, NULL, NULL, &counters, NULL, 0, incstack); 03565 } 03566 03567 /* check for input failure and throw some error messages */ 03568 if (context && !counters.context_existence) { 03569 ast_cli(fd, "There is no existence of '%s' context\n", context); 03570 return RESULT_FAILURE; 03571 } 03572 03573 if (exten && !counters.extension_existence) { 03574 if (context) 03575 ast_cli(fd, "There is no existence of %s@%s extension\n", 03576 exten, context); 03577 else 03578 ast_cli(fd, 03579 "There is no existence of '%s' extension in all contexts\n", 03580 exten); 03581 return RESULT_FAILURE; 03582 } 03583 03584 ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", 03585 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions", 03586 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities", 03587 counters.total_context, counters.total_context == 1 ? "context" : "contexts"); 03588 03589 /* everything ok */ 03590 return RESULT_SUCCESS; 03591 }
|
|
Definition at line 1185 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(). 01186 { 01187 struct ast_custom_function *acf; 01188 /* Maximum number of characters added by terminal coloring is 22 */ 01189 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01190 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01191 char stxtitle[40], *syntax = NULL; 01192 int synopsis_size, description_size, syntax_size; 01193 01194 if (argc < 3) return RESULT_SHOWUSAGE; 01195 01196 if (!(acf = ast_custom_function_find(argv[2]))) { 01197 ast_cli(fd, "No function by that name registered.\n"); 01198 return RESULT_FAILURE; 01199 01200 } 01201 01202 if (acf->synopsis) 01203 synopsis_size = strlen(acf->synopsis) + 23; 01204 else 01205 synopsis_size = strlen("Not available") + 23; 01206 synopsis = alloca(synopsis_size); 01207 01208 if (acf->desc) 01209 description_size = strlen(acf->desc) + 23; 01210 else 01211 description_size = strlen("Not available") + 23; 01212 description = alloca(description_size); 01213 01214 if (acf->syntax) 01215 syntax_size = strlen(acf->syntax) + 23; 01216 else 01217 syntax_size = strlen("Not available") + 23; 01218 syntax = alloca(syntax_size); 01219 01220 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01221 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01222 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01223 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01224 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01225 term_color(syntax, 01226 acf->syntax ? acf->syntax : "Not available", 01227 COLOR_CYAN, 0, syntax_size); 01228 term_color(synopsis, 01229 acf->synopsis ? acf->synopsis : "Not available", 01230 COLOR_CYAN, 0, synopsis_size); 01231 term_color(description, 01232 acf->desc ? acf->desc : "Not available", 01233 COLOR_CYAN, 0, description_size); 01234 01235 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01236 01237 return RESULT_SUCCESS; 01238 }
|
|
Definition at line 1169 of file pbx.c. References acf_root, ast_cli(), ast_mutex_lock(), 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 ast_mutex_lock(&acflock); 01176 for (acf = acf_root ; acf; acf = acf->next) { 01177 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01178 count_acf++; 01179 } 01180 ast_mutex_unlock(&acflock); 01181 ast_cli(fd, "%d custom functions installed.\n", count_acf); 01182 return 0; 01183 }
|
|
handle_show_hints: CLI support for listing registred dial plan hints
Definition at line 3129 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. 03130 { 03131 struct ast_hint *hint; 03132 int num = 0; 03133 int watchers; 03134 struct ast_state_cb *watcher; 03135 03136 if (!hints) { 03137 ast_cli(fd, "There are no registered dialplan hints\n"); 03138 return RESULT_SUCCESS; 03139 } 03140 /* ... we have hints ... */ 03141 ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); 03142 if (ast_mutex_lock(&hintlock)) { 03143 ast_log(LOG_ERROR, "Unable to lock hints\n"); 03144 return -1; 03145 } 03146 hint = hints; 03147 while (hint) { 03148 watchers = 0; 03149 for (watcher = hint->callbacks; watcher; watcher = watcher->next) 03150 watchers++; 03151 ast_cli(fd, " %-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", 03152 ast_get_extension_name(hint->exten), ast_get_extension_app(hint->exten), 03153 ast_extension_state2str(hint->laststate), watchers); 03154 num++; 03155 hint = hint->next; 03156 } 03157 ast_cli(fd, "----------------\n"); 03158 ast_cli(fd, "- %d hints registered\n", num); 03159 ast_mutex_unlock(&hintlock); 03160 return RESULT_SUCCESS; 03161 }
|
|
handle_show_switches: CLI support for listing registred dial plan switches
Definition at line 3164 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. 03165 { 03166 struct ast_switch *sw; 03167 if (!switches) { 03168 ast_cli(fd, "There are no registered alternative switches\n"); 03169 return RESULT_SUCCESS; 03170 } 03171 /* ... we have applications ... */ 03172 ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); 03173 if (ast_mutex_lock(&switchlock)) { 03174 ast_log(LOG_ERROR, "Unable to lock switches\n"); 03175 return -1; 03176 } 03177 sw = switches; 03178 while (sw) { 03179 ast_cli(fd, "%s: %s\n", sw->name, sw->description); 03180 sw = sw->next; 03181 } 03182 ast_mutex_unlock(&switchlock); 03183 return RESULT_SUCCESS; 03184 }
|
|
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 2472 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(). 02473 { 02474 int failed = 0; 02475 double curloadavg; 02476 ast_mutex_lock(&maxcalllock); 02477 if (option_maxcalls) { 02478 if (countcalls >= option_maxcalls) { 02479 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name); 02480 failed = -1; 02481 } 02482 } 02483 if (option_maxload) { 02484 getloadavg(&curloadavg, 1); 02485 if (curloadavg >= option_maxload) { 02486 ast_log(LOG_NOTICE, "Maximum loadavg limit of %lf load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg); 02487 failed = -1; 02488 } 02489 } 02490 if (!failed) 02491 countcalls++; 02492 ast_mutex_unlock(&maxcalllock); 02493 02494 return failed; 02495 }
|
|
Definition at line 6239 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. 06240 { 06241 int x; 06242 06243 /* Initialize the PBX */ 06244 if (option_verbose) { 06245 ast_verbose( "Asterisk PBX Core Initializing\n"); 06246 ast_verbose( "Registering builtin applications:\n"); 06247 } 06248 AST_LIST_HEAD_INIT_NOLOCK(&globals); 06249 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(pbx_cli[0])); 06250 06251 /* Register builtin applications */ 06252 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06253 if (option_verbose) 06254 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06255 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06256 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06257 return -1; 06258 } 06259 } 06260 return 0; 06261 }
|
|
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 4635 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 6128 of file pbx.c. References AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), and ast_var_delete(). Referenced by reload(). 06129 { 06130 struct ast_var_t *vardata; 06131 06132 ast_mutex_lock(&globalslock); 06133 while ((vardata = AST_LIST_REMOVE_HEAD(&globals, entries))) 06134 ast_var_delete(vardata); 06135 ast_mutex_unlock(&globalslock); 06136 }
|
|
Definition at line 5923 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(), get_refer_info(), group_check_exec(), group_count_exec(), group_count_function_read(), group_function_read(), iax2_exec(), import_ch(), 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(). 05924 { 05925 struct ast_var_t *variables; 05926 char *ret = NULL; 05927 int i; 05928 struct varshead *places[2] = { NULL, &globals }; 05929 05930 if (!name) 05931 return NULL; 05932 if (chan) 05933 places[0] = &chan->varshead; 05934 05935 for (i = 0; i < 2; i++) { 05936 if (!places[i]) 05937 continue; 05938 if (places[i] == &globals) 05939 ast_mutex_lock(&globalslock); 05940 AST_LIST_TRAVERSE(places[i], variables, entries) { 05941 if (!strcmp(name, ast_var_name(variables))) { 05942 ret = ast_var_value(variables); 05943 break; 05944 } 05945 } 05946 if (places[i] == &globals) 05947 ast_mutex_unlock(&globalslock); 05948 if (ret) 05949 break; 05950 } 05951 05952 return ret; 05953 }
|
|
Definition at line 6157 of file pbx.c. References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_DEBUG, LOG_WARNING, pbx_builtin_goto(), pbx_checkcondition(), s, and strsep(). 06158 { 06159 char *condition, *branch1, *branch2, *branch; 06160 char *s; 06161 int rc; 06162 char *stringp=NULL; 06163 06164 if (ast_strlen_zero(data)) { 06165 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06166 return 0; 06167 } 06168 06169 s = ast_strdupa(data); 06170 stringp = s; 06171 condition = strsep(&stringp,"?"); 06172 branch1 = strsep(&stringp,":"); 06173 branch2 = strsep(&stringp,""); 06174 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06175 06176 if (ast_strlen_zero(branch)) { 06177 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06178 return 0; 06179 } 06180 06181 rc = pbx_builtin_goto(chan, branch); 06182 06183 return rc; 06184 }
|
|
Definition at line 6067 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. 06068 { 06069 char *name; 06070 char *value; 06071 char *stringp=NULL; 06072 char *channel; 06073 struct ast_channel *chan2; 06074 char tmp[VAR_BUF_SIZE]=""; 06075 char *s; 06076 06077 if (ast_strlen_zero(data)) { 06078 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06079 return 0; 06080 } 06081 06082 stringp = ast_strdupa(data); 06083 name = strsep(&stringp,"="); 06084 channel = strsep(&stringp,"|"); 06085 value = strsep(&stringp,"\0"); 06086 if (channel && value && name) { 06087 chan2 = ast_get_channel_by_name_locked(channel); 06088 if (chan2) { 06089 s = alloca(strlen(value) + 4); 06090 if (s) { 06091 sprintf(s, "${%s}", value); 06092 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 06093 } 06094 ast_mutex_unlock(&chan2->lock); 06095 } 06096 pbx_builtin_setvar_helper(chan, name, tmp); 06097 } 06098 06099 return(0); 06100 }
|
|
Definition at line 6122 of file pbx.c.
|
|
Definition at line 5955 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(). 05956 { 05957 struct ast_var_t *newvariable; 05958 struct varshead *headp; 05959 05960 if (name[strlen(name)-1] == ')') { 05961 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05962 return ast_func_write(chan, name, value); 05963 } 05964 05965 headp = (chan) ? &chan->varshead : &globals; 05966 05967 if (value) { 05968 if ((option_verbose > 1) && (headp == &globals)) 05969 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05970 newvariable = ast_var_assign(name, value); 05971 if (headp == &globals) 05972 ast_mutex_lock(&globalslock); 05973 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05974 if (headp == &globals) 05975 ast_mutex_unlock(&globalslock); 05976 } 05977 }
|
|
Definition at line 6221 of file pbx.c. References ast_say_character_str(), and ast_channel::language. 06222 { 06223 int res = 0; 06224 06225 if (data) 06226 res = ast_say_character_str(chan, (char *)data, "", chan->language); 06227 return res; 06228 }
|
|
Definition at line 6212 of file pbx.c. References ast_say_digit_str(), and ast_channel::language. 06213 { 06214 int res = 0; 06215 06216 if (data) 06217 res = ast_say_digit_str(chan, (char *)data, "", chan->language); 06218 return res; 06219 }
|
|
Definition at line 6186 of file pbx.c. References ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, LOG_WARNING, and strsep(). 06187 { 06188 int res = 0; 06189 char tmp[256]; 06190 char *number = (char *) NULL; 06191 char *options = (char *) NULL; 06192 06193 06194 if (ast_strlen_zero(data)) { 06195 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06196 return -1; 06197 } 06198 ast_copy_string(tmp, (char *) data, sizeof(tmp)); 06199 number=tmp; 06200 strsep(&number, "|"); 06201 options = strsep(&number, "|"); 06202 if (options) { 06203 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06204 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06205 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06206 return -1; 06207 } 06208 } 06209 return res = ast_say_number(chan, atoi((char *) tmp), "", chan->language, options); 06210 }
|
|
Definition at line 6230 of file pbx.c. References ast_say_phonetic_str(), and ast_channel::language. 06231 { 06232 int res = 0; 06233 06234 if (data) 06235 res = ast_say_phonetic_str(chan, (char *)data, "", chan->language); 06236 return res; 06237 }
|
|
Definition at line 5898 of file pbx.c. References ast_build_string(), AST_LIST_TRAVERSE, ast_log(), ast_var_name(), ast_var_value(), LOG_ERROR, total, var, and ast_channel::varshead. Referenced by dumpchan_exec(), and handle_showchan(). 05899 { 05900 struct ast_var_t *variables; 05901 char *var, *val; 05902 int total = 0; 05903 05904 if (!chan) 05905 return 0; 05906 05907 memset(buf, 0, size); 05908 05909 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05910 if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))) { 05911 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05912 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05913 break; 05914 } else 05915 total++; 05916 } else 05917 break; 05918 } 05919 05920 return total; 05921 }
|
|
Definition at line 6102 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, name, pbx_builtin_setvar_helper(), and strsep(). 06103 { 06104 char *name; 06105 char *value; 06106 char *stringp = NULL; 06107 06108 if (ast_strlen_zero(data)) { 06109 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06110 return 0; 06111 } 06112 06113 stringp = data; 06114 name = strsep(&stringp, "="); 06115 value = strsep(&stringp, "\0"); 06116 06117 pbx_builtin_setvar_helper(NULL, name, value); 06118 06119 return(0); 06120 }
|
|
Definition at line 6031 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(). 06032 { 06033 char *name, *value, *mydata; 06034 int argc; 06035 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 06036 int global = 0; 06037 int x; 06038 06039 if (ast_strlen_zero(data)) { 06040 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 06041 return 0; 06042 } 06043 06044 mydata = ast_strdupa(data); 06045 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 06046 06047 /* check for a trailing flags argument */ 06048 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 06049 argc--; 06050 if (strchr(argv[argc], 'g')) 06051 global = 1; 06052 } 06053 06054 for (x = 0; x < argc; x++) { 06055 name = argv[x]; 06056 if ((value = strchr(name, '='))) { 06057 *value = '\0'; 06058 value++; 06059 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 06060 } else 06061 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 06062 } 06063 06064 return(0); 06065 }
|
|
Definition at line 5979 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(), export_ch(), 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(), 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(), process_ast_dsp(), read_exec(), readfile_exec(), realtime_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(). 05980 { 05981 struct ast_var_t *newvariable; 05982 struct varshead *headp; 05983 const char *nametail = name; 05984 05985 if (name[strlen(name)-1] == ')') 05986 return ast_func_write(chan, name, value); 05987 05988 headp = (chan) ? &chan->varshead : &globals; 05989 05990 /* For comparison purposes, we have to strip leading underscores */ 05991 if (*nametail == '_') { 05992 nametail++; 05993 if (*nametail == '_') 05994 nametail++; 05995 } 05996 05997 if (headp == &globals) 05998 ast_mutex_lock(&globalslock); 05999 AST_LIST_TRAVERSE (headp, newvariable, entries) { 06000 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 06001 /* there is already such a variable, delete it */ 06002 AST_LIST_REMOVE(headp, newvariable, entries); 06003 ast_var_delete(newvariable); 06004 break; 06005 } 06006 } 06007 06008 if (value) { 06009 if ((option_verbose > 1) && (headp == &globals)) 06010 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 06011 newvariable = ast_var_assign(name, value); 06012 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 06013 } 06014 06015 if (headp == &globals) 06016 ast_mutex_unlock(&globalslock); 06017 }
|
|
Definition at line 6019 of file pbx.c. References ast_log(), LOG_WARNING, and pbx_builtin_setvar(). 06020 { 06021 static int deprecation_warning = 0; 06022 06023 if (!deprecation_warning) { 06024 ast_log(LOG_WARNING, "SetVar is deprecated, please use Set instead.\n"); 06025 deprecation_warning = 1; 06026 } 06027 06028 return pbx_builtin_setvar(chan, data); 06029 }
|
|
Definition at line 6138 of file pbx.c. Referenced by builtin_function_if(), execif_exec(), gosubif_exec(), macroif_exec(), and pbx_builtin_gotoif(). 06139 { 06140 if (condition) { 06141 if (*condition == '\0') { 06142 /* Empty strings are false */ 06143 return 0; 06144 } else if (*condition >= '0' && *condition <= '9') { 06145 /* Numbers are evaluated for truth */ 06146 return atoi(condition); 06147 } else { 06148 /* Strings are true */ 06149 return 1; 06150 } 06151 } else { 06152 /* NULL is also false */ 06153 return 0; 06154 } 06155 }
|
|
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 1621 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(). 01622 { 01623 struct ast_exten *e; 01624 struct ast_app *app; 01625 struct ast_switch *sw; 01626 char *data; 01627 const char *foundcontext=NULL; 01628 int newstack = 0; 01629 int res; 01630 int status = 0; 01631 char *incstack[AST_PBX_MAX_STACK]; 01632 char passdata[EXT_DATA_SIZE]; 01633 int stacklen = 0; 01634 char tmp[80]; 01635 char tmp2[80]; 01636 char tmp3[EXT_DATA_SIZE]; 01637 char atmp[80]; 01638 char atmp2[EXT_DATA_SIZE+100]; 01639 01640 if (ast_mutex_lock(&conlock)) { 01641 ast_log(LOG_WARNING, "Unable to obtain lock\n"); 01642 if ((action == HELPER_EXISTS) || (action == HELPER_CANMATCH) || (action == HELPER_MATCHMORE)) 01643 return 0; 01644 else 01645 return -1; 01646 } 01647 e = pbx_find_extension(c, con, context, exten, priority, label, callerid, action, incstack, &stacklen, &status, &sw, &data, &foundcontext); 01648 if (e) { 01649 switch(action) { 01650 case HELPER_CANMATCH: 01651 ast_mutex_unlock(&conlock); 01652 return -1; 01653 case HELPER_EXISTS: 01654 ast_mutex_unlock(&conlock); 01655 return -1; 01656 case HELPER_FINDLABEL: 01657 res = e->priority; 01658 ast_mutex_unlock(&conlock); 01659 return res; 01660 case HELPER_MATCHMORE: 01661 ast_mutex_unlock(&conlock); 01662 return -1; 01663 case HELPER_SPAWN: 01664 newstack++; 01665 /* Fall through */ 01666 case HELPER_EXEC: 01667 app = pbx_findapp(e->app); 01668 ast_mutex_unlock(&conlock); 01669 if (app) { 01670 if (c->context != context) 01671 ast_copy_string(c->context, context, sizeof(c->context)); 01672 if (c->exten != exten) 01673 ast_copy_string(c->exten, exten, sizeof(c->exten)); 01674 c->priority = priority; 01675 pbx_substitute_variables(passdata, sizeof(passdata), c, e); 01676 if (option_debug) { 01677 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name); 01678 snprintf(atmp, 80, "STACK-%s-%s-%d", context, exten, priority); 01679 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")); 01680 pbx_builtin_setvar_helper(c, atmp, atmp2); 01681 } 01682 if (option_verbose > 2) 01683 ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n", 01684 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)), 01685 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 01686 term_color(tmp3, (!ast_strlen_zero(passdata) ? (char *)passdata : ""), COLOR_BRMAGENTA, 0, sizeof(tmp3)), 01687 (newstack ? "in new stack" : "in same stack")); 01688 manager_event(EVENT_FLAG_CALL, "Newexten", 01689 "Channel: %s\r\n" 01690 "Context: %s\r\n" 01691 "Extension: %s\r\n" 01692 "Priority: %d\r\n" 01693 "Application: %s\r\n" 01694 "AppData: %s\r\n" 01695 "Uniqueid: %s\r\n", 01696 c->name, c->context, c->exten, c->priority, app->name, passdata ? passdata : "(NULL)", c->uniqueid); 01697 res = pbx_exec(c, app, passdata, newstack); 01698 return res; 01699 } else { 01700 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority); 01701 return -1; 01702 } 01703 default: 01704 ast_log(LOG_WARNING, "Huh (%d)?\n", action); return -1; 01705 } 01706 } else if (sw) { 01707 switch(action) { 01708 case HELPER_CANMATCH: 01709 ast_mutex_unlock(&conlock); 01710 return -1; 01711 case HELPER_EXISTS: 01712 ast_mutex_unlock(&conlock); 01713 return -1; 01714 case HELPER_MATCHMORE: 01715 ast_mutex_unlock(&conlock); 01716 return -1; 01717 case HELPER_FINDLABEL: 01718 ast_mutex_unlock(&conlock); 01719 return -1; 01720 case HELPER_SPAWN: 01721 newstack++; 01722 /* Fall through */ 01723 case HELPER_EXEC: 01724 ast_mutex_unlock(&conlock); 01725 if (sw->exec) 01726 res = sw->exec(c, foundcontext ? foundcontext : context, exten, priority, callerid, newstack, data); 01727 else { 01728 ast_log(LOG_WARNING, "No execution engine for switch %s\n", sw->name); 01729 res = -1; 01730 } 01731 return res; 01732 default: 01733 ast_log(LOG_WARNING, "Huh (%d)?\n", action); 01734 return -1; 01735 } 01736 } else { 01737 ast_mutex_unlock(&conlock); 01738 switch(status) { 01739 case STATUS_NO_CONTEXT: 01740 if ((action != HELPER_EXISTS) && (action != HELPER_MATCHMORE)) 01741 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context); 01742 break; 01743 case STATUS_NO_EXTENSION: 01744 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01745 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context); 01746 break; 01747 case STATUS_NO_PRIORITY: 01748 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01749 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context); 01750 break; 01751 case STATUS_NO_LABEL: 01752 if (context) 01753 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context); 01754 break; 01755 default: 01756 ast_log(LOG_DEBUG, "Shouldn't happen!\n"); 01757 } 01758 01759 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01760 return -1; 01761 else 01762 return 0; 01763 } 01764 01765 }
|
|
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 2567 of file pbx.c. Referenced by pbx_load_module(). 02568 { 02569 int oldval; 02570 oldval = autofallthrough; 02571 if (oldval != newval) 02572 autofallthrough = newval; 02573 return oldval; 02574 }
|
|
Definition at line 1608 of file pbx.c. References ast_exten::data, and pbx_substitute_variables_helper(). Referenced by pbx_extension_helper(). 01609 { 01610 memset(passdata, 0, datalen); 01611 01612 /* No variables or expressions in e->data, so why scan it? */ 01613 if (!strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) { 01614 ast_copy_string(passdata, e->data, datalen); 01615 return; 01616 } 01617 01618 pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1); 01619 }
|
|
Definition at line 1598 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(), pbx_builtin_importvar(), pbx_load_module(), pbx_substitute_variables(), realtime_exec(), sendmail(), and sendpage(). 01599 { 01600 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01601 }
|
|
Definition at line 1421 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(). 01422 { 01423 char *cp4; 01424 const char *tmp, *whereweare; 01425 int length, offset, offset2, isfunction; 01426 char *workspace = NULL; 01427 char *ltmp = NULL, *var = NULL; 01428 char *nextvar, *nextexp, *nextthing; 01429 char *vars, *vare; 01430 int pos, brackets, needsub, len; 01431 01432 /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be 01433 zero-filled */ 01434 whereweare=tmp=cp1; 01435 while(!ast_strlen_zero(whereweare) && count) { 01436 /* Assume we're copying the whole remaining string */ 01437 pos = strlen(whereweare); 01438 nextvar = NULL; 01439 nextexp = NULL; 01440 nextthing = strchr(whereweare, '$'); 01441 if (nextthing) { 01442 switch(nextthing[1]) { 01443 case '{': 01444 nextvar = nextthing; 01445 pos = nextvar - whereweare; 01446 break; 01447 case '[': 01448 nextexp = nextthing; 01449 pos = nextexp - whereweare; 01450 break; 01451 } 01452 } 01453 01454 if (pos) { 01455 /* Can't copy more than 'count' bytes */ 01456 if (pos > count) 01457 pos = count; 01458 01459 /* Copy that many bytes */ 01460 memcpy(cp2, whereweare, pos); 01461 01462 count -= pos; 01463 cp2 += pos; 01464 whereweare += pos; 01465 } 01466 01467 if (nextvar) { 01468 /* We have a variable. Find the start and end, and determine 01469 if we are going to have to recursively call ourselves on the 01470 contents */ 01471 vars = vare = nextvar + 2; 01472 brackets = 1; 01473 needsub = 0; 01474 01475 /* Find the end of it */ 01476 while (brackets && *vare) { 01477 if ((vare[0] == '$') && (vare[1] == '{')) { 01478 needsub++; 01479 } else if (vare[0] == '{') { 01480 brackets++; 01481 } else if (vare[0] == '}') { 01482 brackets--; 01483 } else if ((vare[0] == '$') && (vare[1] == '[')) 01484 needsub++; 01485 vare++; 01486 } 01487 if (brackets) 01488 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n"); 01489 len = vare - vars - 1; 01490 01491 /* Skip totally over variable string */ 01492 whereweare += (len + 3); 01493 01494 if (!var) 01495 var = alloca(VAR_BUF_SIZE); 01496 01497 /* Store variable name (and truncate) */ 01498 ast_copy_string(var, vars, len + 1); 01499 01500 /* Substitute if necessary */ 01501 if (needsub) { 01502 if (!ltmp) 01503 ltmp = alloca(VAR_BUF_SIZE); 01504 01505 memset(ltmp, 0, VAR_BUF_SIZE); 01506 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01507 vars = ltmp; 01508 } else { 01509 vars = var; 01510 } 01511 01512 if (!workspace) 01513 workspace = alloca(VAR_BUF_SIZE); 01514 01515 workspace[0] = '\0'; 01516 01517 parse_variable_name(vars, &offset, &offset2, &isfunction); 01518 if (isfunction) { 01519 /* Evaluate function */ 01520 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE); 01521 01522 ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)"); 01523 } else { 01524 /* Retrieve variable value */ 01525 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp); 01526 } 01527 if (cp4) { 01528 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE); 01529 01530 length = strlen(cp4); 01531 if (length > count) 01532 length = count; 01533 memcpy(cp2, cp4, length); 01534 count -= length; 01535 cp2 += length; 01536 } 01537 } else if (nextexp) { 01538 /* We have an expression. Find the start and end, and determine 01539 if we are going to have to recursively call ourselves on the 01540 contents */ 01541 vars = vare = nextexp + 2; 01542 brackets = 1; 01543 needsub = 0; 01544 01545 /* Find the end of it */ 01546 while(brackets && *vare) { 01547 if ((vare[0] == '$') && (vare[1] == '[')) { 01548 needsub++; 01549 brackets++; 01550 vare++; 01551 } else if (vare[0] == '[') { 01552 brackets++; 01553 } else if (vare[0] == ']') { 01554 brackets--; 01555 } else if ((vare[0] == '$') && (vare[1] == '{')) { 01556 needsub++; 01557 vare++; 01558 } 01559 vare++; 01560 } 01561 if (brackets) 01562 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n"); 01563 len = vare - vars - 1; 01564 01565 /* Skip totally over expression */ 01566 whereweare += (len + 3); 01567 01568 if (!var) 01569 var = alloca(VAR_BUF_SIZE); 01570 01571 /* Store variable name (and truncate) */ 01572 ast_copy_string(var, vars, len + 1); 01573 01574 /* Substitute if necessary */ 01575 if (needsub) { 01576 if (!ltmp) 01577 ltmp = alloca(VAR_BUF_SIZE); 01578 01579 memset(ltmp, 0, VAR_BUF_SIZE); 01580 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01581 vars = ltmp; 01582 } else { 01583 vars = var; 01584 } 01585 01586 length = ast_expr(vars, cp2, count); 01587 01588 if (length) { 01589 ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2); 01590 count -= length; 01591 cp2 += length; 01592 } 01593 } else 01594 break; 01595 } 01596 }
|
|
Definition at line 1603 of file pbx.c. References pbx_substitute_variables_helper_full(). Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_helper(). 01604 { 01605 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01606 }
|
|
Definition at line 2505 of file pbx.c. References __ast_pbx_run(), and decrease_call_count(). Referenced by ast_pbx_start(). 02506 { 02507 /* Oh joyeous kernel, we're a new thread, with nothing to do but 02508 answer this channel and get it going. 02509 */ 02510 /* NOTE: 02511 The launcher of this function _MUST_ increment 'countcalls' 02512 before invoking the function; it will be decremented when the 02513 PBX has finished running on the channel 02514 */ 02515 struct ast_channel *c = data; 02516 02517 __ast_pbx_run(c); 02518 decrease_call_count(); 02519 02520 pthread_exit(NULL); 02521 02522 return NULL; 02523 }
|
|
Definition at line 3342 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(). 03343 { 03344 struct ast_context *c; 03345 int res=0, old_total_exten = dpc->total_exten; 03346 03347 /* try to lock contexts */ 03348 if (ast_lock_contexts()) { 03349 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 03350 return -1; 03351 } 03352 03353 /* walk all contexts ... */ 03354 for (c = ast_walk_contexts(NULL); c ; c = ast_walk_contexts(c)) { 03355 /* show this context? */ 03356 if (!context || 03357 !strcmp(ast_get_context_name(c), context)) { 03358 dpc->context_existence = 1; 03359 03360 /* try to lock context before walking in ... */ 03361 if (!ast_lock_context(c)) { 03362 struct ast_exten *e; 03363 struct ast_include *i; 03364 struct ast_ignorepat *ip; 03365 struct ast_sw *sw; 03366 char buf[256], buf2[256]; 03367 int context_info_printed = 0; 03368 03369 /* are we looking for exten too? if yes, we print context 03370 * if we our extension only 03371 */ 03372 if (!exten) { 03373 dpc->total_context++; 03374 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03375 ast_get_context_name(c), ast_get_context_registrar(c)); 03376 context_info_printed = 1; 03377 } 03378 03379 /* walk extensions ... */ 03380 for (e = ast_walk_context_extensions(c, NULL); e; e = ast_walk_context_extensions(c, e)) { 03381 struct ast_exten *p; 03382 int prio; 03383 03384 /* looking for extension? is this our extension? */ 03385 if (exten && 03386 !ast_extension_match(ast_get_extension_name(e), exten)) 03387 { 03388 /* we are looking for extension and it's not our 03389 * extension, so skip to next extension */ 03390 continue; 03391 } 03392 03393 dpc->extension_existence = 1; 03394 03395 /* may we print context info? */ 03396 if (!context_info_printed) { 03397 dpc->total_context++; 03398 if (rinclude) { 03399 /* TODO Print more info about rinclude */ 03400 ast_cli(fd, "[ Included context '%s' created by '%s' ]\n", 03401 ast_get_context_name(c), 03402 ast_get_context_registrar(c)); 03403 } else { 03404 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03405 ast_get_context_name(c), 03406 ast_get_context_registrar(c)); 03407 } 03408 context_info_printed = 1; 03409 } 03410 dpc->total_prio++; 03411 03412 /* write extension name and first peer */ 03413 bzero(buf, sizeof(buf)); 03414 snprintf(buf, sizeof(buf), "'%s' =>", 03415 ast_get_extension_name(e)); 03416 03417 prio = ast_get_extension_priority(e); 03418 if (prio == PRIORITY_HINT) { 03419 snprintf(buf2, sizeof(buf2), 03420 "hint: %s", 03421 ast_get_extension_app(e)); 03422 } else { 03423 snprintf(buf2, sizeof(buf2), 03424 "%d. %s(%s)", 03425 prio, 03426 ast_get_extension_app(e), 03427 (char *)ast_get_extension_app_data(e)); 03428 } 03429 03430 ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2, 03431 ast_get_extension_registrar(e)); 03432 03433 dpc->total_exten++; 03434 /* walk next extension peers */ 03435 for (p=ast_walk_extension_priorities(e, e); p; p=ast_walk_extension_priorities(e, p)) { 03436 dpc->total_prio++; 03437 bzero((void *)buf2, sizeof(buf2)); 03438 bzero((void *)buf, sizeof(buf)); 03439 if (ast_get_extension_label(p)) 03440 snprintf(buf, sizeof(buf), " [%s]", ast_get_extension_label(p)); 03441 prio = ast_get_extension_priority(p); 03442 if (prio == PRIORITY_HINT) { 03443 snprintf(buf2, sizeof(buf2), 03444 "hint: %s", 03445 ast_get_extension_app(p)); 03446 } else { 03447 snprintf(buf2, sizeof(buf2), 03448 "%d. %s(%s)", 03449 prio, 03450 ast_get_extension_app(p), 03451 (char *)ast_get_extension_app_data(p)); 03452 } 03453 03454 ast_cli(fd," %-17s %-45s [%s]\n", 03455 buf, buf2, 03456 ast_get_extension_registrar(p)); 03457 } 03458 } 03459 03460 /* walk included and write info ... */ 03461 for (i = ast_walk_context_includes(c, NULL); i; i = ast_walk_context_includes(c, i)) { 03462 bzero(buf, sizeof(buf)); 03463 snprintf(buf, sizeof(buf), "'%s'", 03464 ast_get_include_name(i)); 03465 if (exten) { 03466 /* Check all includes for the requested extension */ 03467 if (includecount >= AST_PBX_MAX_STACK) { 03468 ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n"); 03469 } else { 03470 int dupe=0; 03471 int x; 03472 for (x=0;x<includecount;x++) { 03473 if (!strcasecmp(includes[x], ast_get_include_name(i))) { 03474 dupe++; 03475 break; 03476 } 03477 } 03478 if (!dupe) { 03479 includes[includecount] = (char *)ast_get_include_name(i); 03480 show_dialplan_helper(fd, (char *)ast_get_include_name(i), exten, dpc, i, includecount + 1, includes); 03481 } else { 03482 ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context); 03483 } 03484 } 03485 } else { 03486 ast_cli(fd, " Include => %-45s [%s]\n", 03487 buf, ast_get_include_registrar(i)); 03488 } 03489 } 03490 03491 /* walk ignore patterns and write info ... */ 03492 for (ip=ast_walk_context_ignorepats(c, NULL); ip; ip=ast_walk_context_ignorepats(c, ip)) { 03493 const char *ipname = ast_get_ignorepat_name(ip); 03494 char ignorepat[AST_MAX_EXTENSION]; 03495 snprintf(buf, sizeof(buf), "'%s'", ipname); 03496 snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname); 03497 if ((!exten) || ast_extension_match(ignorepat, exten)) { 03498 ast_cli(fd, " Ignore pattern => %-45s [%s]\n", 03499 buf, ast_get_ignorepat_registrar(ip)); 03500 } 03501 } 03502 if (!rinclude) { 03503 for (sw = ast_walk_context_switches(c, NULL); sw; sw = ast_walk_context_switches(c, sw)) { 03504 snprintf(buf, sizeof(buf), "'%s/%s'", 03505 ast_get_switch_name(sw), 03506 ast_get_switch_data(sw)); 03507 ast_cli(fd, " Alt. Switch => %-45s [%s]\n", 03508 buf, ast_get_switch_registrar(sw)); 03509 } 03510 } 03511 03512 ast_unlock_context(c); 03513 03514 /* if we print something in context, make an empty line */ 03515 if (context_info_printed) ast_cli(fd, "\r\n"); 03516 } 03517 } 03518 } 03519 ast_unlock_contexts(); 03520 03521 if (dpc->total_exten == old_total_exten) { 03522 /* Nothing new under the sun */ 03523 return -1; 03524 } else { 03525 return res; 03526 } 03527 }
|
|
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 5392 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(). 05393 { 05394 int res; 05395 struct ast_frame *f; 05396 int waittime; 05397 05398 if (ast_strlen_zero(data) || (sscanf(data, "%d", &waittime) != 1) || (waittime < 0)) 05399 waittime = -1; 05400 if (waittime > -1) { 05401 ast_safe_sleep(chan, waittime * 1000); 05402 } else do { 05403 res = ast_waitfor(chan, -1); 05404 if (res < 0) 05405 return; 05406 f = ast_read(chan); 05407 if (f) 05408 ast_frfree(f); 05409 } while(f); 05410 }
|
|
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 3924 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 3596 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(). |