#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) |
int | __ast_goto_if_exists (struct ast_channel *chan, char *context, char *exten, int priority, int async) |
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) |
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) |
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 | |
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) |
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) | |
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) |
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) |
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) |
void * | async_wait (void *data) |
char * | complete_show_application (char *line, char *word, int pos, int state) |
char * | complete_show_applications (char *line, char *word, int pos, int state) |
char * | complete_show_dialplan_context (char *line, char *word, int pos, int state) |
char * | complete_show_function (char *line, char *word, int pos, int state) |
void | decrease_call_count (void) |
void | destroy_exten (struct ast_exten *e) |
int | ext_strncpy (char *dst, const char *src, int len) |
unsigned int | get_day (char *day) |
unsigned int | get_dow (char *dow) |
get_dow: Get day of week | |
unsigned int | get_month (char *mon) |
void | get_timerange (struct ast_timing *i, char *times) |
int | handle_show_application (int fd, int argc, char *argv[]) |
int | handle_show_applications (int fd, int argc, char *argv[]) |
int | handle_show_dialplan (int fd, int argc, char *argv[]) |
int | handle_show_function (int fd, int argc, char *argv[]) |
int | handle_show_functions (int fd, int argc, char *argv[]) |
int | handle_show_hints (int fd, int argc, char *argv[]) |
handle_show_hints: CLI support for listing registred dial plan hints | |
int | handle_show_switches (int fd, int argc, char *argv[]) |
handle_show_switches: CLI support for listing registred dial plan switches | |
int | include_valid (struct ast_include *i) |
int | increase_call_count (const struct ast_channel *c) |
int | load_pbx (void) |
int | matchcid (const char *cidpattern, const char *callerid) |
void | null_datad (void *foo) |
int | parse_variable_name (char *var, int *offset, int *length, int *isfunc) |
int | pbx_builtin_answer (struct ast_channel *, void *) |
int | pbx_builtin_atimeout (struct ast_channel *, void *) |
int | pbx_builtin_background (struct ast_channel *, void *) |
int | pbx_builtin_busy (struct ast_channel *, void *) |
void | pbx_builtin_clear_globals (void) |
int | pbx_builtin_congestion (struct ast_channel *, void *) |
int | pbx_builtin_dtimeout (struct ast_channel *, void *) |
int | pbx_builtin_execiftime (struct ast_channel *, void *) |
char * | pbx_builtin_getvar_helper (struct ast_channel *chan, const char *name) |
int | pbx_builtin_goto (struct ast_channel *, void *) |
int | pbx_builtin_gotoif (struct ast_channel *, void *) |
int | pbx_builtin_gotoiftime (struct ast_channel *, void *) |
int | pbx_builtin_hangup (struct ast_channel *, void *) |
int | pbx_builtin_importvar (struct ast_channel *, void *) |
int | pbx_builtin_noop (struct ast_channel *, void *) |
int | pbx_builtin_progress (struct ast_channel *, void *) |
void | pbx_builtin_pushvar_helper (struct ast_channel *chan, const char *name, const char *value) |
int | pbx_builtin_resetcdr (struct ast_channel *, void *) |
int | pbx_builtin_ringing (struct ast_channel *, void *) |
int | pbx_builtin_rtimeout (struct ast_channel *, void *) |
int | pbx_builtin_saycharacters (struct ast_channel *, void *) |
int | pbx_builtin_saydigits (struct ast_channel *, void *) |
int | pbx_builtin_saynumber (struct ast_channel *, void *) |
int | pbx_builtin_sayphonetic (struct ast_channel *, void *) |
int | pbx_builtin_serialize_variables (struct ast_channel *chan, char *buf, size_t size) |
int | pbx_builtin_setaccount (struct ast_channel *, void *) |
int | pbx_builtin_setamaflags (struct ast_channel *, void *) |
int | pbx_builtin_setglobalvar (struct ast_channel *, void *) |
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) |
int | pbx_builtin_setvar_old (struct ast_channel *, void *) |
int | pbx_builtin_wait (struct ast_channel *, void *) |
int | pbx_builtin_waitexten (struct ast_channel *, void *) |
int | pbx_checkcondition (char *condition) |
void | pbx_destroy (struct ast_pbx *p) |
int | pbx_exec (struct ast_channel *c, struct ast_app *app, void *data, int newstack) |
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) |
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. | |
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) |
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) |
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) |
void * | pbx_thread (void *data) |
int | show_dialplan_helper (int fd, char *context, char *exten, struct dialplan_counters *dpc, struct ast_include *rinclude, int includecount, char *includes[]) |
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. | |
void | wait_for_hangup (struct ast_channel *chan, void *data) |
Variables | |
ast_custom_function * | acf_root = NULL |
ast_app * | apps = NULL |
int | autofallthrough = 0 |
pbx_builtin | builtins [] |
Declaration of builtin applications. | |
ast_context * | contexts = NULL |
int | countcalls = 0 |
char * | days [] |
varshead | globals |
ast_hint * | hints = NULL |
char * | months [] |
ast_cli_entry | pbx_cli [] |
char | show_application_help [] |
char | show_applications_help [] |
char | show_dialplan_help [] |
char | show_function_help [] |
char | show_functions_help [] |
char | show_hints_help [] |
char | show_switches_help [] |
ast_state_cb * | statecbs = NULL |
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 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 74 of file pbx.c. Referenced by pbx_extension_helper(). |
|
Definition at line 616 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 561 of file pbx.c. Referenced by ast_canmatch_extension(), and pbx_extension_helper(). |
|
Definition at line 560 of file pbx.c. Referenced by ast_exec_extension(), and pbx_extension_helper(). |
|
Definition at line 558 of file pbx.c. Referenced by ast_exists_extension(), ast_hint_extension(), and pbx_extension_helper(). |
|
Definition at line 563 of file pbx.c. Referenced by ast_findlabel_extension(), ast_findlabel_extension2(), and pbx_extension_helper(). |
|
Definition at line 562 of file pbx.c. Referenced by ast_matchmore_extension(), pbx_extension_helper(), and pbx_find_extension(). |
|
Definition at line 559 of file pbx.c. Referenced by ast_spawn_extension(), and pbx_extension_helper(). |
|
|
|
Definition at line 744 of file pbx.c. Referenced by pbx_extension_helper(). |
|
Definition at line 745 of file pbx.c. Referenced by pbx_extension_helper(). |
|
Definition at line 747 of file pbx.c. Referenced by pbx_extension_helper(). |
|
Definition at line 746 of file pbx.c. Referenced by pbx_extension_helper(). |
|
|
|
Definition at line 77 of file pbx.c. Referenced by pbx_find_extension(). |
|
Definition at line 79 of file pbx.c. Referenced by pbx_substitute_variables_helper_full(). |
|
|
|
|
|
|
|
Definition at line 97 of file pbx.c. Referenced by pbx_builtin_waitexten(). |
|
Definition at line 5283 of file pbx.c. References ast_context::alts, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), contexts, destroy_exten(), 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(), and ast_merge_contexts_and_delete(). 05284 { 05285 struct ast_context *tmp, *tmpl=NULL; 05286 struct ast_include *tmpi, *tmpil= NULL; 05287 struct ast_sw *sw, *swl= NULL; 05288 struct ast_exten *e, *el, *en; 05289 struct ast_ignorepat *ipi, *ipl = NULL; 05290 05291 ast_mutex_lock(&conlock); 05292 tmp = contexts; 05293 while(tmp) { 05294 if (((tmp->name && con && con->name && !strcasecmp(tmp->name, con->name)) || !con) && 05295 (!registrar || !strcasecmp(registrar, tmp->registrar))) { 05296 /* Okay, let's lock the structure to be sure nobody else 05297 is searching through it. */ 05298 if (ast_mutex_lock(&tmp->lock)) { 05299 ast_log(LOG_WARNING, "Unable to lock context lock\n"); 05300 return; 05301 } 05302 if (tmpl) 05303 tmpl->next = tmp->next; 05304 else 05305 contexts = tmp->next; 05306 /* Okay, now we're safe to let it go -- in a sense, we were 05307 ready to let it go as soon as we locked it. */ 05308 ast_mutex_unlock(&tmp->lock); 05309 for (tmpi = tmp->includes; tmpi; ) { 05310 /* Free includes */ 05311 tmpil = tmpi; 05312 tmpi = tmpi->next; 05313 free(tmpil); 05314 } 05315 for (ipi = tmp->ignorepats; ipi; ) { 05316 /* Free ignorepats */ 05317 ipl = ipi; 05318 ipi = ipi->next; 05319 free(ipl); 05320 } 05321 for (sw = tmp->alts; sw; ) { 05322 /* Free switches */ 05323 swl = sw; 05324 sw = sw->next; 05325 free(swl); 05326 swl = sw; 05327 } 05328 for (e = tmp->root; e;) { 05329 for (en = e->peer; en;) { 05330 el = en; 05331 en = en->peer; 05332 destroy_exten(el); 05333 } 05334 el = e; 05335 e = e->next; 05336 destroy_exten(el); 05337 } 05338 ast_mutex_destroy(&tmp->lock); 05339 free(tmp); 05340 if (!con) { 05341 /* Might need to get another one -- restart */ 05342 tmp = contexts; 05343 tmpl = NULL; 05344 tmpil = NULL; 05345 continue; 05346 } 05347 ast_mutex_unlock(&conlock); 05348 return; 05349 } 05350 tmpl = tmp; 05351 tmp = tmp->next; 05352 } 05353 ast_mutex_unlock(&conlock); 05354 }
|
|
Definition at line 6405 of file pbx.c. References ast_async_goto(), ast_exists_extension(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, and ast_channel::exten. Referenced by ast_async_goto_if_exists(), and ast_goto_if_exists(). 06406 { 06407 int (*goto_func)(struct ast_channel *chan, const char *context, const char *exten, int priority); 06408 06409 if (!chan) 06410 return -2; 06411 06412 goto_func = (async) ? ast_async_goto : ast_explicit_goto; 06413 if (ast_exists_extension(chan, context ? context : chan->context, 06414 exten ? exten : chan->exten, priority, 06415 chan->cid.cid_num)) 06416 return goto_func(chan, context ? context : chan->context, 06417 exten ? exten : chan->exten, priority); 06418 else 06419 return -3; 06420 }
|
|
Definition at line 2226 of file pbx.c. References ast_channel::_softhangup, ast_channel::amaflags, ast_cdr_alloc(), ast_cdr_init(), ast_cdr_start(), ast_cdr_update(), ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, ast_hangup(), ast_log(), ast_matchmore_extension(), AST_PBX_KEEPALIVE, ast_set2_flag, ast_set_flag, ast_spawn_extension(), ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_waitfordigit(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_pbx::dtimeout, ast_channel::exten, free, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, ast_channel::pbx, pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_destroy(), ast_channel::priority, ast_pbx::rtimeout, ast_cdr::start, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and ast_channel::whentohangup. Referenced by ast_pbx_run(), and pbx_thread(). 02227 { 02228 int firstpass = 1; 02229 int digit; 02230 char exten[256]; 02231 int pos; 02232 int waittime; 02233 int res=0; 02234 int autoloopflag; 02235 02236 /* A little initial setup here */ 02237 if (c->pbx) 02238 ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name); 02239 c->pbx = malloc(sizeof(struct ast_pbx)); 02240 if (!c->pbx) { 02241 ast_log(LOG_ERROR, "Out of memory\n"); 02242 return -1; 02243 } 02244 if (c->amaflags) { 02245 if (!c->cdr) { 02246 c->cdr = ast_cdr_alloc(); 02247 if (!c->cdr) { 02248 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 02249 free(c->pbx); 02250 return -1; 02251 } 02252 ast_cdr_init(c->cdr, c); 02253 } 02254 } 02255 memset(c->pbx, 0, sizeof(struct ast_pbx)); 02256 /* Set reasonable defaults */ 02257 c->pbx->rtimeout = 10; 02258 c->pbx->dtimeout = 5; 02259 02260 autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP); 02261 ast_set_flag(c, AST_FLAG_IN_AUTOLOOP); 02262 02263 /* Start by trying whatever the channel is set to */ 02264 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02265 /* If not successful fall back to 's' */ 02266 if (option_verbose > 1) 02267 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); 02268 ast_copy_string(c->exten, "s", sizeof(c->exten)); 02269 if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02270 /* JK02: And finally back to default if everything else failed */ 02271 if (option_verbose > 1) 02272 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); 02273 ast_copy_string(c->context, "default", sizeof(c->context)); 02274 } 02275 c->priority = 1; 02276 } 02277 if (c->cdr && !c->cdr->start.tv_sec && !c->cdr->start.tv_usec) 02278 ast_cdr_start(c->cdr); 02279 for(;;) { 02280 pos = 0; 02281 digit = 0; 02282 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02283 memset(exten, 0, sizeof(exten)); 02284 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02285 /* Something bad happened, or a hangup has been requested. */ 02286 if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) || 02287 (res == '*') || (res == '#')) { 02288 ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res); 02289 memset(exten, 0, sizeof(exten)); 02290 pos = 0; 02291 exten[pos++] = digit = res; 02292 break; 02293 } 02294 switch(res) { 02295 case AST_PBX_KEEPALIVE: 02296 if (option_debug) 02297 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02298 else if (option_verbose > 1) 02299 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name); 02300 goto out; 02301 break; 02302 default: 02303 if (option_debug) 02304 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02305 else if (option_verbose > 1) 02306 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02307 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02308 c->_softhangup =0; 02309 break; 02310 } 02311 /* atimeout */ 02312 if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02313 break; 02314 } 02315 02316 if (c->cdr) { 02317 ast_cdr_update(c); 02318 } 02319 goto out; 02320 } 02321 } 02322 if ((c->_softhangup == AST_SOFTHANGUP_TIMEOUT) && (ast_exists_extension(c,c->context,"T",1,c->cid.cid_num))) { 02323 ast_copy_string(c->exten, "T", sizeof(c->exten)); 02324 /* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */ 02325 c->whentohangup = 0; 02326 c->priority = 0; 02327 c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT; 02328 } else if (c->_softhangup) { 02329 ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n", 02330 c->exten, c->priority); 02331 goto out; 02332 } 02333 firstpass = 0; 02334 c->priority++; 02335 } 02336 if (!ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) { 02337 /* It's not a valid extension anymore */ 02338 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02339 if (option_verbose > 2) 02340 ast_verbose(VERBOSE_PREFIX_3 "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name); 02341 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten); 02342 ast_copy_string(c->exten, "i", sizeof(c->exten)); 02343 c->priority = 1; 02344 } else { 02345 ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n", 02346 c->name, c->exten, c->context); 02347 goto out; 02348 } 02349 } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) { 02350 /* If we get this far with AST_SOFTHANGUP_TIMEOUT, then we know that the "T" extension is next. */ 02351 c->_softhangup = 0; 02352 } else { 02353 /* Done, wait for an extension */ 02354 waittime = 0; 02355 if (digit) 02356 waittime = c->pbx->dtimeout; 02357 else if (!autofallthrough) 02358 waittime = c->pbx->rtimeout; 02359 if (waittime) { 02360 while (ast_matchmore_extension(c, c->context, exten, 1, c->cid.cid_num)) { 02361 /* As long as we're willing to wait, and as long as it's not defined, 02362 keep reading digits until we can't possibly get a right answer anymore. */ 02363 digit = ast_waitfordigit(c, waittime * 1000); 02364 if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) { 02365 c->_softhangup = 0; 02366 } else { 02367 if (!digit) 02368 /* No entry */ 02369 break; 02370 if (digit < 0) 02371 /* Error, maybe a hangup */ 02372 goto out; 02373 exten[pos++] = digit; 02374 waittime = c->pbx->dtimeout; 02375 } 02376 } 02377 if (ast_exists_extension(c, c->context, exten, 1, c->cid.cid_num)) { 02378 /* Prepare the next cycle */ 02379 ast_copy_string(c->exten, exten, sizeof(c->exten)); 02380 c->priority = 1; 02381 } else { 02382 /* No such extension */ 02383 if (!ast_strlen_zero(exten)) { 02384 /* An invalid extension */ 02385 if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) { 02386 if (option_verbose > 2) 02387 ast_verbose( VERBOSE_PREFIX_3 "Invalid extension '%s' in context '%s' on %s\n", exten, c->context, c->name); 02388 pbx_builtin_setvar_helper(c, "INVALID_EXTEN", exten); 02389 ast_copy_string(c->exten, "i", sizeof(c->exten)); 02390 c->priority = 1; 02391 } else { 02392 ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", exten, c->context); 02393 goto out; 02394 } 02395 } else { 02396 /* A simple timeout */ 02397 if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) { 02398 if (option_verbose > 2) 02399 ast_verbose( VERBOSE_PREFIX_3 "Timeout on %s\n", c->name); 02400 ast_copy_string(c->exten, "t", sizeof(c->exten)); 02401 c->priority = 1; 02402 } else { 02403 ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context); 02404 goto out; 02405 } 02406 } 02407 } 02408 if (c->cdr) { 02409 if (option_verbose > 2) 02410 ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name); 02411 ast_cdr_update(c); 02412 } 02413 } else { 02414 char *status; 02415 02416 status = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 02417 if (!status) 02418 status = "UNKNOWN"; 02419 if (option_verbose > 2) 02420 ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status); 02421 if (!strcasecmp(status, "CONGESTION")) 02422 res = pbx_builtin_congestion(c, "10"); 02423 else if (!strcasecmp(status, "CHANUNAVAIL")) 02424 res = pbx_builtin_congestion(c, "10"); 02425 else if (!strcasecmp(status, "BUSY")) 02426 res = pbx_builtin_busy(c, "10"); 02427 goto out; 02428 } 02429 } 02430 } 02431 if (firstpass) 02432 ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); 02433 out: 02434 if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) { 02435 c->exten[0] = 'h'; 02436 c->exten[1] = '\0'; 02437 c->priority = 1; 02438 while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) { 02439 if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) { 02440 /* Something bad happened, or a hangup has been requested. */ 02441 if (option_debug) 02442 ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02443 else if (option_verbose > 1) 02444 ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name); 02445 break; 02446 } 02447 c->priority++; 02448 } 02449 } 02450 ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP); 02451 02452 pbx_destroy(c->pbx); 02453 c->pbx = NULL; 02454 if (res != AST_PBX_KEEPALIVE) 02455 ast_hangup(c); 02456 return 0; 02457 }
|
|
Definition at line 2550 of file pbx.c. Referenced by handle_chanlist(). 02551 {
02552 return countcalls;
02553 }
|
|
Definition at line 4484 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(). 04486 { 04487 struct ast_context *c; 04488 04489 if (ast_lock_contexts()) { 04490 errno = EBUSY; 04491 return -1; 04492 } 04493 04494 c = ast_walk_contexts(NULL); 04495 while (c) { 04496 if (!strcmp(context, ast_get_context_name(c))) { 04497 int ret = ast_add_extension2(c, replace, extension, priority, label, callerid, 04498 application, data, datad, registrar); 04499 ast_unlock_contexts(); 04500 return ret; 04501 } 04502 c = ast_walk_contexts(c); 04503 } 04504 04505 ast_unlock_contexts(); 04506 errno = ENOENT; 04507 return -1; 04508 }
|
|
For details about the arguements, check ast_add_extension() Definition at line 4623 of file pbx.c. References ast_exten::app, 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, ext_strncpy(), ast_exten::exten, free, globals, ast_exten::label, ast_context::lock, LOG_ERROR, LOG_WARNING, malloc, ast_exten::matchcid, ast_context::name, ast_exten::next, ast_exten::parent, pbx_substitute_variables_varshead(), ast_exten::peer, ast_exten::priority, ast_exten::registrar, ast_context::root, and ast_exten::stuff. Referenced by __build_step(), ast_add_extension(), ast_park_call(), do_parking_thread(), fillin_process(), handle_macro(), load_config(), and pbx_load_module(). 04627 { 04628 04629 #define LOG do { if (option_debug) {\ 04630 if (tmp->matchcid) { \ 04631 ast_log(LOG_DEBUG, "Added extension '%s' priority %d (CID match '%s') to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \ 04632 } else { \ 04633 ast_log(LOG_DEBUG, "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \ 04634 } \ 04635 } else if (option_verbose > 2) { \ 04636 if (tmp->matchcid) { \ 04637 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d (CID match '%s')to %s\n", tmp->exten, tmp->priority, tmp->cidmatch, con->name); \ 04638 } else { \ 04639 ast_verbose( VERBOSE_PREFIX_3 "Added extension '%s' priority %d to %s\n", tmp->exten, tmp->priority, con->name); \ 04640 } \ 04641 } } while(0) 04642 04643 /* 04644 * This is a fairly complex routine. Different extensions are kept 04645 * in order by the extension number. Then, extensions of different 04646 * priorities (same extension) are kept in a list, according to the 04647 * peer pointer. 04648 */ 04649 struct ast_exten *tmp, *e, *el = NULL, *ep = NULL; 04650 int res; 04651 int length; 04652 char *p; 04653 char expand_buf[VAR_BUF_SIZE] = { 0, }; 04654 04655 /* if we are adding a hint, and there are global variables, and the hint 04656 contains variable references, then expand them 04657 */ 04658 if ((priority == PRIORITY_HINT) && AST_LIST_FIRST(&globals) && strstr(application, "${")) { 04659 pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); 04660 application = expand_buf; 04661 } 04662 04663 length = sizeof(struct ast_exten); 04664 length += strlen(extension) + 1; 04665 length += strlen(application) + 1; 04666 if (label) 04667 length += strlen(label) + 1; 04668 if (callerid) 04669 length += strlen(callerid) + 1; 04670 else 04671 length ++; 04672 04673 /* Be optimistic: Build the extension structure first */ 04674 if (datad == NULL) 04675 datad = null_datad; 04676 tmp = malloc(length); 04677 if (tmp) { 04678 memset(tmp, 0, length); 04679 p = tmp->stuff; 04680 if (label) { 04681 tmp->label = p; 04682 strcpy(tmp->label, label); 04683 p += strlen(label) + 1; 04684 } 04685 tmp->exten = p; 04686 p += ext_strncpy(tmp->exten, extension, strlen(extension) + 1) + 1; 04687 tmp->priority = priority; 04688 tmp->cidmatch = p; 04689 if (callerid) { 04690 p += ext_strncpy(tmp->cidmatch, callerid, strlen(callerid) + 1) + 1; 04691 tmp->matchcid = 1; 04692 } else { 04693 tmp->cidmatch[0] = '\0'; 04694 tmp->matchcid = 0; 04695 p++; 04696 } 04697 tmp->app = p; 04698 strcpy(tmp->app, application); 04699 tmp->parent = con; 04700 tmp->data = data; 04701 tmp->datad = datad; 04702 tmp->registrar = registrar; 04703 tmp->peer = NULL; 04704 tmp->next = NULL; 04705 } else { 04706 ast_log(LOG_ERROR, "Out of memory\n"); 04707 errno = ENOMEM; 04708 return -1; 04709 } 04710 if (ast_mutex_lock(&con->lock)) { 04711 free(tmp); 04712 /* And properly destroy the data */ 04713 datad(data); 04714 ast_log(LOG_WARNING, "Failed to lock context '%s'\n", con->name); 04715 errno = EBUSY; 04716 return -1; 04717 } 04718 e = con->root; 04719 while(e) { 04720 /* Make sure patterns are always last! */ 04721 if ((e->exten[0] != '_') && (extension[0] == '_')) 04722 res = -1; 04723 else if ((e->exten[0] == '_') && (extension[0] != '_')) 04724 res = 1; 04725 else 04726 res= strcmp(e->exten, extension); 04727 if (!res) { 04728 if (!e->matchcid && !tmp->matchcid) 04729 res = 0; 04730 else if (tmp->matchcid && !e->matchcid) 04731 res = 1; 04732 else if (e->matchcid && !tmp->matchcid) 04733 res = -1; 04734 else 04735 res = strcasecmp(e->cidmatch, tmp->cidmatch); 04736 } 04737 if (res == 0) { 04738 /* We have an exact match, now we find where we are 04739 and be sure there's no duplicates */ 04740 while(e) { 04741 if (e->priority == tmp->priority) { 04742 /* Can't have something exactly the same. Is this a 04743 replacement? If so, replace, otherwise, bonk. */ 04744 if (replace) { 04745 if (ep) { 04746 /* We're in the peer list, insert ourselves */ 04747 ep->peer = tmp; 04748 tmp->peer = e->peer; 04749 } else if (el) { 04750 /* We're the first extension. Take over e's functions */ 04751 el->next = tmp; 04752 tmp->next = e->next; 04753 tmp->peer = e->peer; 04754 } else { 04755 /* We're the very first extension. */ 04756 con->root = tmp; 04757 tmp->next = e->next; 04758 tmp->peer = e->peer; 04759 } 04760 if (tmp->priority == PRIORITY_HINT) 04761 ast_change_hint(e,tmp); 04762 /* Destroy the old one */ 04763 e->datad(e->data); 04764 free(e); 04765 ast_mutex_unlock(&con->lock); 04766 if (tmp->priority == PRIORITY_HINT) 04767 ast_change_hint(e, tmp); 04768 /* And immediately return success. */ 04769 LOG; 04770 return 0; 04771 } else { 04772 ast_log(LOG_WARNING, "Unable to register extension '%s', priority %d in '%s', already in use\n", tmp->exten, tmp->priority, con->name); 04773 tmp->datad(tmp->data); 04774 free(tmp); 04775 ast_mutex_unlock(&con->lock); 04776 errno = EEXIST; 04777 return -1; 04778 } 04779 } else if (e->priority > tmp->priority) { 04780 /* Slip ourselves in just before e */ 04781 if (ep) { 04782 /* Easy enough, we're just in the peer list */ 04783 ep->peer = tmp; 04784 tmp->peer = e; 04785 } else if (el) { 04786 /* We're the first extension in this peer list */ 04787 el->next = tmp; 04788 tmp->next = e->next; 04789 e->next = NULL; 04790 tmp->peer = e; 04791 } else { 04792 /* We're the very first extension altogether */ 04793 tmp->next = con->root->next; 04794 /* Con->root must always exist or we couldn't get here */ 04795 tmp->peer = con->root; 04796 con->root = tmp; 04797 } 04798 ast_mutex_unlock(&con->lock); 04799 04800 /* And immediately return success. */ 04801 if (tmp->priority == PRIORITY_HINT) 04802 ast_add_hint(tmp); 04803 04804 LOG; 04805 return 0; 04806 } 04807 ep = e; 04808 e = e->peer; 04809 } 04810 /* If we make it here, then it's time for us to go at the very end. 04811 ep *must* be defined or we couldn't have gotten here. */ 04812 ep->peer = tmp; 04813 ast_mutex_unlock(&con->lock); 04814 if (tmp->priority == PRIORITY_HINT) 04815 ast_add_hint(tmp); 04816 04817 /* And immediately return success. */ 04818 LOG; 04819 return 0; 04820 04821 } else if (res > 0) { 04822 /* Insert ourselves just before 'e'. We're the first extension of 04823 this kind */ 04824 tmp->next = e; 04825 if (el) { 04826 /* We're in the list somewhere */ 04827 el->next = tmp; 04828 } else { 04829 /* We're at the top of the list */ 04830 con->root = tmp; 04831 } 04832 ast_mutex_unlock(&con->lock); 04833 if (tmp->priority == PRIORITY_HINT) 04834 ast_add_hint(tmp); 04835 04836 /* And immediately return success. */ 04837 LOG; 04838 return 0; 04839 } 04840 04841 el = e; 04842 e = e->next; 04843 } 04844 /* If we fall all the way through to here, then we need to be on the end. */ 04845 if (el) 04846 el->next = tmp; 04847 else 04848 con->root = tmp; 04849 ast_mutex_unlock(&con->lock); 04850 if (tmp->priority == PRIORITY_HINT) 04851 ast_add_hint(tmp); 04852 LOG; 04853 return 0; 04854 }
|
|
ast_add_hint: Add hint to hint list, check initial extension state
Definition at line 2063 of file pbx.c. References ast_extension_state2(), ast_get_extension_app(), ast_get_extension_name(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_hint::exten, hints, ast_hint::laststate, LOG_DEBUG, malloc, ast_hint::next, and option_debug. Referenced by ast_add_extension2(). 02064 { 02065 struct ast_hint *list; 02066 02067 if (!e) 02068 return -1; 02069 02070 ast_mutex_lock(&hintlock); 02071 list = hints; 02072 02073 /* Search if hint exists, do nothing */ 02074 while (list) { 02075 if (list->exten == e) { 02076 ast_mutex_unlock(&hintlock); 02077 if (option_debug > 1) 02078 ast_log(LOG_DEBUG, "HINTS: Not re-adding existing hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02079 return -1; 02080 } 02081 list = list->next; 02082 } 02083 02084 if (option_debug > 1) 02085 ast_log(LOG_DEBUG, "HINTS: Adding hint %s: %s\n", ast_get_extension_name(e), ast_get_extension_app(e)); 02086 02087 list = malloc(sizeof(struct ast_hint)); 02088 if (!list) { 02089 ast_mutex_unlock(&hintlock); 02090 if (option_debug > 1) 02091 ast_log(LOG_DEBUG, "HINTS: Out of memory...\n"); 02092 return -1; 02093 } 02094 /* Initialize and insert new item at the top */ 02095 memset(list, 0, sizeof(struct ast_hint)); 02096 list->exten = e; 02097 list->laststate = ast_extension_state2(e); 02098 list->next = hints; 02099 hints = list; 02100 02101 ast_mutex_unlock(&hintlock); 02102 return 0; 02103 }
|
|
|
|
|
|
|
|
Definition at line 4529 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(), i4l_read(), misdn_tx2ast_frm(), monitor_handle_owned(), socket_read(), and zt_read(). 04530 { 04531 int res = 0; 04532 04533 ast_mutex_lock(&chan->lock); 04534 04535 if (chan->pbx) { 04536 /* This channel is currently in the PBX */ 04537 ast_explicit_goto(chan, context, exten, priority); 04538 ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO); 04539 } else { 04540 /* In order to do it when the channel doesn't really exist within 04541 the PBX, we have to make a new channel, masquerade, and start the PBX 04542 at the new location */ 04543 struct ast_channel *tmpchan; 04544 tmpchan = ast_channel_alloc(0); 04545 if (tmpchan) { 04546 snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name); 04547 ast_setstate(tmpchan, chan->_state); 04548 /* Make formats okay */ 04549 tmpchan->readformat = chan->readformat; 04550 tmpchan->writeformat = chan->writeformat; 04551 /* Setup proper location */ 04552 ast_explicit_goto(tmpchan, 04553 (!ast_strlen_zero(context)) ? context : chan->context, 04554 (!ast_strlen_zero(exten)) ? exten : chan->exten, 04555 priority); 04556 04557 /* Masquerade into temp channel */ 04558 ast_channel_masquerade(tmpchan, chan); 04559 04560 /* Grab the locks and get going */ 04561 ast_mutex_lock(&tmpchan->lock); 04562 ast_do_masquerade(tmpchan); 04563 ast_mutex_unlock(&tmpchan->lock); 04564 /* Start the PBX going on our stolen channel */ 04565 if (ast_pbx_start(tmpchan)) { 04566 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmpchan->name); 04567 ast_hangup(tmpchan); 04568 res = -1; 04569 } 04570 } else { 04571 res = -1; 04572 } 04573 } 04574 ast_mutex_unlock(&chan->lock); 04575 return res; 04576 }
|
|
Definition at line 4578 of file pbx.c. References ast_async_goto(), ast_get_channel_by_name_locked(), ast_mutex_unlock(), and ast_channel::lock. 04579 { 04580 struct ast_channel *chan; 04581 int res = -1; 04582 04583 chan = ast_get_channel_by_name_locked(channame); 04584 if (chan) { 04585 res = ast_async_goto(chan, context, exten, priority); 04586 ast_mutex_unlock(&chan->lock); 04587 } 04588 return res; 04589 }
|
|
Definition at line 6426 of file pbx.c. References __ast_goto_if_exists(). 06426 { 06427 return __ast_goto_if_exists(chan, context, exten, priority, 1); 06428 }
|
|
Definition at line 4062 of file pbx.c. References ast_strlen_zero(), ast_timing::daymask, ast_timing::dowmask, 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(). 04063 { 04064 char info_save[256]; 04065 char *info; 04066 char *c; 04067 04068 /* Check for empty just in case */ 04069 if (ast_strlen_zero(info_in)) 04070 return 0; 04071 /* make a copy just in case we were passed a static string */ 04072 ast_copy_string(info_save, info_in, sizeof(info_save)); 04073 info = info_save; 04074 /* Assume everything except time */ 04075 i->monthmask = (1 << 12) - 1; 04076 i->daymask = (1 << 30) - 1 + (1 << 30); 04077 i->dowmask = (1 << 7) - 1; 04078 /* Avoid using str tok */ 04079 FIND_NEXT; 04080 /* Info has the time range, start with that */ 04081 get_timerange(i, info); 04082 info = c; 04083 if (!info) 04084 return 1; 04085 FIND_NEXT; 04086 /* Now check for day of week */ 04087 i->dowmask = get_dow(info); 04088 04089 info = c; 04090 if (!info) 04091 return 1; 04092 FIND_NEXT; 04093 /* Now check for the day of the month */ 04094 i->daymask = get_day(info); 04095 info = c; 04096 if (!info) 04097 return 1; 04098 FIND_NEXT; 04099 /* And finally go for the month */ 04100 i->monthmask = get_month(info); 04101 04102 return 1; 04103 }
|
|
Definition at line 2206 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(). 02207 { 02208 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_CANMATCH); 02209 }
|
|
ast_change_hint: Change hint for an extension
Definition at line 2106 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_hint::exten, and ast_hint::next. Referenced by ast_add_extension2(). 02107 { 02108 struct ast_hint *list; 02109 02110 ast_mutex_lock(&hintlock); 02111 list = hints; 02112 02113 while(list) { 02114 if (list->exten == oe) { 02115 list->exten = ne; 02116 ast_mutex_unlock(&hintlock); 02117 return 0; 02118 } 02119 list = list->next; 02120 } 02121 ast_mutex_unlock(&hintlock); 02122 02123 return -1; 02124 }
|
|
Definition at line 4105 of file pbx.c. References ast_log(), ast_timing::daymask, ast_timing::dowmask, LOG_WARNING, ast_timing::minmask, and ast_timing::monthmask. Referenced by builtin_function_iftime(), include_valid(), pbx_builtin_execiftime(), and pbx_builtin_gotoiftime(). 04106 { 04107 struct tm tm; 04108 time_t t; 04109 04110 time(&t); 04111 localtime_r(&t,&tm); 04112 04113 /* If it's not the right month, return */ 04114 if (!(i->monthmask & (1 << tm.tm_mon))) { 04115 return 0; 04116 } 04117 04118 /* If it's not that time of the month.... */ 04119 /* Warning, tm_mday has range 1..31! */ 04120 if (!(i->daymask & (1 << (tm.tm_mday-1)))) 04121 return 0; 04122 04123 /* If it's not the right day of the week */ 04124 if (!(i->dowmask & (1 << tm.tm_wday))) 04125 return 0; 04126 04127 /* Sanity check the hour just to be safe */ 04128 if ((tm.tm_hour < 0) || (tm.tm_hour > 23)) { 04129 ast_log(LOG_WARNING, "Insane time...\n"); 04130 return 0; 04131 } 04132 04133 /* Now the tough part, we calculate if it fits 04134 in the right time based on min/hour */ 04135 if (!(i->minmask[tm.tm_hour] & (1 << (tm.tm_min / 2)))) 04136 return 0; 04137 04138 /* If we got this far, then we're good */ 04139 return 1; 04140 }
|
|
Definition at line 4401 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(). 04402 { 04403 struct ast_context *c; 04404 04405 if (ast_lock_contexts()) { 04406 errno = EBUSY; 04407 return -1; 04408 } 04409 04410 c = ast_walk_contexts(NULL); 04411 while (c) { 04412 if (!strcmp(ast_get_context_name(c), con)) { 04413 int ret = ast_context_add_ignorepat2(c, value, registrar); 04414 ast_unlock_contexts(); 04415 return ret; 04416 } 04417 c = ast_walk_contexts(c); 04418 } 04419 04420 ast_unlock_contexts(); 04421 errno = ENOENT; 04422 return -1; 04423 }
|
|
Definition at line 4425 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(). 04426 { 04427 struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL; 04428 int length; 04429 length = sizeof(struct ast_ignorepat); 04430 length += strlen(value) + 1; 04431 ignorepat = malloc(length); 04432 if (!ignorepat) { 04433 ast_log(LOG_ERROR, "Out of memory\n"); 04434 errno = ENOMEM; 04435 return -1; 04436 } 04437 memset(ignorepat, 0, length); 04438 strcpy(ignorepat->pattern, value); 04439 ignorepat->next = NULL; 04440 ignorepat->registrar = registrar; 04441 ast_mutex_lock(&con->lock); 04442 ignorepatc = con->ignorepats; 04443 while(ignorepatc) { 04444 ignorepatl = ignorepatc; 04445 if (!strcasecmp(ignorepatc->pattern, value)) { 04446 /* Already there */ 04447 ast_mutex_unlock(&con->lock); 04448 errno = EEXIST; 04449 return -1; 04450 } 04451 ignorepatc = ignorepatc->next; 04452 } 04453 if (ignorepatl) 04454 ignorepatl->next = ignorepat; 04455 else 04456 con->ignorepats = ignorepat; 04457 ast_mutex_unlock(&con->lock); 04458 return 0; 04459 04460 }
|
|
Definition at line 3784 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(). 03785 { 03786 struct ast_context *c; 03787 03788 if (ast_lock_contexts()) { 03789 errno = EBUSY; 03790 return -1; 03791 } 03792 03793 /* walk contexts ... */ 03794 c = ast_walk_contexts(NULL); 03795 while (c) { 03796 /* ... search for the right one ... */ 03797 if (!strcmp(ast_get_context_name(c), context)) { 03798 int ret = ast_context_add_include2(c, include, registrar); 03799 /* ... unlock contexts list and return */ 03800 ast_unlock_contexts(); 03801 return ret; 03802 } 03803 c = ast_walk_contexts(c); 03804 } 03805 03806 /* we can't find the right context */ 03807 ast_unlock_contexts(); 03808 errno = ENOENT; 03809 return -1; 03810 }
|
|
Definition at line 4149 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(). 04151 { 04152 struct ast_include *new_include; 04153 char *c; 04154 struct ast_include *i, *il = NULL; /* include, include_last */ 04155 int length; 04156 char *p; 04157 04158 length = sizeof(struct ast_include); 04159 length += 2 * (strlen(value) + 1); 04160 04161 /* allocate new include structure ... */ 04162 if (!(new_include = malloc(length))) { 04163 ast_log(LOG_ERROR, "Out of memory\n"); 04164 errno = ENOMEM; 04165 return -1; 04166 } 04167 04168 /* ... fill in this structure ... */ 04169 memset(new_include, 0, length); 04170 p = new_include->stuff; 04171 new_include->name = p; 04172 strcpy(new_include->name, value); 04173 p += strlen(value) + 1; 04174 new_include->rname = p; 04175 strcpy(new_include->rname, value); 04176 c = new_include->rname; 04177 /* Strip off timing info */ 04178 while(*c && (*c != '|')) 04179 c++; 04180 /* Process if it's there */ 04181 if (*c) { 04182 new_include->hastime = ast_build_timing(&(new_include->timing), c+1); 04183 *c = '\0'; 04184 } 04185 new_include->next = NULL; 04186 new_include->registrar = registrar; 04187 04188 /* ... try to lock this context ... */ 04189 if (ast_mutex_lock(&con->lock)) { 04190 free(new_include); 04191 errno = EBUSY; 04192 return -1; 04193 } 04194 04195 /* ... go to last include and check if context is already included too... */ 04196 i = con->includes; 04197 while (i) { 04198 if (!strcasecmp(i->name, new_include->name)) { 04199 free(new_include); 04200 ast_mutex_unlock(&con->lock); 04201 errno = EEXIST; 04202 return -1; 04203 } 04204 il = i; 04205 i = i->next; 04206 } 04207 04208 /* ... include new context into context list, unlock, return */ 04209 if (il) 04210 il->next = new_include; 04211 else 04212 con->includes = new_include; 04213 if (option_verbose > 2) 04214 ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con)); 04215 ast_mutex_unlock(&con->lock); 04216 04217 return 0; 04218 }
|
|
Definition at line 4225 of file pbx.c. References ast_context_add_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). 04226 { 04227 struct ast_context *c; 04228 04229 if (ast_lock_contexts()) { 04230 errno = EBUSY; 04231 return -1; 04232 } 04233 04234 /* walk contexts ... */ 04235 c = ast_walk_contexts(NULL); 04236 while (c) { 04237 /* ... search for the right one ... */ 04238 if (!strcmp(ast_get_context_name(c), context)) { 04239 int ret = ast_context_add_switch2(c, sw, data, eval, registrar); 04240 /* ... unlock contexts list and return */ 04241 ast_unlock_contexts(); 04242 return ret; 04243 } 04244 c = ast_walk_contexts(c); 04245 } 04246 04247 /* we can't find the right context */ 04248 ast_unlock_contexts(); 04249 errno = ENOENT; 04250 return -1; 04251 }
|
|
Definition at line 4260 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, ast_sw::tmpdata, and VERBOSE_PREFIX_3. Referenced by ast_context_add_switch(), handle_context(), and pbx_load_module(). 04262 { 04263 struct ast_sw *new_sw; 04264 struct ast_sw *i, *il = NULL; /* sw, sw_last */ 04265 int length; 04266 char *p; 04267 04268 length = sizeof(struct ast_sw); 04269 length += strlen(value) + 1; 04270 if (data) 04271 length += strlen(data); 04272 length++; 04273 if (eval) { 04274 /* Create buffer for evaluation of variables */ 04275 length += SWITCH_DATA_LENGTH; 04276 length++; 04277 } 04278 04279 /* allocate new sw structure ... */ 04280 if (!(new_sw = malloc(length))) { 04281 ast_log(LOG_ERROR, "Out of memory\n"); 04282 errno = ENOMEM; 04283 return -1; 04284 } 04285 04286 /* ... fill in this structure ... */ 04287 memset(new_sw, 0, length); 04288 p = new_sw->stuff; 04289 new_sw->name = p; 04290 strcpy(new_sw->name, value); 04291 p += strlen(value) + 1; 04292 new_sw->data = p; 04293 if (data) { 04294 strcpy(new_sw->data, data); 04295 p += strlen(data) + 1; 04296 } else { 04297 strcpy(new_sw->data, ""); 04298 p++; 04299 } 04300 if (eval) 04301 new_sw->tmpdata = p; 04302 new_sw->next = NULL; 04303 new_sw->eval = eval; 04304 new_sw->registrar = registrar; 04305 04306 /* ... try to lock this context ... */ 04307 if (ast_mutex_lock(&con->lock)) { 04308 free(new_sw); 04309 errno = EBUSY; 04310 return -1; 04311 } 04312 04313 /* ... go to last sw and check if context is already swd too... */ 04314 i = con->alts; 04315 while (i) { 04316 if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) { 04317 free(new_sw); 04318 ast_mutex_unlock(&con->lock); 04319 errno = EEXIST; 04320 return -1; 04321 } 04322 il = i; 04323 i = i->next; 04324 } 04325 04326 /* ... sw new context into context list, unlock, return */ 04327 if (il) 04328 il->next = new_sw; 04329 else 04330 con->alts = new_sw; 04331 if (option_verbose > 2) 04332 ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con)); 04333 ast_mutex_unlock(&con->lock); 04334 04335 return 0; 04336 }
|
|
Definition at line 3628 of file pbx.c. References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_context::ignorepats, ast_context::includes, ast_context::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, name, ast_context::name, ast_context::next, option_verbose, ast_context::registrar, ast_context::root, and VERBOSE_PREFIX_3. Referenced by ast_park_call(), do_parking_thread(), handle_context(), handle_macro(), load_config(), pbx_load_module(), reload_config(), and set_config(). 03629 { 03630 struct ast_context *tmp, **local_contexts; 03631 int length; 03632 length = sizeof(struct ast_context); 03633 length += strlen(name) + 1; 03634 if (!extcontexts) { 03635 local_contexts = &contexts; 03636 ast_mutex_lock(&conlock); 03637 } else 03638 local_contexts = extcontexts; 03639 03640 tmp = *local_contexts; 03641 while(tmp) { 03642 if (!strcasecmp(tmp->name, name)) { 03643 ast_mutex_unlock(&conlock); 03644 ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name); 03645 if (!extcontexts) 03646 ast_mutex_unlock(&conlock); 03647 return NULL; 03648 } 03649 tmp = tmp->next; 03650 } 03651 tmp = malloc(length); 03652 if (tmp) { 03653 memset(tmp, 0, length); 03654 ast_mutex_init(&tmp->lock); 03655 strcpy(tmp->name, name); 03656 tmp->root = NULL; 03657 tmp->registrar = registrar; 03658 tmp->next = *local_contexts; 03659 tmp->includes = NULL; 03660 tmp->ignorepats = NULL; 03661 *local_contexts = tmp; 03662 if (option_debug) 03663 ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); 03664 else if (option_verbose > 2) 03665 ast_verbose( VERBOSE_PREFIX_3 "Registered extension context '%s'\n", tmp->name); 03666 } else 03667 ast_log(LOG_ERROR, "Out of memory\n"); 03668 03669 if (!extcontexts) 03670 ast_mutex_unlock(&conlock); 03671 return tmp; 03672 }
|
|
Definition at line 5356 of file pbx.c. References __ast_context_destroy(). Referenced by ael_reload(), reload(), and unload_module(). 05357 { 05358 __ast_context_destroy(con,registrar); 05359 }
|
|
Definition at line 727 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), name, ast_context::name, and ast_context::next. Referenced by ast_context_verify_includes(), ast_ignore_pattern(), ast_park_call(), do_parking_thread(), load_config(), macro_exec(), park_exec(), reload_config(), and set_config(). 00728 { 00729 struct ast_context *tmp; 00730 ast_mutex_lock(&conlock); 00731 if (name) { 00732 tmp = contexts; 00733 while(tmp) { 00734 if (!strcasecmp(name, tmp->name)) 00735 break; 00736 tmp = tmp->next; 00737 } 00738 } else 00739 tmp = contexts; 00740 ast_mutex_unlock(&conlock); 00741 return tmp; 00742 }
|
|
Definition at line 2713 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(). 02714 { 02715 struct ast_context *c; 02716 02717 if (ast_lock_contexts()) return -1; 02718 02719 /* walk contexts ... */ 02720 c = ast_walk_contexts(NULL); 02721 while (c) { 02722 /* ... search for the right one ... */ 02723 if (!strcmp(ast_get_context_name(c), context)) { 02724 /* ... remove extension ... */ 02725 int ret = ast_context_remove_extension2(c, extension, priority, 02726 registrar); 02727 /* ... unlock contexts list and return */ 02728 ast_unlock_contexts(); 02729 return ret; 02730 } 02731 c = ast_walk_contexts(c); 02732 } 02733 02734 /* we can't find the right context */ 02735 ast_unlock_contexts(); 02736 return -1; 02737 }
|
|
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 2749 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_remove_hint(), ast_exten::data, ast_exten::datad, ast_exten::exten, free, ast_context::lock, ast_exten::next, ast_exten::peer, ast_exten::priority, ast_exten::registrar, and ast_context::root. Referenced by ast_context_remove_extension(), do_parking_thread(), load_config(), and park_exec(). 02750 { 02751 struct ast_exten *exten, *prev_exten = NULL; 02752 02753 if (ast_mutex_lock(&con->lock)) return -1; 02754 02755 /* go through all extensions in context and search the right one ... */ 02756 exten = con->root; 02757 while (exten) { 02758 02759 /* look for right extension */ 02760 if (!strcmp(exten->exten, extension) && 02761 (!registrar || !strcmp(exten->registrar, registrar))) { 02762 struct ast_exten *peer; 02763 02764 /* should we free all peers in this extension? (priority == 0)? */ 02765 if (priority == 0) { 02766 /* remove this extension from context list */ 02767 if (prev_exten) 02768 prev_exten->next = exten->next; 02769 else 02770 con->root = exten->next; 02771 02772 /* fire out all peers */ 02773 peer = exten; 02774 while (peer) { 02775 exten = peer->peer; 02776 02777 if (!peer->priority==PRIORITY_HINT) 02778 ast_remove_hint(peer); 02779 02780 peer->datad(peer->data); 02781 free(peer); 02782 02783 peer = exten; 02784 } 02785 02786 ast_mutex_unlock(&con->lock); 02787 return 0; 02788 } else { 02789 /* remove only extension with exten->priority == priority */ 02790 struct ast_exten *previous_peer = NULL; 02791 02792 peer = exten; 02793 while (peer) { 02794 /* is this our extension? */ 02795 if (peer->priority == priority && 02796 (!registrar || !strcmp(peer->registrar, registrar) )) { 02797 /* we are first priority extension? */ 02798 if (!previous_peer) { 02799 /* exists previous extension here? */ 02800 if (prev_exten) { 02801 /* yes, so we must change next pointer in 02802 * previous connection to next peer 02803 */ 02804 if (peer->peer) { 02805 prev_exten->next = peer->peer; 02806 peer->peer->next = exten->next; 02807 } else 02808 prev_exten->next = exten->next; 02809 } else { 02810 /* no previous extension, we are first 02811 * extension, so change con->root ... 02812 */ 02813 if (peer->peer) 02814 con->root = peer->peer; 02815 else 02816 con->root = exten->next; 02817 } 02818 } else { 02819 /* we are not first priority in extension */ 02820 previous_peer->peer = peer->peer; 02821 } 02822 02823 /* now, free whole priority extension */ 02824 if (peer->priority==PRIORITY_HINT) 02825 ast_remove_hint(peer); 02826 peer->datad(peer->data); 02827 free(peer); 02828 02829 ast_mutex_unlock(&con->lock); 02830 return 0; 02831 } else { 02832 /* this is not right extension, skip to next peer */ 02833 previous_peer = peer; 02834 peer = peer->peer; 02835 } 02836 } 02837 02838 ast_mutex_unlock(&con->lock); 02839 return -1; 02840 } 02841 } 02842 02843 prev_exten = exten; 02844 exten = exten->next; 02845 } 02846 02847 /* we can't find right extension */ 02848 ast_mutex_unlock(&con->lock); 02849 return -1; 02850 }
|
|
Definition at line 4342 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(). 04343 { 04344 struct ast_context *c; 04345 04346 if (ast_lock_contexts()) { 04347 errno = EBUSY; 04348 return -1; 04349 } 04350 04351 c = ast_walk_contexts(NULL); 04352 while (c) { 04353 if (!strcmp(ast_get_context_name(c), context)) { 04354 int ret = ast_context_remove_ignorepat2(c, ignorepat, registrar); 04355 ast_unlock_contexts(); 04356 return ret; 04357 } 04358 c = ast_walk_contexts(c); 04359 } 04360 04361 ast_unlock_contexts(); 04362 errno = ENOENT; 04363 return -1; 04364 }
|
|
Definition at line 4366 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(). 04367 { 04368 struct ast_ignorepat *ip, *ipl = NULL; 04369 04370 if (ast_mutex_lock(&con->lock)) { 04371 errno = EBUSY; 04372 return -1; 04373 } 04374 04375 ip = con->ignorepats; 04376 while (ip) { 04377 if (!strcmp(ip->pattern, ignorepat) && 04378 (!registrar || (registrar == ip->registrar))) { 04379 if (ipl) { 04380 ipl->next = ip->next; 04381 free(ip); 04382 } else { 04383 con->ignorepats = ip->next; 04384 free(ip); 04385 } 04386 ast_mutex_unlock(&con->lock); 04387 return 0; 04388 } 04389 ipl = ip; ip = ip->next; 04390 } 04391 04392 ast_mutex_unlock(&con->lock); 04393 errno = EINVAL; 04394 return -1; 04395 }
|
|
See add_include Definition at line 2569 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(). 02570 { 02571 struct ast_context *c; 02572 02573 if (ast_lock_contexts()) return -1; 02574 02575 /* walk contexts and search for the right one ...*/ 02576 c = ast_walk_contexts(NULL); 02577 while (c) { 02578 /* we found one ... */ 02579 if (!strcmp(ast_get_context_name(c), context)) { 02580 int ret; 02581 /* remove include from this context ... */ 02582 ret = ast_context_remove_include2(c, include, registrar); 02583 02584 ast_unlock_contexts(); 02585 02586 /* ... return results */ 02587 return ret; 02588 } 02589 c = ast_walk_contexts(c); 02590 } 02591 02592 /* we can't find the right one context */ 02593 ast_unlock_contexts(); 02594 return -1; 02595 }
|
|
See add_include2 Definition at line 2605 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(). 02606 { 02607 struct ast_include *i, *pi = NULL; 02608 02609 if (ast_mutex_lock(&con->lock)) return -1; 02610 02611 /* walk includes */ 02612 i = con->includes; 02613 while (i) { 02614 /* find our include */ 02615 if (!strcmp(i->name, include) && 02616 (!registrar || !strcmp(i->registrar, registrar))) { 02617 /* remove from list */ 02618 if (pi) 02619 pi->next = i->next; 02620 else 02621 con->includes = i->next; 02622 /* free include and return */ 02623 free(i); 02624 ast_mutex_unlock(&con->lock); 02625 return 0; 02626 } 02627 pi = i; 02628 i = i->next; 02629 } 02630 02631 /* we can't find the right include */ 02632 ast_mutex_unlock(&con->lock); 02633 return -1; 02634 }
|
|
Definition at line 2641 of file pbx.c. References ast_context_remove_switch2(), ast_get_context_name(), ast_lock_contexts(), ast_unlock_contexts(), and ast_walk_contexts(). 02642 { 02643 struct ast_context *c; 02644 02645 if (ast_lock_contexts()) return -1; 02646 02647 /* walk contexts and search for the right one ...*/ 02648 c = ast_walk_contexts(NULL); 02649 while (c) { 02650 /* we found one ... */ 02651 if (!strcmp(ast_get_context_name(c), context)) { 02652 int ret; 02653 /* remove switch from this context ... */ 02654 ret = ast_context_remove_switch2(c, sw, data, registrar); 02655 02656 ast_unlock_contexts(); 02657 02658 /* ... return results */ 02659 return ret; 02660 } 02661 c = ast_walk_contexts(c); 02662 } 02663 02664 /* we can't find the right one context */ 02665 ast_unlock_contexts(); 02666 return -1; 02667 }
|
|
This function locks given context, removes switch, unlock context and return.
Definition at line 2677 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(). 02678 { 02679 struct ast_sw *i, *pi = NULL; 02680 02681 if (ast_mutex_lock(&con->lock)) return -1; 02682 02683 /* walk switchs */ 02684 i = con->alts; 02685 while (i) { 02686 /* find our switch */ 02687 if (!strcmp(i->name, sw) && !strcmp(i->data, data) && 02688 (!registrar || !strcmp(i->registrar, registrar))) { 02689 /* remove from list */ 02690 if (pi) 02691 pi->next = i->next; 02692 else 02693 con->alts = i->next; 02694 /* free switch and return */ 02695 free(i); 02696 ast_mutex_unlock(&con->lock); 02697 return 0; 02698 } 02699 pi = i; 02700 i = i->next; 02701 } 02702 02703 /* we can't find the right switch */ 02704 ast_mutex_unlock(&con->lock); 02705 return -1; 02706 }
|
|
Definition at line 6390 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(). 06391 { 06392 struct ast_include *inc; 06393 int res = 0; 06394 06395 for (inc = ast_walk_context_includes(con, NULL); inc; inc = ast_walk_context_includes(con, inc)) 06396 if (!ast_context_find(inc->rname)) { 06397 res = -1; 06398 ast_log(LOG_WARNING, "Context '%s' tries includes nonexistent context '%s'\n", 06399 ast_get_context_name(con), inc->rname); 06400 } 06401 return res; 06402 }
|
|
Definition at line 1256 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, name, 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(). 01257 { 01258 struct ast_custom_function *acfptr; 01259 01260 /* try to lock functions list ... */ 01261 if (ast_mutex_lock(&acflock)) { 01262 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01263 return NULL; 01264 } 01265 01266 for (acfptr = acf_root; acfptr; acfptr = acfptr->next) { 01267 if (!strcmp(name, acfptr->name)) { 01268 break; 01269 } 01270 } 01271 01272 ast_mutex_unlock(&acflock); 01273 01274 return acfptr; 01275 }
|
|
Definition at line 1312 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(). 01313 { 01314 if (!acf) 01315 return -1; 01316 01317 /* try to lock functions list ... */ 01318 if (ast_mutex_lock(&acflock)) { 01319 ast_log(LOG_ERROR, "Unable to lock function list. Failed registering function %s\n", acf->name); 01320 return -1; 01321 } 01322 01323 if (ast_custom_function_find(acf->name)) { 01324 ast_log(LOG_ERROR, "Function %s already registered.\n", acf->name); 01325 ast_mutex_unlock(&acflock); 01326 return -1; 01327 } 01328 01329 acf->next = acf_root; 01330 acf_root = acf; 01331 01332 ast_mutex_unlock(&acflock); 01333 01334 if (option_verbose > 1) 01335 ast_verbose(VERBOSE_PREFIX_2 "Registered custom function %s\n", acf->name); 01336 01337 return 0; 01338 }
|
|
Definition at line 1277 of file pbx.c. References acf_root, 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 unload_module(). 01278 { 01279 struct ast_custom_function *acfptr, *lastacf = NULL; 01280 int res = -1; 01281 01282 if (!acf) 01283 return -1; 01284 01285 /* try to lock functions list ... */ 01286 if (ast_mutex_lock(&acflock)) { 01287 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01288 return -1; 01289 } 01290 01291 for (acfptr = acf_root; acfptr; acfptr = acfptr->next) { 01292 if (acfptr == acf) { 01293 if (lastacf) { 01294 lastacf->next = acf->next; 01295 } else { 01296 acf_root = acf->next; 01297 } 01298 res = 0; 01299 break; 01300 } 01301 lastacf = acfptr; 01302 } 01303 01304 ast_mutex_unlock(&acflock); 01305 01306 if (!res && (option_verbose > 1)) 01307 ast_verbose(VERBOSE_PREFIX_2 "Unregistered custom function %s\n", acf->name); 01308 01309 return res; 01310 }
|
|
Definition at line 2221 of file pbx.c. References HELPER_EXEC, and pbx_extension_helper(). Referenced by loopback_exec(). 02222 { 02223 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_EXEC); 02224 }
|
|
|
Definition at line 4510 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_async_goto(), ast_parseable_goto(), builtin_atxfer(), disa_exec(), and handle_setpriority(). 04511 { 04512 if (!chan) 04513 return -1; 04514 04515 if (!ast_strlen_zero(context)) 04516 ast_copy_string(chan->context, context, sizeof(chan->context)); 04517 if (!ast_strlen_zero(exten)) 04518 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 04519 if (priority > -1) { 04520 chan->priority = priority; 04521 /* see flag description in channel.h for explanation */ 04522 if (ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP)) 04523 chan->priority--; 04524 } 04525 04526 return 0; 04527 }
|
|
Definition at line 706 of file pbx.c. References ast_strlen_zero(), and EXTENSION_MATCH_CORE. Referenced by pbx_find_extension(), and realtime_switch_common(). 00707 { 00708 int match; 00709 /* If "data" is longer, it can'be a subset of pattern unless 00710 pattern is a pattern match */ 00711 if ((strlen(pattern) < strlen(data)) && (pattern[0] != '_')) 00712 return 0; 00713 00714 if ((ast_strlen_zero((char *)data) || !strncasecmp(pattern, data, strlen(data))) && 00715 (!needmore || (strlen(pattern) > strlen(data)))) { 00716 return 1; 00717 } 00718 EXTENSION_MATCH_CORE(data,pattern,match); 00719 /* If there's more or we don't care about more, or if it's a possible early match, 00720 return non-zero; otherwise it's a miss */ 00721 if (!needmore || *pattern || match == 2) { 00722 return match; 00723 } else 00724 return 0; 00725 }
|
|
Definition at line 693 of file pbx.c. References EXTENSION_MATCH_CORE. Referenced by ast_ignore_pattern(), find_matching_priority(), loopback_canmatch(), loopback_exec(), loopback_exists(), loopback_matchmore(), matchcid(), pbx_find_extension(), realtime_switch_common(), and show_dialplan_helper(). 00694 { 00695 int match; 00696 /* If they're the same return */ 00697 if (!strcmp(pattern, data)) 00698 return 1; 00699 EXTENSION_MATCH_CORE(data,pattern,match); 00700 /* Must be at the end of both */ 00701 if (*data || (*pattern && (*pattern != '/'))) 00702 match = 0; 00703 return match; 00704 }
|
|
ast_extension_state: Check extension state for an extension by using hint
Definition at line 1863 of file pbx.c. References ast_extension_state2(), and ast_hint_extension(). Referenced by action_extensionstate(), and handle_request_subscribe(). 01864 { 01865 struct ast_exten *e; 01866 01867 e = ast_hint_extension(c, context, exten); /* Do we have a hint for this extension ? */ 01868 if (!e) 01869 return -1; /* No hint, return -1 */ 01870 01871 return ast_extension_state2(e); /* Check all devices in the hint */ 01872 }
|
|
ast_extensions_state2: Check state of extension by using hints
Definition at line 1776 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_INUSE, and ast_get_extension_app(). Referenced by ast_add_hint(), ast_extension_state(), and ast_hint_state_changed(). 01777 { 01778 char hint[AST_MAX_EXTENSION] = ""; 01779 char *cur, *rest; 01780 int res = -1; 01781 int allunavailable = 1, allbusy = 1, allfree = 1; 01782 int busy = 0, inuse = 0, ring = 0; 01783 01784 if (!e) 01785 return -1; 01786 01787 ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint)); 01788 01789 cur = hint; /* On or more devices separated with a & character */ 01790 do { 01791 rest = strchr(cur, '&'); 01792 if (rest) { 01793 *rest = 0; 01794 rest++; 01795 } 01796 01797 res = ast_device_state(cur); 01798 switch (res) { 01799 case AST_DEVICE_NOT_INUSE: 01800 allunavailable = 0; 01801 allbusy = 0; 01802 break; 01803 case AST_DEVICE_INUSE: 01804 inuse = 1; 01805 allunavailable = 0; 01806 allfree = 0; 01807 break; 01808 case AST_DEVICE_RINGING: 01809 ring = 1; 01810 allunavailable = 0; 01811 allfree = 0; 01812 break; 01813 case AST_DEVICE_BUSY: 01814 allunavailable = 0; 01815 allfree = 0; 01816 busy = 1; 01817 break; 01818 case AST_DEVICE_UNAVAILABLE: 01819 case AST_DEVICE_INVALID: 01820 allbusy = 0; 01821 allfree = 0; 01822 break; 01823 default: 01824 allunavailable = 0; 01825 allbusy = 0; 01826 allfree = 0; 01827 } 01828 cur = rest; 01829 } while (cur); 01830 01831 if (!inuse && ring) 01832 return AST_EXTENSION_RINGING; 01833 if (inuse && ring) 01834 return (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING); 01835 if (inuse) 01836 return AST_EXTENSION_INUSE; 01837 if (allfree) 01838 return AST_EXTENSION_NOT_INUSE; 01839 if (allbusy) 01840 return AST_EXTENSION_BUSY; 01841 if (allunavailable) 01842 return AST_EXTENSION_UNAVAILABLE; 01843 if (busy) 01844 return AST_EXTENSION_INUSE; 01845 01846 return AST_EXTENSION_NOT_INUSE; 01847 }
|
|
ast_extension_state2str: Return extension_state as string
Definition at line 1850 of file pbx.c. Referenced by __sip_show_channels(), cb_extensionstate(), handle_request_subscribe(), and handle_show_hints(). 01851 { 01852 int i; 01853 01854 for (i = 0; (i < (sizeof(extension_states) / sizeof(extension_states[0]))); i++) { 01855 if (extension_states[i].extension_state == extension_state) { 01856 return extension_states[i].text; 01857 } 01858 } 01859 return "Unknown"; 01860 }
|
|
ast_extension_state_add: Add watcher for extension states
Definition at line 1917 of file pbx.c. References ast_hint_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_state_cb::id, malloc, ast_state_cb::next, ast_hint::next, statecbs, and stateid. Referenced by handle_request_subscribe(), and init_manager(). 01919 { 01920 struct ast_hint *list; 01921 struct ast_state_cb *cblist; 01922 struct ast_exten *e; 01923 01924 /* If there's no context and extension: add callback to statecbs list */ 01925 if (!context && !exten) { 01926 ast_mutex_lock(&hintlock); 01927 01928 cblist = statecbs; 01929 while (cblist) { 01930 if (cblist->callback == callback) { 01931 cblist->data = data; 01932 ast_mutex_unlock(&hintlock); 01933 return 0; 01934 } 01935 cblist = cblist->next; 01936 } 01937 01938 /* Now insert the callback */ 01939 cblist = malloc(sizeof(struct ast_state_cb)); 01940 if (!cblist) { 01941 ast_mutex_unlock(&hintlock); 01942 return -1; 01943 } 01944 memset(cblist, 0, sizeof(struct ast_state_cb)); 01945 cblist->id = 0; 01946 cblist->callback = callback; 01947 cblist->data = data; 01948 01949 cblist->next = statecbs; 01950 statecbs = cblist; 01951 01952 ast_mutex_unlock(&hintlock); 01953 return 0; 01954 } 01955 01956 if (!context || !exten) 01957 return -1; 01958 01959 /* This callback type is for only one hint, so get the hint */ 01960 e = ast_hint_extension(NULL, context, exten); 01961 if (!e) { 01962 return -1; 01963 } 01964 01965 /* Find the hint in the list of hints */ 01966 ast_mutex_lock(&hintlock); 01967 list = hints; 01968 01969 while (list) { 01970 if (list->exten == e) 01971 break; 01972 list = list->next; 01973 } 01974 01975 if (!list) { 01976 /* We have no hint, sorry */ 01977 ast_mutex_unlock(&hintlock); 01978 return -1; 01979 } 01980 01981 /* Now insert the callback in the callback list */ 01982 cblist = malloc(sizeof(struct ast_state_cb)); 01983 if (!cblist) { 01984 ast_mutex_unlock(&hintlock); 01985 return -1; 01986 } 01987 memset(cblist, 0, sizeof(struct ast_state_cb)); 01988 cblist->id = stateid++; /* Unique ID for this callback */ 01989 cblist->callback = callback; /* Pointer to callback routine */ 01990 cblist->data = data; /* Data for the callback */ 01991 01992 cblist->next = list->callbacks; 01993 list->callbacks = cblist; 01994 01995 ast_mutex_unlock(&hintlock); 01996 return cblist->id; 01997 }
|
|
ast_extension_state_del: Remove a watcher from the callback list
Definition at line 2000 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, free, ast_state_cb::id, ast_state_cb::next, ast_hint::next, and statecbs. Referenced by __sip_destroy(). 02001 { 02002 struct ast_hint *list; 02003 struct ast_state_cb *cblist, *cbprev; 02004 02005 if (!id && !callback) 02006 return -1; 02007 02008 ast_mutex_lock(&hintlock); 02009 02010 /* id is zero is a callback without extension */ 02011 if (!id) { 02012 cbprev = NULL; 02013 cblist = statecbs; 02014 while (cblist) { 02015 if (cblist->callback == callback) { 02016 if (!cbprev) 02017 statecbs = cblist->next; 02018 else 02019 cbprev->next = cblist->next; 02020 02021 free(cblist); 02022 02023 ast_mutex_unlock(&hintlock); 02024 return 0; 02025 } 02026 cbprev = cblist; 02027 cblist = cblist->next; 02028 } 02029 02030 ast_mutex_unlock(&hintlock); 02031 return -1; 02032 } 02033 02034 /* id greater than zero is a callback with extension */ 02035 /* Find the callback based on ID */ 02036 list = hints; 02037 while (list) { 02038 cblist = list->callbacks; 02039 cbprev = NULL; 02040 while (cblist) { 02041 if (cblist->id==id) { 02042 if (!cbprev) 02043 list->callbacks = cblist->next; 02044 else 02045 cbprev->next = cblist->next; 02046 02047 free(cblist); 02048 02049 ast_mutex_unlock(&hintlock); 02050 return 0; 02051 } 02052 cbprev = cblist; 02053 cblist = cblist->next; 02054 } 02055 list = list->next; 02056 } 02057 02058 ast_mutex_unlock(&hintlock); 02059 return -1; 02060 }
|
|
Definition at line 2196 of file pbx.c. References HELPER_FINDLABEL, and pbx_extension_helper(). Referenced by ast_parseable_goto(), and handle_setpriority(). 02197 { 02198 return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, HELPER_FINDLABEL); 02199 }
|
|
Definition at line 2201 of file pbx.c. References HELPER_FINDLABEL, and pbx_extension_helper(). Referenced by pbx_load_module(). 02202 { 02203 return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, HELPER_FINDLABEL); 02204 }
|
|
Definition at line 1340 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(). 01341 { 01342 char *args = NULL, *function, *p; 01343 char *ret = "0"; 01344 struct ast_custom_function *acfptr; 01345 01346 function = ast_strdupa(in); 01347 if (!function) { 01348 ast_log(LOG_ERROR, "Out of memory\n"); 01349 return ret; 01350 } 01351 if ((args = strchr(function, '('))) { 01352 *args = '\0'; 01353 args++; 01354 if ((p = strrchr(args, ')'))) { 01355 *p = '\0'; 01356 } else { 01357 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01358 } 01359 } else { 01360 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01361 } 01362 01363 if ((acfptr = ast_custom_function_find(function))) { 01364 /* run the custom function */ 01365 if (acfptr->read) { 01366 return acfptr->read(chan, function, args, workspace, len); 01367 } else { 01368 ast_log(LOG_ERROR, "Function %s cannot be read\n", function); 01369 } 01370 } else { 01371 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01372 } 01373 return ret; 01374 }
|
|
Definition at line 1376 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(). 01377 { 01378 char *args = NULL, *function, *p; 01379 struct ast_custom_function *acfptr; 01380 01381 function = ast_strdupa(in); 01382 if (!function) { 01383 ast_log(LOG_ERROR, "Out of memory\n"); 01384 return; 01385 } 01386 if ((args = strchr(function, '('))) { 01387 *args = '\0'; 01388 args++; 01389 if ((p = strrchr(args, ')'))) { 01390 *p = '\0'; 01391 } else { 01392 ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n"); 01393 } 01394 } else { 01395 ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n"); 01396 } 01397 01398 if ((acfptr = ast_custom_function_find(function))) { 01399 /* run the custom function */ 01400 if (acfptr->write) { 01401 acfptr->write(chan, function, args, value); 01402 } else { 01403 ast_log(LOG_ERROR, "Function %s is read-only, it cannot be written to\n", function); 01404 } 01405 } else { 01406 ast_log(LOG_ERROR, "Function %s not registered\n", function); 01407 } 01408 }
|
|
Definition at line 6246 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(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper(). 06247 { 06248 return con ? con->name : NULL; 06249 }
|
|
Definition at line 6279 of file pbx.c. References ast_context::registrar. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06280 { 06281 return c ? c->registrar : NULL; 06282 }
|
|
Definition at line 6309 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(). 06310 { 06311 return e ? e->app : NULL; 06312 }
|
|
Definition at line 6314 of file pbx.c. References ast_exten::data. Referenced by ast_get_hint(), handle_save_dialplan(), and show_dialplan_helper(). 06315 { 06316 return e ? e->data : NULL; 06317 }
|
|
Definition at line 6304 of file pbx.c. References ast_exten::cidmatch. Referenced by find_matching_priority(), and handle_save_dialplan(). 06305 { 06306 return e ? e->cidmatch : NULL; 06307 }
|
|
Definition at line 6256 of file pbx.c. References ast_exten::label. Referenced by show_dialplan_helper(). 06257 { 06258 return exten ? exten->label : NULL; 06259 }
|
|
Definition at line 6299 of file pbx.c. References ast_exten::matchcid. Referenced by find_matching_priority(), and handle_save_dialplan(). 06300 { 06301 return e ? e->matchcid : 0; 06302 }
|
|
Definition at line 6251 of file pbx.c. References ast_exten::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(). 06252 { 06253 return exten ? exten->exten : NULL; 06254 }
|
|
Definition at line 6271 of file pbx.c. References ast_exten::priority. Referenced by complete_context_remove_extension(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper(). 06272 { 06273 return exten ? exten->priority : -1; 06274 }
|
|
Definition at line 6284 of file pbx.c. References ast_exten::registrar. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06285 { 06286 return e ? e->registrar : NULL; 06287 }
|
|
ast_get_hint: Get hint for channel
Definition at line 2172 of file pbx.c. References ast_get_extension_app(), ast_get_extension_app_data(), ast_hint_extension(), and name. Referenced by action_extensionstate(), get_cid_name(), pbx_retrieve_variable(), and transmit_state_notify(). 02173 { 02174 struct ast_exten *e; 02175 void *tmp; 02176 02177 e = ast_hint_extension(c, context, exten); 02178 if (e) { 02179 if (hint) 02180 ast_copy_string(hint, ast_get_extension_app(e), hintsize); 02181 if (name) { 02182 tmp = ast_get_extension_app_data(e); 02183 if (tmp) 02184 ast_copy_string(name, (char *) tmp, namesize); 02185 } 02186 return -1; 02187 } 02188 return 0; 02189 }
|
|
Definition at line 6266 of file pbx.c. References ast_ignorepat::pattern. Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), handle_save_dialplan(), and show_dialplan_helper(). 06267 { 06268 return ip ? ip->pattern : NULL; 06269 }
|
|
Definition at line 6294 of file pbx.c. References ast_ignorepat::registrar. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06295 { 06296 return ip ? ip->registrar : NULL; 06297 }
|
|
Definition at line 6261 of file pbx.c. References ast_include::name. Referenced by complete_context_add_include(), complete_context_dont_include(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper(). 06262 { 06263 return inc ? inc->name : NULL; 06264 }
|
|
Definition at line 6289 of file pbx.c. References ast_include::registrar. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06290 { 06291 return i ? i->registrar : NULL; 06292 }
|
|
Definition at line 6324 of file pbx.c. References ast_sw::data. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06325 { 06326 return sw ? sw->data : NULL; 06327 }
|
|
Definition at line 6319 of file pbx.c. References ast_sw::name. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06320 { 06321 return sw ? sw->name : NULL; 06322 }
|
|
Definition at line 6329 of file pbx.c. References ast_sw::registrar. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06330 { 06331 return sw ? sw->registrar : NULL; 06332 }
|
|
Definition at line 6422 of file pbx.c. References __ast_goto_if_exists(). Referenced by aqm_exec(), auth_exec(), background_detect_exec(), chanavail_exec(), conf_run(), controlplayback_exec(), dial_exec_full(), do_directory(), dundi_lookup_exec(), 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(). 06422 { 06423 return __ast_goto_if_exists(chan, context, exten, priority, 0); 06424 }
|
|
ast_hint_extension: Find hint for given extension in context
Definition at line 1756 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), HELPER_EXISTS, LOG_WARNING, pbx_find_extension(), and PRIORITY_HINT. Referenced by ast_extension_state(), ast_extension_state_add(), ast_get_hint(), and ast_merge_contexts_and_delete(). 01757 { 01758 struct ast_exten *e; 01759 struct ast_switch *sw; 01760 char *data; 01761 const char *foundcontext = NULL; 01762 int status = 0; 01763 char *incstack[AST_PBX_MAX_STACK]; 01764 int stacklen = 0; 01765 01766 if (ast_mutex_lock(&conlock)) { 01767 ast_log(LOG_WARNING, "Unable to obtain lock\n"); 01768 return NULL; 01769 } 01770 e = pbx_find_extension(c, NULL, context, exten, PRIORITY_HINT, NULL, "", HELPER_EXISTS, incstack, &stacklen, &status, &sw, &data, &foundcontext); 01771 ast_mutex_unlock(&conlock); 01772 return e; 01773 }
|
|
Definition at line 1874 of file pbx.c. References ast_extension_state2(), ast_get_extension_app(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_hint::exten, ast_exten::exten, ast_hint::laststate, ast_context::name, ast_hint::next, ast_state_cb::next, ast_exten::parent, and strsep(). Referenced by do_state_change(). 01875 { 01876 struct ast_hint *hint; 01877 struct ast_state_cb *cblist; 01878 char buf[AST_MAX_EXTENSION]; 01879 char *parse; 01880 char *cur; 01881 int state; 01882 01883 ast_mutex_lock(&hintlock); 01884 01885 for (hint = hints; hint; hint = hint->next) { 01886 ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); 01887 parse = buf; 01888 for (cur = strsep(&parse, "&"); cur; cur = strsep(&parse, "&")) { 01889 if (strcasecmp(cur, device)) 01890 continue; 01891 01892 /* Get device state for this hint */ 01893 state = ast_extension_state2(hint->exten); 01894 01895 if ((state == -1) || (state == hint->laststate)) 01896 continue; 01897 01898 /* Device state changed since last check - notify the watchers */ 01899 01900 /* For general callbacks */ 01901 for (cblist = statecbs; cblist; cblist = cblist->next) 01902 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01903 01904 /* For extension callbacks */ 01905 for (cblist = hint->callbacks; cblist; cblist = cblist->next) 01906 cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data); 01907 01908 hint->laststate = state; 01909 break; 01910 } 01911 } 01912 01913 ast_mutex_unlock(&hintlock); 01914 }
|
|
Definition at line 4462 of file pbx.c. References ast_context_find(), ast_extension_match(), ast_context::ignorepats, ast_ignorepat::next, and ast_ignorepat::pattern. Referenced by ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), mgcp_ss(), skinny_ss(), and ss_thread(). 04463 { 04464 struct ast_context *con; 04465 struct ast_ignorepat *pat; 04466 04467 con = ast_context_find(context); 04468 if (con) { 04469 pat = con->ignorepats; 04470 while (pat) { 04471 if (ast_extension_match(pat->pattern, pattern)) 04472 return 1; 04473 pat = pat->next; 04474 } 04475 } 04476 return 0; 04477 }
|
|
|
|
Definition at line 6233 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(). 06234 { 06235 return ast_mutex_lock(&con->lock); 06236 }
|
|
Locks the context list Returns 0 on success, -1 on error Definition at line 6220 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(). 06221 { 06222 return ast_mutex_lock(&conlock); 06223 }
|
|
Definition at line 2211 of file pbx.c. References HELPER_MATCHMORE, and pbx_extension_helper(). Referenced by __ast_pbx_run(), ast_app_dtget(), disa_exec(), dp_lookup(), dundi_lookup_local(), loopback_matchmore(), mgcp_ss(), skinny_ss(), and ss_thread(). 02212 { 02213 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_MATCHMORE); 02214 }
|
|
Definition at line 3687 of file pbx.c. References __ast_context_destroy(), AST_EXTENSION_REMOVED, ast_hint_extension(), AST_LIST_HEAD_INIT, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, calloc, contexts, ast_state_cb::data, ast_hint::exten, ast_exten::exten, free, ast_hint::laststate, LOG_WARNING, ast_context::name, ast_hint::next, ast_context::next, ast_state_cb::next, ast_exten::parent, and ast_context::registrar. Referenced by pbx_load_module(). 03688 { 03689 struct ast_context *tmp, *lasttmp = NULL; 03690 struct store_hints store; 03691 struct store_hint *this; 03692 struct ast_hint *hint; 03693 struct ast_exten *exten; 03694 int length; 03695 struct ast_state_cb *thiscb, *prevcb; 03696 03697 /* preserve all watchers for hints associated with this registrar */ 03698 AST_LIST_HEAD_INIT(&store); 03699 ast_mutex_lock(&hintlock); 03700 for (hint = hints; hint; hint = hint->next) { 03701 if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { 03702 length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); 03703 this = calloc(1, length); 03704 if (!this) { 03705 ast_log(LOG_WARNING, "Could not allocate memory to preserve hint\n"); 03706 continue; 03707 } 03708 this->callbacks = hint->callbacks; 03709 hint->callbacks = NULL; 03710 this->laststate = hint->laststate; 03711 this->context = this->data; 03712 strcpy(this->data, hint->exten->parent->name); 03713 this->exten = this->data + strlen(this->context) + 1; 03714 strcpy(this->exten, hint->exten->exten); 03715 AST_LIST_INSERT_HEAD(&store, this, list); 03716 } 03717 } 03718 ast_mutex_unlock(&hintlock); 03719 03720 tmp = *extcontexts; 03721 ast_mutex_lock(&conlock); 03722 if (registrar) { 03723 __ast_context_destroy(NULL,registrar); 03724 while (tmp) { 03725 lasttmp = tmp; 03726 tmp = tmp->next; 03727 } 03728 } else { 03729 while (tmp) { 03730 __ast_context_destroy(tmp,tmp->registrar); 03731 lasttmp = tmp; 03732 tmp = tmp->next; 03733 } 03734 } 03735 if (lasttmp) { 03736 lasttmp->next = contexts; 03737 contexts = *extcontexts; 03738 *extcontexts = NULL; 03739 } else 03740 ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); 03741 ast_mutex_unlock(&conlock); 03742 03743 /* restore the watchers for hints that can be found; notify those that 03744 cannot be restored 03745 */ 03746 while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { 03747 exten = ast_hint_extension(NULL, this->context, this->exten); 03748 /* Find the hint in the list of hints */ 03749 ast_mutex_lock(&hintlock); 03750 for (hint = hints; hint; hint = hint->next) { 03751 if (hint->exten == exten) 03752 break; 03753 } 03754 if (!exten || !hint) { 03755 /* this hint has been removed, notify the watchers */ 03756 prevcb = NULL; 03757 thiscb = this->callbacks; 03758 while (thiscb) { 03759 prevcb = thiscb; 03760 thiscb = thiscb->next; 03761 prevcb->callback(this->context, this->exten, AST_EXTENSION_REMOVED, prevcb->data); 03762 free(prevcb); 03763 } 03764 } else { 03765 thiscb = this->callbacks; 03766 while (thiscb->next) 03767 thiscb = thiscb->next; 03768 thiscb->next = hint->callbacks; 03769 hint->callbacks = this->callbacks; 03770 hint->laststate = this->laststate; 03771 } 03772 ast_mutex_unlock(&hintlock); 03773 free(this); 03774 } 03775 03776 return; 03777 }
|
|
|
|
|
|
|
|
|
|
Lock for the custom function list |
|
|
|
Definition at line 6430 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, ast_channel::exten, LOG_WARNING, ast_channel::priority, s, and strsep(). Referenced by _while_exec(), check_goto_on_transfer(), dial_exec_full(), gosub_exec(), ivr_dispatch(), pbx_builtin_goto(), random_exec(), and return_exec(). 06431 { 06432 char *s; 06433 char *exten, *pri, *context; 06434 char *stringp=NULL; 06435 int ipri; 06436 int mode = 0; 06437 06438 if (ast_strlen_zero(goto_string)) { 06439 ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n"); 06440 return -1; 06441 } 06442 s = ast_strdupa(goto_string); 06443 stringp=s; 06444 context = strsep(&stringp, "|"); 06445 exten = strsep(&stringp, "|"); 06446 if (!exten) { 06447 /* Only a priority in this one */ 06448 pri = context; 06449 exten = NULL; 06450 context = NULL; 06451 } else { 06452 pri = strsep(&stringp, "|"); 06453 if (!pri) { 06454 /* Only an extension and priority in this one */ 06455 pri = exten; 06456 exten = context; 06457 context = NULL; 06458 } 06459 } 06460 if (*pri == '+') { 06461 mode = 1; 06462 pri++; 06463 } else if (*pri == '-') { 06464 mode = -1; 06465 pri++; 06466 } 06467 if (sscanf(pri, "%d", &ipri) != 1) { 06468 if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, (exten && strcasecmp(exten, "BYEXTENSION")) ? exten : chan->exten, 06469 pri, chan->cid.cid_num)) < 1) { 06470 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri); 06471 return -1; 06472 } else 06473 mode = 0; 06474 } 06475 /* At this point we have a priority and maybe an extension and a context */ 06476 06477 if (exten && !strcasecmp(exten, "BYEXTENSION")) 06478 exten = NULL; 06479 06480 if (mode) 06481 ipri = chan->priority + (ipri * mode); 06482 06483 ast_explicit_goto(chan, context, exten, ipri); 06484 ast_cdr_update(chan); 06485 return 0; 06486 06487 }
|
|
Definition at line 5128 of file pbx.c. References __ast_request_and_dial(), ast_channel::_state, app_tmp::app, 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_strlen_zero(), ast_variables_destroy(), ast_verbose(), async_wait(), ast_channel::cdr, app_tmp::chan, async_stat::chan, app_tmp::data, free, ast_channel::hangupcause, ast_channel::lock, LOG_ERROR, LOG_WARNING, malloc, ast_channel::name, option_verbose, async_stat::p, ast_channel::pbx, app_tmp::t, async_stat::timeout, type, outgoing_helper::vars, and VERBOSE_PREFIX_4. Referenced by action_originate(), attempt_thread(), fast_originate(), and page_thread(). 05129 { 05130 struct ast_channel *chan; 05131 struct async_stat *as; 05132 struct app_tmp *tmp; 05133 int res = -1, cdr_res = -1; 05134 struct outgoing_helper oh; 05135 pthread_attr_t attr; 05136 05137 memset(&oh, 0, sizeof(oh)); 05138 oh.vars = vars; 05139 oh.account = account; 05140 05141 if (locked_channel) 05142 *locked_channel = NULL; 05143 if (ast_strlen_zero(app)) { 05144 res = -1; 05145 goto outgoing_app_cleanup; 05146 } 05147 if (sync) { 05148 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05149 if (chan) { 05150 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 05151 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 05152 } else { 05153 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 05154 if(!chan->cdr) { 05155 /* allocation of the cdr failed */ 05156 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 05157 free(chan->pbx); 05158 res = -1; 05159 goto outgoing_app_cleanup; 05160 } 05161 /* allocation of the cdr was successful */ 05162 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 05163 ast_cdr_start(chan->cdr); 05164 } 05165 ast_set_variables(chan, vars); 05166 if (account) 05167 ast_cdr_setaccount(chan, account); 05168 if (chan->_state == AST_STATE_UP) { 05169 res = 0; 05170 if (option_verbose > 3) 05171 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 05172 tmp = malloc(sizeof(struct app_tmp)); 05173 if (tmp) { 05174 memset(tmp, 0, sizeof(struct app_tmp)); 05175 ast_copy_string(tmp->app, app, sizeof(tmp->app)); 05176 if (appdata) 05177 ast_copy_string(tmp->data, appdata, sizeof(tmp->data)); 05178 tmp->chan = chan; 05179 if (sync > 1) { 05180 if (locked_channel) 05181 ast_mutex_unlock(&chan->lock); 05182 ast_pbx_run_app(tmp); 05183 } else { 05184 pthread_attr_init(&attr); 05185 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05186 if (locked_channel) 05187 ast_mutex_lock(&chan->lock); 05188 if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) { 05189 ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno)); 05190 free(tmp); 05191 if (locked_channel) 05192 ast_mutex_unlock(&chan->lock); 05193 ast_hangup(chan); 05194 res = -1; 05195 } else { 05196 if (locked_channel) 05197 *locked_channel = chan; 05198 } 05199 } 05200 } else { 05201 ast_log(LOG_ERROR, "Out of memory :(\n"); 05202 res = -1; 05203 } 05204 } else { 05205 if (option_verbose > 3) 05206 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05207 if (chan->cdr) { /* update the cdr */ 05208 /* here we update the status of the call, which sould be busy. 05209 * if that fails then we set the status to failed */ 05210 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05211 ast_cdr_failed(chan->cdr); 05212 } 05213 ast_hangup(chan); 05214 } 05215 } 05216 05217 if (res < 0) { /* the call failed for some reason */ 05218 if (*reason == 0) { /* if the call failed (not busy or no answer) 05219 * update the cdr with the failed message */ 05220 cdr_res = ast_pbx_outgoing_cdr_failed(); 05221 if (cdr_res != 0) { 05222 res = cdr_res; 05223 goto outgoing_app_cleanup; 05224 } 05225 } 05226 } 05227 05228 } else { 05229 as = malloc(sizeof(struct async_stat)); 05230 if (!as) { 05231 res = -1; 05232 goto outgoing_app_cleanup; 05233 } 05234 memset(as, 0, sizeof(struct async_stat)); 05235 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 05236 if (!chan) { 05237 free(as); 05238 res = -1; 05239 goto outgoing_app_cleanup; 05240 } 05241 as->chan = chan; 05242 ast_copy_string(as->app, app, sizeof(as->app)); 05243 if (appdata) 05244 ast_copy_string(as->appdata, appdata, sizeof(as->appdata)); 05245 as->timeout = timeout; 05246 ast_set_variables(chan, vars); 05247 if (account) 05248 ast_cdr_setaccount(chan, account); 05249 /* Start a new thread, and get something handling this channel. */ 05250 pthread_attr_init(&attr); 05251 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05252 if (locked_channel) 05253 ast_mutex_lock(&chan->lock); 05254 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05255 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05256 free(as); 05257 if (locked_channel) 05258 ast_mutex_unlock(&chan->lock); 05259 ast_hangup(chan); 05260 res = -1; 05261 goto outgoing_app_cleanup; 05262 } else { 05263 if (locked_channel) 05264 *locked_channel = chan; 05265 } 05266 res = 0; 05267 } 05268 outgoing_app_cleanup: 05269 ast_variables_destroy(vars); 05270 return res; 05271 }
|
|
Function to update the cdr after a spool call fails. This function updates the cdr for a failed spool call and takes the channel of the failed call as an argument. Definition at line 4930 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(). 04931 { 04932 /* allocate a channel */ 04933 struct ast_channel *chan = ast_channel_alloc(0); 04934 if(!chan) { 04935 /* allocation of the channel failed, let some peeps know */ 04936 ast_log(LOG_WARNING, "Unable to allocate channel structure for CDR record\n"); 04937 return -1; /* failure */ 04938 } 04939 04940 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 04941 04942 if(!chan->cdr) { 04943 /* allocation of the cdr failed */ 04944 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 04945 ast_channel_free(chan); /* free the channel */ 04946 return -1; /* return failure */ 04947 } 04948 04949 /* allocation of the cdr was successful */ 04950 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 04951 ast_cdr_start(chan->cdr); /* record the start and stop time */ 04952 ast_cdr_end(chan->cdr); 04953 ast_cdr_failed(chan->cdr); /* set the status to failed */ 04954 ast_cdr_detach(chan->cdr); /* post and free the record */ 04955 ast_channel_free(chan); /* free the channel */ 04956 04957 return 0; /* success */ 04958 }
|
|
Definition at line 4960 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_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, type, and VERBOSE_PREFIX_4. Referenced by action_originate(), attempt_thread(), and fast_originate(). 04961 { 04962 struct ast_channel *chan; 04963 struct async_stat *as; 04964 int res = -1, cdr_res = -1; 04965 struct outgoing_helper oh; 04966 pthread_attr_t attr; 04967 04968 if (sync) { 04969 LOAD_OH(oh); 04970 chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); 04971 if (channel) { 04972 *channel = chan; 04973 if (chan) 04974 ast_mutex_lock(&chan->lock); 04975 } 04976 if (chan) { 04977 if (chan->cdr) { /* check if the channel already has a cdr record, if not give it one */ 04978 ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name); 04979 } else { 04980 chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */ 04981 if (!chan->cdr) { 04982 /* allocation of the cdr failed */ 04983 ast_log(LOG_WARNING, "Unable to create Call Detail Record\n"); 04984 free(chan->pbx); 04985 res = -1; 04986 goto outgoing_exten_cleanup; 04987 } 04988 /* allocation of the cdr was successful */ 04989 ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */ 04990 ast_cdr_start(chan->cdr); 04991 } 04992 if (chan->_state == AST_STATE_UP) { 04993 res = 0; 04994 if (option_verbose > 3) 04995 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name); 04996 04997 if (sync > 1) { 04998 if (channel) 04999 ast_mutex_unlock(&chan->lock); 05000 if (ast_pbx_run(chan)) { 05001 ast_log(LOG_ERROR, "Unable to run PBX on %s\n", chan->name); 05002 if (channel) 05003 *channel = NULL; 05004 ast_hangup(chan); 05005 res = -1; 05006 } 05007 } else { 05008 if (ast_pbx_start(chan)) { 05009 ast_log(LOG_ERROR, "Unable to start PBX on %s\n", chan->name); 05010 if (channel) 05011 *channel = NULL; 05012 ast_hangup(chan); 05013 res = -1; 05014 } 05015 } 05016 } else { 05017 if (option_verbose > 3) 05018 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name); 05019 05020 if(chan->cdr) { /* update the cdr */ 05021 /* here we update the status of the call, which sould be busy. 05022 * if that fails then we set the status to failed */ 05023 if (ast_cdr_disposition(chan->cdr, chan->hangupcause)) 05024 ast_cdr_failed(chan->cdr); 05025 } 05026 05027 if (channel) 05028 *channel = NULL; 05029 ast_hangup(chan); 05030 } 05031 } 05032 05033 if(res < 0) { /* the call failed for some reason */ 05034 if (*reason == 0) { /* if the call failed (not busy or no answer) 05035 * update the cdr with the failed message */ 05036 cdr_res = ast_pbx_outgoing_cdr_failed(); 05037 if (cdr_res != 0) { 05038 res = cdr_res; 05039 goto outgoing_exten_cleanup; 05040 } 05041 } 05042 05043 /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ 05044 /* check if "failed" exists */ 05045 if (ast_exists_extension(chan, context, "failed", 1, NULL)) { 05046 chan = ast_channel_alloc(0); 05047 if (chan) { 05048 ast_copy_string(chan->name, "OutgoingSpoolFailed", sizeof(chan->name)); 05049 if (!ast_strlen_zero(context)) 05050 ast_copy_string(chan->context, context, sizeof(chan->context)); 05051 ast_copy_string(chan->exten, "failed", sizeof(chan->exten)); 05052 chan->priority = 1; 05053 ast_set_variables(chan, vars); 05054 if (account) 05055 ast_cdr_setaccount(chan, account); 05056 ast_pbx_run(chan); 05057 } else 05058 ast_log(LOG_WARNING, "Can't allocate the channel structure, skipping execution of extension 'failed'\n"); 05059 } 05060 } 05061 } else { 05062 as = malloc(sizeof(struct async_stat)); 05063 if (!as) { 05064 res = -1; 05065 goto outgoing_exten_cleanup; 05066 } 05067 memset(as, 0, sizeof(struct async_stat)); 05068 chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); 05069 if (channel) { 05070 *channel = chan; 05071 if (chan) 05072 ast_mutex_lock(&chan->lock); 05073 } 05074 if (!chan) { 05075 free(as); 05076 res = -1; 05077 goto outgoing_exten_cleanup; 05078 } 05079 as->chan = chan; 05080 ast_copy_string(as->context, context, sizeof(as->context)); 05081 ast_copy_string(as->exten, exten, sizeof(as->exten)); 05082 as->priority = priority; 05083 as->timeout = timeout; 05084 ast_set_variables(chan, vars); 05085 if (account) 05086 ast_cdr_setaccount(chan, account); 05087 pthread_attr_init(&attr); 05088 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05089 if (ast_pthread_create(&as->p, &attr, async_wait, as)) { 05090 ast_log(LOG_WARNING, "Failed to start async wait\n"); 05091 free(as); 05092 if (channel) 05093 *channel = NULL; 05094 ast_hangup(chan); 05095 res = -1; 05096 goto outgoing_exten_cleanup; 05097 } 05098 res = 0; 05099 } 05100 outgoing_exten_cleanup: 05101 ast_variables_destroy(vars); 05102 return res; 05103 }
|
|
Definition at line 2537 of file pbx.c. References __ast_pbx_run(), ast_pbx_result, decrease_call_count(), and increase_call_count(). Referenced by ast_pbx_outgoing_exten(), async_wait(), mgcp_ss(), skinny_ss(), and ss_thread(). 02538 { 02539 enum ast_pbx_result res = AST_PBX_SUCCESS; 02540 02541 if (increase_call_count(c)) 02542 return AST_PBX_CALL_LIMIT; 02543 02544 res = __ast_pbx_run(c); 02545 decrease_call_count(); 02546 02547 return res; 02548 }
|
|
Definition at line 5112 of file pbx.c. References app_tmp::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(). 05113 { 05114 struct app_tmp *tmp = data; 05115 struct ast_app *app; 05116 app = pbx_findapp(tmp->app); 05117 if (app) { 05118 if (option_verbose > 3) 05119 ast_verbose(VERBOSE_PREFIX_4 "Launching %s(%s) on %s\n", tmp->app, tmp->data, tmp->chan->name); 05120 pbx_exec(tmp->chan, app, tmp->data, 1); 05121 } else 05122 ast_log(LOG_WARNING, "No such application '%s'\n", tmp->app); 05123 ast_hangup(tmp->chan); 05124 free(tmp); 05125 return NULL; 05126 }
|
|
Definition at line 2513 of file pbx.c. References ast_log(), ast_pbx_result, ast_pthread_create, increase_call_count(), LOG_WARNING, and pbx_thread(). Referenced by __oh323_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_modem_new(), ast_pbx_outgoing_exten(), cb_events(), check_goto_on_transfer(), dial_exec_full(), do_immediate_setup(), do_parking_thread(), handle_request_invite(), local_call(), mgcp_new(), nbs_new(), oss_new(), phone_new(), rpt_call(), sip_new(), skinny_new(), vpb_new(), and zt_new(). 02514 { 02515 pthread_t t; 02516 pthread_attr_t attr; 02517 02518 if (!c) { 02519 ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n"); 02520 return AST_PBX_FAILED; 02521 } 02522 02523 if (increase_call_count(c)) 02524 return AST_PBX_CALL_LIMIT; 02525 02526 /* Start a new thread, and get something handling this channel. */ 02527 pthread_attr_init(&attr); 02528 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02529 if (ast_pthread_create(&t, &attr, pbx_thread, c)) { 02530 ast_log(LOG_WARNING, "Failed to create new channel thread\n"); 02531 return AST_PBX_FAILED; 02532 } 02533 02534 return AST_PBX_SUCCESS; 02535 }
|
|
Dynamically register a new dial plan application.
Definition at line 2854 of file pbx.c. References apps, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), COLOR_BRCYAN, ast_app::description, ast_app::execute, LOG_ERROR, LOG_WARNING, malloc, ast_app::name, ast_app::next, option_verbose, ast_app::synopsis, term_color(), and VERBOSE_PREFIX_2. Referenced by load_module(), and load_pbx(). 02855 { 02856 struct ast_app *tmp, *prev, *cur; 02857 char tmps[80]; 02858 int length; 02859 length = sizeof(struct ast_app); 02860 length += strlen(app) + 1; 02861 if (ast_mutex_lock(&applock)) { 02862 ast_log(LOG_ERROR, "Unable to lock application list\n"); 02863 return -1; 02864 } 02865 tmp = apps; 02866 while(tmp) { 02867 if (!strcasecmp(app, tmp->name)) { 02868 ast_log(LOG_WARNING, "Already have an application '%s'\n", app); 02869 ast_mutex_unlock(&applock); 02870 return -1; 02871 } 02872 tmp = tmp->next; 02873 } 02874 tmp = malloc(length); 02875 if (tmp) { 02876 memset(tmp, 0, length); 02877 strcpy(tmp->name, app); 02878 tmp->execute = execute; 02879 tmp->synopsis = synopsis; 02880 tmp->description = description; 02881 /* Store in alphabetical order */ 02882 cur = apps; 02883 prev = NULL; 02884 while(cur) { 02885 if (strcasecmp(tmp->name, cur->name) < 0) 02886 break; 02887 prev = cur; 02888 cur = cur->next; 02889 } 02890 if (prev) { 02891 tmp->next = prev->next; 02892 prev->next = tmp; 02893 } else { 02894 tmp->next = apps; 02895 apps = tmp; 02896 } 02897 } else { 02898 ast_log(LOG_ERROR, "Out of memory\n"); 02899 ast_mutex_unlock(&applock); 02900 return -1; 02901 } 02902 if (option_verbose > 1) 02903 ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps))); 02904 ast_mutex_unlock(&applock); 02905 return 0; 02906 }
|
|
Definition at line 2908 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(). 02909 { 02910 struct ast_switch *tmp, *prev=NULL; 02911 if (ast_mutex_lock(&switchlock)) { 02912 ast_log(LOG_ERROR, "Unable to lock switch lock\n"); 02913 return -1; 02914 } 02915 tmp = switches; 02916 while(tmp) { 02917 if (!strcasecmp(tmp->name, sw->name)) 02918 break; 02919 prev = tmp; 02920 tmp = tmp->next; 02921 } 02922 if (tmp) { 02923 ast_mutex_unlock(&switchlock); 02924 ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name); 02925 return -1; 02926 } 02927 sw->next = NULL; 02928 if (prev) 02929 prev->next = sw; 02930 else 02931 switches = sw; 02932 ast_mutex_unlock(&switchlock); 02933 return 0; 02934 }
|
|
ast_remove_hint: Remove hint from extension
Definition at line 2127 of file pbx.c. References AST_EXTENSION_DEACTIVATED, ast_mutex_lock(), ast_mutex_unlock(), ast_state_cb::callback, ast_hint::callbacks, ast_state_cb::data, ast_exten::exten, ast_hint::exten, free, hints, ast_context::name, ast_hint::next, ast_state_cb::next, and ast_exten::parent. Referenced by ast_context_remove_extension2(), and destroy_exten(). 02128 { 02129 /* Cleanup the Notifys if hint is removed */ 02130 struct ast_hint *list, *prev = NULL; 02131 struct ast_state_cb *cblist, *cbprev; 02132 02133 if (!e) 02134 return -1; 02135 02136 ast_mutex_lock(&hintlock); 02137 02138 list = hints; 02139 while(list) { 02140 if (list->exten==e) { 02141 cbprev = NULL; 02142 cblist = list->callbacks; 02143 while (cblist) { 02144 /* Notify with -1 and remove all callbacks */ 02145 cbprev = cblist; 02146 cblist = cblist->next; 02147 cbprev->callback(list->exten->parent->name, list->exten->exten, AST_EXTENSION_DEACTIVATED, cbprev->data); 02148 free(cbprev); 02149 } 02150 list->callbacks = NULL; 02151 02152 if (!prev) 02153 hints = list->next; 02154 else 02155 prev->next = list->next; 02156 free(list); 02157 02158 ast_mutex_unlock(&hintlock); 02159 return 0; 02160 } else { 02161 prev = list; 02162 list = list->next; 02163 } 02164 } 02165 02166 ast_mutex_unlock(&hintlock); 02167 return -1; 02168 }
|
|
Definition at line 2216 of file pbx.c. References HELPER_SPAWN, and pbx_extension_helper(). Referenced by __ast_pbx_run(), loopback_exec(), and macro_exec(). 02217 { 02218 return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, HELPER_SPAWN); 02219 }
|
|
Definition at line 6238 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(), handle_save_dialplan(), and show_dialplan_helper(). 06239 { 06240 return ast_mutex_unlock(&con->lock); 06241 }
|
|
Returns 0 on success, -1 on failure Definition at line 6225 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(), find_matching_endwhile(), handle_save_dialplan(), and show_dialplan_helper(). 06226 { 06227 return ast_mutex_unlock(&conlock); 06228 }
|
|
Definition at line 3601 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(). 03602 { 03603 struct ast_app *tmp, *tmpl = NULL; 03604 if (ast_mutex_lock(&applock)) { 03605 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03606 return -1; 03607 } 03608 tmp = apps; 03609 while(tmp) { 03610 if (!strcasecmp(app, tmp->name)) { 03611 if (tmpl) 03612 tmpl->next = tmp->next; 03613 else 03614 apps = tmp->next; 03615 if (option_verbose > 1) 03616 ast_verbose( VERBOSE_PREFIX_2 "Unregistered application '%s'\n", tmp->name); 03617 free(tmp); 03618 ast_mutex_unlock(&applock); 03619 return 0; 03620 } 03621 tmpl = tmp; 03622 tmp = tmp->next; 03623 } 03624 ast_mutex_unlock(&applock); 03625 return -1; 03626 }
|
|
Definition at line 2936 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(). 02937 { 02938 struct ast_switch *tmp, *prev=NULL; 02939 if (ast_mutex_lock(&switchlock)) { 02940 ast_log(LOG_ERROR, "Unable to lock switch lock\n"); 02941 return; 02942 } 02943 tmp = switches; 02944 while(tmp) { 02945 if (tmp == sw) { 02946 if (prev) 02947 prev->next = tmp->next; 02948 else 02949 switches = tmp->next; 02950 tmp->next = NULL; 02951 break; 02952 } 02953 prev = tmp; 02954 tmp = tmp->next; 02955 } 02956 ast_mutex_unlock(&switchlock); 02957 }
|
|
Definition at line 6345 of file pbx.c. References ast_exten::next, and ast_context::root. Referenced by complete_context_remove_extension(), dundi_precache_full(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper(). 06347 { 06348 if (!exten) 06349 return con ? con->root : NULL; 06350 else 06351 return exten->next; 06352 }
|
|
Definition at line 6381 of file pbx.c. References ast_context::ignorepats, and ast_ignorepat::next. Referenced by complete_context_add_ignorepat(), complete_context_remove_ignorepat(), handle_save_dialplan(), and show_dialplan_helper(). 06383 { 06384 if (!ip) 06385 return con ? con->ignorepats : NULL; 06386 else 06387 return ip->next; 06388 }
|
|
Definition at line 6372 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(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper(). 06374 { 06375 if (!inc) 06376 return con ? con->includes : NULL; 06377 else 06378 return inc->next; 06379 }
|
|
Definition at line 6354 of file pbx.c. References ast_context::alts, and ast_sw::next. Referenced by handle_save_dialplan(), and show_dialplan_helper(). 06356 { 06357 if (!sw) 06358 return con ? con->alts : NULL; 06359 else 06360 return sw->next; 06361 }
|
|
Definition at line 6337 of file pbx.c. References 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(), find_matching_priority(), handle_save_dialplan(), pbx_load_module(), and show_dialplan_helper(). 06338 { 06339 if (!con) 06340 return contexts; 06341 else 06342 return con->next; 06343 }
|
|
Definition at line 6363 of file pbx.c. References ast_exten::peer. Referenced by complete_context_remove_extension(), find_matching_priority(), handle_save_dialplan(), and show_dialplan_helper(). 06365 { 06366 if (!priority) 06367 return exten; 06368 else 06369 return priority->peer; 06370 }
|
|
Definition at line 4867 of file pbx.c. References ast_channel::_state, async_stat::app, async_stat::appdata, ast_frfree(), ast_hangup(), ast_log(), ast_pbx_run(), ast_read(), 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(). 04868 { 04869 struct async_stat *as = data; 04870 struct ast_channel *chan = as->chan; 04871 int timeout = as->timeout; 04872 int res; 04873 struct ast_frame *f; 04874 struct ast_app *app; 04875 04876 while(timeout && (chan->_state != AST_STATE_UP)) { 04877 res = ast_waitfor(chan, timeout); 04878 if (res < 1) 04879 break; 04880 if (timeout > -1) 04881 timeout = res; 04882 f = ast_read(chan); 04883 if (!f) 04884 break; 04885 if (f->frametype == AST_FRAME_CONTROL) { 04886 if ((f->subclass == AST_CONTROL_BUSY) || 04887 (f->subclass == AST_CONTROL_CONGESTION) ) 04888 break; 04889 } 04890 ast_frfree(f); 04891 } 04892 if (chan->_state == AST_STATE_UP) { 04893 if (!ast_strlen_zero(as->app)) { 04894 app = pbx_findapp(as->app); 04895 if (app) { 04896 if (option_verbose > 2) 04897 ast_verbose(VERBOSE_PREFIX_3 "Launching %s(%s) on %s\n", as->app, as->appdata, chan->name); 04898 pbx_exec(chan, app, as->appdata, 1); 04899 } else 04900 ast_log(LOG_WARNING, "No such application '%s'\n", as->app); 04901 } else { 04902 if (!ast_strlen_zero(as->context)) 04903 ast_copy_string(chan->context, as->context, sizeof(chan->context)); 04904 if (!ast_strlen_zero(as->exten)) 04905 ast_copy_string(chan->exten, as->exten, sizeof(chan->exten)); 04906 if (as->priority > 0) 04907 chan->priority = as->priority; 04908 /* Run the PBX */ 04909 if (ast_pbx_run(chan)) { 04910 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", chan->name); 04911 } else { 04912 /* PBX will have taken care of this */ 04913 chan = NULL; 04914 } 04915 } 04916 04917 } 04918 free(as); 04919 if (chan) 04920 ast_hangup(chan); 04921 return NULL; 04922 }
|
|
Definition at line 3007 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_app::name, ast_app::next, and strdup. 03009 { 03010 struct ast_app *a; 03011 int which = 0; 03012 03013 /* try to lock applications list ... */ 03014 if (ast_mutex_lock(&applock)) { 03015 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03016 return NULL; 03017 } 03018 03019 /* ... walk all applications ... */ 03020 a = apps; 03021 while (a) { 03022 /* ... check if word matches this application ... */ 03023 if (!strncasecmp(word, a->name, strlen(word))) { 03024 /* ... if this is right app serve it ... */ 03025 if (++which > state) { 03026 char *ret = strdup(a->name); 03027 ast_mutex_unlock(&applock); 03028 return ret; 03029 } 03030 } 03031 a = a->next; 03032 } 03033 03034 /* no application match */ 03035 ast_mutex_unlock(&applock); 03036 return NULL; 03037 }
|
|
Definition at line 3254 of file pbx.c. References ast_strlen_zero(), and strdup. 03255 { 03256 if (pos == 2) { 03257 if (ast_strlen_zero(word)) { 03258 switch (state) { 03259 case 0: 03260 return strdup("like"); 03261 case 1: 03262 return strdup("describing"); 03263 default: 03264 return NULL; 03265 } 03266 } else if (! strncasecmp(word, "like", strlen(word))) { 03267 if (state == 0) { 03268 return strdup("like"); 03269 } else { 03270 return NULL; 03271 } 03272 } else if (! strncasecmp(word, "describing", strlen(word))) { 03273 if (state == 0) { 03274 return strdup("describing"); 03275 } else { 03276 return NULL; 03277 } 03278 } 03279 } 03280 return NULL; 03281 }
|
|
Definition at line 3286 of file pbx.c. References ast_get_context_name(), ast_lock_contexts(), ast_log(), ast_unlock_contexts(), ast_walk_contexts(), LOG_ERROR, and strdup. 03288 { 03289 struct ast_context *c; 03290 int which = 0; 03291 03292 /* we are do completion of [exten@]context on second position only */ 03293 if (pos != 2) return NULL; 03294 03295 /* try to lock contexts list ... */ 03296 if (ast_lock_contexts()) { 03297 ast_log(LOG_ERROR, "Unable to lock context list\n"); 03298 return NULL; 03299 } 03300 03301 /* ... walk through all contexts ... */ 03302 c = ast_walk_contexts(NULL); 03303 while(c) { 03304 /* ... word matches context name? yes? ... */ 03305 if (!strncasecmp(word, ast_get_context_name(c), strlen(word))) { 03306 /* ... for serve? ... */ 03307 if (++which > state) { 03308 /* ... yes, serve this context name ... */ 03309 char *ret = strdup(ast_get_context_name(c)); 03310 ast_unlock_contexts(); 03311 return ret; 03312 } 03313 } 03314 c = ast_walk_contexts(c); 03315 } 03316 03317 /* ... unlock and return */ 03318 ast_unlock_contexts(); 03319 return NULL; 03320 }
|
|
Definition at line 1229 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, ast_custom_function::name, ast_custom_function::next, and strdup. 01230 { 01231 struct ast_custom_function *acf; 01232 int which = 0; 01233 01234 /* try to lock functions list ... */ 01235 if (ast_mutex_lock(&acflock)) { 01236 ast_log(LOG_ERROR, "Unable to lock function list\n"); 01237 return NULL; 01238 } 01239 01240 acf = acf_root; 01241 while (acf) { 01242 if (!strncasecmp(word, acf->name, strlen(word))) { 01243 if (++which > state) { 01244 char *ret = strdup(acf->name); 01245 ast_mutex_unlock(&acflock); 01246 return ret; 01247 } 01248 } 01249 acf = acf->next; 01250 } 01251 01252 ast_mutex_unlock(&acflock); 01253 return NULL; 01254 }
|
|
Definition at line 2485 of file pbx.c. References ast_mutex_lock(), ast_mutex_unlock(), and countcalls. Referenced by ast_pbx_run(), and pbx_thread(). 02486 { 02487 ast_mutex_lock(&maxcalllock); 02488 if (countcalls > 0) 02489 countcalls--; 02490 ast_mutex_unlock(&maxcalllock); 02491 }
|
|
Definition at line 5273 of file pbx.c. References ast_remove_hint(), ast_exten::data, ast_exten::datad, free, and ast_exten::priority. Referenced by __ast_context_destroy(). 05274 { 05275 if (e->priority == PRIORITY_HINT) 05276 ast_remove_hint(e); 05277 05278 if (e->datad) 05279 e->datad(e->data); 05280 free(e); 05281 }
|
|
Definition at line 4591 of file pbx.c. Referenced by ast_add_extension2(). 04592 { 04593 int count=0; 04594 04595 while(*src && (count < len - 1)) { 04596 switch(*src) { 04597 case ' ': 04598 /* otherwise exten => [a-b],1,... doesn't work */ 04599 /* case '-': */ 04600 /* Ignore */ 04601 break; 04602 default: 04603 *dst = *src; 04604 dst++; 04605 } 04606 src++; 04607 count++; 04608 } 04609 *dst = '\0'; 04610 04611 return count; 04612 }
|
|
Definition at line 3957 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and s. Referenced by ast_build_timing(). 03958 { 03959 char *c; 03960 /* The following line is coincidence, really! */ 03961 int s, e, x; 03962 unsigned int mask; 03963 03964 /* Check for all days */ 03965 if (ast_strlen_zero(day) || !strcmp(day, "*")) { 03966 mask = (1 << 30) + ((1 << 30) - 1); 03967 return mask; 03968 } 03969 /* Get start and ending days */ 03970 c = strchr(day, '-'); 03971 if (c) { 03972 *c = '\0'; 03973 c++; 03974 } 03975 /* Find the start */ 03976 if (sscanf(day, "%d", &s) != 1) { 03977 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day); 03978 return 0; 03979 } 03980 if ((s < 1) || (s > 31)) { 03981 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day); 03982 return 0; 03983 } 03984 s--; 03985 if (c) { 03986 if (sscanf(c, "%d", &e) != 1) { 03987 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 03988 return 0; 03989 } 03990 if ((e < 1) || (e > 31)) { 03991 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 03992 return 0; 03993 } 03994 e--; 03995 } else 03996 e = s; 03997 mask = 0; 03998 for (x=s; x!=e; x = (x + 1) % 31) { 03999 mask |= (1 << x); 04000 } 04001 mask |= (1 << x); 04002 return mask; 04003 }
|
|
get_dow: Get day of week
Definition at line 3915 of file pbx.c. References ast_log(), ast_strlen_zero(), days, LOG_WARNING, and s. Referenced by ast_build_timing(). 03916 { 03917 char *c; 03918 /* The following line is coincidence, really! */ 03919 int s, e, x; 03920 unsigned int mask; 03921 03922 /* Check for all days */ 03923 if (ast_strlen_zero(dow) || !strcmp(dow, "*")) 03924 return (1 << 7) - 1; 03925 /* Get start and ending days */ 03926 c = strchr(dow, '-'); 03927 if (c) { 03928 *c = '\0'; 03929 c++; 03930 } else 03931 c = NULL; 03932 /* Find the start */ 03933 s = 0; 03934 while((s < 7) && strcasecmp(dow, days[s])) s++; 03935 if (s >= 7) { 03936 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", dow); 03937 return 0; 03938 } 03939 if (c) { 03940 e = 0; 03941 while((e < 7) && strcasecmp(c, days[e])) e++; 03942 if (e >= 7) { 03943 ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c); 03944 return 0; 03945 } 03946 } else 03947 e = s; 03948 mask = 0; 03949 for (x=s; x != e; x = (x + 1) % 7) { 03950 mask |= (1 << x); 03951 } 03952 /* One last one */ 03953 mask |= (1 << x); 03954 return mask; 03955 }
|
|
Definition at line 4021 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, months, and s. Referenced by ast_build_timing(). 04022 { 04023 char *c; 04024 /* The following line is coincidence, really! */ 04025 int s, e, x; 04026 unsigned int mask; 04027 04028 /* Check for all days */ 04029 if (ast_strlen_zero(mon) || !strcmp(mon, "*")) 04030 return (1 << 12) - 1; 04031 /* Get start and ending days */ 04032 c = strchr(mon, '-'); 04033 if (c) { 04034 *c = '\0'; 04035 c++; 04036 } 04037 /* Find the start */ 04038 s = 0; 04039 while((s < 12) && strcasecmp(mon, months[s])) s++; 04040 if (s >= 12) { 04041 ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", mon); 04042 return 0; 04043 } 04044 if (c) { 04045 e = 0; 04046 while((e < 12) && strcasecmp(mon, months[e])) e++; 04047 if (e >= 12) { 04048 ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", c); 04049 return 0; 04050 } 04051 } else 04052 e = s; 04053 mask = 0; 04054 for (x=s; x!=e; x = (x + 1) % 12) { 04055 mask |= (1 << x); 04056 } 04057 /* One last one */ 04058 mask |= (1 << x); 04059 return mask; 04060 }
|
|
Definition at line 3819 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_timing::minmask. Referenced by ast_build_timing(). 03820 { 03821 char *e; 03822 int x; 03823 int s1, s2; 03824 int e1, e2; 03825 /* int cth, ctm; */ 03826 03827 /* start disabling all times, fill the fields with 0's, as they may contain garbage */ 03828 memset(i->minmask, 0, sizeof(i->minmask)); 03829 03830 /* Star is all times */ 03831 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 03832 for (x=0; x<24; x++) 03833 i->minmask[x] = (1 << 30) - 1; 03834 return; 03835 } 03836 /* Otherwise expect a range */ 03837 e = strchr(times, '-'); 03838 if (!e) { 03839 ast_log(LOG_WARNING, "Time range is not valid. Assuming no restrictions based on time.\n"); 03840 return; 03841 } 03842 *e = '\0'; 03843 e++; 03844 while(*e && !isdigit(*e)) 03845 e++; 03846 if (!*e) { 03847 ast_log(LOG_WARNING, "Invalid time range. Assuming no restrictions based on time.\n"); 03848 return; 03849 } 03850 if (sscanf(times, "%d:%d", &s1, &s2) != 2) { 03851 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", times); 03852 return; 03853 } 03854 if (sscanf(e, "%d:%d", &e1, &e2) != 2) { 03855 ast_log(LOG_WARNING, "%s isn't a time. Assuming no restrictions based on time.\n", e); 03856 return; 03857 } 03858 03859 #if 1 03860 s1 = s1 * 30 + s2/2; 03861 if ((s1 < 0) || (s1 >= 24*30)) { 03862 ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times); 03863 return; 03864 } 03865 e1 = e1 * 30 + e2/2; 03866 if ((e1 < 0) || (e1 >= 24*30)) { 03867 ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e); 03868 return; 03869 } 03870 /* Go through the time and enable each appropriate bit */ 03871 for (x=s1;x != e1;x = (x + 1) % (24 * 30)) { 03872 i->minmask[x/30] |= (1 << (x % 30)); 03873 } 03874 /* Do the last one */ 03875 i->minmask[x/30] |= (1 << (x % 30)); 03876 #else 03877 for (cth=0; cth<24; cth++) { 03878 /* Initialize masks to blank */ 03879 i->minmask[cth] = 0; 03880 for (ctm=0; ctm<30; ctm++) { 03881 if ( 03882 /* First hour with more than one hour */ 03883 (((cth == s1) && (ctm >= s2)) && 03884 ((cth < e1))) 03885 /* Only one hour */ 03886 || (((cth == s1) && (ctm >= s2)) && 03887 ((cth == e1) && (ctm <= e2))) 03888 /* In between first and last hours (more than 2 hours) */ 03889 || ((cth > s1) && 03890 (cth < e1)) 03891 /* Last hour with more than one hour */ 03892 || ((cth > s1) && 03893 ((cth == e1) && (ctm <= e2))) 03894 ) 03895 i->minmask[cth] |= (1 << (ctm / 2)); 03896 } 03897 } 03898 #endif 03899 /* All done */ 03900 return; 03901 }
|
|
Definition at line 3039 of file pbx.c. References ast_cli(), ast_log(), AST_MAX_APP, ast_mutex_lock(), ast_mutex_unlock(), COLOR_CYAN, COLOR_MAGENTA, ast_app::description, description, LOG_ERROR, ast_app::name, ast_app::next, ast_app::synopsis, and term_color(). 03040 { 03041 struct ast_app *a; 03042 int app, no_registered_app = 1; 03043 03044 if (argc < 3) return RESULT_SHOWUSAGE; 03045 03046 /* try to lock applications list ... */ 03047 if (ast_mutex_lock(&applock)) { 03048 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03049 return -1; 03050 } 03051 03052 /* ... go through all applications ... */ 03053 a = apps; 03054 while (a) { 03055 /* ... compare this application name with all arguments given 03056 * to 'show application' command ... */ 03057 for (app = 2; app < argc; app++) { 03058 if (!strcasecmp(a->name, argv[app])) { 03059 /* Maximum number of characters added by terminal coloring is 22 */ 03060 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 03061 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 03062 int synopsis_size, description_size; 03063 03064 no_registered_app = 0; 03065 03066 if (a->synopsis) 03067 synopsis_size = strlen(a->synopsis) + 23; 03068 else 03069 synopsis_size = strlen("Not available") + 23; 03070 synopsis = alloca(synopsis_size); 03071 03072 if (a->description) 03073 description_size = strlen(a->description) + 23; 03074 else 03075 description_size = strlen("Not available") + 23; 03076 description = alloca(description_size); 03077 03078 if (synopsis && description) { 03079 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name); 03080 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 03081 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 03082 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 03083 term_color(synopsis, 03084 a->synopsis ? a->synopsis : "Not available", 03085 COLOR_CYAN, 0, synopsis_size); 03086 term_color(description, 03087 a->description ? a->description : "Not available", 03088 COLOR_CYAN, 0, description_size); 03089 03090 ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); 03091 } else { 03092 /* ... one of our applications, show info ...*/ 03093 ast_cli(fd,"\n -= Info about application '%s' =- \n\n" 03094 "[Synopsis]\n %s\n\n" 03095 "[Description]\n%s\n", 03096 a->name, 03097 a->synopsis ? a->synopsis : "Not available", 03098 a->description ? a->description : "Not available"); 03099 } 03100 } 03101 } 03102 a = a->next; 03103 } 03104 03105 ast_mutex_unlock(&applock); 03106 03107 /* we found at least one app? no? */ 03108 if (no_registered_app) { 03109 ast_cli(fd, "Your application(s) is (are) not registered\n"); 03110 return RESULT_FAILURE; 03111 } 03112 03113 return RESULT_SUCCESS; 03114 }
|
|
Definition at line 3177 of file pbx.c. References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_app::description, LOG_ERROR, ast_app::name, ast_app::next, strcasestr(), and ast_app::synopsis. 03178 { 03179 struct ast_app *a; 03180 int like=0, describing=0; 03181 int total_match = 0; /* Number of matches in like clause */ 03182 int total_apps = 0; /* Number of apps registered */ 03183 03184 /* try to lock applications list ... */ 03185 if (ast_mutex_lock(&applock)) { 03186 ast_log(LOG_ERROR, "Unable to lock application list\n"); 03187 return -1; 03188 } 03189 03190 /* ... have we got at least one application (first)? no? */ 03191 if (!apps) { 03192 ast_cli(fd, "There are no registered applications\n"); 03193 ast_mutex_unlock(&applock); 03194 return -1; 03195 } 03196 03197 /* show applications like <keyword> */ 03198 if ((argc == 4) && (!strcmp(argv[2], "like"))) { 03199 like = 1; 03200 } else if ((argc > 3) && (!strcmp(argv[2], "describing"))) { 03201 describing = 1; 03202 } 03203 03204 /* show applications describing <keyword1> [<keyword2>] [...] */ 03205 if ((!like) && (!describing)) { 03206 ast_cli(fd, " -= Registered Asterisk Applications =-\n"); 03207 } else { 03208 ast_cli(fd, " -= Matching Asterisk Applications =-\n"); 03209 } 03210 03211 /* ... go through all applications ... */ 03212 for (a = apps; a; a = a->next) { 03213 /* ... show informations about applications ... */ 03214 int printapp=0; 03215 total_apps++; 03216 if (like) { 03217 if (strcasestr(a->name, argv[3])) { 03218 printapp = 1; 03219 total_match++; 03220 } 03221 } else if (describing) { 03222 if (a->description) { 03223 /* Match all words on command line */ 03224 int i; 03225 printapp = 1; 03226 for (i=3; i<argc; i++) { 03227 if (!strcasestr(a->description, argv[i])) { 03228 printapp = 0; 03229 } else { 03230 total_match++; 03231 } 03232 } 03233 } 03234 } else { 03235 printapp = 1; 03236 } 03237 03238 if (printapp) { 03239 ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>"); 03240 } 03241 } 03242 if ((!like) && (!describing)) { 03243 ast_cli(fd, " -= %d Applications Registered =-\n",total_apps); 03244 } else { 03245 ast_cli(fd, " -= %d Applications Matching =-\n",total_match); 03246 } 03247 03248 /* ... unlock and return */ 03249 ast_mutex_unlock(&applock); 03250 03251 return RESULT_SUCCESS; 03252 }
|
|
Definition at line 3517 of file pbx.c. References ast_cli(), ast_strdupa, ast_strlen_zero(), show_dialplan_helper(), and strsep(). 03518 { 03519 char *exten = NULL, *context = NULL; 03520 /* Variables used for different counters */ 03521 struct dialplan_counters counters; 03522 char *incstack[AST_PBX_MAX_STACK]; 03523 memset(&counters, 0, sizeof(counters)); 03524 03525 if (argc != 2 && argc != 3) 03526 return RESULT_SHOWUSAGE; 03527 03528 /* we obtain [exten@]context? if yes, split them ... */ 03529 if (argc == 3) { 03530 char *splitter = ast_strdupa(argv[2]); 03531 /* is there a '@' character? */ 03532 if (splitter && strchr(argv[2], '@')) { 03533 /* yes, split into exten & context ... */ 03534 exten = strsep(&splitter, "@"); 03535 context = splitter; 03536 03537 /* check for length and change to NULL if ast_strlen_zero() */ 03538 if (ast_strlen_zero(exten)) 03539 exten = NULL; 03540 if (ast_strlen_zero(context)) 03541 context = NULL; 03542 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03543 } else { 03544 /* no '@' char, only context given */ 03545 context = argv[2]; 03546 if (ast_strlen_zero(context)) 03547 context = NULL; 03548 show_dialplan_helper(fd, context, exten, &counters, NULL, 0, incstack); 03549 } 03550 } else { 03551 /* Show complete dial plan */ 03552 show_dialplan_helper(fd, NULL, NULL, &counters, NULL, 0, incstack); 03553 } 03554 03555 /* check for input failure and throw some error messages */ 03556 if (context && !counters.context_existence) { 03557 ast_cli(fd, "There is no existence of '%s' context\n", context); 03558 return RESULT_FAILURE; 03559 } 03560 03561 if (exten && !counters.extension_existence) { 03562 if (context) 03563 ast_cli(fd, "There is no existence of %s@%s extension\n", 03564 exten, context); 03565 else 03566 ast_cli(fd, 03567 "There is no existence of '%s' extension in all contexts\n", 03568 exten); 03569 return RESULT_FAILURE; 03570 } 03571 03572 ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", 03573 counters.total_exten, counters.total_exten == 1 ? "extension" : "extensions", 03574 counters.total_prio, counters.total_prio == 1 ? "priority" : "priorities", 03575 counters.total_context, counters.total_context == 1 ? "context" : "contexts"); 03576 03577 /* everything ok */ 03578 return RESULT_SUCCESS; 03579 }
|
|
Definition at line 1174 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, ast_custom_function::synopsis, ast_custom_function::syntax, and term_color(). 01175 { 01176 struct ast_custom_function *acf; 01177 /* Maximum number of characters added by terminal coloring is 22 */ 01178 char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; 01179 char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; 01180 char stxtitle[40], *syntax = NULL; 01181 int synopsis_size, description_size, syntax_size; 01182 01183 if (argc < 3) return RESULT_SHOWUSAGE; 01184 01185 if (!(acf = ast_custom_function_find(argv[2]))) { 01186 ast_cli(fd, "No function by that name registered.\n"); 01187 return RESULT_FAILURE; 01188 01189 } 01190 01191 if (acf->synopsis) 01192 synopsis_size = strlen(acf->synopsis) + 23; 01193 else 01194 synopsis_size = strlen("Not available") + 23; 01195 synopsis = alloca(synopsis_size); 01196 01197 if (acf->desc) 01198 description_size = strlen(acf->desc) + 23; 01199 else 01200 description_size = strlen("Not available") + 23; 01201 description = alloca(description_size); 01202 01203 if (acf->syntax) 01204 syntax_size = strlen(acf->syntax) + 23; 01205 else 01206 syntax_size = strlen("Not available") + 23; 01207 syntax = alloca(syntax_size); 01208 01209 snprintf(info, 64 + AST_MAX_APP, "\n -= Info about function '%s' =- \n\n", acf->name); 01210 term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22); 01211 term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01212 term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01213 term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40); 01214 term_color(syntax, 01215 acf->syntax ? acf->syntax : "Not available", 01216 COLOR_CYAN, 0, syntax_size); 01217 term_color(synopsis, 01218 acf->synopsis ? acf->synopsis : "Not available", 01219 COLOR_CYAN, 0, synopsis_size); 01220 term_color(description, 01221 acf->desc ? acf->desc : "Not available", 01222 COLOR_CYAN, 0, description_size); 01223 01224 ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); 01225 01226 return RESULT_SUCCESS; 01227 }
|
|
Definition at line 1160 of file pbx.c. References ast_cli(), ast_custom_function::name, ast_custom_function::next, ast_custom_function::synopsis, and ast_custom_function::syntax. 01161 { 01162 struct ast_custom_function *acf; 01163 int count_acf = 0; 01164 01165 ast_cli(fd, "Installed Custom Functions:\n--------------------------------------------------------------------------------\n"); 01166 for (acf = acf_root ; acf; acf = acf->next) { 01167 ast_cli(fd, "%-20.20s %-35.35s %s\n", acf->name, acf->syntax, acf->synopsis); 01168 count_acf++; 01169 } 01170 ast_cli(fd, "%d custom functions installed.\n", count_acf); 01171 return 0; 01172 }
|
|
handle_show_hints: CLI support for listing registred dial plan hints
Definition at line 3117 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, ast_hint::laststate, LOG_ERROR, ast_hint::next, and ast_state_cb::next. 03118 { 03119 struct ast_hint *hint; 03120 int num = 0; 03121 int watchers; 03122 struct ast_state_cb *watcher; 03123 03124 if (!hints) { 03125 ast_cli(fd, "There are no registered dialplan hints\n"); 03126 return RESULT_SUCCESS; 03127 } 03128 /* ... we have hints ... */ 03129 ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); 03130 if (ast_mutex_lock(&hintlock)) { 03131 ast_log(LOG_ERROR, "Unable to lock hints\n"); 03132 return -1; 03133 } 03134 hint = hints; 03135 while (hint) { 03136 watchers = 0; 03137 for (watcher = hint->callbacks; watcher; watcher = watcher->next) 03138 watchers++; 03139 ast_cli(fd, " %-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", 03140 ast_get_extension_name(hint->exten), ast_get_extension_app(hint->exten), 03141 ast_extension_state2str(hint->laststate), watchers); 03142 num++; 03143 hint = hint->next; 03144 } 03145 ast_cli(fd, "----------------\n"); 03146 ast_cli(fd, "- %d hints registered\n", num); 03147 ast_mutex_unlock(&hintlock); 03148 return RESULT_SUCCESS; 03149 }
|
|
handle_show_switches: CLI support for listing registred dial plan switches
Definition at line 3152 of file pbx.c. References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_switch::description, LOG_ERROR, ast_switch::name, and ast_switch::next. 03153 { 03154 struct ast_switch *sw; 03155 if (!switches) { 03156 ast_cli(fd, "There are no registered alternative switches\n"); 03157 return RESULT_SUCCESS; 03158 } 03159 /* ... we have applications ... */ 03160 ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); 03161 if (ast_mutex_lock(&switchlock)) { 03162 ast_log(LOG_ERROR, "Unable to lock switches\n"); 03163 return -1; 03164 } 03165 sw = switches; 03166 while (sw) { 03167 ast_cli(fd, "%s: %s\n", sw->name, sw->description); 03168 sw = sw->next; 03169 } 03170 ast_mutex_unlock(&switchlock); 03171 return RESULT_SUCCESS; 03172 }
|
|
Definition at line 603 of file pbx.c. References ast_check_timing(), ast_include::hastime, and ast_include::timing. Referenced by pbx_find_extension(). 00604 { 00605 if (!i->hastime) 00606 return 1; 00607 00608 return ast_check_timing(&(i->timing)); 00609 }
|
|
Definition at line 2460 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), countcalls, getloadavg(), LOG_NOTICE, ast_channel::name, option_maxcalls, and option_maxload. Referenced by ast_pbx_run(), and ast_pbx_start(). 02461 { 02462 int failed = 0; 02463 double curloadavg; 02464 ast_mutex_lock(&maxcalllock); 02465 if (option_maxcalls) { 02466 if (countcalls >= option_maxcalls) { 02467 ast_log(LOG_NOTICE, "Maximum call limit of %d calls exceeded by '%s'!\n", option_maxcalls, c->name); 02468 failed = -1; 02469 } 02470 } 02471 if (option_maxload) { 02472 getloadavg(&curloadavg, 1); 02473 if (curloadavg >= option_maxload) { 02474 ast_log(LOG_NOTICE, "Maximum loadavg limit of %lf load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg); 02475 failed = -1; 02476 } 02477 } 02478 if (!failed) 02479 countcalls++; 02480 ast_mutex_unlock(&maxcalllock); 02481 02482 return failed; 02483 }
|
|
Definition at line 6193 of file pbx.c. References ast_cli_register_multiple(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_register_application(), ast_verbose(), builtins, description, globals, LOG_ERROR, name, pbx_cli, and VERBOSE_PREFIX_1. Referenced by main(). 06194 { 06195 int x; 06196 06197 /* Initialize the PBX */ 06198 if (option_verbose) { 06199 ast_verbose( "Asterisk PBX Core Initializing\n"); 06200 ast_verbose( "Registering builtin applications:\n"); 06201 } 06202 AST_LIST_HEAD_INIT_NOLOCK(&globals); 06203 ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(pbx_cli[0])); 06204 06205 /* Register builtin applications */ 06206 for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) { 06207 if (option_verbose) 06208 ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name); 06209 if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) { 06210 ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name); 06211 return -1; 06212 } 06213 } 06214 return 0; 06215 }
|
|
Definition at line 750 of file pbx.c. References ast_extension_match(), and ast_strlen_zero(). Referenced by pbx_find_extension(). 00751 { 00752 int failresult; 00753 00754 /* If the Caller*ID pattern is empty, then we're matching NO Caller*ID, so 00755 failing to get a number should count as a match, otherwise not */ 00756 00757 if (!ast_strlen_zero(cidpattern)) 00758 failresult = 0; 00759 else 00760 failresult = 1; 00761 00762 if (!callerid) 00763 return failresult; 00764 00765 return ast_extension_match(cidpattern, callerid); 00766 }
|
|
Definition at line 4614 of file pbx.c. 04615 { 04616 }
|
|
Definition at line 896 of file pbx.c. Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full(). 00897 { 00898 char *varchar, *offsetchar = NULL; 00899 int parens=0; 00900 00901 *offset = 0; 00902 *length = DONT_HAVE_LENGTH; 00903 *isfunc = 0; 00904 for (varchar=var; *varchar; varchar++) { 00905 switch (*varchar) { 00906 case '(': 00907 (*isfunc)++; 00908 parens++; 00909 break; 00910 case ')': 00911 parens--; 00912 break; 00913 case ':': 00914 if (parens == 0) { 00915 offsetchar = varchar + 1; 00916 *varchar = '\0'; 00917 goto pvn_endfor; 00918 } 00919 } 00920 } 00921 pvn_endfor: 00922 if (offsetchar) { 00923 sscanf(offsetchar, "%d:%d", offset, length); 00924 return 1; 00925 } else { 00926 return 0; 00927 } 00928 }
|
|
Definition at line 6083 of file pbx.c. References AST_LIST_EMPTY, AST_LIST_REMOVE_HEAD, ast_var_delete(), and globals. Referenced by reload(). 06084 { 06085 struct ast_var_t *vardata; 06086 while (!AST_LIST_EMPTY(&globals)) { 06087 vardata = AST_LIST_REMOVE_HEAD(&globals, entries); 06088 ast_var_delete(vardata); 06089 } 06090 }
|
|
Definition at line 5892 of file pbx.c. References AST_LIST_TRAVERSE, ast_var_name(), ast_var_value(), name, and ast_channel::varshead. Referenced by __ast_pbx_run(), __login_exec(), _while_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(), chanspy_exec(), check_goto_on_transfer(), conf_exec(), conf_run(), dial_exec_full(), do_chanreads(), dundi_exec(), dundi_helper(), get_index(), group_check_exec(), group_count_exec(), group_count_function_read(), group_function_read(), iax2_exec(), leave_voicemail(), macro_exec(), misdn_answer(), misdn_hangup(), oh323_hangup(), ospfinished_exec(), ospnext_exec(), queue_exec(), retrydial_exec(), return_exec(), set_config_flags(), sip_addheader(), sip_answer(), try_calling(), wait_for_answer(), zt_call(), and zt_hangup(). 05893 { 05894 struct ast_var_t *variables; 05895 struct varshead *headp; 05896 05897 if (chan) 05898 headp=&chan->varshead; 05899 else 05900 headp=&globals; 05901 05902 if (name) { 05903 AST_LIST_TRAVERSE(headp,variables,entries) { 05904 if (!strcmp(name, ast_var_name(variables))) 05905 return ast_var_value(variables); 05906 } 05907 if (headp != &globals) { 05908 /* Check global variables if we haven't already */ 05909 headp = &globals; 05910 AST_LIST_TRAVERSE(headp,variables,entries) { 05911 if (!strcmp(name, ast_var_name(variables))) 05912 return ast_var_value(variables); 05913 } 05914 } 05915 } 05916 return NULL; 05917 }
|
|
Definition at line 6111 of file pbx.c. References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_DEBUG, LOG_WARNING, pbx_builtin_goto(), pbx_checkcondition(), s, and strsep(). 06112 { 06113 char *condition, *branch1, *branch2, *branch; 06114 char *s; 06115 int rc; 06116 char *stringp=NULL; 06117 06118 if (ast_strlen_zero(data)) { 06119 ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n"); 06120 return 0; 06121 } 06122 06123 s = ast_strdupa(data); 06124 stringp = s; 06125 condition = strsep(&stringp,"?"); 06126 branch1 = strsep(&stringp,":"); 06127 branch2 = strsep(&stringp,""); 06128 branch = pbx_checkcondition(condition) ? branch1 : branch2; 06129 06130 if (ast_strlen_zero(branch)) { 06131 ast_log(LOG_DEBUG, "Not taking any branch\n"); 06132 return 0; 06133 } 06134 06135 rc = pbx_builtin_goto(chan, branch); 06136 06137 return rc; 06138 }
|
|
Definition at line 6022 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, and strsep(). 06023 { 06024 char *name; 06025 char *value; 06026 char *stringp=NULL; 06027 char *channel; 06028 struct ast_channel *chan2; 06029 char tmp[VAR_BUF_SIZE]=""; 06030 char *s; 06031 06032 if (ast_strlen_zero(data)) { 06033 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06034 return 0; 06035 } 06036 06037 stringp = ast_strdupa(data); 06038 name = strsep(&stringp,"="); 06039 channel = strsep(&stringp,"|"); 06040 value = strsep(&stringp,"\0"); 06041 if (channel && value && name) { 06042 chan2 = ast_get_channel_by_name_locked(channel); 06043 if (chan2) { 06044 s = alloca(strlen(value) + 4); 06045 if (s) { 06046 sprintf(s, "${%s}", value); 06047 pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1); 06048 } 06049 ast_mutex_unlock(&chan2->lock); 06050 } 06051 pbx_builtin_setvar_helper(chan, name, tmp); 06052 } 06053 06054 return(0); 06055 }
|
|
Definition at line 6077 of file pbx.c. 06078 {
06079 return 0;
06080 }
|
|
Definition at line 5919 of file pbx.c. References ast_func_write(), AST_LIST_INSERT_HEAD, ast_log(), ast_var_assign(), ast_verbose(), LOG_WARNING, name, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2. Referenced by gosub_exec(). 05920 { 05921 struct ast_var_t *newvariable; 05922 struct varshead *headp; 05923 05924 if (name[strlen(name)-1] == ')') { 05925 ast_log(LOG_WARNING, "Cannot push a value onto a function\n"); 05926 return ast_func_write(chan, name, value); 05927 } 05928 05929 headp = (chan) ? &chan->varshead : &globals; 05930 05931 if (value) { 05932 if ((option_verbose > 1) && (headp == &globals)) 05933 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05934 newvariable = ast_var_assign(name, value); 05935 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05936 } 05937 }
|
|
Definition at line 6175 of file pbx.c. References ast_say_character_str(), and ast_channel::language. 06176 { 06177 int res = 0; 06178 06179 if (data) 06180 res = ast_say_character_str(chan, (char *)data, "", chan->language); 06181 return res; 06182 }
|
|
Definition at line 6166 of file pbx.c. References ast_say_digit_str(), and ast_channel::language. 06167 { 06168 int res = 0; 06169 06170 if (data) 06171 res = ast_say_digit_str(chan, (char *)data, "", chan->language); 06172 return res; 06173 }
|
|
Definition at line 6140 of file pbx.c. References ast_log(), ast_say_number(), ast_strlen_zero(), ast_channel::language, LOG_WARNING, and strsep(). 06141 { 06142 int res = 0; 06143 char tmp[256]; 06144 char *number = (char *) NULL; 06145 char *options = (char *) NULL; 06146 06147 06148 if (ast_strlen_zero(data)) { 06149 ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n"); 06150 return -1; 06151 } 06152 ast_copy_string(tmp, (char *) data, sizeof(tmp)); 06153 number=tmp; 06154 strsep(&number, "|"); 06155 options = strsep(&number, "|"); 06156 if (options) { 06157 if ( strcasecmp(options, "f") && strcasecmp(options,"m") && 06158 strcasecmp(options, "c") && strcasecmp(options, "n") ) { 06159 ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n"); 06160 return -1; 06161 } 06162 } 06163 return res = ast_say_number(chan, atoi((char *) tmp), "", chan->language, options); 06164 }
|
|
Definition at line 6184 of file pbx.c. References ast_say_phonetic_str(), and ast_channel::language. 06185 { 06186 int res = 0; 06187 06188 if (data) 06189 res = ast_say_phonetic_str(chan, (char *)data, "", chan->language); 06190 return res; 06191 }
|
|
Definition at line 5865 of file pbx.c. References ast_build_string(), AST_LIST_TRAVERSE, ast_log(), ast_strlen_zero(), ast_var_name(), ast_var_value(), LOG_ERROR, val, var, and ast_channel::varshead. Referenced by dumpchan_exec(), and handle_showchan(). 05866 { 05867 struct ast_var_t *variables; 05868 char *var, *val; 05869 int total = 0; 05870 05871 if (!chan) 05872 return 0; 05873 05874 memset(buf, 0, size); 05875 05876 AST_LIST_TRAVERSE(&chan->varshead, variables, entries) { 05877 if(variables && 05878 (var=ast_var_name(variables)) && (val=ast_var_value(variables)) && 05879 !ast_strlen_zero(var) && !ast_strlen_zero(val)) { 05880 if (ast_build_string(&buf, &size, "%s=%s\n", var, val)) { 05881 ast_log(LOG_ERROR, "Data Buffer Size Exceeded!\n"); 05882 break; 05883 } else 05884 total++; 05885 } else 05886 break; 05887 } 05888 05889 return total; 05890 }
|
|
Definition at line 6057 of file pbx.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, name, pbx_builtin_setvar_helper(), and strsep(). 06058 { 06059 char *name; 06060 char *value; 06061 char *stringp = NULL; 06062 06063 if (ast_strlen_zero(data)) { 06064 ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n"); 06065 return 0; 06066 } 06067 06068 stringp = data; 06069 name = strsep(&stringp, "="); 06070 value = strsep(&stringp, "\0"); 06071 06072 pbx_builtin_setvar_helper(NULL, name, value); 06073 06074 return(0); 06075 }
|
|
Definition at line 5986 of file pbx.c. References ast_app_separate_args(), ast_log(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, name, and pbx_builtin_setvar_helper(). 05987 { 05988 char *name, *value, *mydata; 05989 int argc; 05990 char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */ 05991 int global = 0; 05992 int x; 05993 05994 if (ast_strlen_zero(data)) { 05995 ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n"); 05996 return 0; 05997 } 05998 05999 mydata = ast_strdupa(data); 06000 argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0])); 06001 06002 /* check for a trailing flags argument */ 06003 if ((argc > 1) && !strchr(argv[argc-1], '=')) { 06004 argc--; 06005 if (strchr(argv[argc], 'g')) 06006 global = 1; 06007 } 06008 06009 for (x = 0; x < argc; x++) { 06010 name = argv[x]; 06011 if ((value = strchr(name, '='))) { 06012 *value = '\0'; 06013 value++; 06014 pbx_builtin_setvar_helper((global) ? NULL : chan, name, value); 06015 } else 06016 ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name); 06017 } 06018 06019 return(0); 06020 }
|
|
Definition at line 5939 of file pbx.c. References ast_func_write(), AST_LIST_INSERT_HEAD, AST_LIST_REMOVE, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_delete(), ast_var_name(), ast_verbose(), name, option_verbose, ast_channel::varshead, and VERBOSE_PREFIX_2. Referenced by __ast_pbx_run(), __login_exec(), _while_exec(), 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(), conf_run(), controlplayback_exec(), count_exec(), curl_exec(), cut_exec(), dial_exec_full(), disa_exec(), do_waiting(), dundi_lookup_exec(), enumlookup_exec(), eval_exec(), function_db_exists(), function_db_read(), get_exec(), get_refer_info(), group_check_exec(), group_count_exec(), group_match_count_exec(), handle_setvariable(), hasvoicemail_exec(), i4l_read(), leave_voicemail(), lookupblacklist_exec(), macro_exec(), math_exec(), md5_exec(), md5check_exec(), misdn_call(), misdn_tx2ast_frm(), mixmonitor_exec(), monitor_handle_owned(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_importvar(), pbx_builtin_setglobalvar(), pbx_builtin_setvar(), pbx_extension_helper(), pbx_load_module(), play_message_datetime(), playback_exec(), pop_exec(), pqm_exec(), prep_email_sub_vars(), privacy_exec(), read_exec(), readfile_exec(), realtime_exec(), record_exec(), return_exec(), rqm_exec(), sendimage_exec(), sendtext_exec(), sendurl_exec(), set_agentbycallerid(), set_queue_result(), sip_addheader(), sip_getheader(), sip_new(), sort_exec(), start_monitor_exec(), system_exec_helper(), transfer_exec(), txtcidname_exec(), upqm_exec(), vm_box_exists(), vm_exec(), vmauthenticate(), zt_new(), and zt_read(). 05940 { 05941 struct ast_var_t *newvariable; 05942 struct varshead *headp; 05943 const char *nametail = name; 05944 05945 if (name[strlen(name)-1] == ')') 05946 return ast_func_write(chan, name, value); 05947 05948 headp = (chan) ? &chan->varshead : &globals; 05949 05950 /* For comparison purposes, we have to strip leading underscores */ 05951 if (*nametail == '_') { 05952 nametail++; 05953 if (*nametail == '_') 05954 nametail++; 05955 } 05956 05957 AST_LIST_TRAVERSE (headp, newvariable, entries) { 05958 if (strcasecmp(ast_var_name(newvariable), nametail) == 0) { 05959 /* there is already such a variable, delete it */ 05960 AST_LIST_REMOVE(headp, newvariable, entries); 05961 ast_var_delete(newvariable); 05962 break; 05963 } 05964 } 05965 05966 if (value) { 05967 if ((option_verbose > 1) && (headp == &globals)) 05968 ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value); 05969 newvariable = ast_var_assign(name, value); 05970 AST_LIST_INSERT_HEAD(headp, newvariable, entries); 05971 } 05972 }
|
|
Definition at line 5974 of file pbx.c. References ast_log(), LOG_WARNING, and pbx_builtin_setvar(). 05975 { 05976 static int deprecation_warning = 0; 05977 05978 if (!deprecation_warning) { 05979 ast_log(LOG_WARNING, "SetVar is deprecated, please use Set instead.\n"); 05980 deprecation_warning = 1; 05981 } 05982 05983 return pbx_builtin_setvar(chan, data); 05984 }
|
|
Definition at line 6092 of file pbx.c. Referenced by pbx_builtin_gotoif(). 06093 { 06094 if (condition) { 06095 if (*condition == '\0') { 06096 /* Empty strings are false */ 06097 return 0; 06098 } else if (*condition >= '0' && *condition <= '9') { 06099 /* Numbers are evaluated for truth */ 06100 return atoi(condition); 06101 } else { 06102 /* Strings are true */ 06103 return 1; 06104 } 06105 } else { 06106 /* NULL is also false */ 06107 return 0; 06108 } 06109 }
|
|
Definition at line 611 of file pbx.c. References free. Referenced by __ast_pbx_run(). 00612 { 00613 free(p); 00614 }
|
|
Definition at line 522 of file pbx.c. References ast_channel::appl, ast_cdr_setapp(), ast_log(), ast_channel::cdr, ast_channel::data, ast_app::execute, LOG_WARNING, and ast_app::name. Referenced by ast_bridge_call(), ast_pbx_run_app(), async_wait(), builtin_automonitor(), conf_run(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and realtime_exec(). 00526 { 00527 int res; 00528 00529 char *saved_c_appl; 00530 char *saved_c_data; 00531 00532 int (*execute)(struct ast_channel *chan, void *data) = app->execute; 00533 00534 if (newstack) { 00535 if (c->cdr) 00536 ast_cdr_setapp(c->cdr, app->name, data); 00537 00538 /* save channel values */ 00539 saved_c_appl= c->appl; 00540 saved_c_data= c->data; 00541 00542 c->appl = app->name; 00543 c->data = data; 00544 res = execute(c, data); 00545 /* restore channel values */ 00546 c->appl= saved_c_appl; 00547 c->data= saved_c_data; 00548 return res; 00549 } else 00550 ast_log(LOG_WARNING, "You really didn't want to call this function with newstack set to 0\n"); 00551 return -1; 00552 }
|
|
Definition at line 1609 of file pbx.c. References ast_exten::app, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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, ast_app::name, 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(). 01610 { 01611 struct ast_exten *e; 01612 struct ast_app *app; 01613 struct ast_switch *sw; 01614 char *data; 01615 const char *foundcontext=NULL; 01616 int newstack = 0; 01617 int res; 01618 int status = 0; 01619 char *incstack[AST_PBX_MAX_STACK]; 01620 char passdata[EXT_DATA_SIZE]; 01621 int stacklen = 0; 01622 char tmp[80]; 01623 char tmp2[80]; 01624 char tmp3[EXT_DATA_SIZE]; 01625 char atmp[80]; 01626 char atmp2[EXT_DATA_SIZE+100]; 01627 01628 if (ast_mutex_lock(&conlock)) { 01629 ast_log(LOG_WARNING, "Unable to obtain lock\n"); 01630 if ((action == HELPER_EXISTS) || (action == HELPER_CANMATCH) || (action == HELPER_MATCHMORE)) 01631 return 0; 01632 else 01633 return -1; 01634 } 01635 e = pbx_find_extension(c, con, context, exten, priority, label, callerid, action, incstack, &stacklen, &status, &sw, &data, &foundcontext); 01636 if (e) { 01637 switch(action) { 01638 case HELPER_CANMATCH: 01639 ast_mutex_unlock(&conlock); 01640 return -1; 01641 case HELPER_EXISTS: 01642 ast_mutex_unlock(&conlock); 01643 return -1; 01644 case HELPER_FINDLABEL: 01645 res = e->priority; 01646 ast_mutex_unlock(&conlock); 01647 return res; 01648 case HELPER_MATCHMORE: 01649 ast_mutex_unlock(&conlock); 01650 return -1; 01651 case HELPER_SPAWN: 01652 newstack++; 01653 /* Fall through */ 01654 case HELPER_EXEC: 01655 app = pbx_findapp(e->app); 01656 ast_mutex_unlock(&conlock); 01657 if (app) { 01658 if (c->context != context) 01659 ast_copy_string(c->context, context, sizeof(c->context)); 01660 if (c->exten != exten) 01661 ast_copy_string(c->exten, exten, sizeof(c->exten)); 01662 c->priority = priority; 01663 pbx_substitute_variables(passdata, sizeof(passdata), c, e); 01664 if (option_debug) { 01665 ast_log(LOG_DEBUG, "Launching '%s'\n", app->name); 01666 snprintf(atmp, 80, "STACK-%s-%s-%d", context, exten, priority); 01667 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")); 01668 pbx_builtin_setvar_helper(c, atmp, atmp2); 01669 } 01670 if (option_verbose > 2) 01671 ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n", 01672 term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)), 01673 term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 01674 term_color(tmp3, (!ast_strlen_zero(passdata) ? (char *)passdata : ""), COLOR_BRMAGENTA, 0, sizeof(tmp3)), 01675 (newstack ? "in new stack" : "in same stack")); 01676 manager_event(EVENT_FLAG_CALL, "Newexten", 01677 "Channel: %s\r\n" 01678 "Context: %s\r\n" 01679 "Extension: %s\r\n" 01680 "Priority: %d\r\n" 01681 "Application: %s\r\n" 01682 "AppData: %s\r\n" 01683 "Uniqueid: %s\r\n", 01684 c->name, c->context, c->exten, c->priority, app->name, passdata ? passdata : "(NULL)", c->uniqueid); 01685 res = pbx_exec(c, app, passdata, newstack); 01686 return res; 01687 } else { 01688 ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority); 01689 return -1; 01690 } 01691 default: 01692 ast_log(LOG_WARNING, "Huh (%d)?\n", action); return -1; 01693 } 01694 } else if (sw) { 01695 switch(action) { 01696 case HELPER_CANMATCH: 01697 ast_mutex_unlock(&conlock); 01698 return -1; 01699 case HELPER_EXISTS: 01700 ast_mutex_unlock(&conlock); 01701 return -1; 01702 case HELPER_MATCHMORE: 01703 ast_mutex_unlock(&conlock); 01704 return -1; 01705 case HELPER_FINDLABEL: 01706 ast_mutex_unlock(&conlock); 01707 return -1; 01708 case HELPER_SPAWN: 01709 newstack++; 01710 /* Fall through */ 01711 case HELPER_EXEC: 01712 ast_mutex_unlock(&conlock); 01713 if (sw->exec) 01714 res = sw->exec(c, foundcontext ? foundcontext : context, exten, priority, callerid, newstack, data); 01715 else { 01716 ast_log(LOG_WARNING, "No execution engine for switch %s\n", sw->name); 01717 res = -1; 01718 } 01719 return res; 01720 default: 01721 ast_log(LOG_WARNING, "Huh (%d)?\n", action); 01722 return -1; 01723 } 01724 } else { 01725 ast_mutex_unlock(&conlock); 01726 switch(status) { 01727 case STATUS_NO_CONTEXT: 01728 if ((action != HELPER_EXISTS) && (action != HELPER_MATCHMORE)) 01729 ast_log(LOG_NOTICE, "Cannot find extension context '%s'\n", context); 01730 break; 01731 case STATUS_NO_EXTENSION: 01732 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01733 ast_log(LOG_NOTICE, "Cannot find extension '%s' in context '%s'\n", exten, context); 01734 break; 01735 case STATUS_NO_PRIORITY: 01736 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01737 ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context); 01738 break; 01739 case STATUS_NO_LABEL: 01740 if (context) 01741 ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context); 01742 break; 01743 default: 01744 ast_log(LOG_DEBUG, "Shouldn't happen!\n"); 01745 } 01746 01747 if ((action != HELPER_EXISTS) && (action != HELPER_CANMATCH) && (action != HELPER_MATCHMORE)) 01748 return -1; 01749 else 01750 return 0; 01751 } 01752 01753 }
|
|
Definition at line 768 of file pbx.c. References ast_context::alts, ast_extension_close(), ast_extension_match(), ast_log(), ast_switch::canmatch, ast_exten::cidmatch, ast_sw::data, ast_sw::eval, ast_switch::exists, ast_exten::exten, HELPER_MATCHMORE, include_valid(), ast_context::includes, ast_exten::label, LOG_WARNING, matchcid(), ast_exten::matchcid, ast_switch::matchmore, ast_sw::name, ast_context::name, ast_context::next, ast_include::next, ast_sw::next, ast_exten::next, pbx_findswitch(), pbx_substitute_variables_helper(), ast_exten::peer, ast_exten::priority, ast_include::rname, ast_context::root, SWITCH_DATA_LENGTH, and ast_sw::tmpdata. Referenced by ast_hint_extension(), and pbx_extension_helper(). 00769 { 00770 int x, res; 00771 struct ast_context *tmp; 00772 struct ast_exten *e, *eroot; 00773 struct ast_include *i; 00774 struct ast_sw *sw; 00775 struct ast_switch *asw; 00776 00777 /* Initialize status if appropriate */ 00778 if (!*stacklen) { 00779 *status = STATUS_NO_CONTEXT; 00780 *swo = NULL; 00781 *data = NULL; 00782 } 00783 /* Check for stack overflow */ 00784 if (*stacklen >= AST_PBX_MAX_STACK) { 00785 ast_log(LOG_WARNING, "Maximum PBX stack exceeded\n"); 00786 return NULL; 00787 } 00788 /* Check first to see if we've already been checked */ 00789 for (x=0; x<*stacklen; x++) { 00790 if (!strcasecmp(incstack[x], context)) 00791 return NULL; 00792 } 00793 if (bypass) 00794 tmp = bypass; 00795 else 00796 tmp = contexts; 00797 while(tmp) { 00798 /* Match context */ 00799 if (bypass || !strcmp(tmp->name, context)) { 00800 struct ast_exten *earlymatch = NULL; 00801 00802 if (*status < STATUS_NO_EXTENSION) 00803 *status = STATUS_NO_EXTENSION; 00804 for (eroot = tmp->root; eroot; eroot=eroot->next) { 00805 int match = 0; 00806 /* Match extension */ 00807 if ((((action != HELPER_MATCHMORE) && ast_extension_match(eroot->exten, exten)) || 00808 ((action == HELPER_CANMATCH) && (ast_extension_close(eroot->exten, exten, 0))) || 00809 ((action == HELPER_MATCHMORE) && (match = ast_extension_close(eroot->exten, exten, 1)))) && 00810 (!eroot->matchcid || matchcid(eroot->cidmatch, callerid))) { 00811 00812 if (action == HELPER_MATCHMORE && match == 2 && !earlymatch) { 00813 /* It matched an extension ending in a '!' wildcard 00814 So ignore it for now, unless there's a better match */ 00815 earlymatch = eroot; 00816 } else { 00817 e = eroot; 00818 if (*status < STATUS_NO_PRIORITY) 00819 *status = STATUS_NO_PRIORITY; 00820 while(e) { 00821 /* Match priority */ 00822 if (action == HELPER_FINDLABEL) { 00823 if (*status < STATUS_NO_LABEL) 00824 *status = STATUS_NO_LABEL; 00825 if (label && e->label && !strcmp(label, e->label)) { 00826 *status = STATUS_SUCCESS; 00827 *foundcontext = context; 00828 return e; 00829 } 00830 } else if (e->priority == priority) { 00831 *status = STATUS_SUCCESS; 00832 *foundcontext = context; 00833 return e; 00834 } 00835 e = e->peer; 00836 } 00837 } 00838 } 00839 } 00840 if (earlymatch) { 00841 /* Bizarre logic for HELPER_MATCHMORE. We return zero to break out 00842 of the loop waiting for more digits, and _then_ match (normally) 00843 the extension we ended up with. We got an early-matching wildcard 00844 pattern, so return NULL to break out of the loop. */ 00845 return NULL; 00846 } 00847 /* Check alternative switches */ 00848 sw = tmp->alts; 00849 while(sw) { 00850 if ((asw = pbx_findswitch(sw->name))) { 00851 /* Substitute variables now */ 00852 if (sw->eval) 00853 pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1); 00854 if (action == HELPER_CANMATCH) 00855 res = asw->canmatch ? asw->canmatch(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; 00856 else if (action == HELPER_MATCHMORE) 00857 res = asw->matchmore ? asw->matchmore(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; 00858 else 00859 res = asw->exists ? asw->exists(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; 00860 if (res) { 00861 /* Got a match */ 00862 *swo = asw; 00863 *data = sw->eval ? sw->tmpdata : sw->data; 00864 *foundcontext = context; 00865 return NULL; 00866 } 00867 } else { 00868 ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); 00869 } 00870 sw = sw->next; 00871 } 00872 /* Setup the stack */ 00873 incstack[*stacklen] = tmp->name; 00874 (*stacklen)++; 00875 /* Now try any includes we have in this context */ 00876 i = tmp->includes; 00877 while(i) { 00878 if (include_valid(i)) { 00879 if ((e = pbx_find_extension(chan, bypass, i->rname, exten, priority, label, callerid, action, incstack, stacklen, status, swo, data, foundcontext))) 00880 return e; 00881 if (*swo) 00882 return NULL; 00883 } 00884 i = i->next; 00885 } 00886 break; 00887 } 00888 tmp = tmp->next; 00889 } 00890 return NULL; 00891 }
|
|
Find application handle in linked list.
Definition at line 567 of file pbx.c. References 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(), dial_exec_full(), dundi_exec(), exec_exec(), execif_exec(), feature_exec_app(), forward_message(), handle_exec(), iax2_exec(), page_exec(), pbx_builtin_execiftime(), pbx_extension_helper(), and realtime_exec(). 00568 { 00569 struct ast_app *tmp; 00570 00571 if (ast_mutex_lock(&applock)) { 00572 ast_log(LOG_WARNING, "Unable to obtain application lock\n"); 00573 return NULL; 00574 } 00575 tmp = apps; 00576 while(tmp) { 00577 if (!strcasecmp(tmp->name, app)) 00578 break; 00579 tmp = tmp->next; 00580 } 00581 ast_mutex_unlock(&applock); 00582 return tmp; 00583 }
|
|
Definition at line 585 of file pbx.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, ast_switch::name, and ast_switch::next. Referenced by pbx_find_extension(). 00586 { 00587 struct ast_switch *asw; 00588 00589 if (ast_mutex_lock(&switchlock)) { 00590 ast_log(LOG_WARNING, "Unable to obtain application lock\n"); 00591 return NULL; 00592 } 00593 asw = switches; 00594 while(asw) { 00595 if (!strcasecmp(asw->name, sw)) 00596 break; 00597 asw = asw->next; 00598 } 00599 ast_mutex_unlock(&switchlock); 00600 return asw; 00601 }
|
|
pbx_retrieve_variable: Support for Asterisk built-in variables and functions in the dialplan ---
Definition at line 970 of file pbx.c. References ast_channel::accountcode, ast_get_hint(), AST_LIST_TRAVERSE, ast_log(), 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, globals, ast_channel::hangupcause, ast_channel::language, LOG_WARNING, ast_channel::name, parse_variable_name(), ast_channel::priority, substring(), ast_channel::uniqueid, var, and ast_channel::varshead. Referenced by function_fieldqty(), handle_getvariable(), and pbx_substitute_variables_helper_full(). 00971 { 00972 char tmpvar[80]; 00973 time_t thistime; 00974 struct tm brokentime; 00975 int offset, offset2, isfunc; 00976 struct ast_var_t *variables; 00977 00978 if (c) 00979 headp=&c->varshead; 00980 *ret=NULL; 00981 ast_copy_string(tmpvar, var, sizeof(tmpvar)); 00982 if (parse_variable_name(tmpvar, &offset, &offset2, &isfunc)) { 00983 pbx_retrieve_variable(c, tmpvar, ret, workspace, workspacelen, headp); 00984 if (!(*ret)) 00985 return; 00986 *ret = substring(*ret, offset, offset2, workspace, workspacelen); 00987 } else if (c && !strncmp(var, "CALL", 4)) { 00988 if (!strncmp(var + 4, "ER", 2)) { 00989 if (!strncmp(var + 6, "ID", 2)) { 00990 if (!var[8]) { /* CALLERID */ 00991 if (c->cid.cid_num) { 00992 if (c->cid.cid_name) { 00993 snprintf(workspace, workspacelen, "\"%s\" <%s>", c->cid.cid_name, c->cid.cid_num); 00994 } else { 00995 ast_copy_string(workspace, c->cid.cid_num, workspacelen); 00996 } 00997 *ret = workspace; 00998 } else if (c->cid.cid_name) { 00999 ast_copy_string(workspace, c->cid.cid_name, workspacelen); 01000 *ret = workspace; 01001 } else 01002 *ret = NULL; 01003 } else if (!strcmp(var + 8, "NUM")) { 01004 /* CALLERIDNUM */ 01005 if (c->cid.cid_num) { 01006 ast_copy_string(workspace, c->cid.cid_num, workspacelen); 01007 *ret = workspace; 01008 } else 01009 *ret = NULL; 01010 } else if (!strcmp(var + 8, "NAME")) { 01011 /* CALLERIDNAME */ 01012 if (c->cid.cid_name) { 01013 ast_copy_string(workspace, c->cid.cid_name, workspacelen); 01014 *ret = workspace; 01015 } else 01016 *ret = NULL; 01017 } 01018 } else if (!strcmp(var + 6, "ANI")) { 01019 /* CALLERANI */ 01020 if (c->cid.cid_ani) { 01021 ast_copy_string(workspace, c->cid.cid_ani, workspacelen); 01022 *ret = workspace; 01023 } else 01024 *ret = NULL; 01025 } else 01026 goto icky; 01027 } else if (!strncmp(var + 4, "ING", 3)) { 01028 if (!strcmp(var + 7, "PRES")) { 01029 /* CALLINGPRES */ 01030 snprintf(workspace, workspacelen, "%d", c->cid.cid_pres); 01031 *ret = workspace; 01032 } else if (!strcmp(var + 7, "ANI2")) { 01033 /* CALLINGANI2 */ 01034 snprintf(workspace, workspacelen, "%d", c->cid.cid_ani2); 01035 *ret = workspace; 01036 } else if (!strcmp(var + 7, "TON")) { 01037 /* CALLINGTON */ 01038 snprintf(workspace, workspacelen, "%d", c->cid.cid_ton); 01039 *ret = workspace; 01040 } else if (!strcmp(var + 7, "TNS")) { 01041 /* CALLINGTNS */ 01042 snprintf(workspace, workspacelen, "%d", c->cid.cid_tns); 01043 *ret = workspace; 01044 } else 01045 goto icky; 01046 } else 01047 goto icky; 01048 } else if (c && !strcmp(var, "DNID")) { 01049 if (c->cid.cid_dnid) { 01050 ast_copy_string(workspace, c->cid.cid_dnid, workspacelen); 01051 *ret = workspace; 01052 } else 01053 *ret = NULL; 01054 } else if (c && !strcmp(var, "HINT")) { 01055 if (!ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten)) 01056 *ret = NULL; 01057 else 01058 *ret = workspace; 01059 } else if (c && !strcmp(var, "HINTNAME")) { 01060 if (!ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten)) 01061 *ret = NULL; 01062 else 01063 *ret = workspace; 01064 } else if (c && !strcmp(var, "EXTEN")) { 01065 ast_copy_string(workspace, c->exten, workspacelen); 01066 *ret = workspace; 01067 } else if (c && !strcmp(var, "RDNIS")) { 01068 if (c->cid.cid_rdnis) { 01069 ast_copy_string(workspace, c->cid.cid_rdnis, workspacelen); 01070 *ret = workspace; 01071 } else 01072 *ret = NULL; 01073 } else if (c && !strcmp(var, "CONTEXT")) { 01074 ast_copy_string(workspace, c->context, workspacelen); 01075 *ret = workspace; 01076 } else if (c && !strcmp(var, "PRIORITY")) { 01077 snprintf(workspace, workspacelen, "%d", c->priority); 01078 *ret = workspace; 01079 } else if (c && !strcmp(var, "CHANNEL")) { 01080 ast_copy_string(workspace, c->name, workspacelen); 01081 *ret = workspace; 01082 } else if (!strcmp(var, "EPOCH")) { 01083 snprintf(workspace, workspacelen, "%u",(int)time(NULL)); 01084 *ret = workspace; 01085 } else if (!strcmp(var, "DATETIME")) { 01086 thistime=time(NULL); 01087 localtime_r(&thistime, &brokentime); 01088 snprintf(workspace, workspacelen, "%02d%02d%04d-%02d:%02d:%02d", 01089 brokentime.tm_mday, 01090 brokentime.tm_mon+1, 01091 brokentime.tm_year+1900, 01092 brokentime.tm_hour, 01093 brokentime.tm_min, 01094 brokentime.tm_sec 01095 ); 01096 *ret = workspace; 01097 } else if (!strcmp(var, "TIMESTAMP")) { 01098 thistime=time(NULL); 01099 localtime_r(&thistime, &brokentime); 01100 /* 20031130-150612 */ 01101 snprintf(workspace, workspacelen, "%04d%02d%02d-%02d%02d%02d", 01102 brokentime.tm_year+1900, 01103 brokentime.tm_mon+1, 01104 brokentime.tm_mday, 01105 brokentime.tm_hour, 01106 brokentime.tm_min, 01107 brokentime.tm_sec 01108 ); 01109 *ret = workspace; 01110 } else if (c && !strcmp(var, "UNIQUEID")) { 01111 snprintf(workspace, workspacelen, "%s", c->uniqueid); 01112 *ret = workspace; 01113 } else if (c && !strcmp(var, "HANGUPCAUSE")) { 01114 snprintf(workspace, workspacelen, "%d", c->hangupcause); 01115 *ret = workspace; 01116 } else if (c && !strcmp(var, "ACCOUNTCODE")) { 01117 ast_copy_string(workspace, c->accountcode, workspacelen); 01118 *ret = workspace; 01119 } else if (c && !strcmp(var, "LANGUAGE")) { 01120 ast_copy_string(workspace, c->language, workspacelen); 01121 *ret = workspace; 01122 } else { 01123 icky: 01124 if (headp) { 01125 AST_LIST_TRAVERSE(headp,variables,entries) { 01126 #if 0 01127 ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",var,ast_var_name(variables)); 01128 #endif 01129 if (strcasecmp(ast_var_name(variables),var)==0) { 01130 *ret=ast_var_value(variables); 01131 if (*ret) { 01132 ast_copy_string(workspace, *ret, workspacelen); 01133 *ret = workspace; 01134 } 01135 break; 01136 } 01137 } 01138 } 01139 if (!(*ret)) { 01140 /* Try globals */ 01141 AST_LIST_TRAVERSE(&globals,variables,entries) { 01142 #if 0 01143 ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",var,ast_var_name(variables)); 01144 #endif 01145 if (strcasecmp(ast_var_name(variables),var)==0) { 01146 *ret = ast_var_value(variables); 01147 if (*ret) { 01148 ast_copy_string(workspace, *ret, workspacelen); 01149 *ret = workspace; 01150 } 01151 } 01152 } 01153 } 01154 } 01155 }
|
|
Definition at line 2555 of file pbx.c. References autofallthrough. Referenced by pbx_load_module(). 02556 { 02557 int oldval; 02558 oldval = autofallthrough; 02559 if (oldval != newval) 02560 autofallthrough = newval; 02561 return oldval; 02562 }
|
|
Definition at line 1596 of file pbx.c. References ast_exten::data, and pbx_substitute_variables_helper(). Referenced by pbx_extension_helper(). 01597 { 01598 memset(passdata, 0, datalen); 01599 01600 /* No variables or expressions in e->data, so why scan it? */ 01601 if (!strchr(e->data, '$') && !strstr(e->data,"${") && !strstr(e->data,"$[") && !strstr(e->data,"$(")) { 01602 ast_copy_string(passdata, e->data, datalen); 01603 return; 01604 } 01605 01606 pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1); 01607 }
|
|
Definition at line 1586 of file pbx.c. References pbx_substitute_variables_helper_full(), and ast_channel::varshead. Referenced by custom_log(), cut_internal(), eval_exec(), exec_exec(), function_eval(), handle_getvariablefull(), mixmonitor_thread(), pbx_builtin_importvar(), pbx_find_extension(), pbx_load_module(), pbx_substitute_variables(), realtime_exec(), rpt_exec(), sendmail(), and sendpage(). 01587 { 01588 pbx_substitute_variables_helper_full(c, (c) ? &c->varshead : NULL, cp1, cp2, count); 01589 }
|
|
Definition at line 1410 of file pbx.c. References ast_expr(), ast_func_read(), ast_log(), ast_strlen_zero(), LOG_DEBUG, LOG_NOTICE, parse_variable_name(), pbx_retrieve_variable(), substring(), var, and VAR_BUF_SIZE. Referenced by pbx_substitute_variables_helper(), and pbx_substitute_variables_varshead(). 01411 { 01412 char *cp4; 01413 const char *tmp, *whereweare; 01414 int length, offset, offset2, isfunction; 01415 char *workspace = NULL; 01416 char *ltmp = NULL, *var = NULL; 01417 char *nextvar, *nextexp, *nextthing; 01418 char *vars, *vare; 01419 int pos, brackets, needsub, len; 01420 01421 /* Substitutes variables into cp2, based on string cp1, and assuming cp2 to be 01422 zero-filled */ 01423 whereweare=tmp=cp1; 01424 while(!ast_strlen_zero(whereweare) && count) { 01425 /* Assume we're copying the whole remaining string */ 01426 pos = strlen(whereweare); 01427 nextvar = NULL; 01428 nextexp = NULL; 01429 nextthing = strchr(whereweare, '$'); 01430 if (nextthing) { 01431 switch(nextthing[1]) { 01432 case '{': 01433 nextvar = nextthing; 01434 pos = nextvar - whereweare; 01435 break; 01436 case '[': 01437 nextexp = nextthing; 01438 pos = nextexp - whereweare; 01439 break; 01440 } 01441 } 01442 01443 if (pos) { 01444 /* Can't copy more than 'count' bytes */ 01445 if (pos > count) 01446 pos = count; 01447 01448 /* Copy that many bytes */ 01449 memcpy(cp2, whereweare, pos); 01450 01451 count -= pos; 01452 cp2 += pos; 01453 whereweare += pos; 01454 } 01455 01456 if (nextvar) { 01457 /* We have a variable. Find the start and end, and determine 01458 if we are going to have to recursively call ourselves on the 01459 contents */ 01460 vars = vare = nextvar + 2; 01461 brackets = 1; 01462 needsub = 0; 01463 01464 /* Find the end of it */ 01465 while(brackets && *vare) { 01466 if ((vare[0] == '$') && (vare[1] == '{')) { 01467 needsub++; 01468 brackets++; 01469 } else if (vare[0] == '}') { 01470 brackets--; 01471 } else if ((vare[0] == '$') && (vare[1] == '[')) 01472 needsub++; 01473 vare++; 01474 } 01475 if (brackets) 01476 ast_log(LOG_NOTICE, "Error in extension logic (missing '}')\n"); 01477 len = vare - vars - 1; 01478 01479 /* Skip totally over variable string */ 01480 whereweare += (len + 3); 01481 01482 if (!var) 01483 var = alloca(VAR_BUF_SIZE); 01484 01485 /* Store variable name (and truncate) */ 01486 ast_copy_string(var, vars, len + 1); 01487 01488 /* Substitute if necessary */ 01489 if (needsub) { 01490 if (!ltmp) 01491 ltmp = alloca(VAR_BUF_SIZE); 01492 01493 memset(ltmp, 0, VAR_BUF_SIZE); 01494 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01495 vars = ltmp; 01496 } else { 01497 vars = var; 01498 } 01499 01500 if (!workspace) 01501 workspace = alloca(VAR_BUF_SIZE); 01502 01503 workspace[0] = '\0'; 01504 01505 parse_variable_name(vars, &offset, &offset2, &isfunction); 01506 if (isfunction) { 01507 /* Evaluate function */ 01508 cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE); 01509 01510 ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)"); 01511 } else { 01512 /* Retrieve variable value */ 01513 pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp); 01514 } 01515 if (cp4) { 01516 cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE); 01517 01518 length = strlen(cp4); 01519 if (length > count) 01520 length = count; 01521 memcpy(cp2, cp4, length); 01522 count -= length; 01523 cp2 += length; 01524 } 01525 } else if (nextexp) { 01526 /* We have an expression. Find the start and end, and determine 01527 if we are going to have to recursively call ourselves on the 01528 contents */ 01529 vars = vare = nextexp + 2; 01530 brackets = 1; 01531 needsub = 0; 01532 01533 /* Find the end of it */ 01534 while(brackets && *vare) { 01535 if ((vare[0] == '$') && (vare[1] == '[')) { 01536 needsub++; 01537 brackets++; 01538 vare++; 01539 } else if (vare[0] == '[') { 01540 brackets++; 01541 } else if (vare[0] == ']') { 01542 brackets--; 01543 } else if ((vare[0] == '$') && (vare[1] == '{')) { 01544 needsub++; 01545 vare++; 01546 } 01547 vare++; 01548 } 01549 if (brackets) 01550 ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n"); 01551 len = vare - vars - 1; 01552 01553 /* Skip totally over expression */ 01554 whereweare += (len + 3); 01555 01556 if (!var) 01557 var = alloca(VAR_BUF_SIZE); 01558 01559 /* Store variable name (and truncate) */ 01560 ast_copy_string(var, vars, len + 1); 01561 01562 /* Substitute if necessary */ 01563 if (needsub) { 01564 if (!ltmp) 01565 ltmp = alloca(VAR_BUF_SIZE); 01566 01567 memset(ltmp, 0, VAR_BUF_SIZE); 01568 pbx_substitute_variables_helper_full(c, headp, var, ltmp, VAR_BUF_SIZE - 1); 01569 vars = ltmp; 01570 } else { 01571 vars = var; 01572 } 01573 01574 length = ast_expr(vars, cp2, count); 01575 01576 if (length) { 01577 ast_log(LOG_DEBUG, "Expression result is '%s'\n", cp2); 01578 count -= length; 01579 cp2 += length; 01580 } 01581 } else 01582 break; 01583 } 01584 }
|
|
Definition at line 1591 of file pbx.c. References pbx_substitute_variables_helper_full(). Referenced by ast_add_extension2(), dundi_lookup_local(), and loopback_helper(). 01592 { 01593 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count); 01594 }
|
|
Definition at line 2493 of file pbx.c. References __ast_pbx_run(), and decrease_call_count(). Referenced by ast_pbx_start(). 02494 { 02495 /* Oh joyeous kernel, we're a new thread, with nothing to do but 02496 answer this channel and get it going. 02497 */ 02498 /* NOTE: 02499 The launcher of this function _MUST_ increment 'countcalls' 02500 before invoking the function; it will be decremented when the 02501 PBX has finished running on the channel 02502 */ 02503 struct ast_channel *c = data; 02504 02505 __ast_pbx_run(c); 02506 decrease_call_count(); 02507 02508 pthread_exit(NULL); 02509 02510 return NULL; 02511 }
|
|
Definition at line 3330 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_ignorepat_name(), ast_get_ignorepat_registrar(), ast_get_include_name(), ast_get_include_registrar(), ast_get_switch_data(), ast_get_switch_name(), ast_get_switch_registrar(), ast_lock_context(), ast_lock_contexts(), ast_log(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), ast_walk_contexts(), ast_walk_extension_priorities(), dialplan_counters::context_existence, dialplan_counters::extension_existence, LOG_NOTICE, LOG_WARNING, dialplan_counters::total_context, dialplan_counters::total_exten, and dialplan_counters::total_prio. Referenced by handle_show_dialplan(). 03331 { 03332 struct ast_context *c; 03333 int res=0, old_total_exten = dpc->total_exten; 03334 03335 /* try to lock contexts */ 03336 if (ast_lock_contexts()) { 03337 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 03338 return -1; 03339 } 03340 03341 /* walk all contexts ... */ 03342 for (c = ast_walk_contexts(NULL); c ; c = ast_walk_contexts(c)) { 03343 /* show this context? */ 03344 if (!context || 03345 !strcmp(ast_get_context_name(c), context)) { 03346 dpc->context_existence = 1; 03347 03348 /* try to lock context before walking in ... */ 03349 if (!ast_lock_context(c)) { 03350 struct ast_exten *e; 03351 struct ast_include *i; 03352 struct ast_ignorepat *ip; 03353 struct ast_sw *sw; 03354 char buf[256], buf2[256]; 03355 int context_info_printed = 0; 03356 03357 /* are we looking for exten too? if yes, we print context 03358 * if we our extension only 03359 */ 03360 if (!exten) { 03361 dpc->total_context++; 03362 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03363 ast_get_context_name(c), ast_get_context_registrar(c)); 03364 context_info_printed = 1; 03365 } 03366 03367 /* walk extensions ... */ 03368 for (e = ast_walk_context_extensions(c, NULL); e; e = ast_walk_context_extensions(c, e)) { 03369 struct ast_exten *p; 03370 int prio; 03371 03372 /* looking for extension? is this our extension? */ 03373 if (exten && 03374 !ast_extension_match(ast_get_extension_name(e), exten)) 03375 { 03376 /* we are looking for extension and it's not our 03377 * extension, so skip to next extension */ 03378 continue; 03379 } 03380 03381 dpc->extension_existence = 1; 03382 03383 /* may we print context info? */ 03384 if (!context_info_printed) { 03385 dpc->total_context++; 03386 if (rinclude) { 03387 /* TODO Print more info about rinclude */ 03388 ast_cli(fd, "[ Included context '%s' created by '%s' ]\n", 03389 ast_get_context_name(c), 03390 ast_get_context_registrar(c)); 03391 } else { 03392 ast_cli(fd, "[ Context '%s' created by '%s' ]\n", 03393 ast_get_context_name(c), 03394 ast_get_context_registrar(c)); 03395 } 03396 context_info_printed = 1; 03397 } 03398 dpc->total_prio++; 03399 03400 /* write extension name and first peer */ 03401 bzero(buf, sizeof(buf)); 03402 snprintf(buf, sizeof(buf), "'%s' =>", 03403 ast_get_extension_name(e)); 03404 03405 prio = ast_get_extension_priority(e); 03406 if (prio == PRIORITY_HINT) { 03407 snprintf(buf2, sizeof(buf2), 03408 "hint: %s", 03409 ast_get_extension_app(e)); 03410 } else { 03411 snprintf(buf2, sizeof(buf2), 03412 "%d. %s(%s)", 03413 prio, 03414 ast_get_extension_app(e), 03415 (char *)ast_get_extension_app_data(e)); 03416 } 03417 03418 ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2, 03419 ast_get_extension_registrar(e)); 03420 03421 dpc->total_exten++; 03422 /* walk next extension peers */ 03423 for (p=ast_walk_extension_priorities(e, e); p; p=ast_walk_extension_priorities(e, p)) { 03424 dpc->total_prio++; 03425 bzero((void *)buf2, sizeof(buf2)); 03426 bzero((void *)buf, sizeof(buf)); 03427 if (ast_get_extension_label(p)) 03428 snprintf(buf, sizeof(buf), " [%s]", ast_get_extension_label(p)); 03429 prio = ast_get_extension_priority(p); 03430 if (prio == PRIORITY_HINT) { 03431 snprintf(buf2, sizeof(buf2), 03432 "hint: %s", 03433 ast_get_extension_app(p)); 03434 } else { 03435 snprintf(buf2, sizeof(buf2), 03436 "%d. %s(%s)", 03437 prio, 03438 ast_get_extension_app(p), 03439 (char *)ast_get_extension_app_data(p)); 03440 } 03441 03442 ast_cli(fd," %-17s %-45s [%s]\n", 03443 buf, buf2, 03444 ast_get_extension_registrar(p)); 03445 } 03446 } 03447 03448 /* walk included and write info ... */ 03449 for (i = ast_walk_context_includes(c, NULL); i; i = ast_walk_context_includes(c, i)) { 03450 bzero(buf, sizeof(buf)); 03451 snprintf(buf, sizeof(buf), "'%s'", 03452 ast_get_include_name(i)); 03453 if (exten) { 03454 /* Check all includes for the requested extension */ 03455 if (includecount >= AST_PBX_MAX_STACK) { 03456 ast_log(LOG_NOTICE, "Maximum include depth exceeded!\n"); 03457 } else { 03458 int dupe=0; 03459 int x; 03460 for (x=0;x<includecount;x++) { 03461 if (!strcasecmp(includes[x], ast_get_include_name(i))) { 03462 dupe++; 03463 break; 03464 } 03465 } 03466 if (!dupe) { 03467 includes[includecount] = (char *)ast_get_include_name(i); 03468 show_dialplan_helper(fd, (char *)ast_get_include_name(i), exten, dpc, i, includecount + 1, includes); 03469 } else { 03470 ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context); 03471 } 03472 } 03473 } else { 03474 ast_cli(fd, " Include => %-45s [%s]\n", 03475 buf, ast_get_include_registrar(i)); 03476 } 03477 } 03478 03479 /* walk ignore patterns and write info ... */ 03480 for (ip=ast_walk_context_ignorepats(c, NULL); ip; ip=ast_walk_context_ignorepats(c, ip)) { 03481 const char *ipname = ast_get_ignorepat_name(ip); 03482 char ignorepat[AST_MAX_EXTENSION]; 03483 snprintf(buf, sizeof(buf), "'%s'", ipname); 03484 snprintf(ignorepat, sizeof(ignorepat), "_%s.", ipname); 03485 if ((!exten) || ast_extension_match(ignorepat, exten)) { 03486 ast_cli(fd, " Ignore pattern => %-45s [%s]\n", 03487 buf, ast_get_ignorepat_registrar(ip)); 03488 } 03489 } 03490 if (!rinclude) { 03491 for (sw = ast_walk_context_switches(c, NULL); sw; sw = ast_walk_context_switches(c, sw)) { 03492 snprintf(buf, sizeof(buf), "'%s/%s'", 03493 ast_get_switch_name(sw), 03494 ast_get_switch_data(sw)); 03495 ast_cli(fd, " Alt. Switch => %-45s [%s]\n", 03496 buf, ast_get_switch_registrar(sw)); 03497 } 03498 } 03499 03500 ast_unlock_context(c); 03501 03502 /* if we print something in context, make an empty line */ 03503 if (context_info_printed) ast_cli(fd, "\r\n"); 03504 } 03505 } 03506 } 03507 ast_unlock_contexts(); 03508 03509 if (dpc->total_exten == old_total_exten) { 03510 /* Nothing new under the sun */ 03511 return -1; 03512 } else { 03513 return res; 03514 } 03515 }
|
|
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 938 of file pbx.c. Referenced by pbx_retrieve_variable(), and pbx_substitute_variables_helper_full(). 00939 { 00940 char *ret = workspace; 00941 int lr; /* length of the input string after the copy */ 00942 00943 ast_copy_string(workspace, value, workspace_len); /* always make a copy */ 00944 00945 if (offset == 0 && length < 0) /* take the whole string */ 00946 return ret; 00947 00948 lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */ 00949 00950 if (offset < 0) { /* translate negative offset into positive ones */ 00951 offset = lr + offset; 00952 if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */ 00953 offset = 0; 00954 } 00955 00956 /* too large offset result in empty string so we know what to return */ 00957 if (offset >= lr) 00958 return ret + lr; /* the final '\0' */ 00959 00960 ret += offset; /* move to the start position */ 00961 if (length >= 0 && length < lr - offset) /* truncate if necessary */ 00962 ret[length] = '\0'; 00963 00964 return ret; 00965 }
|
|
Definition at line 5361 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(). 05362 { 05363 int res; 05364 struct ast_frame *f; 05365 int waittime; 05366 05367 if (ast_strlen_zero(data) || (sscanf(data, "%d", &waittime) != 1) || (waittime < 0)) 05368 waittime = -1; 05369 if (waittime > -1) { 05370 ast_safe_sleep(chan, waittime * 1000); 05371 } else do { 05372 res = ast_waitfor(chan, -1); 05373 if (res < 0) 05374 return; 05375 f = ast_read(chan); 05376 if (f) 05377 ast_frfree(f); 05378 } while(f); 05379 }
|
|
Definition at line 236 of file pbx.c. Referenced by ast_custom_function_register(), and ast_custom_function_unregister(). |
|
Definition at line 508 of file pbx.c. Referenced by ast_register_application(), and ast_unregister_application(). |
|
Definition at line 230 of file pbx.c. Referenced by pbx_set_autofallthrough(). |
|
Declaration of builtin applications.
Referenced by load_pbx(). |
|
Definition at line 506 of file pbx.c. Referenced by __ast_context_destroy(), and ast_merge_contexts_and_delete(). |
|
Definition at line 233 of file pbx.c. Referenced by decrease_call_count(), and increase_call_count(). |
|
Definition at line 3903 of file pbx.c. Referenced by get_dow(). |
|
Definition at line 228 of file pbx.c. Referenced by ast_add_extension2(), load_pbx(), pbx_builtin_clear_globals(), and pbx_retrieve_variable(). |
|
Definition at line 516 of file pbx.c. Referenced by ast_add_hint(), and ast_remove_hint(). |
|
Definition at line 4005 of file pbx.c. Referenced by get_month(). |
|
Definition at line 3584 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 517 of file pbx.c. Referenced by ast_extension_state_add(), and ast_extension_state_del(). |
|
Definition at line 515 of file pbx.c. Referenced by ast_extension_state_add(). |
|
Definition at line 511 of file pbx.c. Referenced by ast_register_switch(), and ast_unregister_switch(). |