callback to display queues status in manager More...
Data Structures | |
| struct | actions |
| list of actions registered More... | |
| struct | all_events |
| struct | ast_manager_user |
| user descriptor, as read from the config file. More... | |
| struct | channelvars |
| struct | eventqent |
| struct | fast_originate_helper |
| helper function for originate More... | |
| struct | manager_channel_variable |
| struct | manager_hooks |
| list of hooks registered More... | |
| struct | mansession |
| In case you didn't read that giant block of text above the mansession_session struct, the struct mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data. More... | |
| struct | mansession_session |
| struct | permalias |
| struct | users |
| list of users found in the config file More... | |
Defines | |
| #define | ASTMAN_APPEND_BUF_INITSIZE 256 |
| initial allocated size for the astman_append_buf and astman_send_*_va | |
| #define | DEFAULT_REALM "asterisk" |
| #define | GET_HEADER_FIRST_MATCH 0 |
| #define | GET_HEADER_LAST_MATCH 1 |
| #define | GET_HEADER_SKIP_EMPTY 2 |
| #define | MANAGER_EVENT_BUF_INITSIZE 256 |
| #define | MAX_BLACKLIST_CMD_LEN 2 |
| Descriptor for a manager session, either on the AMI socket or over HTTP. | |
| #define | MSG_MOREDATA ((char *)astman_send_response) |
Enumerations | |
| enum | add_filter_result { FILTER_SUCCESS, FILTER_ALLOC_FAILED, FILTER_COMPILE_FAIL } |
| enum | error_type { UNKNOWN_ACTION = 1, UNKNOWN_CATEGORY, UNSPECIFIED_CATEGORY, UNSPECIFIED_ARGUMENT, FAILURE_ALLOCATION, FAILURE_NEWCAT, FAILURE_DELCAT, FAILURE_EMPTYCAT, FAILURE_UPDATE, FAILURE_DELETE, FAILURE_APPEND } |
| enum | mansession_message_parsing { MESSAGE_OKAY, MESSAGE_LINE_TOO_LONG } |
Functions | |
| int | __ast_manager_event_multichan (int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt,...) |
| static const char * | __astman_get_header (const struct message *m, char *var, int mode) |
| Return a matching header value. | |
| static void | __init_astman_append_buf (void) |
| thread local buffer for astman_append | |
| static void | __init_manager_event_buf (void) |
| static void | __init_manager_event_funcbuf (void) |
| static void | __init_userevent_buf (void) |
| static void | acl_change_event_cb (const struct ast_event *event, void *userdata) |
| static void | acl_change_event_subscribe (void) |
| static void | acl_change_event_unsubscribe (void) |
| static int | action_aocmessage (struct mansession *s, const struct message *m) |
| static int | action_atxfer (struct mansession *s, const struct message *m) |
| static int | action_challenge (struct mansession *s, const struct message *m) |
| static int | action_command (struct mansession *s, const struct message *m) |
| Manager command "command" - execute CLI command. | |
| static int | action_coresettings (struct mansession *s, const struct message *m) |
| Show PBX core settings information. | |
| static int | action_coreshowchannels (struct mansession *s, const struct message *m) |
| Manager command "CoreShowChannels" - List currently defined channels and some information about them. | |
| static int | action_corestatus (struct mansession *s, const struct message *m) |
| Show PBX core status information. | |
| static int | action_createconfig (struct mansession *s, const struct message *m) |
| static void | action_destroy (void *obj) |
| static int | action_events (struct mansession *s, const struct message *m) |
| static int | action_extensionstate (struct mansession *s, const struct message *m) |
| static int | action_filter (struct mansession *s, const struct message *m) |
| Manager command to add an event filter to a manager session. | |
| static struct manager_action * | action_find (const char *name) |
| static int | action_getconfig (struct mansession *s, const struct message *m) |
| static int | action_getconfigjson (struct mansession *s, const struct message *m) |
| static int | action_getvar (struct mansession *s, const struct message *m) |
| static int | action_hangup (struct mansession *s, const struct message *m) |
| static int | action_listcategories (struct mansession *s, const struct message *m) |
| static int | action_listcommands (struct mansession *s, const struct message *m) |
| static int | action_login (struct mansession *s, const struct message *m) |
| static int | action_logoff (struct mansession *s, const struct message *m) |
| static int | action_mailboxcount (struct mansession *s, const struct message *m) |
| static int | action_mailboxstatus (struct mansession *s, const struct message *m) |
| static int | action_originate (struct mansession *s, const struct message *m) |
| static int | action_ping (struct mansession *s, const struct message *m) |
| static int | action_presencestate (struct mansession *s, const struct message *m) |
| static int | action_redirect (struct mansession *s, const struct message *m) |
| action_redirect: The redirect manager command | |
| static int | action_reload (struct mansession *s, const struct message *m) |
| Send a reload event. | |
| static int | action_sendtext (struct mansession *s, const struct message *m) |
| static int | action_setvar (struct mansession *s, const struct message *m) |
| static int | action_status (struct mansession *s, const struct message *m) |
| Manager "status" command to show channels. | |
| static int | action_timeout (struct mansession *s, const struct message *m) |
| static int | action_updateconfig (struct mansession *s, const struct message *m) |
| static int | action_userevent (struct mansession *s, const struct message *m) |
| static int | action_waitevent (struct mansession *s, const struct message *m) |
| static struct eventqent * | advance_event (struct eventqent *e) |
| static | AO2_GLOBAL_OBJ_STATIC (mgr_sessions) |
| static | AO2_GLOBAL_OBJ_STATIC (event_docs) |
| A container of event documentation nodes. | |
| static int | aocmessage_get_unit_entry (const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num) |
| static void | append_channel_vars (struct ast_str **pbuf, struct ast_channel *chan) |
| static int | append_event (const char *str, int category) |
| events are appended to a queue from where they can be dispatched to clients. | |
| int | ast_hook_send_action (struct manager_custom_hook *hook, const char *msg) |
| access for hooks to send action messages to ami | |
| static int | ast_instring (const char *bigstr, const char *smallstr, const char delim) |
| int | ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), struct ast_module *module, const char *synopsis, const char *description) |
| register a new command with manager, including online help. This is the preferred way to register a manager command | |
| void | ast_manager_register_hook (struct manager_custom_hook *hook) |
| Add a custom hook to be called when an event is fired. | |
| static int | ast_manager_register_struct (struct manager_action *act) |
| int | ast_manager_unregister (const char *action) |
| support functions to register/unregister AMI action handlers, | |
| void | ast_manager_unregister_hook (struct manager_custom_hook *hook) |
| Delete a custom hook to be called when an event is fired. | |
| void | astman_append (struct mansession *s, const char *fmt,...) |
| static void | astman_append_json (struct mansession *s, const char *str) |
| const char * | astman_get_header (const struct message *m, char *var) |
| Return the first matching variable from an array. | |
| struct ast_variable * | astman_get_variables (const struct message *m) |
| Get a linked list of the Variable: headers. | |
| void | astman_send_ack (struct mansession *s, const struct message *m, char *msg) |
| Send ack in manager transaction. | |
| void | astman_send_error (struct mansession *s, const struct message *m, char *error) |
| Send error in manager transaction. | |
| void | astman_send_error_va (struct mansession *s, const struct message *m, const char *fmt,...) |
| Send error in manager transaction (with va_args support) | |
| void | astman_send_listack (struct mansession *s, const struct message *m, char *msg, char *listflag) |
| Send ack in manager list transaction. | |
| void | astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg) |
| Send response in manager transaction. | |
| static void | astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag) |
| send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. | |
| static void | astman_start_ack (struct mansession *s, const struct message *m) |
| static int | authenticate (struct mansession *s, const struct message *m) |
| static const char * | authority_to_str (int authority, struct ast_str **res) |
| Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be returned. | |
| static int | blackfilter_cmp_fn (void *obj, void *arg, void *data, int flags) |
| static struct mansession_session * | build_mansession (const struct ast_sockaddr *addr) |
| Allocate manager session structure and add it to the list of sessions. | |
| static int | check_blacklist (const char *cmd) |
| int | check_manager_enabled (void) |
| Check if AMI is enabled. | |
| static int | check_manager_session_inuse (const char *name) |
| int | check_webmanager_enabled (void) |
| Check if AMI/HTTP is enabled. | |
| static void | destroy_fast_originate_helper (struct fast_originate_helper *doomed) |
| static int | do_message (struct mansession *s) |
| static void | event_filter_destructor (void *obj) |
| static void * | fast_originate (void *data) |
| static void | free_channelvars (void) |
| static int | function_capable_string_allowed_with_auths (const char *evaluating, int writepermlist) |
| Checks to see if a string which can be used to evaluate functions should be rejected. | |
| static int | get_input (struct mansession *s, char *output) |
| static struct ast_manager_user * | get_manager_by_name_locked (const char *name) |
| static int | get_perm (const char *instr) |
| static struct eventqent * | grab_last (void) |
| static char * | handle_manager_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command manager reload. | |
| static char * | handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static void | handle_parse_error (struct mansession *s, struct message *m, char *error) |
| static char * | handle_showmanager (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_showmanagers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_showmancmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_showmancmds (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command manager list commands. | |
| static char * | handle_showmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command manager list connected. | |
| static char * | handle_showmaneventq (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command manager list eventq. | |
| static enum error_type | handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn) |
| helper function for action_updateconfig | |
| static void | json_escape (char *out, const char *in) |
| static struct ast_variable * | man_do_variable_value (struct ast_variable *head, const char *hdr_val) |
| static enum add_filter_result | manager_add_filter (const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters) |
| Add an event filter to a manager session. | |
| static int | manager_displayconnects (struct mansession_session *session) |
| Get displayconnects config option. | |
| static int | manager_modulecheck (struct mansession *s, const struct message *m) |
| Manager function to check if module is loaded. | |
| static int | manager_moduleload (struct mansession *s, const struct message *m) |
| static int | manager_state_cb (char *context, char *exten, struct ast_state_cb_info *info, void *data) |
| static int | mansession_cmp_fn (void *obj, void *arg, int flags) |
| static enum ast_security_event_transport_type | mansession_get_transport (const struct mansession *s) |
| static void | mansession_lock (struct mansession *s) |
| Lock the 'mansession' structure. | |
| static void | mansession_unlock (struct mansession *s) |
| Unlock the 'mansession' structure. | |
| static int | match_filter (struct mansession *s, char *eventdata) |
| static int | process_events (struct mansession *s) |
| static int | process_message (struct mansession *s, const struct message *m) |
| Process an AMI message, performing desired action. Return 0 on success, -1 on error that require the session to be destroyed. | |
| static void | purge_events (void) |
| static void | purge_sessions (int n_max) |
| remove at most n_max stale session from the list. | |
| static void | report_auth_success (const struct mansession *s) |
| static void | report_failed_acl (const struct mansession *s, const char *username) |
| static void | report_failed_challenge_response (const struct mansession *s, const char *response, const char *expected_response) |
| static void | report_inval_password (const struct mansession *s, const char *username) |
| static void | report_invalid_user (const struct mansession *s, const char *username) |
| static void | report_req_bad_format (const struct mansession *s, const char *action) |
| static void | report_req_not_allowed (const struct mansession *s, const char *action) |
| static void | report_session_limit (const struct mansession *s) |
| static int | send_string (struct mansession *s, char *string) |
| static void | session_destroy (struct mansession_session *s) |
| static void | session_destructor (void *obj) |
| static void * | session_do (void *data) |
| The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ) | |
| static int | set_eventmask (struct mansession *s, const char *eventmask) |
| Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm. | |
| static int | strings_to_mask (const char *string) |
| static struct mansession_session * | unref_mansession (struct mansession_session *s) |
| Unreference manager session object. If no more references, then go ahead and delete it. | |
| static const char * | user_authority_to_str (int authority, struct ast_str **res) |
| Convert authority code to a list of options for a user. This will only display those authority codes that have an explicit match on authority. | |
| static int | whitefilter_cmp_fn (void *obj, void *arg, void *data, int flags) |
Variables | |
| static struct ast_event_sub * | acl_change_event_subscription |
| static struct actions | actions |
| static struct all_events | all_events |
| static int | allowmultiplelogin = 1 |
| static struct ast_threadstorage | astman_append_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_astman_append_buf , .custom_init = NULL , } |
| static int | authlimit |
| static int | authtimeout |
| static int | block_sockets |
| static int | broken_events_action = 0 |
| static struct channelvars | channelvars |
| struct { | |
| const char * words [AST_MAX_CMD_LEN] | |
| } | command_blacklist [] |
| static int | displayconnects = 1 |
| static char | global_realm [MAXHOSTNAMELEN] |
| static int | httptimeout = 60 |
| static char * | manager_channelvars |
| static int | manager_debug = 0 |
| static int | manager_enabled = 0 |
| static struct ast_threadstorage | manager_event_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_buf , .custom_init = NULL , } |
| static struct ast_threadstorage | manager_event_funcbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_funcbuf , .custom_init = NULL , } |
| static struct manager_hooks | manager_hooks |
| static struct permalias | perms [] |
| static int | timestampevents |
| static int | unauth_sessions = 0 |
| static struct ast_threadstorage | userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , } |
| static struct users | users |
| static int | webmanager_enabled = 0 |
callback to display queues status in manager
| #define ASTMAN_APPEND_BUF_INITSIZE 256 |
initial allocated size for the astman_append_buf and astman_send_*_va
Definition at line 2236 of file manager.c.
Referenced by astman_append(), and astman_send_error_va().
| #define DEFAULT_REALM "asterisk" |
Definition at line 1023 of file manager.c.
Referenced by manager_set_defaults(), and reload_config().
| #define GET_HEADER_FIRST_MATCH 0 |
Definition at line 1985 of file manager.c.
Referenced by astman_get_header().
| #define GET_HEADER_LAST_MATCH 1 |
Definition at line 1986 of file manager.c.
Referenced by __astman_get_header().
| #define GET_HEADER_SKIP_EMPTY 2 |
Definition at line 1987 of file manager.c.
Referenced by __astman_get_header(), and process_message().
| #define MANAGER_EVENT_BUF_INITSIZE 256 |
Definition at line 5698 of file manager.c.
Referenced by __ast_manager_event_multichan().
| #define MAX_BLACKLIST_CMD_LEN 2 |
Descriptor for a manager session, either on the AMI socket or over HTTP.
Definition at line 1040 of file manager.c.
Referenced by check_blacklist().
| #define MSG_MOREDATA ((char *)astman_send_response) |
Definition at line 2271 of file manager.c.
Referenced by astman_send_response_full(), and astman_start_ack().
| enum add_filter_result |
| enum error_type |
| int __ast_manager_event_multichan | ( | int | category, |
| const char * | event, | ||
| int | chancount, | ||
| struct ast_channel ** | chans, | ||
| const char * | file, | ||
| int | line, | ||
| const char * | func, | ||
| const char * | contents, | ||
| ... | |||
| ) |
External routines may send asterisk manager events this way
| category | Event category, matches manager authorization |
| event | Event name |
| chancount | Number of channels in chans parameter |
| chans | A pointer to an array of channels involved in the event |
| contents | Format string describing event |
Definition at line 5700 of file manager.c.
References ao2_cleanup, ao2_container_count(), ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, append_channel_vars(), append_event(), ast_atomic_fetchadd_int(), AST_PTHREADT_NULL, AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va(), ast_str_buffer(), ast_str_set(), ast_str_thread_get(), ast_tvnow(), authority_to_str(), chancount, manager_custom_hook::helper, manager_event_buf, MANAGER_EVENT_BUF_INITSIZE, mansession_session::pending_event, eventqent::seq, unref_mansession(), and mansession_session::waiting_thread.
{
RAII_VAR(struct ao2_container *, sessions, ao2_global_obj_ref(mgr_sessions), ao2_cleanup);
struct mansession_session *session;
struct manager_custom_hook *hook;
struct ast_str *auth = ast_str_alloca(80);
const char *cat_str;
va_list ap;
struct timeval now;
struct ast_str *buf;
int i;
if (!(sessions && ao2_container_count(sessions)) && AST_RWLIST_EMPTY(&manager_hooks)) {
return 0;
}
if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) {
return -1;
}
cat_str = authority_to_str(category, &auth);
ast_str_set(&buf, 0,
"Event: %s\r\nPrivilege: %s\r\n",
event, cat_str);
if (timestampevents) {
now = ast_tvnow();
ast_str_append(&buf, 0,
"Timestamp: %ld.%06lu\r\n",
(long)now.tv_sec, (unsigned long) now.tv_usec);
}
if (manager_debug) {
static int seq;
ast_str_append(&buf, 0,
"SequenceNumber: %d\r\n",
ast_atomic_fetchadd_int(&seq, 1));
ast_str_append(&buf, 0,
"File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func);
}
va_start(ap, fmt);
ast_str_append_va(&buf, 0, fmt, ap);
va_end(ap);
for (i = 0; i < chancount; i++) {
append_channel_vars(&buf, chans[i]);
}
ast_str_append(&buf, 0, "\r\n");
append_event(ast_str_buffer(buf), category);
/* Wake up any sleeping sessions */
if (sessions) {
struct ao2_iterator i;
i = ao2_iterator_init(sessions, 0);
while ((session = ao2_iterator_next(&i))) {
ao2_lock(session);
if (session->waiting_thread != AST_PTHREADT_NULL) {
pthread_kill(session->waiting_thread, SIGURG);
} else {
/* We have an event to process, but the mansession is
* not waiting for it. We still need to indicate that there
* is an event waiting so that get_input processes the pending
* event instead of polling.
*/
session->pending_event = 1;
}
ao2_unlock(session);
unref_mansession(session);
}
ao2_iterator_destroy(&i);
}
if (!AST_RWLIST_EMPTY(&manager_hooks)) {
AST_RWLIST_RDLOCK(&manager_hooks);
AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
hook->helper(category, event, ast_str_buffer(buf));
}
AST_RWLIST_UNLOCK(&manager_hooks);
}
return 0;
}
| static const char* __astman_get_header | ( | const struct message * | m, |
| char * | var, | ||
| int | mode | ||
| ) | [static] |
Return a matching header value.
Generic function to return either the first or the last matching header from a list of variables, possibly skipping empty strings.
Definition at line 2002 of file manager.c.
References ast_skip_blanks(), ast_strlen_zero(), GET_HEADER_LAST_MATCH, GET_HEADER_SKIP_EMPTY, message::hdrcount, message::headers, and value.
Referenced by astman_get_header(), and process_message().
{
int x, l = strlen(var);
const char *result = "";
if (!m) {
return result;
}
for (x = 0; x < m->hdrcount; x++) {
const char *h = m->headers[x];
if (!strncasecmp(var, h, l) && h[l] == ':') {
const char *value = h + l + 1;
value = ast_skip_blanks(value); /* ignore leading spaces in the value */
/* found a potential candidate */
if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
continue; /* not interesting */
}
if (mode & GET_HEADER_LAST_MATCH) {
result = value; /* record the last match so far */
} else {
return value;
}
}
}
return result;
}
| static void __init_astman_append_buf | ( | void | ) | [static] |
thread local buffer for astman_append
Definition at line 2231 of file manager.c.
{
| static void __init_manager_event_buf | ( | void | ) | [static] |
| static void __init_manager_event_funcbuf | ( | void | ) | [static] |
| static void __init_userevent_buf | ( | void | ) | [static] |
| static void acl_change_event_cb | ( | const struct ast_event * | event, |
| void * | userdata | ||
| ) | [static] |
Definition at line 8027 of file manager.c.
References __init_manager(), ast_log(), and LOG_NOTICE.
Referenced by acl_change_event_subscribe().
{
/* For now, this is going to be performed simply and just execute a forced reload. */
ast_log(LOG_NOTICE, "Reloading manager in response to ACL change event.\n");
__init_manager(1, 1);
| static void acl_change_event_subscribe | ( | void | ) | [static] |
Definition at line 1051 of file manager.c.
References acl_change_event_cb(), acl_change_event_subscription, AST_EVENT_ACL_CHANGE, AST_EVENT_IE_END, and ast_event_subscribe().
Referenced by __init_manager().
{
if (!acl_change_event_subscription) {
acl_change_event_subscription = ast_event_subscribe(AST_EVENT_ACL_CHANGE,
acl_change_event_cb, "Manager must react to Named ACL changes", NULL, AST_EVENT_IE_END);
}
}
| static void acl_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 1059 of file manager.c.
References acl_change_event_subscription, and ast_event_unsubscribe().
Referenced by __init_manager().
| static int action_aocmessage | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 4175 of file manager.c.
References ast_aoc_unit_entry::amount, aocmessage_get_unit_entry(), ast_aoc_add_unit_entry(), AST_AOC_BILLING_CALL_DEFLECTION, AST_AOC_BILLING_CALL_FWD_BUSY, AST_AOC_BILLING_CALL_FWD_NO_REPLY, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL, AST_AOC_BILLING_CALL_TRANSFER, AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, ast_aoc_create(), AST_AOC_D, ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), AST_AOC_E, ast_aoc_encode(), AST_AOC_MULT_HUNDRED, AST_AOC_MULT_ONE, AST_AOC_MULT_ONEHUNDREDTH, AST_AOC_MULT_ONETENTH, AST_AOC_MULT_ONETHOUSANDTH, AST_AOC_MULT_TEN, AST_AOC_MULT_THOUSAND, ast_aoc_set_association_id(), ast_aoc_set_association_number(), ast_aoc_set_billing_id(), ast_aoc_set_currency_info(), ast_aoc_set_total_type(), AST_AOC_SUBTOTAL, AST_AOC_TOTAL, ast_channel_get_by_name(), ast_channel_get_by_name_prefix(), ast_channel_unref, AST_CONTROL_AOC, ast_indicate_data(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_aoc_unit_entry::type, ast_aoc_unit_entry::valid_amount, and ast_aoc_unit_entry::valid_type.
Referenced by __init_manager().
{
const char *channel = astman_get_header(m, "Channel");
const char *pchannel = astman_get_header(m, "ChannelPrefix");
const char *msgtype = astman_get_header(m, "MsgType");
const char *chargetype = astman_get_header(m, "ChargeType");
const char *currencyname = astman_get_header(m, "CurrencyName");
const char *currencyamount = astman_get_header(m, "CurrencyAmount");
const char *mult = astman_get_header(m, "CurrencyMultiplier");
const char *totaltype = astman_get_header(m, "TotalType");
const char *aocbillingid = astman_get_header(m, "AOCBillingId");
const char *association_id= astman_get_header(m, "ChargingAssociationId");
const char *association_num = astman_get_header(m, "ChargingAssociationNumber");
const char *association_plan = astman_get_header(m, "ChargingAssociationPlan");
enum ast_aoc_type _msgtype;
enum ast_aoc_charge_type _chargetype;
enum ast_aoc_currency_multiplier _mult = AST_AOC_MULT_ONE;
enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL;
enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA;
unsigned int _currencyamount = 0;
int _association_id = 0;
unsigned int _association_plan = 0;
struct ast_channel *chan = NULL;
struct ast_aoc_decoded *decoded = NULL;
struct ast_aoc_encoded *encoded = NULL;
size_t encoded_size = 0;
if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
goto aocmessage_cleanup;
}
if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
}
if (!chan) {
astman_send_error(s, m, "No such channel");
goto aocmessage_cleanup;
}
if (ast_strlen_zero(msgtype) || (strcasecmp(msgtype, "d") && strcasecmp(msgtype, "e"))) {
astman_send_error(s, m, "Invalid MsgType");
goto aocmessage_cleanup;
}
if (ast_strlen_zero(chargetype)) {
astman_send_error(s, m, "ChargeType not specified");
goto aocmessage_cleanup;
}
_msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D;
if (!strcasecmp(chargetype, "NA")) {
_chargetype = AST_AOC_CHARGE_NA;
} else if (!strcasecmp(chargetype, "Free")) {
_chargetype = AST_AOC_CHARGE_FREE;
} else if (!strcasecmp(chargetype, "Currency")) {
_chargetype = AST_AOC_CHARGE_CURRENCY;
} else if (!strcasecmp(chargetype, "Unit")) {
_chargetype = AST_AOC_CHARGE_UNIT;
} else {
astman_send_error(s, m, "Invalid ChargeType");
goto aocmessage_cleanup;
}
if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) {
astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency");
goto aocmessage_cleanup;
}
if (ast_strlen_zero(mult)) {
astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
goto aocmessage_cleanup;
} else if (!strcasecmp(mult, "onethousandth")) {
_mult = AST_AOC_MULT_ONETHOUSANDTH;
} else if (!strcasecmp(mult, "onehundredth")) {
_mult = AST_AOC_MULT_ONEHUNDREDTH;
} else if (!strcasecmp(mult, "onetenth")) {
_mult = AST_AOC_MULT_ONETENTH;
} else if (!strcasecmp(mult, "one")) {
_mult = AST_AOC_MULT_ONE;
} else if (!strcasecmp(mult, "ten")) {
_mult = AST_AOC_MULT_TEN;
} else if (!strcasecmp(mult, "hundred")) {
_mult = AST_AOC_MULT_HUNDRED;
} else if (!strcasecmp(mult, "thousand")) {
_mult = AST_AOC_MULT_THOUSAND;
} else {
astman_send_error(s, m, "Invalid ChargeMultiplier");
goto aocmessage_cleanup;
}
}
/* create decoded object and start setting values */
if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) {
astman_send_error(s, m, "Message Creation Failed");
goto aocmessage_cleanup;
}
if (_msgtype == AST_AOC_D) {
if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) {
_totaltype = AST_AOC_SUBTOTAL;
}
if (ast_strlen_zero(aocbillingid)) {
/* ignore this is optional */
} else if (!strcasecmp(aocbillingid, "Normal")) {
_billingid = AST_AOC_BILLING_NORMAL;
} else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
_billingid = AST_AOC_BILLING_REVERSE_CHARGE;
} else if (!strcasecmp(aocbillingid, "CreditCard")) {
_billingid = AST_AOC_BILLING_CREDIT_CARD;
} else {
astman_send_error(s, m, "Invalid AOC-D AOCBillingId");
goto aocmessage_cleanup;
}
} else {
if (ast_strlen_zero(aocbillingid)) {
/* ignore this is optional */
} else if (!strcasecmp(aocbillingid, "Normal")) {
_billingid = AST_AOC_BILLING_NORMAL;
} else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
_billingid = AST_AOC_BILLING_REVERSE_CHARGE;
} else if (!strcasecmp(aocbillingid, "CreditCard")) {
_billingid = AST_AOC_BILLING_CREDIT_CARD;
} else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) {
_billingid = AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL;
} else if (!strcasecmp(aocbillingid, "CallFwdBusy")) {
_billingid = AST_AOC_BILLING_CALL_FWD_BUSY;
} else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) {
_billingid = AST_AOC_BILLING_CALL_FWD_NO_REPLY;
} else if (!strcasecmp(aocbillingid, "CallDeflection")) {
_billingid = AST_AOC_BILLING_CALL_DEFLECTION;
} else if (!strcasecmp(aocbillingid, "CallTransfer")) {
_billingid = AST_AOC_BILLING_CALL_TRANSFER;
} else {
astman_send_error(s, m, "Invalid AOC-E AOCBillingId");
goto aocmessage_cleanup;
}
if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) {
astman_send_error(s, m, "Invalid ChargingAssociationId");
goto aocmessage_cleanup;
}
if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) {
astman_send_error(s, m, "Invalid ChargingAssociationPlan");
goto aocmessage_cleanup;
}
if (_association_id) {
ast_aoc_set_association_id(decoded, _association_id);
} else if (!ast_strlen_zero(association_num)) {
ast_aoc_set_association_number(decoded, association_num, _association_plan);
}
}
if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname);
} else if (_chargetype == AST_AOC_CHARGE_UNIT) {
struct ast_aoc_unit_entry entry;
int i;
/* multiple unit entries are possible, lets get them all */
for (i = 0; i < 32; i++) {
if (aocmessage_get_unit_entry(m, &entry, i)) {
break; /* that's the end then */
}
ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type);
}
/* at least one unit entry is required */
if (!i) {
astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit");
goto aocmessage_cleanup;
}
}
ast_aoc_set_billing_id(decoded, _billingid);
ast_aoc_set_total_type(decoded, _totaltype);
if ((encoded = ast_aoc_encode(decoded, &encoded_size, NULL)) && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
astman_send_ack(s, m, "AOC Message successfully queued on channel");
} else {
astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel");
}
aocmessage_cleanup:
ast_aoc_destroy_decoded(decoded);
ast_aoc_destroy_encoded(encoded);
if (chan) {
chan = ast_channel_unref(chan);
}
return 0;
}
| static int action_atxfer | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3901 of file manager.c.
References ast_channel_get_by_name(), ast_channel_unref, ast_find_call_feature(), AST_FRAME_DTMF, ast_queue_frame(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, ast_call_feature::exten, exten, and pbx_builtin_setvar_helper().
Referenced by __init_manager().
{
const char *name = astman_get_header(m, "Channel");
const char *exten = astman_get_header(m, "Exten");
const char *context = astman_get_header(m, "Context");
struct ast_channel *chan = NULL;
struct ast_call_feature *atxfer_feature = NULL;
char *feature_code = NULL;
if (ast_strlen_zero(name)) {
astman_send_error(s, m, "No channel specified");
return 0;
}
if (ast_strlen_zero(exten)) {
astman_send_error(s, m, "No extension specified");
return 0;
}
if (!(atxfer_feature = ast_find_call_feature("atxfer"))) {
astman_send_error(s, m, "No attended transfer feature found");
return 0;
}
if (!(chan = ast_channel_get_by_name(name))) {
astman_send_error(s, m, "Channel specified does not exist");
return 0;
}
if (!ast_strlen_zero(context)) {
pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
}
for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) {
struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *feature_code };
ast_queue_frame(chan, &f);
}
for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) {
struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *feature_code };
ast_queue_frame(chan, &f);
}
chan = ast_channel_unref(chan);
astman_send_ack(s, m, "Atxfer successfully queued");
return 0;
}
| static int action_challenge | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3324 of file manager.c.
References ast_random(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mansession_session::challenge, mansession_lock(), mansession_unlock(), and mansession::session.
Referenced by __init_manager().
{
const char *authtype = astman_get_header(m, "AuthType");
if (!strcasecmp(authtype, "MD5")) {
if (ast_strlen_zero(s->session->challenge)) {
snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
}
mansession_lock(s);
astman_start_ack(s, m);
astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
mansession_unlock(s);
} else {
astman_send_error(s, m, "Must specify AuthType");
}
return 0;
}
| static int action_command | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Manager command "command" - execute CLI command.
Definition at line 3986 of file manager.c.
References ast_free, ast_log(), AST_LOG_WARNING, ast_malloc, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), check_blacklist(), errno, LOG_WARNING, and term_strip().
Referenced by __init_manager().
{
const char *cmd = astman_get_header(m, "Command");
const char *id = astman_get_header(m, "ActionID");
char *buf = NULL, *final_buf = NULL;
char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */
int fd;
off_t l;
if (ast_strlen_zero(cmd)) {
astman_send_error(s, m, "No command provided");
return 0;
}
if (check_blacklist(cmd)) {
astman_send_error(s, m, "Command blacklisted");
return 0;
}
if ((fd = mkstemp(template)) < 0) {
ast_log(AST_LOG_WARNING, "Failed to create temporary file for command: %s\n", strerror(errno));
astman_send_error(s, m, "Command response construction error");
return 0;
}
astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
if (!ast_strlen_zero(id)) {
astman_append(s, "ActionID: %s\r\n", id);
}
/* FIXME: Wedge a ActionID response in here, waiting for later changes */
ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */
/* Determine number of characters available */
if ((l = lseek(fd, 0, SEEK_END)) < 0) {
ast_log(LOG_WARNING, "Failed to determine number of characters for command: %s\n", strerror(errno));
goto action_command_cleanup;
}
/* This has a potential to overflow the stack. Hence, use the heap. */
buf = ast_malloc(l + 1);
final_buf = ast_malloc(l + 1);
if (!buf || !final_buf) {
ast_log(LOG_WARNING, "Failed to allocate memory for temporary buffer\n");
goto action_command_cleanup;
}
if (lseek(fd, 0, SEEK_SET) < 0) {
ast_log(LOG_WARNING, "Failed to set position on temporary file for command: %s\n", strerror(errno));
goto action_command_cleanup;
}
if (read(fd, buf, l) < 0) {
ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
goto action_command_cleanup;
}
buf[l] = '\0';
term_strip(final_buf, buf, l);
final_buf[l] = '\0';
astman_append(s, "%s", final_buf);
action_command_cleanup:
close(fd);
unlink(template);
astman_append(s, "--END COMMAND--\r\n\r\n");
ast_free(buf);
ast_free(final_buf);
return 0;
}
| static int action_coresettings | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Show PBX core settings information.
Definition at line 4901 of file manager.c.
References AMI_VERSION, AST_CLI_YESNO, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SYSTEM_NAME, ast_get_version(), ast_realtime_enabled(), ast_strlen_zero(), astman_append(), astman_get_header(), check_cdr_enabled(), check_webmanager_enabled(), option_maxcalls, option_maxfiles, and option_maxload.
Referenced by __init_manager().
{
const char *actionid = astman_get_header(m, "ActionID");
char idText[150];
if (!ast_strlen_zero(actionid)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
} else {
idText[0] = '\0';
}
astman_append(s, "Response: Success\r\n"
"%s"
"AMIversion: %s\r\n"
"AsteriskVersion: %s\r\n"
"SystemName: %s\r\n"
"CoreMaxCalls: %d\r\n"
"CoreMaxLoadAvg: %f\r\n"
"CoreRunUser: %s\r\n"
"CoreRunGroup: %s\r\n"
"CoreMaxFilehandles: %d\r\n"
"CoreRealTimeEnabled: %s\r\n"
"CoreCDRenabled: %s\r\n"
"CoreHTTPenabled: %s\r\n"
"\r\n",
idText,
AMI_VERSION,
ast_get_version(),
ast_config_AST_SYSTEM_NAME,
option_maxcalls,
option_maxload,
ast_config_AST_RUN_USER,
ast_config_AST_RUN_GROUP,
option_maxfiles,
AST_CLI_YESNO(ast_realtime_enabled()),
AST_CLI_YESNO(check_cdr_enabled()),
AST_CLI_YESNO(check_webmanager_enabled())
);
return 0;
}
| static int action_coreshowchannels | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Manager command "CoreShowChannels" - List currently defined channels and some information about them.
Definition at line 5010 of file manager.c.
References ast_bridged_channel(), ast_channel_accountcode(), ast_channel_appl(), ast_channel_caller(), ast_channel_cdr(), ast_channel_connected(), ast_channel_context(), ast_channel_data(), ast_channel_exten(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_name(), ast_channel_priority(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_listack(), S_COR, and S_OR.
Referenced by __init_manager().
{
const char *actionid = astman_get_header(m, "ActionID");
char idText[256];
struct ast_channel *c = NULL;
int numchans = 0;
int duration, durh, durm, durs;
struct ast_channel_iterator *iter;
if (!ast_strlen_zero(actionid)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
} else {
idText[0] = '\0';
}
if (!(iter = ast_channel_iterator_all_new())) {
astman_send_error(s, m, "Memory Allocation Failure");
return 1;
}
astman_send_listack(s, m, "Channels will follow", "start");
for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
struct ast_channel *bc;
char durbuf[10] = "";
ast_channel_lock(c);
bc = ast_bridged_channel(c);
if (ast_channel_cdr(c) && !ast_tvzero(ast_channel_cdr(c)->start)) {
duration = (int)(ast_tvdiff_ms(ast_tvnow(), ast_channel_cdr(c)->start) / 1000);
durh = duration / 3600;
durm = (duration % 3600) / 60;
durs = duration % 60;
snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
}
astman_append(s,
"Event: CoreShowChannel\r\n"
"%s"
"Channel: %s\r\n"
"UniqueID: %s\r\n"
"Context: %s\r\n"
"Extension: %s\r\n"
"Priority: %d\r\n"
"ChannelState: %d\r\n"
"ChannelStateDesc: %s\r\n"
"Application: %s\r\n"
"ApplicationData: %s\r\n"
"CallerIDnum: %s\r\n"
"CallerIDname: %s\r\n"
"ConnectedLineNum: %s\r\n"
"ConnectedLineName: %s\r\n"
"Duration: %s\r\n"
"AccountCode: %s\r\n"
"BridgedChannel: %s\r\n"
"BridgedUniqueID: %s\r\n"
"\r\n", idText, ast_channel_name(c), ast_channel_uniqueid(c), ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_state(c),
ast_state2str(ast_channel_state(c)), ast_channel_appl(c) ? ast_channel_appl(c) : "", ast_channel_data(c) ? S_OR(ast_channel_data(c), "") : "",
S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, ""),
S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, ""),
S_COR(ast_channel_connected(c)->id.number.valid, ast_channel_connected(c)->id.number.str, ""),
S_COR(ast_channel_connected(c)->id.name.valid, ast_channel_connected(c)->id.name.str, ""),
durbuf, S_OR(ast_channel_accountcode(c), ""), bc ? ast_channel_name(bc) : "", bc ? ast_channel_uniqueid(bc) : "");
ast_channel_unlock(c);
numchans++;
}
astman_append(s,
"Event: CoreShowChannelsComplete\r\n"
"EventList: Complete\r\n"
"ListItems: %d\r\n"
"%s"
"\r\n", numchans, idText);
ast_channel_iterator_destroy(iter);
return 0;
}
| static int action_corestatus | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Show PBX core status information.
Definition at line 4943 of file manager.c.
References ast_active_channels(), ast_lastreloadtime, ast_localtime(), ast_startuptime, ast_strftime(), ast_strlen_zero(), astman_append(), and astman_get_header().
Referenced by __init_manager().
{
const char *actionid = astman_get_header(m, "ActionID");
char idText[150];
char startuptime[150], startupdate[150];
char reloadtime[150], reloaddate[150];
struct ast_tm tm;
if (!ast_strlen_zero(actionid)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
} else {
idText[0] = '\0';
}
ast_localtime(&ast_startuptime, &tm, NULL);
ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm);
ast_localtime(&ast_lastreloadtime, &tm, NULL);
ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm);
astman_append(s, "Response: Success\r\n"
"%s"
"CoreStartupDate: %s\r\n"
"CoreStartupTime: %s\r\n"
"CoreReloadDate: %s\r\n"
"CoreReloadTime: %s\r\n"
"CoreCurrentCalls: %d\r\n"
"\r\n",
idText,
startupdate,
startuptime,
reloaddate,
reloadtime,
ast_active_channels()
);
return 0;
}
| static int action_createconfig | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3100 of file manager.c.
References ast_config_AST_CONFIG_DIR, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), astman_get_header(), astman_send_ack(), astman_send_error(), and errno.
Referenced by __init_manager().
{
int fd;
const char *fn = astman_get_header(m, "Filename");
struct ast_str *filepath = ast_str_alloca(PATH_MAX);
ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
ast_str_append(&filepath, 0, "%s", fn);
if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
close(fd);
astman_send_ack(s, m, "New configuration file created successfully");
} else {
astman_send_error(s, m, strerror(errno));
}
return 0;
}
| static void action_destroy | ( | void * | obj | ) | [static] |
Definition at line 5910 of file manager.c.
References ast_string_field_free_memory, and manager_action::synopsis.
Referenced by ast_manager_register2().
{
struct manager_action *doomed = obj;
if (doomed->synopsis) {
/* The string fields were initialized. */
ast_string_field_free_memory(doomed);
}
}
| static int action_events | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3243 of file manager.c.
References ARRAY_LEN, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), permalias::num, perms, and set_eventmask().
Referenced by __init_manager().
{
const char *mask = astman_get_header(m, "EventMask");
int res, x;
const char *id = astman_get_header(m, "ActionID");
char id_text[256];
if (!ast_strlen_zero(id)) {
snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
} else {
id_text[0] = '\0';
}
res = set_eventmask(s, mask);
if (broken_events_action) {
/* if this option is set we should not return a response on
* error, or when all events are set */
if (res > 0) {
for (x = 0; x < ARRAY_LEN(perms); x++) {
if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
return 0;
}
}
astman_append(s, "Response: Success\r\n%s"
"Events: On\r\n\r\n", id_text);
} else if (res == 0)
astman_append(s, "Response: Success\r\n%s"
"Events: Off\r\n\r\n", id_text);
return 0;
}
if (res > 0)
astman_append(s, "Response: Success\r\n%s"
"Events: On\r\n\r\n", id_text);
else if (res == 0)
astman_append(s, "Response: Success\r\n%s"
"Events: Off\r\n\r\n", id_text);
else
astman_send_error(s, m, "Invalid event mask");
return 0;
}
| static int action_extensionstate | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 4612 of file manager.c.
References ast_extension_state(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), context, exten, and status.
Referenced by __init_manager().
{
const char *exten = astman_get_header(m, "Exten");
const char *context = astman_get_header(m, "Context");
char hint[256] = "";
int status;
if (ast_strlen_zero(exten)) {
astman_send_error(s, m, "Extension not specified");
return 0;
}
if (ast_strlen_zero(context)) {
context = "default";
}
status = ast_extension_state(NULL, context, exten);
ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
astman_start_ack(s, m);
astman_append(s, "Message: Extension Status\r\n"
"Exten: %s\r\n"
"Context: %s\r\n"
"Hint: %s\r\n"
"Status: %d\r\n\r\n",
exten, context, hint, status);
return 0;
}
| static int action_filter | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Manager command to add an event filter to a manager session.
Definition at line 4745 of file manager.c.
References astman_get_header(), astman_send_ack(), astman_send_error(), mansession_session::blackfilters, filter(), FILTER_ALLOC_FAILED, FILTER_COMPILE_FAIL, FILTER_SUCCESS, manager_add_filter(), mansession::session, and mansession_session::whitefilters.
Referenced by __init_manager().
{
const char *filter = astman_get_header(m, "Filter");
const char *operation = astman_get_header(m, "Operation");
int res;
if (!strcasecmp(operation, "Add")) {
res = manager_add_filter(filter, s->session->whitefilters, s->session->blackfilters);
if (res != FILTER_SUCCESS) {
if (res == FILTER_ALLOC_FAILED) {
astman_send_error(s, m, "Internal Error. Failed to allocate regex for filter");
return 0;
} else if (res == FILTER_COMPILE_FAIL) {
astman_send_error(s, m, "Filter did not compile. Check the syntax of the filter given.");
return 0;
} else {
astman_send_error(s, m, "Internal Error. Failed adding filter.");
return 0;
}
}
astman_send_ack(s, m, "Success");
return 0;
}
astman_send_error(s, m, "Unknown operation");
return 0;
}
| static struct manager_action* action_find | ( | const char * | name | ) | [static, read] |
Definition at line 1210 of file manager.c.
References manager_action::action, ao2_t_ref, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.
Referenced by ast_hook_send_action(), and process_message().
{
struct manager_action *act;
AST_RWLIST_RDLOCK(&actions);
AST_RWLIST_TRAVERSE(&actions, act, list) {
if (!strcasecmp(name, act->action)) {
ao2_t_ref(act, +1, "found action object");
break;
}
}
AST_RWLIST_UNLOCK(&actions);
return act;
}
| static int action_getconfig | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 2718 of file manager.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __init_manager().
{
struct ast_config *cfg;
const char *fn = astman_get_header(m, "Filename");
const char *category = astman_get_header(m, "Category");
int catcount = 0;
int lineno = 0;
char *cur_category = NULL;
struct ast_variable *v;
struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
if (ast_strlen_zero(fn)) {
astman_send_error(s, m, "Filename not specified");
return 0;
}
cfg = ast_config_load2(fn, "manager", config_flags);
if (cfg == CONFIG_STATUS_FILEMISSING) {
astman_send_error(s, m, "Config file not found");
return 0;
} else if (cfg == CONFIG_STATUS_FILEINVALID) {
astman_send_error(s, m, "Config file has invalid format");
return 0;
}
astman_start_ack(s, m);
while ((cur_category = ast_category_browse(cfg, cur_category))) {
if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) {
lineno = 0;
astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category);
for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) {
astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
}
catcount++;
}
}
if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
astman_append(s, "No categories found\r\n");
}
ast_config_destroy(cfg);
astman_append(s, "\r\n");
return 0;
}
| static int action_getconfigjson | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 2828 of file manager.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_append_json(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __init_manager().
{
struct ast_config *cfg;
const char *fn = astman_get_header(m, "Filename");
char *category = NULL;
struct ast_variable *v;
int comma1 = 0;
struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
if (ast_strlen_zero(fn)) {
astman_send_error(s, m, "Filename not specified");
return 0;
}
if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
astman_send_error(s, m, "Config file not found");
return 0;
} else if (cfg == CONFIG_STATUS_FILEINVALID) {
astman_send_error(s, m, "Config file has invalid format");
return 0;
}
astman_start_ack(s, m);
astman_append(s, "JSON: {");
while ((category = ast_category_browse(cfg, category))) {
int comma2 = 0;
astman_append(s, "%s\"", comma1 ? "," : "");
astman_append_json(s, category);
astman_append(s, "\":[");
comma1 = 1;
for (v = ast_variable_browse(cfg, category); v; v = v->next) {
astman_append(s, "%s\"", comma2 ? "," : "");
astman_append_json(s, v->name);
astman_append(s, "\":\"");
astman_append_json(s, v->value);
astman_append(s, "\"");
comma2 = 1;
}
astman_append(s, "]");
}
astman_append(s, "}\r\n\r\n");
ast_config_destroy(cfg);
return 0;
}
| static int action_getvar | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3497 of file manager.c.
References ast_channel_get_by_name(), ast_channel_unref, ast_dummy_channel_alloc(), ast_func_read(), ast_log(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), function_capable_string_allowed_with_auths(), LOG_ERROR, pbx_retrieve_variable(), S_OR, mansession::session, and mansession_session::writeperm.
Referenced by __init_manager().
{
struct ast_channel *c = NULL;
const char *name = astman_get_header(m, "Channel");
const char *varname = astman_get_header(m, "Variable");
char *varval;
char workspace[1024];
if (ast_strlen_zero(varname)) {
astman_send_error(s, m, "No variable specified");
return 0;
}
/* We don't want users with insufficient permissions using certain functions. */
if (!(function_capable_string_allowed_with_auths(varname, s->session->writeperm))) {
astman_send_error(s, m, "GetVar Access Forbidden: Variable");
return 0;
}
if (!ast_strlen_zero(name)) {
if (!(c = ast_channel_get_by_name(name))) {
astman_send_error(s, m, "No such channel");
return 0;
}
}
workspace[0] = '\0';
if (varname[strlen(varname) - 1] == ')') {
if (!c) {
c = ast_dummy_channel_alloc();
if (c) {
ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
} else
ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
} else {
ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
}
varval = workspace;
} else {
pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
}
if (c) {
c = ast_channel_unref(c);
}
astman_start_ack(s, m);
astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, ""));
return 0;
}
| static int action_hangup | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3342 of file manager.c.
References mansession_session::addr, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_name(), ast_channel_softhangup_withcause_locked(), ast_channel_unref, ast_free, ast_log(), ast_regex_string_to_regex_pattern(), ast_sockaddr_stringify_addr(), ast_str_buffer(), ast_str_create(), ast_strlen_zero(), ast_verb, astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), astman_send_error_va(), astman_send_listack(), LOG_NOTICE, mansession_session::managerid, mansession::session, and mansession_session::username.
Referenced by __init_manager().
{
struct ast_channel *c = NULL;
int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */
const char *id = astman_get_header(m, "ActionID");
const char *name_or_regex = astman_get_header(m, "Channel");
const char *cause = astman_get_header(m, "Cause");
char idText[256];
regex_t regexbuf;
struct ast_channel_iterator *iter = NULL;
struct ast_str *regex_string;
int channels_matched = 0;
if (ast_strlen_zero(name_or_regex)) {
astman_send_error(s, m, "No channel specified");
return 0;
}
if (!ast_strlen_zero(id)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
} else {
idText[0] = '\0';
}
if (!ast_strlen_zero(cause)) {
char *endptr;
causecode = strtol(cause, &endptr, 10);
if (causecode < 0 || causecode > 127 || *endptr != '\0') {
ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause);
/* keep going, better to hangup without cause than to not hang up at all */
causecode = 0; /* do not set channel's hangupcause */
}
}
/************************************************/
/* Regular explicit match channel byname hangup */
if (name_or_regex[0] != '/') {
if (!(c = ast_channel_get_by_name(name_or_regex))) {
ast_log(LOG_NOTICE, "Request to hangup non-existent channel: %s\n",
name_or_regex);
astman_send_error(s, m, "No such channel");
return 0;
}
ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
(s->session->managerid ? "HTTP " : ""),
s->session->username,
ast_sockaddr_stringify_addr(&s->session->addr),
ast_channel_name(c));
ast_channel_softhangup_withcause_locked(c, causecode);
c = ast_channel_unref(c);
astman_send_ack(s, m, "Channel Hungup");
return 0;
}
/***********************************************/
/* find and hangup any channels matching regex */
regex_string = ast_str_create(strlen(name_or_regex));
if (!regex_string) {
astman_send_error(s, m, "Memory Allocation Failure");
return 0;
}
/* Make "/regex/" into "regex" */
if (ast_regex_string_to_regex_pattern(name_or_regex, ®ex_string) != 0) {
astman_send_error(s, m, "Regex format invalid, Channel param should be /regex/");
ast_free(regex_string);
return 0;
}
/* if regex compilation fails, hangup fails */
if (regcomp(®exbuf, ast_str_buffer(regex_string), REG_EXTENDED | REG_NOSUB)) {
astman_send_error_va(s, m, "Regex compile failed on: %s", name_or_regex);
ast_free(regex_string);
return 0;
}
astman_send_listack(s, m, "Channels hung up will follow", "start");
iter = ast_channel_iterator_all_new();
if (iter) {
for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
if (regexec(®exbuf, ast_channel_name(c), 0, NULL, 0)) {
continue;
}
ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
(s->session->managerid ? "HTTP " : ""),
s->session->username,
ast_sockaddr_stringify_addr(&s->session->addr),
ast_channel_name(c));
ast_channel_softhangup_withcause_locked(c, causecode);
channels_matched++;
astman_append(s,
"Event: ChannelHungup\r\n"
"Channel: %s\r\n"
"%s"
"\r\n", ast_channel_name(c), idText);
}
ast_channel_iterator_destroy(iter);
}
regfree(®exbuf);
ast_free(regex_string);
astman_append(s,
"Event: ChannelsHungupListComplete\r\n"
"EventList: Complete\r\n"
"ListItems: %d\r\n"
"%s"
"\r\n", channels_matched, idText);
return 0;
}
| static int action_listcategories | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 2762 of file manager.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, and CONFIG_STATUS_FILEINVALID.
Referenced by __init_manager().
{
struct ast_config *cfg;
const char *fn = astman_get_header(m, "Filename");
char *category = NULL;
struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
int catcount = 0;
if (ast_strlen_zero(fn)) {
astman_send_error(s, m, "Filename not specified");
return 0;
}
if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
astman_send_error(s, m, "Config file not found");
return 0;
} else if (cfg == CONFIG_STATUS_FILEINVALID) {
astman_send_error(s, m, "Config file has invalid format");
return 0;
}
astman_start_ack(s, m);
while ((category = ast_category_browse(cfg, category))) {
astman_append(s, "Category-%06d: %s\r\n", catcount, category);
catcount++;
}
if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
astman_append(s, "Error: no categories found\r\n");
}
ast_config_destroy(cfg);
astman_append(s, "\r\n");
return 0;
}
| static int action_listcommands | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3224 of file manager.c.
References manager_action::action, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, astman_append(), astman_start_ack(), manager_action::authority, authority_to_str(), mansession::session, manager_action::synopsis, and mansession_session::writeperm.
Referenced by __init_manager().
{
struct manager_action *cur;
struct ast_str *temp = ast_str_alloca(256);
astman_start_ack(s, m);
AST_RWLIST_RDLOCK(&actions);
AST_RWLIST_TRAVERSE(&actions, cur, list) {
if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
astman_append(s, "%s: %s (Priv: %s)\r\n",
cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
}
}
AST_RWLIST_UNLOCK(&actions);
astman_append(s, "\r\n");
return 0;
}
| static int action_login | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3293 of file manager.c.
References mansession_session::addr, ast_atomic_fetchadd_int(), AST_OPT_FLAG_FULLY_BOOTED, ast_options, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_test_flag, ast_verb, astman_append(), astman_send_ack(), astman_send_error(), authenticate(), mansession_session::authenticated, authority_to_str(), EVENT_FLAG_SYSTEM, manager_displayconnects(), mansession_session::managerid, mansession_session::send_events, mansession::session, unauth_sessions, and mansession_session::username.
Referenced by __init_manager().
{
/* still authenticated - don't process again */
if (s->session->authenticated) {
astman_send_ack(s, m, "Already authenticated");
return 0;
}
if (authenticate(s, m)) {
sleep(1);
astman_send_error(s, m, "Authentication failed");
return -1;
}
s->session->authenticated = 1;
ast_atomic_fetchadd_int(&unauth_sessions, -1);
if (manager_displayconnects(s->session)) {
ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_sockaddr_stringify_addr(&s->session->addr));
}
astman_send_ack(s, m, "Authentication accepted");
if ((s->session->send_events & EVENT_FLAG_SYSTEM)
&& ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
struct ast_str *auth = ast_str_alloca(80);
const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
astman_append(s, "Event: FullyBooted\r\n"
"Privilege: %s\r\n"
"Status: Fully Booted\r\n\r\n", cat_str);
}
return 0;
}
| static int action_logoff | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3287 of file manager.c.
References astman_send_response().
Referenced by __init_manager().
{
astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
return -1;
}
| static int action_mailboxcount | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 4591 of file manager.c.
References ast_app_inboxcount2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and mailbox.
Referenced by __init_manager().
{
const char *mailbox = astman_get_header(m, "Mailbox");
int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
if (ast_strlen_zero(mailbox)) {
astman_send_error(s, m, "Mailbox not specified");
return 0;
}
ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
astman_start_ack(s, m);
astman_append(s, "Message: Mailbox Message Count\r\n"
"Mailbox: %s\r\n"
"UrgMessages: %d\r\n"
"NewMessages: %d\r\n"
"OldMessages: %d\r\n"
"\r\n",
mailbox, urgentmsgs, newmsgs, oldmsgs);
return 0;
}
| static int action_mailboxstatus | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 4574 of file manager.c.
References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and mailbox.
Referenced by __init_manager().
{
const char *mailbox = astman_get_header(m, "Mailbox");
int ret;
if (ast_strlen_zero(mailbox)) {
astman_send_error(s, m, "Mailbox not specified");
return 0;
}
ret = ast_app_has_voicemail(mailbox, NULL);
astman_start_ack(s, m);
astman_append(s, "Message: Mailbox Status\r\n"
"Mailbox: %s\r\n"
"Waiting: %d\r\n\r\n", mailbox, ret);
return 0;
}
| static int action_originate | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 4380 of file manager.c.
References app, ast_callerid_parse(), ast_calloc, ast_copy_string(), ast_exists_extension(), ast_findlabel_extension(), ast_format_cap_add(), ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_remove_all(), ast_format_set(), AST_FORMAT_SLINEAR, ast_free, ast_parse_allow_disallow(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create_detached, ast_shrink_phone_number(), ast_string_field_build, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_true(), ast_variables_destroy(), ast_variables_dup(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), fast_originate_helper::cap, mansession_session::chanvars, cid_name, cid_num, context, ast_frame::data, destroy_fast_originate_helper(), fast_originate_helper::early_media, EVENT_FLAG_SYSTEM, exten, fast_originate(), ast_variable::next, fast_originate_helper::priority, mansession::session, fast_originate_helper::timeout, fast_originate_helper::vars, and mansession_session::writeperm.
Referenced by __init_manager().
{
const char *name = astman_get_header(m, "Channel");
const char *exten = astman_get_header(m, "Exten");
const char *context = astman_get_header(m, "Context");
const char *priority = astman_get_header(m, "Priority");
const char *timeout = astman_get_header(m, "Timeout");
const char *callerid = astman_get_header(m, "CallerID");
const char *account = astman_get_header(m, "Account");
const char *app = astman_get_header(m, "Application");
const char *appdata = astman_get_header(m, "Data");
const char *async = astman_get_header(m, "Async");
const char *id = astman_get_header(m, "ActionID");
const char *codecs = astman_get_header(m, "Codecs");
const char *early_media = astman_get_header(m, "Earlymedia");
struct ast_variable *vars = NULL;
char *tech, *data;
char *l = NULL, *n = NULL;
int pi = 0;
int res;
int to = 30000;
int reason = 0;
char tmp[256];
char tmp2[256];
struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
struct ast_format tmp_fmt;
pthread_t th;
int bridge_early = 0;
if (!cap) {
astman_send_error(s, m, "Internal Error. Memory allocation failure.");
return 0;
}
ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0));
if (ast_strlen_zero(name)) {
astman_send_error(s, m, "Channel not specified");
res = 0;
goto fast_orig_cleanup;
}
if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
astman_send_error(s, m, "Invalid priority");
res = 0;
goto fast_orig_cleanup;
}
}
if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
astman_send_error(s, m, "Invalid timeout");
res = 0;
goto fast_orig_cleanup;
}
ast_copy_string(tmp, name, sizeof(tmp));
tech = tmp;
data = strchr(tmp, '/');
if (!data) {
astman_send_error(s, m, "Invalid channel");
res = 0;
goto fast_orig_cleanup;
}
*data++ = '\0';
ast_copy_string(tmp2, callerid, sizeof(tmp2));
ast_callerid_parse(tmp2, &n, &l);
if (n) {
if (ast_strlen_zero(n)) {
n = NULL;
}
}
if (l) {
ast_shrink_phone_number(l);
if (ast_strlen_zero(l)) {
l = NULL;
}
}
if (!ast_strlen_zero(codecs)) {
ast_format_cap_remove_all(cap);
ast_parse_allow_disallow(NULL, cap, codecs, 1);
}
if (!ast_strlen_zero(app) && s->session) {
int bad_appdata = 0;
/* To run the System application (or anything else that goes to
* shell), you must have the additional System privilege */
if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
&& (
strcasestr(app, "system") || /* System(rm -rf /)
TrySystem(rm -rf /) */
strcasestr(app, "exec") || /* Exec(System(rm -rf /))
TryExec(System(rm -rf /)) */
strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /)
EAGI(/bin/rm,-rf /) */
strcasestr(app, "mixmonitor") || /* MixMonitor(blah,,rm -rf) */
strcasestr(app, "externalivr") || /* ExternalIVR(rm -rf) */
(strstr(appdata, "SHELL") && (bad_appdata = 1)) || /* NoOp(${SHELL(rm -rf /)}) */
(strstr(appdata, "EVAL") && (bad_appdata = 1)) /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
)) {
char error_buf[64];
snprintf(error_buf, sizeof(error_buf), "Originate Access Forbidden: %s", bad_appdata ? "Data" : "Application");
astman_send_error(s, m, error_buf);
res = 0;
goto fast_orig_cleanup;
}
}
/* Check early if the extension exists. If not, we need to bail out here. */
if (exten && context && pi) {
if (! ast_exists_extension(NULL, context, exten, pi, l)) {
/* The extension does not exist. */
astman_send_error(s, m, "Extension does not exist.");
res = 0;
goto fast_orig_cleanup;
}
}
/* Allocate requested channel variables */
vars = astman_get_variables(m);
if (s->session && s->session->chanvars) {
struct ast_variable *v, *old;
old = vars;
vars = NULL;
/* The variables in the AMI originate action are appended at the end of the list, to override any user variables that apply*/
vars = ast_variables_dup(s->session->chanvars);
if (old) {
for (v = vars; v->next; v = v->next );
if (v->next) {
v->next = old; /* Append originate variables at end of list */
}
}
}
/* For originate async - we can bridge in early media stage */
bridge_early = ast_true(early_media);
if (ast_true(async)) {
struct fast_originate_helper *fast;
fast = ast_calloc(1, sizeof(*fast));
if (!fast || ast_string_field_init(fast, 252)) {
ast_free(fast);
ast_variables_destroy(vars);
res = -1;
} else {
if (!ast_strlen_zero(id)) {
ast_string_field_build(fast, idtext, "ActionID: %s\r\n", id);
}
ast_string_field_set(fast, tech, tech);
ast_string_field_set(fast, data, data);
ast_string_field_set(fast, app, app);
ast_string_field_set(fast, appdata, appdata);
ast_string_field_set(fast, cid_num, l);
ast_string_field_set(fast, cid_name, n);
ast_string_field_set(fast, context, context);
ast_string_field_set(fast, exten, exten);
ast_string_field_set(fast, account, account);
fast->vars = vars;
fast->cap = cap;
cap = NULL; /* transfered originate helper the capabilities structure. It is now responsible for freeing it. */
fast->timeout = to;
fast->early_media = bridge_early;
fast->priority = pi;
if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) {
destroy_fast_originate_helper(fast);
res = -1;
} else {
res = 0;
}
}
} else if (!ast_strlen_zero(app)) {
res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
/* Any vars memory was passed to ast_pbx_outgoing_app(). */
} else {
if (exten && context && pi) {
res = ast_pbx_outgoing_exten(tech, cap, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL, bridge_early);
/* Any vars memory was passed to ast_pbx_outgoing_exten(). */
} else {
astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
ast_variables_destroy(vars);
res = 0;
goto fast_orig_cleanup;
}
}
if (!res) {
astman_send_ack(s, m, "Originate successfully queued");
} else {
astman_send_error(s, m, "Originate failed");
}
fast_orig_cleanup:
ast_format_cap_destroy(cap);
return 0;
}
| static int action_ping | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 2700 of file manager.c.
References ast_strlen_zero(), ast_tvnow(), astman_append(), and astman_get_header().
Referenced by __init_manager().
{
const char *actionid = astman_get_header(m, "ActionID");
struct timeval now = ast_tvnow();
astman_append(s, "Response: Success\r\n");
if (!ast_strlen_zero(actionid)){
astman_append(s, "ActionID: %s\r\n", actionid);
}
astman_append(
s,
"Ping: Pong\r\n"
"Timestamp: %ld.%06lu\r\n"
"\r\n",
(long) now.tv_sec, (unsigned long) now.tv_usec);
return 0;
}
| static int action_presencestate | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 4637 of file manager.c.
References AST_PRESENCE_INVALID, ast_presence_state2str(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_error_va(), and state.
Referenced by __init_manager().
{
const char *provider = astman_get_header(m, "Provider");
enum ast_presence_state state;
char *subtype;
char *message;
char subtype_header[256] = "";
char message_header[256] = "";
if (ast_strlen_zero(provider)) {
astman_send_error(s, m, "No provider specified");
return 0;
}
state = ast_presence_state(provider, &subtype, &message);
if (state == AST_PRESENCE_INVALID) {
astman_send_error_va(s, m, "Invalid provider %s or provider in invalid state", provider);
return 0;
}
if (!ast_strlen_zero(subtype)) {
snprintf(subtype_header, sizeof(subtype_header),
"Subtype: %s\r\n", subtype);
}
if (!ast_strlen_zero(message)) {
snprintf(message_header, sizeof(message_header),
"Message: %s\r\n", message);
}
astman_append(s, "Message: Presence State\r\n"
"State: %s\r\n"
"%s"
"%s"
"\r\n",
ast_presence_state2str(state),
subtype_header,
message_header);
return 0;
}
| static int action_redirect | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
action_redirect: The redirect manager command
Definition at line 3748 of file manager.c.
References ast_async_goto(), ast_channel_flags(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_pbx(), ast_channel_unlock, ast_channel_unref, ast_check_hangup_locked(), ast_clear_flag, ast_findlabel_extension(), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT, AST_FLAG_BRIDGE_HANGUP_DONT, ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, and ast_channel::priority.
Referenced by __init_manager().
{
char buf[256];
const char *name = astman_get_header(m, "Channel");
const char *name2 = astman_get_header(m, "ExtraChannel");
const char *exten = astman_get_header(m, "Exten");
const char *exten2 = astman_get_header(m, "ExtraExten");
const char *context = astman_get_header(m, "Context");
const char *context2 = astman_get_header(m, "ExtraContext");
const char *priority = astman_get_header(m, "Priority");
const char *priority2 = astman_get_header(m, "ExtraPriority");
struct ast_channel *chan;
struct ast_channel *chan2;
int pi = 0;
int pi2 = 0;
int res;
if (ast_strlen_zero(name)) {
astman_send_error(s, m, "Channel not specified");
return 0;
}
if (ast_strlen_zero(context)) {
astman_send_error(s, m, "Context not specified");
return 0;
}
if (ast_strlen_zero(exten)) {
astman_send_error(s, m, "Exten not specified");
return 0;
}
if (ast_strlen_zero(priority)) {
astman_send_error(s, m, "Priority not specified");
return 0;
}
if (sscanf(priority, "%30d", &pi) != 1) {
pi = ast_findlabel_extension(NULL, context, exten, priority, NULL);
}
if (pi < 1) {
astman_send_error(s, m, "Priority is invalid");
return 0;
}
if (!ast_strlen_zero(name2) && !ast_strlen_zero(context2)) {
/* We have an ExtraChannel and an ExtraContext */
if (ast_strlen_zero(exten2)) {
astman_send_error(s, m, "ExtraExten not specified");
return 0;
}
if (ast_strlen_zero(priority2)) {
astman_send_error(s, m, "ExtraPriority not specified");
return 0;
}
if (sscanf(priority2, "%30d", &pi2) != 1) {
pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL);
}
if (pi2 < 1) {
astman_send_error(s, m, "ExtraPriority is invalid");
return 0;
}
}
chan = ast_channel_get_by_name(name);
if (!chan) {
snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
astman_send_error(s, m, buf);
return 0;
}
if (ast_check_hangup_locked(chan)) {
astman_send_error(s, m, "Redirect failed, channel not up.");
chan = ast_channel_unref(chan);
return 0;
}
if (ast_strlen_zero(name2)) {
/* Single channel redirect in progress. */
if (ast_channel_pbx(chan)) {
ast_channel_lock(chan);
/* don't let the after-bridge code run the h-exten */
ast_set_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_HANGUP_DONT);
ast_channel_unlock(chan);
}
res = ast_async_goto(chan, context, exten, pi);
if (!res) {
astman_send_ack(s, m, "Redirect successful");
} else {
astman_send_error(s, m, "Redirect failed");
}
chan = ast_channel_unref(chan);
return 0;
}
chan2 = ast_channel_get_by_name(name2);
if (!chan2) {
snprintf(buf, sizeof(buf), "ExtraChannel does not exist: %s", name2);
astman_send_error(s, m, buf);
chan = ast_channel_unref(chan);
return 0;
}
if (ast_check_hangup_locked(chan2)) {
astman_send_error(s, m, "Redirect failed, extra channel not up.");
chan2 = ast_channel_unref(chan2);
chan = ast_channel_unref(chan);
return 0;
}
/* Dual channel redirect in progress. */
if (ast_channel_pbx(chan)) {
ast_channel_lock(chan);
/* don't let the after-bridge code run the h-exten */
ast_set_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_HANGUP_DONT
| AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
ast_channel_unlock(chan);
}
if (ast_channel_pbx(chan2)) {
ast_channel_lock(chan2);
/* don't let the after-bridge code run the h-exten */
ast_set_flag(ast_channel_flags(chan2), AST_FLAG_BRIDGE_HANGUP_DONT
| AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
ast_channel_unlock(chan2);
}
res = ast_async_goto(chan, context, exten, pi);
if (!res) {
if (!ast_strlen_zero(context2)) {
res = ast_async_goto(chan2, context2, exten2, pi2);
} else {
res = ast_async_goto(chan2, context, exten, pi);
}
if (!res) {
astman_send_ack(s, m, "Dual Redirect successful");
} else {
astman_send_error(s, m, "Secondary redirect failed");
}
} else {
astman_send_error(s, m, "Redirect failed");
}
/* Release the bridge wait. */
if (ast_channel_pbx(chan)) {
ast_channel_lock(chan);
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
ast_channel_unlock(chan);
}
if (ast_channel_pbx(chan2)) {
ast_channel_lock(chan2);
ast_clear_flag(ast_channel_flags(chan2), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
ast_channel_unlock(chan2);
}
chan2 = ast_channel_unref(chan2);
chan = ast_channel_unref(chan);
return 0;
}
| static int action_reload | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Send a reload event.
Definition at line 4983 of file manager.c.
References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.
Referenced by __init_manager().
{
const char *module = astman_get_header(m, "Module");
int res = ast_module_reload(S_OR(module, NULL));
switch (res) {
case -1:
astman_send_error(s, m, "A reload is in progress");
break;
case 0:
astman_send_error(s, m, "No such module");
break;
case 1:
astman_send_error(s, m, "Module does not support reload");
break;
case 2:
astman_send_ack(s, m, "Module Reloaded");
break;
default:
astman_send_error(s, m, "An unknown error occurred");
break;
}
return 0;
}
| static int action_sendtext | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3713 of file manager.c.
References ast_channel_get_by_name(), ast_channel_unref, ast_sendtext(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), and astman_send_error().
Referenced by __init_manager().
{
struct ast_channel *c = NULL;
const char *name = astman_get_header(m, "Channel");
const char *textmsg = astman_get_header(m, "Message");
int res = 0;
if (ast_strlen_zero(name)) {
astman_send_error(s, m, "No channel specified");
return 0;
}
if (ast_strlen_zero(textmsg)) {
astman_send_error(s, m, "No Message specified");
return 0;
}
if (!(c = ast_channel_get_by_name(name))) {
astman_send_error(s, m, "No such channel");
return 0;
}
res = ast_sendtext(c, textmsg);
c = ast_channel_unref(c);
if (res >= 0) {
astman_send_ack(s, m, "Success");
} else {
astman_send_error(s, m, "Failure");
}
return 0;
}
| static int action_setvar | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3464 of file manager.c.
References ast_channel_get_by_name(), ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), pbx_builtin_setvar_helper(), and S_OR.
Referenced by __init_manager().
{
struct ast_channel *c = NULL;
const char *name = astman_get_header(m, "Channel");
const char *varname = astman_get_header(m, "Variable");
const char *varval = astman_get_header(m, "Value");
int res = 0;
if (ast_strlen_zero(varname)) {
astman_send_error(s, m, "No variable specified");
return 0;
}
if (!ast_strlen_zero(name)) {
if (!(c = ast_channel_get_by_name(name))) {
astman_send_error(s, m, "No such channel");
return 0;
}
}
res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
if (c) {
c = ast_channel_unref(c);
}
if (res == 0) {
astman_send_ack(s, m, "Variable Set");
} else {
astman_send_error(s, m, "Variable not set");
}
return 0;
}
| static int action_status | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Manager "status" command to show channels.
Definition at line 3551 of file manager.c.
References AST_APP_ARG, ast_channel_accountcode(), ast_channel_caller(), ast_channel_cdr(), ast_channel_connected(), ast_channel_context(), ast_channel_exten(), ast_channel_get_by_name(), ast_channel_internal_bridged_channel(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_name(), ast_channel_pbx(), ast_channel_priority(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, AST_DECLARE_APP_ARGS, ast_free, ast_func_read(), AST_STANDARD_APP_ARGS, ast_state2str(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_strlen_zero(), ast_tvnow(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::bridge, channels, function_capable_string_allowed_with_auths(), ast_channel::name, pbx_retrieve_variable(), S_COR, S_OR, mansession::session, ast_cdr::start, str, and mansession_session::writeperm.
Referenced by __init_manager().
{
const char *name = astman_get_header(m, "Channel");
const char *cvariables = astman_get_header(m, "Variables");
char *variables = ast_strdupa(S_OR(cvariables, ""));
struct ast_channel *c;
char bridge[256];
struct timeval now = ast_tvnow();
long elapsed_seconds = 0;
int channels = 0;
int all = ast_strlen_zero(name); /* set if we want all channels */
const char *id = astman_get_header(m, "ActionID");
char idText[256];
AST_DECLARE_APP_ARGS(vars,
AST_APP_ARG(name)[100];
);
struct ast_str *str = ast_str_create(1000);
struct ast_channel_iterator *iter = NULL;
if (!ast_strlen_zero(id)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
} else {
idText[0] = '\0';
}
if (!(function_capable_string_allowed_with_auths(variables, s->session->writeperm))) {
astman_send_error(s, m, "Status Access Forbidden: Variables");
return 0;
}
if (all) {
if (!(iter = ast_channel_iterator_all_new())) {
ast_free(str);
astman_send_error(s, m, "Memory Allocation Failure");
return 1;
}
c = ast_channel_iterator_next(iter);
} else {
if (!(c = ast_channel_get_by_name(name))) {
astman_send_error(s, m, "No such channel");
ast_free(str);
return 0;
}
}
astman_send_ack(s, m, "Channel status will follow");
if (!ast_strlen_zero(cvariables)) {
AST_STANDARD_APP_ARGS(vars, variables);
}
/* if we look by name, we break after the first iteration */
for (; c; c = ast_channel_iterator_next(iter)) {
ast_channel_lock(c);
if (!ast_strlen_zero(cvariables)) {
int i;
ast_str_reset(str);
for (i = 0; i < vars.argc; i++) {
char valbuf[512], *ret = NULL;
if (vars.name[i][strlen(vars.name[i]) - 1] == ')') {
if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) {
valbuf[0] = '\0';
}
ret = valbuf;
} else {
pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL);
}
ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret);
}
}
channels++;
if (ast_channel_internal_bridged_channel(c)) {
snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", ast_channel_name(ast_channel_internal_bridged_channel(c)), ast_channel_uniqueid(ast_channel_internal_bridged_channel(c)));
} else {
bridge[0] = '\0';
}
if (ast_channel_pbx(c)) {
if (ast_channel_cdr(c)) {
elapsed_seconds = now.tv_sec - ast_channel_cdr(c)->start.tv_sec;
}
astman_append(s,
"Event: Status\r\n"
"Privilege: Call\r\n"
"Channel: %s\r\n"
"CallerIDNum: %s\r\n"
"CallerIDName: %s\r\n"
"ConnectedLineNum: %s\r\n"
"ConnectedLineName: %s\r\n"
"Accountcode: %s\r\n"
"ChannelState: %d\r\n"
"ChannelStateDesc: %s\r\n"
"Context: %s\r\n"
"Extension: %s\r\n"
"Priority: %d\r\n"
"Seconds: %ld\r\n"
"%s"
"Uniqueid: %s\r\n"
"%s"
"%s"
"\r\n",
ast_channel_name(c),
S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, "<unknown>"),
S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, "<unknown>"),
S_COR(ast_channel_connected(c)->id.number.valid, ast_channel_connected(c)->id.number.str, "<unknown>"),
S_COR(ast_channel_connected(c)->id.name.valid, ast_channel_connected(c)->id.name.str, "<unknown>"),
ast_channel_accountcode(c),
ast_channel_state(c),
ast_state2str(ast_channel_state(c)), ast_channel_context(c),
ast_channel_exten(c), ast_channel_priority(c), (long)elapsed_seconds, bridge, ast_channel_uniqueid(c), ast_str_buffer(str), idText);
} else {
astman_append(s,
"Event: Status\r\n"
"Privilege: Call\r\n"
"Channel: %s\r\n"
"CallerIDNum: %s\r\n"
"CallerIDName: %s\r\n"
"ConnectedLineNum: %s\r\n"
"ConnectedLineName: %s\r\n"
"Account: %s\r\n"
"State: %s\r\n"
"%s"
"Uniqueid: %s\r\n"
"%s"
"%s"
"\r\n",
ast_channel_name(c),
S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, "<unknown>"),
S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, "<unknown>"),
S_COR(ast_channel_connected(c)->id.number.valid, ast_channel_connected(c)->id.number.str, "<unknown>"),
S_COR(ast_channel_connected(c)->id.name.valid, ast_channel_connected(c)->id.name.str, "<unknown>"),
ast_channel_accountcode(c),
ast_state2str(ast_channel_state(c)), bridge, ast_channel_uniqueid(c),
ast_str_buffer(str), idText);
}
ast_channel_unlock(c);
c = ast_channel_unref(c);
if (!all) {
break;
}
}
if (iter) {
ast_channel_iterator_destroy(iter);
}
astman_append(s,
"Event: StatusComplete\r\n"
"%s"
"Items: %d\r\n"
"\r\n", idText, channels);
ast_free(str);
return 0;
}
| static int action_timeout | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 4678 of file manager.c.
References ast_channel_get_by_name(), ast_channel_lock, ast_channel_setwhentohangup_tv(), ast_channel_unlock, ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), and astman_send_error().
Referenced by __init_manager().
{
struct ast_channel *c;
const char *name = astman_get_header(m, "Channel");
double timeout = atof(astman_get_header(m, "Timeout"));
struct timeval when = { timeout, 0 };
if (ast_strlen_zero(name)) {
astman_send_error(s, m, "No channel specified");
return 0;
}
if (!timeout || timeout < 0) {
astman_send_error(s, m, "No timeout specified");
return 0;
}
if (!(c = ast_channel_get_by_name(name))) {
astman_send_error(s, m, "No such channel");
return 0;
}
when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
ast_channel_lock(c);
ast_channel_setwhentohangup_tv(c, when);
ast_channel_unlock(c);
c = ast_channel_unref(c);
astman_send_ack(s, m, "Timeout Set");
return 0;
}
| static int action_updateconfig | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3022 of file manager.c.
References ast_config_destroy(), ast_config_load2(), ast_config_text_file_save(), ast_include_rename(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, FAILURE_ALLOCATION, FAILURE_APPEND, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, handle_updates(), UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.
Referenced by __init_manager().
{
struct ast_config *cfg;
const char *sfn = astman_get_header(m, "SrcFilename");
const char *dfn = astman_get_header(m, "DstFilename");
int res;
const char *rld = astman_get_header(m, "Reload");
struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
enum error_type result;
if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
astman_send_error(s, m, "Filename not specified");
return 0;
}
if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
astman_send_error(s, m, "Config file not found");
return 0;
} else if (cfg == CONFIG_STATUS_FILEINVALID) {
astman_send_error(s, m, "Config file has invalid format");
return 0;
}
result = handle_updates(s, m, cfg, dfn);
if (!result) {
ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
res = ast_config_text_file_save(dfn, cfg, "Manager");
ast_config_destroy(cfg);
if (res) {
astman_send_error(s, m, "Save of config failed");
return 0;
}
astman_send_ack(s, m, NULL);
if (!ast_strlen_zero(rld)) {
if (ast_true(rld)) {
rld = NULL;
}
ast_module_reload(rld);
}
} else {
ast_config_destroy(cfg);
switch(result) {
case UNKNOWN_ACTION:
astman_send_error(s, m, "Unknown action command");
break;
case UNKNOWN_CATEGORY:
astman_send_error(s, m, "Given category does not exist");
break;
case UNSPECIFIED_CATEGORY:
astman_send_error(s, m, "Category not specified");
break;
case UNSPECIFIED_ARGUMENT:
astman_send_error(s, m, "Problem with category, value, or line (if required)");
break;
case FAILURE_ALLOCATION:
astman_send_error(s, m, "Memory allocation failure, this should not happen");
break;
case FAILURE_NEWCAT:
astman_send_error(s, m, "Create category did not complete successfully");
break;
case FAILURE_DELCAT:
astman_send_error(s, m, "Delete category did not complete successfully");
break;
case FAILURE_EMPTYCAT:
astman_send_error(s, m, "Empty category did not complete successfully");
break;
case FAILURE_UPDATE:
astman_send_error(s, m, "Update did not complete successfully");
break;
case FAILURE_DELETE:
astman_send_error(s, m, "Delete did not complete successfully");
break;
case FAILURE_APPEND:
astman_send_error(s, m, "Append did not complete successfully");
break;
}
}
return 0;
}
| static int action_userevent | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 4881 of file manager.c.
References ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), astman_send_ack(), EVENT_FLAG_USER, message::hdrcount, message::headers, manager_event, and userevent_buf.
Referenced by __init_manager().
{
const char *event = astman_get_header(m, "UserEvent");
struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
int x;
ast_str_reset(body);
for (x = 0; x < m->hdrcount; x++) {
if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
}
}
astman_send_ack(s, m, "Event Sent");
manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
return 0;
}
| static int action_waitevent | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 3118 of file manager.c.
References advance_event(), ao2_lock, ao2_unlock, ast_debug, AST_PTHREADT_NULL, AST_RWLIST_NEXT, ast_strlen_zero(), ast_wait_for_input(), astman_append(), astman_get_header(), astman_send_response(), eventqent::category, mansession_session::fd, mansession_session::last_ev, mansession_session::managerid, mansession_session::needdestroy, mansession_session::readperm, mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, and mansession_session::waiting_thread.
Referenced by __init_manager().
{
const char *timeouts = astman_get_header(m, "Timeout");
int timeout = -1;
int x;
int needexit = 0;
const char *id = astman_get_header(m, "ActionID");
char idText[256];
if (!ast_strlen_zero(id)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
} else {
idText[0] = '\0';
}
if (!ast_strlen_zero(timeouts)) {
sscanf(timeouts, "%30i", &timeout);
if (timeout < -1) {
timeout = -1;
}
/* XXX maybe put an upper bound, or prevent the use of 0 ? */
}
ao2_lock(s->session);
if (s->session->waiting_thread != AST_PTHREADT_NULL) {
pthread_kill(s->session->waiting_thread, SIGURG);
}
if (s->session->managerid) { /* AMI-over-HTTP session */
/*
* Make sure the timeout is within the expire time of the session,
* as the client will likely abort the request if it does not see
* data coming after some amount of time.
*/
time_t now = time(NULL);
int max = s->session->sessiontimeout - now - 10;
if (max < 0) { /* We are already late. Strange but possible. */
max = 0;
}
if (timeout < 0 || timeout > max) {
timeout = max;
}
if (!s->session->send_events) { /* make sure we record events */
s->session->send_events = -1;
}
}
ao2_unlock(s->session);
/* XXX should this go inside the lock ? */
s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
ast_debug(1, "Starting waiting for an event!\n");
for (x = 0; x < timeout || timeout < 0; x++) {
ao2_lock(s->session);
if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
needexit = 1;
}
/* We can have multiple HTTP session point to the same mansession entry.
* The way we deal with it is not very nice: newcomers kick out the previous
* HTTP session. XXX this needs to be improved.
*/
if (s->session->waiting_thread != pthread_self()) {
needexit = 1;
}
if (s->session->needdestroy) {
needexit = 1;
}
ao2_unlock(s->session);
if (needexit) {
break;
}
if (s->session->managerid == 0) { /* AMI session */
if (ast_wait_for_input(s->session->fd, 1000)) {
break;
}
} else { /* HTTP session */
sleep(1);
}
}
ast_debug(1, "Finished waiting for an event!\n");
ao2_lock(s->session);
if (s->session->waiting_thread == pthread_self()) {
struct eventqent *eqe = s->session->last_ev;
astman_send_response(s, m, "Success", "Waiting for Event completed.");
while ((eqe = advance_event(eqe))) {
if (((s->session->readperm & eqe->category) == eqe->category) &&
((s->session->send_events & eqe->category) == eqe->category)) {
astman_append(s, "%s", eqe->eventdata);
}
s->session->last_ev = eqe;
}
astman_append(s,
"Event: WaitEventComplete\r\n"
"%s"
"\r\n", idText);
s->session->waiting_thread = AST_PTHREADT_NULL;
} else {
ast_debug(1, "Abandoning event request!\n");
}
ao2_unlock(s->session);
return 0;
}
| static struct eventqent* advance_event | ( | struct eventqent * | e | ) | [static, read] |
Definition at line 1972 of file manager.c.
References ast_atomic_fetchadd_int(), AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and eventqent::usecount.
Referenced by action_waitevent(), and process_events().
{
struct eventqent *next;
AST_RWLIST_RDLOCK(&all_events);
if ((next = AST_RWLIST_NEXT(e, eq_next))) {
ast_atomic_fetchadd_int(&next->usecount, 1);
ast_atomic_fetchadd_int(&e->usecount, -1);
}
AST_RWLIST_UNLOCK(&all_events);
return next;
}
| static AO2_GLOBAL_OBJ_STATIC | ( | mgr_sessions | ) | [static] |
Active manager connection sessions container.
| static AO2_GLOBAL_OBJ_STATIC | ( | event_docs | ) | [static] |
A container of event documentation nodes.
| static int aocmessage_get_unit_entry | ( | const struct message * | m, |
| struct ast_aoc_unit_entry * | entry, | ||
| unsigned int | entry_num | ||
| ) | [static] |
Definition at line 4150 of file manager.c.
References ast_aoc_unit_entry::amount, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), astman_get_header(), str, ast_aoc_unit_entry::type, ast_aoc_unit_entry::valid_amount, and ast_aoc_unit_entry::valid_type.
Referenced by action_aocmessage().
{
const char *unitamount;
const char *unittype;
struct ast_str *str = ast_str_alloca(32);
memset(entry, 0, sizeof(*entry));
ast_str_set(&str, 0, "UnitAmount(%u)", entry_num);
unitamount = astman_get_header(m, ast_str_buffer(str));
ast_str_set(&str, 0, "UnitType(%u)", entry_num);
unittype = astman_get_header(m, ast_str_buffer(str));
if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) {
entry->valid_amount = 1;
}
if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) {
entry->valid_type = 1;
}
return 0;
}
| static void append_channel_vars | ( | struct ast_str ** | pbuf, |
| struct ast_channel * | chan | ||
| ) | [static] |
Definition at line 5672 of file manager.c.
References ast_channel_name(), ast_func_read2(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_str_append(), ast_str_buffer(), ast_str_thread_get(), manager_channel_variable::isfunc, manager_event_funcbuf, manager_channel_variable::name, pbx_builtin_getvar_helper(), and var.
Referenced by __ast_manager_event_multichan().
{
struct manager_channel_variable *var;
AST_RWLIST_RDLOCK(&channelvars);
AST_LIST_TRAVERSE(&channelvars, var, entry) {
const char *val;
struct ast_str *res;
if (var->isfunc) {
res = ast_str_thread_get(&manager_event_funcbuf, 16);
if (res && ast_func_read2(chan, var->name, &res, 0) == 0) {
val = ast_str_buffer(res);
} else {
val = NULL;
}
} else {
val = pbx_builtin_getvar_helper(chan, var->name);
}
ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", ast_channel_name(chan), var->name, val ? val : "");
}
AST_RWLIST_UNLOCK(&channelvars);
}
| static int append_event | ( | const char * | str, |
| int | category | ||
| ) | [static] |
events are appended to a queue from where they can be dispatched to clients.
Definition at line 5646 of file manager.c.
References ast_atomic_fetchadd_int(), ast_malloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_NEXT, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tvnow(), eventqent::category, eventqent::seq, eventqent::tv, and eventqent::usecount.
Referenced by __ast_manager_event_multichan(), and __init_manager().
{
struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
static int seq; /* sequence number */
if (!tmp) {
return -1;
}
/* need to init all fields, because ast_malloc() does not */
tmp->usecount = 0;
tmp->category = category;
tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
tmp->tv = ast_tvnow();
AST_RWLIST_NEXT(tmp, eq_next) = NULL;
strcpy(tmp->eventdata, str);
AST_RWLIST_WRLOCK(&all_events);
AST_RWLIST_INSERT_TAIL(&all_events, tmp, eq_next);
AST_RWLIST_UNLOCK(&all_events);
return 0;
}
| int ast_hook_send_action | ( | struct manager_custom_hook * | hook, |
| const char * | msg | ||
| ) |
access for hooks to send action messages to ami
Registered hooks can call this function to invoke actions and they will receive responses through registered callback.
Definition at line 2118 of file manager.c.
References action_find(), ao2_lock, ao2_t_ref, ao2_unlock, ARRAY_LEN, ast_free, ast_module_ref(), ast_module_unref(), ast_strdup, astman_get_header(), mansession::f, manager_action::func, message::hdrcount, message::headers, mansession::hook, manager_action::module, manager_action::registered, and mansession::session.
{
const char *action;
int ret = 0;
struct manager_action *act_found;
struct mansession s = {.session = NULL, };
struct message m = { 0 };
char *dup_str;
char *src;
int x = 0;
int curlen;
if (hook == NULL) {
return -1;
}
/* Create our own copy of the AMI action msg string. */
src = dup_str = ast_strdup(msg);
if (!dup_str) {
return -1;
}
/* convert msg string to message struct */
curlen = strlen(src);
for (x = 0; x < curlen; x++) {
int cr; /* set if we have \r */
if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n')
cr = 2; /* Found. Update length to include \r\n */
else if (src[x] == '\n')
cr = 1; /* also accept \n only */
else
continue;
/* don't keep empty lines */
if (x && m.hdrcount < ARRAY_LEN(m.headers)) {
/* ... but trim \r\n and terminate the header string */
src[x] = '\0';
m.headers[m.hdrcount++] = src;
}
x += cr;
curlen -= x; /* remaining size */
src += x; /* update pointer */
x = -1; /* reset loop */
}
action = astman_get_header(&m, "Action");
if (strcasecmp(action, "login")) {
act_found = action_find(action);
if (act_found) {
/*
* we have to simulate a session for this action request
* to be able to pass it down for processing
* This is necessary to meet the previous design of manager.c
*/
s.hook = hook;
s.f = (void*)1; /* set this to something so our request will make it through all functions that test it*/
ao2_lock(act_found);
if (act_found->registered && act_found->func) {
if (act_found->module) {
ast_module_ref(act_found->module);
}
ao2_unlock(act_found);
ret = act_found->func(&s, &m);
ao2_lock(act_found);
if (act_found->module) {
ast_module_unref(act_found->module);
}
} else {
ret = -1;
}
ao2_unlock(act_found);
ao2_t_ref(act_found, -1, "done with found action object");
}
}
ast_free(dup_str);
return ret;
}
| static int ast_instring | ( | const char * | bigstr, |
| const char * | smallstr, | ||
| const char | delim | ||
| ) | [static] |
Tells you if smallstr exists inside bigstr which is delim by delim and uses no buf or stringsep ast_instring("this|that|more","this",'|') == 1;
feel free to move this to app.c -anthm
Definition at line 1395 of file manager.c.
Referenced by get_perm().
{
const char *val = bigstr, *next;
do {
if ((next = strchr(val, delim))) {
if (!strncmp(val, smallstr, (next - val))) {
return 1;
} else {
continue;
}
} else {
return !strcmp(smallstr, val);
}
} while (*(val = (next + 1)));
return 0;
}
| int ast_manager_register2 | ( | const char * | action, |
| int | auth, | ||
| int(*)(struct mansession *s, const struct message *m) | func, | ||
| struct ast_module * | module, | ||
| const char * | synopsis, | ||
| const char * | description | ||
| ) |
register a new command with manager, including online help. This is the preferred way to register a manager command
Register a manager command with the manager interface.
Definition at line 5922 of file manager.c.
References manager_action::action, action_destroy(), ao2_alloc, ao2_t_ref, ast_free, ast_manager_register_struct(), AST_STATIC_DOC, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), AST_XML_DOC, ast_xmldoc_build_arguments(), ast_xmldoc_build_description(), ast_xmldoc_build_seealso(), ast_xmldoc_build_synopsis(), ast_xmldoc_build_syntax(), manager_action::authority, manager_action::docsrc, manager_action::func, and manager_action::module.
{
struct manager_action *cur;
cur = ao2_alloc(sizeof(*cur), action_destroy);
if (!cur) {
return -1;
}
if (ast_string_field_init(cur, 128)) {
ao2_t_ref(cur, -1, "action object creation failed");
return -1;
}
cur->action = action;
cur->authority = auth;
cur->func = func;
cur->module = module;
#ifdef AST_XML_DOCS
if (ast_strlen_zero(synopsis) && ast_strlen_zero(description)) {
char *tmpxml;
tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
ast_string_field_set(cur, synopsis, tmpxml);
ast_free(tmpxml);
tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
ast_string_field_set(cur, syntax, tmpxml);
ast_free(tmpxml);
tmpxml = ast_xmldoc_build_description("manager", action, NULL);
ast_string_field_set(cur, description, tmpxml);
ast_free(tmpxml);
tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
ast_string_field_set(cur, seealso, tmpxml);
ast_free(tmpxml);
tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
ast_string_field_set(cur, arguments, tmpxml);
ast_free(tmpxml);
cur->docsrc = AST_XML_DOC;
} else
#endif
{
ast_string_field_set(cur, synopsis, synopsis);
ast_string_field_set(cur, description, description);
#ifdef AST_XML_DOCS
cur->docsrc = AST_STATIC_DOC;
#endif
}
if (ast_manager_register_struct(cur)) {
ao2_t_ref(cur, -1, "action object registration failed");
return -1;
}
ao2_t_ref(cur, -1, "action object registration successful");
return 0;
}
| void ast_manager_register_hook | ( | struct manager_custom_hook * | hook | ) |
Add a custom hook to be called when an event is fired.
Add a custom hook to be called when an event is fired
| hook | struct manager_custom_hook object to add |
Definition at line 1227 of file manager.c.
References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
{
AST_RWLIST_WRLOCK(&manager_hooks);
AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list);
AST_RWLIST_UNLOCK(&manager_hooks);
}
| static int ast_manager_register_struct | ( | struct manager_action * | act | ) | [static] |
Definition at line 5867 of file manager.c.
References manager_action::action, ao2_t_ref, ast_log(), AST_RWLIST_INSERT_AFTER, AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, LOG_WARNING, and manager_action::registered.
Referenced by ast_manager_register2().
{
struct manager_action *cur, *prev = NULL;
AST_RWLIST_WRLOCK(&actions);
AST_RWLIST_TRAVERSE(&actions, cur, list) {
int ret;
ret = strcasecmp(cur->action, act->action);
if (ret == 0) {
ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
AST_RWLIST_UNLOCK(&actions);
return -1;
}
if (ret > 0) { /* Insert these alphabetically */
prev = cur;
break;
}
}
ao2_t_ref(act, +1, "action object added to list");
act->registered = 1;
if (prev) {
AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
} else {
AST_RWLIST_INSERT_HEAD(&actions, act, list);
}
ast_verb(2, "Manager registered action %s\n", act->action);
AST_RWLIST_UNLOCK(&actions);
return 0;
}
| int ast_manager_unregister | ( | const char * | action | ) |
support functions to register/unregister AMI action handlers,
Unregister a registered manager command.
Definition at line 5789 of file manager.c.
References manager_action::action, ao2_lock, ao2_t_ref, ao2_unlock, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and manager_action::registered.
Referenced by __unload_module(), astdb_atexit(), data_shutdown(), features_shutdown(), manager_shutdown(), message_shutdown(), unload_module(), and unload_pbx().
{
struct manager_action *cur;
AST_RWLIST_WRLOCK(&actions);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) {
if (!strcasecmp(action, cur->action)) {
AST_RWLIST_REMOVE_CURRENT(list);
break;
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&actions);
if (cur) {
/*
* We have removed the action object from the container so we
* are no longer in a hurry.
*/
ao2_lock(cur);
cur->registered = 0;
ao2_unlock(cur);
ao2_t_ref(cur, -1, "action object removed from list");
ast_verb(2, "Manager unregistered action %s\n", action);
}
return 0;
}
| void ast_manager_unregister_hook | ( | struct manager_custom_hook * | hook | ) |
Delete a custom hook to be called when an event is fired.
Delete a custom hook to be called when an event is fired
| hook | struct manager_custom_hook object to delete |
Definition at line 1235 of file manager.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
{
AST_RWLIST_WRLOCK(&manager_hooks);
AST_RWLIST_REMOVE(&manager_hooks, hook, list);
AST_RWLIST_UNLOCK(&manager_hooks);
}
| void astman_append | ( | struct mansession * | s, |
| const char * | fmt, | ||
| ... | |||
| ) |
utility functions for creating AMI replies
Definition at line 2241 of file manager.c.
References ast_str_buffer(), ast_str_set_va(), ast_str_thread_get(), ast_verbose(), astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, mansession_session::f, mansession::f, send_string(), and mansession::session.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers_one(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), _skinny_show_lines(), action_agents(), action_challenge(), action_command(), action_confbridgelist(), action_confbridgelist_item(), action_confbridgelistrooms(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_listcommands(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_meetmelistrooms(), action_ping(), action_presencestate(), action_prishowspans(), action_status(), action_waitevent(), ast_cli_netstats(), astman_append_json(), astman_send_response_full(), data_result_manager_output(), do_print(), manager_data_get(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_jabber_send(), manager_list_voicemail_users(), manager_mixmonitor(), manager_modulecheck(), manager_mute_mixmonitor(), manager_mutestream(), manager_parking_status(), manager_parkinglot_list(), manager_queue_rule_show(), manager_queues_show(), manager_queues_status(), manager_queues_summary(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_show_registry(), manager_sip_peer_status(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_skinny_show_device(), manager_skinny_show_devices(), manager_skinny_show_line(), manager_skinny_show_lines(), manager_stop_mixmonitor(), send_manager_peer_status(), session_do(), and sig_pri_ami_show_spans().
{
va_list ap;
struct ast_str *buf;
if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
return;
}
va_start(ap, fmt);
ast_str_set_va(&buf, 0, fmt, ap);
va_end(ap);
if (s->f != NULL || s->session->f != NULL) {
send_string(s, ast_str_buffer(buf));
} else {
ast_verbose("fd == -1 in astman_append, should not happen\n");
}
}
| static void astman_append_json | ( | struct mansession * | s, |
| const char * | str | ||
| ) | [static] |
Definition at line 2819 of file manager.c.
References ast_alloca, astman_append(), and json_escape().
Referenced by action_getconfigjson().
{
char *buf;
buf = ast_alloca(2 * strlen(str) + 1);
json_escape(buf, str);
astman_append(s, "%s", buf);
}
| const char* astman_get_header | ( | const struct message * | m, |
| char * | var | ||
| ) |
Return the first matching variable from an array.
Get header from mananger transaction.
Definition at line 2039 of file manager.c.
References __astman_get_header(), and GET_HEADER_FIRST_MATCH.
Referenced by _sip_show_peer(), _sip_show_peers(), _skinny_show_devices(), _skinny_show_lines(), action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_aocmessage(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_confbridgekick(), action_confbridgelist(), action_confbridgelistrooms(), action_confbridgesetsinglevideosrc(), action_confbridgestartrecord(), action_confbridgestoprecord(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_filter(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_lock_unlock_helper(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_meetmelistrooms(), action_messagesend(), action_mute_unmute_helper(), action_originate(), action_ping(), action_presencestate(), action_prishowspans(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), aocmessage_get_unit_entry(), ast_hook_send_action(), astman_send_response_full(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), manager_data_get(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_jabber_send(), manager_list_voicemail_users(), manager_mixmonitor(), manager_modulecheck(), manager_moduleload(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_parking_status(), manager_parkinglot_list(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_member_ringinuse(), manager_queue_reload(), manager_queue_reset(), manager_queue_rule_show(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_show_dialplan(), manager_show_registry(), manager_sip_peer_status(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), manager_skinny_show_device(), manager_skinny_show_devices(), manager_skinny_show_line(), manager_skinny_show_lines(), manager_stop_mixmonitor(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
{
return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH);
}
| struct ast_variable* astman_get_variables | ( | const struct message * | m | ) | [read] |
Get a linked list of the Variable: headers.
Definition at line 2097 of file manager.c.
References message::hdrcount, message::headers, and man_do_variable_value().
Referenced by action_messagesend(), action_originate(), and manager_sipnotify().
{
int varlen;
int x;
struct ast_variable *head = NULL;
static const char var_hdr[] = "Variable:";
/* Process all "Variable:" headers. */
varlen = strlen(var_hdr);
for (x = 0; x < m->hdrcount; x++) {
if (strncasecmp(var_hdr, m->headers[x], varlen)) {
continue;
}
head = man_do_variable_value(head, m->headers[x] + varlen);
}
return head;
}
| void astman_send_ack | ( | struct mansession * | s, |
| const struct message * | m, | ||
| char * | msg | ||
| ) |
Send ack in manager transaction.
Definition at line 2333 of file manager.c.
References astman_send_response_full().
Referenced by action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_aocmessage(), action_atxfer(), action_bridge(), action_confbridgekick(), action_confbridgesetsinglevideosrc(), action_confbridgestartrecord(), action_confbridgestoprecord(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_dahdishowchannels(), action_filter(), action_hangup(), action_lock_unlock_helper(), action_login(), action_messagesend(), action_mute_unmute_helper(), action_originate(), action_prishowspans(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_list_voicemail_users(), manager_moduleload(), manager_optimize_away(), manager_park(), manager_parking_status(), manager_parkinglot_list(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_member_ringinuse(), manager_queue_reload(), manager_queue_reset(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_sip_peer_status(), manager_sipnotify(), meetmemute(), start_monitor_action(), and stop_monitor_action().
{
astman_send_response_full(s, m, "Success", msg, NULL);
}
| void astman_send_error | ( | struct mansession * | s, |
| const struct message * | m, | ||
| char * | error | ||
| ) |
Send error in manager transaction.
Definition at line 2305 of file manager.c.
References astman_send_response_full().
Referenced by _sip_qualify_peer(), _sip_show_peer(), action_add_agi_cmd(), action_agent_logoff(), action_aocmessage(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_confbridgekick(), action_confbridgelist(), action_confbridgelistrooms(), action_confbridgesetsinglevideosrc(), action_confbridgestartrecord(), action_confbridgestoprecord(), action_coreshowchannels(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_events(), action_extensionstate(), action_filter(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_lock_unlock_helper(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_meetmelistrooms(), action_messagesend(), action_mute_unmute_helper(), action_originate(), action_presencestate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), change_monitor_action(), do_message(), do_pause_or_unpause(), handle_parse_error(), manager_add_queue_member(), manager_data_get(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_mixmonitor(), manager_modulecheck(), manager_moduleload(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_member_ringinuse(), manager_queue_reload(), manager_queue_reset(), manager_remove_queue_member(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_sip_peer_status(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sipnotify(), manager_skinny_show_device(), manager_skinny_show_line(), manager_stop_mixmonitor(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
{
astman_send_response_full(s, m, "Error", error, NULL);
}
| void astman_send_error_va | ( | struct mansession * | s, |
| const struct message * | m, | ||
| const char * | fmt, | ||
| ... | |||
| ) |
Send error in manager transaction (with va_args support)
Definition at line 2310 of file manager.c.
References ast_str_buffer(), ast_str_set_va(), ast_str_thread_get(), astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, and astman_send_response_full().
Referenced by action_hangup(), and action_presencestate().
{
va_list ap;
struct ast_str *buf;
char *msg;
if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
return;
}
va_start(ap, fmt);
ast_str_set_va(&buf, 0, fmt, ap);
va_end(ap);
/* astman_append will use the same underlying buffer, so copy the message out
* before sending the response */
msg = ast_str_buffer(buf);
if (msg) {
msg = ast_strdupa(msg);
}
astman_send_response_full(s, m, "Error", msg, NULL);
}
| void astman_send_listack | ( | struct mansession * | s, |
| const struct message * | m, | ||
| char * | msg, | ||
| char * | listflag | ||
| ) |
Send ack in manager list transaction.
Definition at line 2343 of file manager.c.
References astman_send_response_full().
Referenced by action_confbridgelist(), action_confbridgelistrooms(), action_coreshowchannels(), action_hangup(), action_meetmelist(), action_meetmelistrooms(), manager_dpsendack(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_show_registry(), manager_sip_show_peers(), manager_skinny_show_devices(), and manager_skinny_show_lines().
{
astman_send_response_full(s, m, "Success", msg, listflag);
}
| void astman_send_response | ( | struct mansession * | s, |
| const struct message * | m, | ||
| char * | resp, | ||
| char * | msg | ||
| ) |
Send response in manager transaction.
Definition at line 2300 of file manager.c.
References astman_send_response_full().
Referenced by action_logoff(), and action_waitevent().
{
astman_send_response_full(s, m, resp, msg, NULL);
}
| static void astman_send_response_full | ( | struct mansession * | s, |
| const struct message * | m, | ||
| char * | resp, | ||
| char * | msg, | ||
| char * | listflag | ||
| ) | [static] |
send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field.
Use the explicit constant MSG_MOREDATA to remove the empty line. XXX MSG_MOREDATA should go to a header file.
Definition at line 2280 of file manager.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), and MSG_MOREDATA.
Referenced by astman_send_ack(), astman_send_error(), astman_send_error_va(), astman_send_listack(), astman_send_response(), and astman_start_ack().
{
const char *id = astman_get_header(m, "ActionID");
astman_append(s, "Response: %s\r\n", resp);
if (!ast_strlen_zero(id)) {
astman_append(s, "ActionID: %s\r\n", id);
}
if (listflag) {
astman_append(s, "EventList: %s\r\n", listflag); /* Start, complete, cancelled */
}
if (msg == MSG_MOREDATA) {
return;
} else if (msg) {
astman_append(s, "Message: %s\r\n\r\n", msg);
} else {
astman_append(s, "\r\n");
}
}
| static void astman_start_ack | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 2338 of file manager.c.
References astman_send_response_full(), and MSG_MOREDATA.
Referenced by action_challenge(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), and action_mailboxstatus().
{
astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL);
}
| static int authenticate | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 2603 of file manager.c.
References ast_manager_user::acl, mansession_session::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_t_link, ao2_t_ref, ast_apply_acl(), ast_copy_string(), ast_debug, ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, AST_SENSE_DENY, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_tvnow(), ast_variables_dup(), astman_get_header(), mansession_session::blackfilters, ast_manager_user::blackfilters, mansession_session::challenge, mansession_session::chanvars, ast_manager_user::chanvars, get_manager_by_name_locked(), len(), LOG_NOTICE, MD5Final(), MD5Init(), MD5Update(), mansession_session::readperm, ast_manager_user::readperm, report_auth_success(), report_failed_acl(), report_failed_challenge_response(), report_inval_password(), report_invalid_user(), S_OR, ast_manager_user::secret, mansession::session, mansession_session::sessionstart, mansession_session::sessionstart_tv, set_eventmask(), mansession_session::username, mansession_session::whitefilters, ast_manager_user::whitefilters, mansession_session::writeperm, ast_manager_user::writeperm, mansession_session::writetimeout, and ast_manager_user::writetimeout.
Referenced by action_login().
{
const char *username = astman_get_header(m, "Username");
const char *password = astman_get_header(m, "Secret");
int error = -1;
struct ast_manager_user *user = NULL;
regex_t *regex_filter;
struct ao2_iterator filter_iter;
if (ast_strlen_zero(username)) { /* missing username */
return -1;
}
/* locate user in locked state */
AST_RWLIST_WRLOCK(&users);
if (!(user = get_manager_by_name_locked(username))) {
report_invalid_user(s, username);
ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
} else if (user->acl && (ast_apply_acl(user->acl, &s->session->addr, "Manager User ACL: ") == AST_SENSE_DENY)) {
report_failed_acl(s, username);
ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
} else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
const char *key = astman_get_header(m, "Key");
if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
int x;
int len = 0;
char md5key[256] = "";
struct MD5Context md5;
unsigned char digest[16];
MD5Init(&md5);
MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
MD5Final(digest, &md5);
for (x = 0; x < 16; x++)
len += sprintf(md5key + len, "%2.2x", digest[x]);
if (!strcmp(md5key, key)) {
error = 0;
} else {
report_failed_challenge_response(s, key, md5key);
}
} else {
ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n",
S_OR(s->session->challenge, ""));
}
} else if (user->secret) {
if (!strcmp(password, user->secret)) {
error = 0;
} else {
report_inval_password(s, username);
}
}
if (error) {
ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
AST_RWLIST_UNLOCK(&users);
return -1;
}
/* auth complete */
/* All of the user parameters are copied to the session so that in the event
* of a reload and a configuration change, the session parameters are not
* changed. */
ast_copy_string(s->session->username, username, sizeof(s->session->username));
s->session->readperm = user->readperm;
s->session->writeperm = user->writeperm;
s->session->writetimeout = user->writetimeout;
if (user->chanvars) {
s->session->chanvars = ast_variables_dup(user->chanvars);
}
filter_iter = ao2_iterator_init(user->whitefilters, 0);
while ((regex_filter = ao2_iterator_next(&filter_iter))) {
ao2_t_link(s->session->whitefilters, regex_filter, "add white user filter to session");
ao2_t_ref(regex_filter, -1, "remove iterator ref");
}
ao2_iterator_destroy(&filter_iter);
filter_iter = ao2_iterator_init(user->blackfilters, 0);
while ((regex_filter = ao2_iterator_next(&filter_iter))) {
ao2_t_link(s->session->blackfilters, regex_filter, "add black user filter to session");
ao2_t_ref(regex_filter, -1, "remove iterator ref");
}
ao2_iterator_destroy(&filter_iter);
s->session->sessionstart = time(NULL);
s->session->sessionstart_tv = ast_tvnow();
set_eventmask(s, astman_get_header(m, "Events"));
report_auth_success(s);
AST_RWLIST_UNLOCK(&users);
return 0;
}
| static const char* authority_to_str | ( | int | authority, |
| struct ast_str ** | res | ||
| ) | [static] |
Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be returned.
Definition at line 1371 of file manager.c.
References ARRAY_LEN, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), and perms.
Referenced by __ast_manager_event_multichan(), action_listcommands(), action_login(), handle_showmancmd(), and handle_showmancmds().
{
int i;
char *sep = "";
ast_str_reset(*res);
for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
if (authority & perms[i].num) {
ast_str_append(res, 0, "%s%s", sep, perms[i].label);
sep = ",";
}
}
if (ast_str_strlen(*res) == 0) /* replace empty string with something sensible */
ast_str_append(res, 0, "<none>");
return ast_str_buffer(*res);
}
| static int blackfilter_cmp_fn | ( | void * | obj, |
| void * | arg, | ||
| void * | data, | ||
| int | flags | ||
| ) | [static] |
Definition at line 4726 of file manager.c.
References CMP_MATCH, CMP_STOP, and ast_frame::data.
Referenced by match_filter().
| static struct mansession_session* build_mansession | ( | const struct ast_sockaddr * | addr | ) | [static, read] |
Allocate manager session structure and add it to the list of sessions.
Definition at line 1522 of file manager.c.
References mansession_session::addr, ao2_alloc, ao2_container_alloc, ao2_global_obj_ref, ao2_link, ao2_ref, AST_PTHREADT_NULL, ast_sockaddr_copy(), mansession_session::blackfilters, mansession_session::fd, mansession_session::send_events, session_destructor(), sessions, mansession_session::waiting_thread, mansession_session::whitefilters, and mansession_session::writetimeout.
Referenced by auth_http_callback(), generic_http_callback(), and session_do().
{
struct ao2_container *sessions;
struct mansession_session *newsession;
newsession = ao2_alloc(sizeof(*newsession), session_destructor);
if (!newsession) {
return NULL;
}
newsession->whitefilters = ao2_container_alloc(1, NULL, NULL);
newsession->blackfilters = ao2_container_alloc(1, NULL, NULL);
if (!newsession->whitefilters || !newsession->blackfilters) {
ao2_ref(newsession, -1);
return NULL;
}
newsession->fd = -1;
newsession->waiting_thread = AST_PTHREADT_NULL;
newsession->writetimeout = 100;
newsession->send_events = -1;
ast_sockaddr_copy(&newsession->addr, addr);
sessions = ao2_global_obj_ref(mgr_sessions);
if (sessions) {
ao2_link(sessions, newsession);
ao2_ref(sessions, -1);
}
return newsession;
}
| static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 3950 of file manager.c.
References ARRAY_LEN, ast_strip(), ast_strlen_zero(), command_blacklist, match(), MAX_BLACKLIST_CMD_LEN, and words.
Referenced by action_command().
{
char *cmd_copy, *cur_cmd;
char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, };
int i;
cmd_copy = ast_strdupa(cmd);
for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
cur_cmd = ast_strip(cur_cmd);
if (ast_strlen_zero(cur_cmd)) {
i--;
continue;
}
cmd_words[i] = cur_cmd;
}
for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
int j, match = 1;
for (j = 0; command_blacklist[i].words[j]; j++) {
if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
match = 0;
break;
}
}
if (match) {
return 1;
}
}
return 0;
}
| int check_manager_enabled | ( | void | ) |
Check if AMI is enabled.
Definition at line 1242 of file manager.c.
References manager_enabled.
Referenced by handle_show_settings().
{
return manager_enabled;
}
| static int check_manager_session_inuse | ( | const char * | name | ) | [static] |
Definition at line 1574 of file manager.c.
References ao2_find, ao2_global_obj_ref, ao2_ref, mansession_session::inuse, sessions, and unref_mansession().
Referenced by process_message().
{
struct ao2_container *sessions;
struct mansession_session *session;
int inuse = 0;
sessions = ao2_global_obj_ref(mgr_sessions);
if (sessions) {
session = ao2_find(sessions, (char *) name, 0);
ao2_ref(sessions, -1);
if (session) {
unref_mansession(session);
inuse = 1;
}
}
return inuse;
}
| int check_webmanager_enabled | ( | void | ) |
Check if AMI/HTTP is enabled.
Definition at line 1247 of file manager.c.
Referenced by action_coresettings(), and handle_show_settings().
{
return (webmanager_enabled && manager_enabled);
}
| static void destroy_fast_originate_helper | ( | struct fast_originate_helper * | doomed | ) | [static] |
Definition at line 4088 of file manager.c.
References ast_format_cap_destroy(), ast_free, ast_string_field_free_memory, ast_variables_destroy(), fast_originate_helper::cap, and fast_originate_helper::vars.
Referenced by action_originate(), and fast_originate().
{
ast_format_cap_destroy(doomed->cap);
ast_variables_destroy(doomed->vars);
ast_string_field_free_memory(doomed);
ast_free(doomed);
}
| static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 5422 of file manager.c.
References mansession_session::addr, ARRAY_LEN, ast_free, ast_log(), ast_sockaddr_stringify_addr(), ast_strdup, ast_strlen_zero(), ast_verb, astman_send_error(), mansession_session::authenticated, mansession_session::authstart, errno, get_input(), handle_parse_error(), message::hdrcount, message::headers, mansession_session::inbuf, LOG_ERROR, mansession_lock(), mansession_unlock(), MESSAGE_LINE_TOO_LONG, MESSAGE_OKAY, mansession::parsing, process_events(), process_message(), and mansession::session.
Referenced by session_do().
{
struct message m = { 0 };
char header_buf[sizeof(s->session->inbuf)] = { '\0' };
int res;
int idx;
int hdr_loss;
time_t now;
hdr_loss = 0;
for (;;) {
/* Check if any events are pending and do them if needed */
if (process_events(s)) {
res = -1;
break;
}
res = get_input(s, header_buf);
if (res == 0) {
/* No input line received. */
if (!s->session->authenticated) {
if (time(&now) == -1) {
ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
res = -1;
break;
}
if (now - s->session->authstart > authtimeout) {
if (displayconnects) {
ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_sockaddr_stringify_addr(&s->session->addr), authtimeout);
}
res = -1;
break;
}
}
continue;
} else if (res > 0) {
/* Input line received. */
if (ast_strlen_zero(header_buf)) {
if (hdr_loss) {
mansession_lock(s);
astman_send_error(s, &m, "Too many lines in message or allocation failure");
mansession_unlock(s);
res = 0;
} else {
switch (s->parsing) {
case MESSAGE_OKAY:
res = process_message(s, &m) ? -1 : 0;
break;
case MESSAGE_LINE_TOO_LONG:
handle_parse_error(s, &m, "Failed to parse message: line too long");
res = 0;
break;
}
}
break;
} else if (m.hdrcount < ARRAY_LEN(m.headers)) {
m.headers[m.hdrcount] = ast_strdup(header_buf);
if (!m.headers[m.hdrcount]) {
/* Allocation failure. */
hdr_loss = 1;
} else {
++m.hdrcount;
}
} else {
/* Too many lines in message. */
hdr_loss = 1;
}
} else {
/* Input error. */
break;
}
}
/* Free AMI request headers. */
for (idx = 0; idx < m.hdrcount; ++idx) {
ast_free((void *) m.headers[idx]);
}
return res;
}
| static void event_filter_destructor | ( | void * | obj | ) | [static] |
Definition at line 1475 of file manager.c.
Referenced by manager_add_filter().
{
regex_t *regex_filter = obj;
regfree(regex_filter);
}
| static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 4096 of file manager.c.
References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_name(), ast_channel_uniqueid(), ast_channel_unlock, ast_manager_event_multichan, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), fast_originate_helper::cap, fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, ast_frame::data, fast_originate_helper::data, destroy_fast_originate_helper(), fast_originate_helper::early_media, EVENT_FLAG_CALL, fast_originate_helper::exten, fast_originate_helper::idtext, fast_originate_helper::priority, S_OR, fast_originate_helper::tech, fast_originate_helper::timeout, and fast_originate_helper::vars.
Referenced by action_originate().
{
struct fast_originate_helper *in = data;
int res;
int reason = 0;
struct ast_channel *chan = NULL, *chans[1];
char requested_channel[AST_CHANNEL_NAME];
if (!ast_strlen_zero(in->app)) {
res = ast_pbx_outgoing_app(in->tech, in->cap, in->data,
in->timeout, in->app, in->appdata, &reason, 1,
S_OR(in->cid_num, NULL),
S_OR(in->cid_name, NULL),
in->vars, in->account, &chan);
} else {
res = ast_pbx_outgoing_exten(in->tech, in->cap, in->data,
in->timeout, in->context, in->exten, in->priority, &reason, 1,
S_OR(in->cid_num, NULL),
S_OR(in->cid_name, NULL),
in->vars, in->account, &chan, in->early_media);
}
/* Any vars memory was passed to the ast_pbx_outgoing_xxx() calls. */
in->vars = NULL;
if (!chan) {
snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);
}
/* Tell the manager what happened with the channel */
chans[0] = chan;
ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
"%s"
"Response: %s\r\n"
"Channel: %s\r\n"
"Context: %s\r\n"
"Exten: %s\r\n"
"Reason: %d\r\n"
"Uniqueid: %s\r\n"
"CallerIDNum: %s\r\n"
"CallerIDName: %s\r\n",
in->idtext, res ? "Failure" : "Success",
chan ? ast_channel_name(chan) : requested_channel, in->context, in->exten, reason,
chan ? ast_channel_uniqueid(chan) : "<null>",
S_OR(in->cid_num, "<unknown>"),
S_OR(in->cid_name, "<unknown>")
);
/* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
if (chan) {
ast_channel_unlock(chan);
}
destroy_fast_originate_helper(in);
return NULL;
}
| static void free_channelvars | ( | void | ) | [static] |
Definition at line 8035 of file manager.c.
References ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and var.
Referenced by load_channelvars(), and manager_set_defaults().
{
struct manager_channel_variable *var;
AST_RWLIST_WRLOCK(&channelvars);
while ((var = AST_RWLIST_REMOVE_HEAD(&channelvars, entry))) {
ast_free(var);
}
AST_RWLIST_UNLOCK(&channelvars);
| static int function_capable_string_allowed_with_auths | ( | const char * | evaluating, |
| int | writepermlist | ||
| ) | [static] |
Checks to see if a string which can be used to evaluate functions should be rejected.
Definition at line 1335 of file manager.c.
References EVENT_FLAG_SYSTEM.
Referenced by action_getvar(), and action_status().
{
if (!(writepermlist & EVENT_FLAG_SYSTEM)
&& (
strstr(evaluating, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */
strstr(evaluating, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
)) {
return 0;
}
return 1;
}
| static int get_input | ( | struct mansession * | s, |
| char * | output | ||
| ) | [static] |
Read one full line (including crlf) from the manager socket.
* \r\n is the only valid terminator for the line. * (Note that, later, '\0' will be considered as the end-of-line marker, * so everything between the '\0' and the '\r\n' will not be used). * Also note that we assume output to have at least "maxlen" space. *
Definition at line 5307 of file manager.c.
References mansession_session::addr, ao2_lock, ao2_unlock, ast_log(), AST_PTHREADT_NULL, ast_sockaddr_stringify_addr(), ast_wait_for_input(), mansession_session::authenticated, mansession_session::authstart, errno, mansession_session::f, mansession_session::fd, mansession_session::inbuf, mansession_session::inlen, LOG_ERROR, LOG_WARNING, MESSAGE_LINE_TOO_LONG, mansession::parsing, mansession_session::pending_event, mansession::session, ast_frame::src, and mansession_session::waiting_thread.
Referenced by do_message().
{
int res, x;
int maxlen = sizeof(s->session->inbuf) - 1;
char *src = s->session->inbuf;
int timeout = -1;
time_t now;
/*
* Look for \r\n within the buffer. If found, copy to the output
* buffer and return, trimming the \r\n (not used afterwards).
*/
for (x = 0; x < s->session->inlen; x++) {
int cr; /* set if we have \r */
if (src[x] == '\r' && x+1 < s->session->inlen && src[x + 1] == '\n') {
cr = 2; /* Found. Update length to include \r\n */
} else if (src[x] == '\n') {
cr = 1; /* also accept \n only */
} else {
continue;
}
memmove(output, src, x); /*... but trim \r\n */
output[x] = '\0'; /* terminate the string */
x += cr; /* number of bytes used */
s->session->inlen -= x; /* remaining size */
memmove(src, src + x, s->session->inlen); /* remove used bytes */
return 1;
}
if (s->session->inlen >= maxlen) {
/* no crlf found, and buffer full - sorry, too long for us */
ast_log(LOG_WARNING, "Discarding message from %s. Line too long: %.25s...\n", ast_sockaddr_stringify_addr(&s->session->addr), src);
s->session->inlen = 0;
s->parsing = MESSAGE_LINE_TOO_LONG;
}
res = 0;
while (res == 0) {
/* calculate a timeout if we are not authenticated */
if (!s->session->authenticated) {
if(time(&now) == -1) {
ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
return -1;
}
timeout = (authtimeout - (now - s->session->authstart)) * 1000;
if (timeout < 0) {
/* we have timed out */
return 0;
}
}
ao2_lock(s->session);
if (s->session->pending_event) {
s->session->pending_event = 0;
ao2_unlock(s->session);
return 0;
}
s->session->waiting_thread = pthread_self();
ao2_unlock(s->session);
res = ast_wait_for_input(s->session->fd, timeout);
ao2_lock(s->session);
s->session->waiting_thread = AST_PTHREADT_NULL;
ao2_unlock(s->session);
}
if (res < 0) {
/* If we get a signal from some other thread (typically because
* there are new events queued), return 0 to notify the caller.
*/
if (errno == EINTR || errno == EAGAIN) {
return 0;
}
ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
return -1;
}
ao2_lock(s->session);
res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f);
if (res < 1) {
res = -1; /* error return */
} else {
s->session->inlen += res;
src[s->session->inlen] = '\0';
res = 0;
}
ao2_unlock(s->session);
return res;
}
| static struct ast_manager_user* get_manager_by_name_locked | ( | const char * | name | ) | [static, read] |
lookup an entry in the list of registered users. must be called with the list lock held.
Definition at line 1597 of file manager.c.
References AST_RWLIST_TRAVERSE, user, and ast_manager_user::username.
Referenced by __init_manager(), auth_http_callback(), authenticate(), function_amiclient(), handle_showmanager(), and manager_displayconnects().
{
struct ast_manager_user *user = NULL;
AST_RWLIST_TRAVERSE(&users, user, list) {
if (!strcasecmp(user->username, name)) {
break;
}
}
return user;
}
| static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 1414 of file manager.c.
References ARRAY_LEN, ast_instring(), permalias::num, and perms.
Referenced by __init_manager(), and strings_to_mask().
Grab a reference to the last event, update usecount as needed. Can handle a NULL pointer.
Definition at line 1256 of file manager.c.
References ast_atomic_fetchadd_int(), AST_RWLIST_LAST, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and eventqent::usecount.
Referenced by auth_http_callback(), generic_http_callback(), and session_do().
{
struct eventqent *ret;
AST_RWLIST_WRLOCK(&all_events);
ret = AST_RWLIST_LAST(&all_events);
/* the list is never empty now, but may become so when
* we optimize it in the future, so be prepared.
*/
if (ret) {
ast_atomic_fetchadd_int(&ret->usecount, 1);
}
AST_RWLIST_UNLOCK(&all_events);
return ret;
}
| static char* handle_manager_reload | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
CLI command manager reload.
Definition at line 1953 of file manager.c.
References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, reload_manager(), and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "manager reload";
e->usage =
"Usage: manager reload\n"
" Reloads the manager configuration.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc > 2) {
return CLI_SHOWUSAGE;
}
reload_manager();
return CLI_SUCCESS;
}
| static char* handle_mandebug | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 1710 of file manager.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "manager set debug [on|off]";
e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc == 3) {
ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
} else if (a->argc == 4) {
if (!strcasecmp(a->argv[3], "on")) {
manager_debug = 1;
} else if (!strcasecmp(a->argv[3], "off")) {
manager_debug = 0;
} else {
return CLI_SHOWUSAGE;
}
}
return CLI_SUCCESS;
}
| static void handle_parse_error | ( | struct mansession * | s, |
| struct message * | m, | ||
| char * | error | ||
| ) | [static] |
Definition at line 5405 of file manager.c.
References astman_send_error(), mansession_lock(), mansession_unlock(), MESSAGE_OKAY, and mansession::parsing.
Referenced by do_message().
{
mansession_lock(s);
astman_send_error(s, m, error);
s->parsing = MESSAGE_OKAY;
mansession_unlock(s);
}
| static char* handle_showmanager | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 1735 of file manager.c.
References ast_manager_user::acl, ast_cli_args::argc, ast_cli_args::argv, ast_acl_list_is_empty(), ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, ast_manager_user::chanvars, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_manager_user::displayconnects, ast_cli_args::fd, get_manager_by_name_locked(), ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, ast_manager_user::readperm, ast_manager_user::secret, ast_cli_entry::usage, user_authority_to_str(), ast_manager_user::username, ast_variable::value, ast_cli_args::word, and ast_manager_user::writeperm.
{
struct ast_manager_user *user = NULL;
int l, which;
char *ret = NULL;
struct ast_str *rauthority = ast_str_alloca(128);
struct ast_str *wauthority = ast_str_alloca(128);
struct ast_variable *v;
switch (cmd) {
case CLI_INIT:
e->command = "manager show user";
e->usage =
" Usage: manager show user <user>\n"
" Display all information related to the manager user specified.\n";
return NULL;
case CLI_GENERATE:
l = strlen(a->word);
which = 0;
if (a->pos != 3) {
return NULL;
}
AST_RWLIST_RDLOCK(&users);
AST_RWLIST_TRAVERSE(&users, user, list) {
if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) {
ret = ast_strdup(user->username);
break;
}
}
AST_RWLIST_UNLOCK(&users);
return ret;
}
if (a->argc != 4) {
return CLI_SHOWUSAGE;
}
AST_RWLIST_RDLOCK(&users);
if (!(user = get_manager_by_name_locked(a->argv[3]))) {
ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
AST_RWLIST_UNLOCK(&users);
return CLI_SUCCESS;
}
ast_cli(a->fd, "\n");
ast_cli(a->fd,
" username: %s\n"
" secret: %s\n"
" ACL: %s\n"
" read perm: %s\n"
" write perm: %s\n"
"displayconnects: %s\n",
(user->username ? user->username : "(N/A)"),
(user->secret ? "<Set>" : "(N/A)"),
((user->acl && !ast_acl_list_is_empty(user->acl)) ? "yes" : "no"),
user_authority_to_str(user->readperm, &rauthority),
user_authority_to_str(user->writeperm, &wauthority),
(user->displayconnects ? "yes" : "no"));
ast_cli(a->fd, " Variables: \n");
for (v = user->chanvars ; v ; v = v->next) {
ast_cli(a->fd, " %s = %s\n", v->name, v->value);
}
AST_RWLIST_UNLOCK(&users);
return CLI_SUCCESS;
}
| static char* handle_showmanagers | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 1804 of file manager.c.
References ast_cli_args::argc, ast_cli(), AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_entry::usage, and ast_manager_user::username.
{
struct ast_manager_user *user = NULL;
int count_amu = 0;
switch (cmd) {
case CLI_INIT:
e->command = "manager show users";
e->usage =
"Usage: manager show users\n"
" Prints a listing of all managers that are currently configured on that\n"
" system.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 3) {
return CLI_SHOWUSAGE;
}
AST_RWLIST_RDLOCK(&users);
/* If there are no users, print out something along those lines */
if (AST_RWLIST_EMPTY(&users)) {
ast_cli(a->fd, "There are no manager users.\n");
AST_RWLIST_UNLOCK(&users);
return CLI_SUCCESS;
}
ast_cli(a->fd, "\nusername\n--------\n");
AST_RWLIST_TRAVERSE(&users, user, list) {
ast_cli(a->fd, "%s\n", user->username);
count_amu++;
}
AST_RWLIST_UNLOCK(&users);
ast_cli(a->fd,"-------------------\n"
"%d manager users configured.\n", count_amu);
return CLI_SUCCESS;
}
| static char* handle_showmancmd | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 1628 of file manager.c.
References manager_action::action, ast_cli_args::argc, manager_action::arguments, ast_cli_args::argv, ast_cli(), ast_free, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, AST_XML_DOC, ast_xmldoc_printable(), manager_action::authority, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, COLOR_MAGENTA, ast_cli_entry::command, manager_action::description, manager_action::docsrc, ast_cli_args::fd, ast_cli_args::n, S_OR, manager_action::seealso, manager_action::synopsis, synopsis, manager_action::syntax, term_color(), ast_cli_entry::usage, and ast_cli_args::word.
{
struct manager_action *cur;
struct ast_str *authority;
int num, l, which;
char *ret = NULL;
#ifdef AST_XML_DOCS
char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64];
#endif
switch (cmd) {
case CLI_INIT:
e->command = "manager show command";
e->usage =
"Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
" Shows the detailed description for a specific Asterisk manager interface command.\n";
return NULL;
case CLI_GENERATE:
l = strlen(a->word);
which = 0;
AST_RWLIST_RDLOCK(&actions);
AST_RWLIST_TRAVERSE(&actions, cur, list) {
if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) {
ret = ast_strdup(cur->action);
break; /* make sure we exit even if ast_strdup() returns NULL */
}
}
AST_RWLIST_UNLOCK(&actions);
return ret;
}
authority = ast_str_alloca(80);
if (a->argc < 4) {
return CLI_SHOWUSAGE;
}
#ifdef AST_XML_DOCS
/* setup the titles */
term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40);
term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
#endif
AST_RWLIST_RDLOCK(&actions);
AST_RWLIST_TRAVERSE(&actions, cur, list) {
for (num = 3; num < a->argc; num++) {
if (!strcasecmp(cur->action, a->argv[num])) {
#ifdef AST_XML_DOCS
if (cur->docsrc == AST_XML_DOC) {
char *syntax = ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1);
char *synopsis = ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1);
char *description = ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1);
char *arguments = ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1);
char *seealso = ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1);
ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n",
syntax_title, syntax,
synopsis_title, synopsis,
description_title, description,
arguments_title, arguments,
seealso_title, seealso);
ast_free(syntax);
ast_free(synopsis);
ast_free(description);
ast_free(arguments);
ast_free(seealso);
} else
#endif
{
ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
cur->action, cur->synopsis,
authority_to_str(cur->authority, &authority),
S_OR(cur->description, ""));
}
}
}
}
AST_RWLIST_UNLOCK(&actions);
return CLI_SUCCESS;
}
| static char* handle_showmancmds | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
CLI command manager list commands.
Definition at line 1847 of file manager.c.
References manager_action::action, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, manager_action::authority, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HSMC_FORMAT, manager_action::synopsis, and ast_cli_entry::usage.
{
struct manager_action *cur;
struct ast_str *authority;
#define HSMC_FORMAT " %-15.15s %-15.15s %-55.55s\n"
switch (cmd) {
case CLI_INIT:
e->command = "manager show commands";
e->usage =
"Usage: manager show commands\n"
" Prints a listing of all the available Asterisk manager interface commands.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
authority = ast_str_alloca(80);
ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis");
ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------");
AST_RWLIST_RDLOCK(&actions);
AST_RWLIST_TRAVERSE(&actions, cur, list) {
ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis);
}
AST_RWLIST_UNLOCK(&actions);
return CLI_SUCCESS;
}
| static char* handle_showmanconn | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
CLI command manager list connected.
Definition at line 1876 of file manager.c.
References mansession_session::addr, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli(), ast_sockaddr_stringify_addr(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, mansession_session::fd, HSMCONN_FORMAT1, HSMCONN_FORMAT2, mansession_session::inuse, mansession_session::readperm, sessions, mansession_session::sessionstart, unref_mansession(), ast_cli_entry::usage, mansession_session::username, and mansession_session::writeperm.
{
struct ao2_container *sessions;
struct mansession_session *session;
time_t now = time(NULL);
#define HSMCONN_FORMAT1 " %-15.15s %-55.55s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n"
#define HSMCONN_FORMAT2 " %-15.15s %-55.55s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n"
int count = 0;
struct ao2_iterator i;
switch (cmd) {
case CLI_INIT:
e->command = "manager show connected";
e->usage =
"Usage: manager show connected\n"
" Prints a listing of the users that are currently connected to the\n"
"Asterisk manager interface.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write");
sessions = ao2_global_obj_ref(mgr_sessions);
if (sessions) {
i = ao2_iterator_init(sessions, 0);
ao2_ref(sessions, -1);
while ((session = ao2_iterator_next(&i))) {
ao2_lock(session);
ast_cli(a->fd, HSMCONN_FORMAT2, session->username,
ast_sockaddr_stringify_addr(&session->addr),
(int) (session->sessionstart),
(int) (now - session->sessionstart),
session->fd,
session->inuse,
session->readperm,
session->writeperm);
count++;
ao2_unlock(session);
unref_mansession(session);
}
ao2_iterator_destroy(&i);
}
ast_cli(a->fd, "%d users connected.\n", count);
return CLI_SUCCESS;
}
| static char* handle_showmaneventq | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
CLI command manager list eventq.
Definition at line 1927 of file manager.c.
References ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, eventqent::category, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_entry::usage, and eventqent::usecount.
{
struct eventqent *s;
switch (cmd) {
case CLI_INIT:
e->command = "manager show eventq";
e->usage =
"Usage: manager show eventq\n"
" Prints a listing of all events pending in the Asterisk manger\n"
"event queue.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
AST_RWLIST_RDLOCK(&all_events);
AST_RWLIST_TRAVERSE(&all_events, s, eq_next) {
ast_cli(a->fd, "Usecount: %d\n", s->usecount);
ast_cli(a->fd, "Category: %d\n", s->category);
ast_cli(a->fd, "Event:\n%s", s->eventdata);
}
AST_RWLIST_UNLOCK(&all_events);
return CLI_SUCCESS;
}
| static enum error_type handle_updates | ( | struct mansession * | s, |
| const struct message * | m, | ||
| struct ast_config * | cfg, | ||
| const char * | dfn | ||
| ) | [static] |
helper function for action_updateconfig
Definition at line 2877 of file manager.c.
References ast_category_append(), ast_category_delete(), ast_category_empty(), ast_category_get(), ast_category_insert(), ast_category_new(), ast_category_rename(), ast_free, ast_log(), ast_str_create(), ast_strlen_zero(), ast_variable_append(), ast_variable_delete(), ast_variable_insert(), ast_variable_new(), ast_variable_update(), astman_get_header(), eventqent::category, FAILURE_ALLOCATION, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, LOG_WARNING, match(), ast_variable::object, UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, UNSPECIFIED_CATEGORY, value, and var.
Referenced by action_updateconfig().
{
int x;
char hdr[40];
const char *action, *cat, *var, *value, *match, *line;
struct ast_category *category;
struct ast_variable *v;
struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
enum error_type result = 0;
for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */
unsigned int object = 0;
snprintf(hdr, sizeof(hdr), "Action-%06d", x);
action = astman_get_header(m, hdr);
if (ast_strlen_zero(action)) /* breaks the for loop if no action header */
break; /* this could cause problems if actions come in misnumbered */
snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
cat = astman_get_header(m, hdr);
if (ast_strlen_zero(cat)) { /* every action needs a category */
result = UNSPECIFIED_CATEGORY;
break;
}
snprintf(hdr, sizeof(hdr), "Var-%06d", x);
var = astman_get_header(m, hdr);
snprintf(hdr, sizeof(hdr), "Value-%06d", x);
value = astman_get_header(m, hdr);
if (!ast_strlen_zero(value) && *value == '>') {
object = 1;
value++;
}
snprintf(hdr, sizeof(hdr), "Match-%06d", x);
match = astman_get_header(m, hdr);
snprintf(hdr, sizeof(hdr), "Line-%06d", x);
line = astman_get_header(m, hdr);
if (!strcasecmp(action, "newcat")) {
if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */
result = FAILURE_NEWCAT; /* already exist */
break;
}
if (!(category = ast_category_new(cat, dfn, -1))) {
result = FAILURE_ALLOCATION;
break;
}
if (ast_strlen_zero(match)) {
ast_category_append(cfg, category);
} else {
ast_category_insert(cfg, category, match);
}
} else if (!strcasecmp(action, "renamecat")) {
if (ast_strlen_zero(value)) {
result = UNSPECIFIED_ARGUMENT;
break;
}
if (!(category = ast_category_get(cfg, cat))) {
result = UNKNOWN_CATEGORY;
break;
}
ast_category_rename(category, value);
} else if (!strcasecmp(action, "delcat")) {
if (ast_category_delete(cfg, cat)) {
result = FAILURE_DELCAT;
break;
}
} else if (!strcasecmp(action, "emptycat")) {
if (ast_category_empty(cfg, cat)) {
result = FAILURE_EMPTYCAT;
break;
}
} else if (!strcasecmp(action, "update")) {
if (ast_strlen_zero(var)) {
result = UNSPECIFIED_ARGUMENT;
break;
}
if (!(category = ast_category_get(cfg,cat))) {
result = UNKNOWN_CATEGORY;
break;
}
if (ast_variable_update(category, var, value, match, object)) {
result = FAILURE_UPDATE;
break;
}
} else if (!strcasecmp(action, "delete")) {
if ((ast_strlen_zero(var) && ast_strlen_zero(line))) {
result = UNSPECIFIED_ARGUMENT;
break;
}
if (!(category = ast_category_get(cfg, cat))) {
result = UNKNOWN_CATEGORY;
break;
}
if (ast_variable_delete(category, var, match, line)) {
result = FAILURE_DELETE;
break;
}
} else if (!strcasecmp(action, "append")) {
if (ast_strlen_zero(var)) {
result = UNSPECIFIED_ARGUMENT;
break;
}
if (!(category = ast_category_get(cfg, cat))) {
result = UNKNOWN_CATEGORY;
break;
}
if (!(v = ast_variable_new(var, value, dfn))) {
result = FAILURE_ALLOCATION;
break;
}
if (object || (match && !strcasecmp(match, "object"))) {
v->object = 1;
}
ast_variable_append(category, v);
} else if (!strcasecmp(action, "insert")) {
if (ast_strlen_zero(var) || ast_strlen_zero(line)) {
result = UNSPECIFIED_ARGUMENT;
break;
}
if (!(category = ast_category_get(cfg, cat))) {
result = UNKNOWN_CATEGORY;
break;
}
if (!(v = ast_variable_new(var, value, dfn))) {
result = FAILURE_ALLOCATION;
break;
}
ast_variable_insert(category, v, line);
}
else {
ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action);
result = UNKNOWN_ACTION;
break;
}
}
ast_free(str1);
ast_free(str2);
return result;
}
| static void json_escape | ( | char * | out, |
| const char * | in | ||
| ) | [static] |
The amount of space in out must be at least ( 2 * strlen(in) + 1 )
Definition at line 2799 of file manager.c.
Referenced by astman_append_json().
{
for (; *in; in++) {
if (*in == '\\' || *in == '\"') {
*out++ = '\\';
}
*out++ = *in;
}
*out = '\0';
}
| static struct ast_variable* man_do_variable_value | ( | struct ast_variable * | head, |
| const char * | hdr_val | ||
| ) | [static, read] |
Definition at line 2053 of file manager.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_skip_blanks(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_variable_new(), ast_variable::next, parse(), and var.
Referenced by astman_get_variables().
{
char *parse;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(vars)[64];
);
hdr_val = ast_skip_blanks(hdr_val); /* ignore leading spaces in the value */
parse = ast_strdupa(hdr_val);
/* Break the header value string into name=val pair items. */
AST_STANDARD_APP_ARGS(args, parse);
if (args.argc) {
int y;
/* Process each name=val pair item. */
for (y = 0; y < args.argc; y++) {
struct ast_variable *cur;
char *var;
char *val;
if (!args.vars[y]) {
continue;
}
var = val = args.vars[y];
strsep(&val, "=");
/* XXX We may wish to trim whitespace from the strings. */
if (!val || ast_strlen_zero(var)) {
continue;
}
/* Create new variable list node and prepend it to the list. */
cur = ast_variable_new(var, val, "");
if (cur) {
cur->next = head;
head = cur;
}
}
}
return head;
}
| static enum add_filter_result manager_add_filter | ( | const char * | filter_pattern, |
| struct ao2_container * | whitefilters, | ||
| struct ao2_container * | blackfilters | ||
| ) | [static] |
Add an event filter to a manager session.
| filter_pattern | Filter syntax to add, see below for syntax |
Filter will be used to match against each line of a manager event Filter can be any valid regular expression Filter can be a valid regular expression prefixed with !, which will add the filter as a black filter
Examples:
filter_pattern = "Event: Newchannel" filter_pattern = "Event: New.*" filter_pattern = "!Channel: DAHDI.*"
Definition at line 4796 of file manager.c.
References ao2_ref, ao2_t_alloc, ao2_t_link, ao2_t_ref, event_filter_destructor(), FILTER_ALLOC_FAILED, FILTER_COMPILE_FAIL, and FILTER_SUCCESS.
Referenced by __init_manager(), and action_filter().
{
regex_t *new_filter = ao2_t_alloc(sizeof(*new_filter), event_filter_destructor, "event_filter allocation");
int is_blackfilter;
if (!new_filter) {
return FILTER_ALLOC_FAILED;
}
if (filter_pattern[0] == '!') {
is_blackfilter = 1;
filter_pattern++;
} else {
is_blackfilter = 0;
}
if (regcomp(new_filter, filter_pattern, 0)) { /* XXX: the only place we use non-REG_EXTENDED */
ao2_t_ref(new_filter, -1, "failed to make regex");
return FILTER_COMPILE_FAIL;
}
if (is_blackfilter) {
ao2_t_link(blackfilters, new_filter, "link new filter into black user container");
} else {
ao2_t_link(whitefilters, new_filter, "link new filter into white user container");
}
ao2_ref(new_filter, -1);
return FILTER_SUCCESS;
}
| static int manager_displayconnects | ( | struct mansession_session * | session | ) | [static] |
Get displayconnects config option.
| session | manager session to get parameter from. |
Definition at line 1614 of file manager.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_manager_user::displayconnects, get_manager_by_name_locked(), and mansession_session::username.
Referenced by action_login(), generic_http_callback(), purge_sessions(), and session_do().
{
struct ast_manager_user *user = NULL;
int ret = 0;
AST_RWLIST_RDLOCK(&users);
if ((user = get_manager_by_name_locked(session->username))) {
ret = user->displayconnects;
}
AST_RWLIST_UNLOCK(&users);
return ret;
}
| static int manager_modulecheck | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Manager function to check if module is loaded.
Definition at line 5093 of file manager.c.
References ast_copy_string(), ast_debug, ast_file_version_find(), ast_module_check(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and version.
Referenced by __init_manager().
{
int res;
const char *module = astman_get_header(m, "Module");
const char *id = astman_get_header(m, "ActionID");
char idText[256];
#if !defined(LOW_MEMORY)
const char *version;
#endif
char filename[PATH_MAX];
char *cut;
ast_copy_string(filename, module, sizeof(filename));
if ((cut = strchr(filename, '.'))) {
*cut = '\0';
} else {
cut = filename + strlen(filename);
}
snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so");
ast_debug(1, "**** ModuleCheck .so file %s\n", filename);
res = ast_module_check(filename);
if (!res) {
astman_send_error(s, m, "Module not loaded");
return 0;
}
snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c");
ast_debug(1, "**** ModuleCheck .c file %s\n", filename);
#if !defined(LOW_MEMORY)
version = ast_file_version_find(filename);
#endif
if (!ast_strlen_zero(id)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
} else {
idText[0] = '\0';
}
astman_append(s, "Response: Success\r\n%s", idText);
#if !defined(LOW_MEMORY)
astman_append(s, "Version: %s\r\n\r\n", version ? version : "");
#endif
return 0;
}
| static int manager_moduleload | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Definition at line 5136 of file manager.c.
References AST_FORCE_SOFT, ast_load_resource(), ast_module_reload(), ast_strlen_zero(), ast_unload_resource(), astman_get_header(), astman_send_ack(), and astman_send_error().
Referenced by __init_manager().
{
int res;
const char *module = astman_get_header(m, "Module");
const char *loadtype = astman_get_header(m, "LoadType");
if (!loadtype || strlen(loadtype) == 0) {
astman_send_error(s, m, "Incomplete ModuleLoad action.");
}
if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) {
astman_send_error(s, m, "Need module name");
}
if (!strcasecmp(loadtype, "load")) {
res = ast_load_resource(module);
if (res) {
astman_send_error(s, m, "Could not load module.");
} else {
astman_send_ack(s, m, "Module loaded.");
}
} else if (!strcasecmp(loadtype, "unload")) {
res = ast_unload_resource(module, AST_FORCE_SOFT);
if (res) {
astman_send_error(s, m, "Could not unload module.");
} else {
astman_send_ack(s, m, "Module unloaded.");
}
} else if (!strcasecmp(loadtype, "reload")) {
if (!ast_strlen_zero(module)) {
res = ast_module_reload(module);
if (res == 0) {
astman_send_error(s, m, "No such module.");
} else if (res == 1) {
astman_send_error(s, m, "Module does not support reload action.");
} else {
astman_send_ack(s, m, "Module reloaded.");
}
} else {
ast_module_reload(NULL); /* Reload all modules */
astman_send_ack(s, m, "All modules reloaded");
}
} else
astman_send_error(s, m, "Incomplete ModuleLoad action.");
return 0;
}
| static int manager_state_cb | ( | char * | context, |
| char * | exten, | ||
| struct ast_state_cb_info * | info, | ||
| void * | data | ||
| ) | [static] |
Definition at line 5819 of file manager.c.
References ast_get_hint(), AST_HINT_UPDATE_DEVICE, AST_HINT_UPDATE_PRESENCE, ast_presence_state2str(), EVENT_FLAG_CALL, ast_state_cb_info::exten_state, manager_event, ast_state_cb_info::presence_message, ast_state_cb_info::presence_state, ast_state_cb_info::presence_subtype, and ast_state_cb_info::reason.
Referenced by __init_manager().
{
/* Notify managers of change */
char hint[512];
ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
switch(info->reason) {
case AST_HINT_UPDATE_DEVICE:
/*** DOCUMENTATION
<managerEventInstance>
<synopsis>Raised when an extension state has changed.</synopsis>
</managerEventInstance>
***/
manager_event(EVENT_FLAG_CALL, "ExtensionStatus",
"Exten: %s\r\n"
"Context: %s\r\n"
"Hint: %s\r\n"
"Status: %d\r\n",
exten,
context,
hint,
info->exten_state);
break;
case AST_HINT_UPDATE_PRESENCE:
/*** DOCUMENTATION
<managerEventInstance>
<synopsis>Raised when a presence state has changed.</synopsis>
</managerEventInstance>
***/
manager_event(EVENT_FLAG_CALL, "PresenceStatus",
"Exten: %s\r\n"
"Context: %s\r\n"
"Hint: %s\r\n"
"Status: %s\r\n"
"Subtype: %s\r\n"
"Message: %s\r\n",
exten,
context,
hint,
ast_presence_state2str(info->presence_state),
info->presence_subtype,
info->presence_message);
break;
}
return 0;
}
| static int mansession_cmp_fn | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 1554 of file manager.c.
References CMP_MATCH, str, and mansession_session::username.
Referenced by __init_manager().
{
struct mansession_session *s = obj;
char *str = arg;
return !strcasecmp(s->username, str) ? CMP_MATCH : 0;
}
| static enum ast_security_event_transport_type mansession_get_transport | ( | const struct mansession * | s | ) | [static] |
Definition at line 2377 of file manager.c.
References AST_SECURITY_EVENT_TRANSPORT_TCP, AST_SECURITY_EVENT_TRANSPORT_TLS, ast_tcptls_session_instance::parent, mansession::tcptls_session, and ast_tcptls_session_args::tls_cfg.
Referenced by report_auth_success(), report_failed_acl(), report_failed_challenge_response(), report_inval_password(), report_invalid_user(), report_req_bad_format(), report_req_not_allowed(), and report_session_limit().
{
return s->tcptls_session->parent->tls_cfg ? AST_SECURITY_EVENT_TRANSPORT_TLS :
AST_SECURITY_EVENT_TRANSPORT_TCP;
}
| static void mansession_lock | ( | struct mansession * | s | ) | [static] |
Lock the 'mansession' structure.
Definition at line 2349 of file manager.c.
References ast_mutex_lock, and mansession::lock.
Referenced by action_challenge(), do_message(), handle_parse_error(), and process_message().
{
ast_mutex_lock(&s->lock);
}
| static void mansession_unlock | ( | struct mansession * | s | ) | [static] |
Unlock the 'mansession' structure.
Definition at line 2355 of file manager.c.
References ast_mutex_unlock, and mansession::lock.
Referenced by action_challenge(), do_message(), handle_parse_error(), and process_message().
{
ast_mutex_unlock(&s->lock);
}
| static int match_filter | ( | struct mansession * | s, |
| char * | eventdata | ||
| ) | [static] |
Definition at line 4827 of file manager.c.
References ao2_container_count(), ao2_t_callback_data, ast_debug, blackfilter_cmp_fn(), mansession_session::blackfilters, OBJ_NODATA, mansession::session, whitefilter_cmp_fn(), and mansession_session::whitefilters.
Referenced by process_events().
{
int result = 0;
ast_debug(3, "Examining event:\n%s\n", eventdata);
if (!ao2_container_count(s->session->whitefilters) && !ao2_container_count(s->session->blackfilters)) {
return 1; /* no filtering means match all */
} else if (ao2_container_count(s->session->whitefilters) && !ao2_container_count(s->session->blackfilters)) {
/* white filters only: implied black all filter processed first, then white filters */
ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container");
} else if (!ao2_container_count(s->session->whitefilters) && ao2_container_count(s->session->blackfilters)) {
/* black filters only: implied white all filter processed first, then black filters */
ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container");
} else {
/* white and black filters: implied black all filter processed first, then white filters, and lastly black filters */
ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container");
if (result) {
result = 0;
ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container");
}
}
return result;
}
| static int process_events | ( | struct mansession * | s | ) | [static] |
Send any applicable events to the client listening on this socket. Wait only for a finite time on each event, and drop all events whether they are successfully sent or not.
Definition at line 4857 of file manager.c.
References advance_event(), ao2_lock, ao2_unlock, mansession_session::authenticated, eventqent::category, mansession_session::f, mansession_session::last_ev, match_filter(), mansession_session::readperm, mansession_session::send_events, send_string(), and mansession::session.
Referenced by do_message(), and process_message().
{
int ret = 0;
ao2_lock(s->session);
if (s->session->f != NULL) {
struct eventqent *eqe = s->session->last_ev;
while ((eqe = advance_event(eqe))) {
if (!ret && s->session->authenticated &&
(s->session->readperm & eqe->category) == eqe->category &&
(s->session->send_events & eqe->category) == eqe->category) {
if (match_filter(s, eqe->eventdata)) {
if (send_string(s, eqe->eventdata) < 0)
ret = -1; /* don't send more */
}
}
s->session->last_ev = eqe;
}
}
ao2_unlock(s->session);
return ret;
}
| static int process_message | ( | struct mansession * | s, |
| const struct message * | m | ||
| ) | [static] |
Process an AMI message, performing desired action. Return 0 on success, -1 on error that require the session to be destroyed.
Definition at line 5195 of file manager.c.
References __astman_get_header(), manager_action::action, action_find(), ao2_lock, ao2_t_ref, ao2_unlock, ast_debug, ast_module_ref(), ast_module_unref(), ast_strlen_zero(), astman_get_header(), astman_send_error(), mansession_session::authenticated, manager_action::authority, check_manager_session_inuse(), manager_action::func, GET_HEADER_SKIP_EMPTY, mansession_lock(), mansession_unlock(), manager_action::module, process_events(), manager_action::registered, report_req_bad_format(), report_req_not_allowed(), report_session_limit(), mansession::session, user, and mansession_session::writeperm.
Referenced by auth_http_callback(), do_message(), and generic_http_callback().
{
int ret = 0;
struct manager_action *act_found;
const char *user;
const char *action;
action = __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY);
if (ast_strlen_zero(action)) {
report_req_bad_format(s, "NONE");
mansession_lock(s);
astman_send_error(s, m, "Missing action in request");
mansession_unlock(s);
return 0;
}
if (!s->session->authenticated
&& strcasecmp(action, "Login")
&& strcasecmp(action, "Logoff")
&& strcasecmp(action, "Challenge")) {
if (!s->session->authenticated) {
report_req_not_allowed(s, action);
}
mansession_lock(s);
astman_send_error(s, m, "Permission denied");
mansession_unlock(s);
return 0;
}
if (!allowmultiplelogin
&& !s->session->authenticated
&& (!strcasecmp(action, "Login")
|| !strcasecmp(action, "Challenge"))) {
user = astman_get_header(m, "Username");
if (!ast_strlen_zero(user) && check_manager_session_inuse(user)) {
report_session_limit(s);
sleep(1);
mansession_lock(s);
astman_send_error(s, m, "Login Already In Use");
mansession_unlock(s);
return -1;
}
}
act_found = action_find(action);
if (act_found) {
/* Found the requested AMI action. */
int acted = 0;
if ((s->session->writeperm & act_found->authority)
|| act_found->authority == 0) {
/* We have the authority to execute the action. */
ao2_lock(act_found);
if (act_found->registered && act_found->func) {
ast_debug(1, "Running action '%s'\n", act_found->action);
if (act_found->module) {
ast_module_ref(act_found->module);
}
ao2_unlock(act_found);
ret = act_found->func(s, m);
acted = 1;
ao2_lock(act_found);
if (act_found->module) {
ast_module_unref(act_found->module);
}
}
ao2_unlock(act_found);
}
if (!acted) {
/*
* We did not execute the action because access was denied, it
* was no longer registered, or no action was really registered.
* Complain about it and leave.
*/
report_req_not_allowed(s, action);
mansession_lock(s);
astman_send_error(s, m, "Permission denied");
mansession_unlock(s);
}
ao2_t_ref(act_found, -1, "done with found action object");
} else {
char buf[512];
report_req_bad_format(s, action);
snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
mansession_lock(s);
astman_send_error(s, m, buf);
mansession_unlock(s);
}
if (ret) {
return ret;
}
/* Once done with our message, deliver any pending events unless the
requester doesn't want them as part of this response.
*/
if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) {
return process_events(s);
} else {
return ret;
}
}
| static void purge_events | ( | void | ) | [static] |
Purge unused events. Remove elements from the head as long as their usecount is 0 and there is a next element.
Definition at line 1276 of file manager.c.
References ast_free, AST_RWLIST_FIRST, AST_RWLIST_NEXT, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tvdiff_sec(), ast_tvnow(), eventqent::tv, and eventqent::usecount.
Referenced by purge_old_stuff().
{
struct eventqent *ev;
struct timeval now = ast_tvnow();
AST_RWLIST_WRLOCK(&all_events);
while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
AST_RWLIST_REMOVE_HEAD(&all_events, eq_next);
ast_free(ev);
}
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&all_events, ev, eq_next) {
/* Never release the last event */
if (!AST_RWLIST_NEXT(ev, eq_next)) {
break;
}
/* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
AST_RWLIST_REMOVE_CURRENT(eq_next);
ast_free(ev);
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&all_events);
}
| static void purge_sessions | ( | int | n_max | ) | [static] |
remove at most n_max stale session from the list.
Definition at line 5609 of file manager.c.
References mansession_session::addr, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_sockaddr_stringify_addr(), ast_verb, mansession_session::authenticated, mansession_session::inuse, manager_displayconnects(), session_destroy(), sessions, mansession_session::sessiontimeout, unref_mansession(), mansession_session::username, and VERBOSITY_ATLEAST.
Referenced by purge_old_stuff().
{
struct ao2_container *sessions;
struct mansession_session *session;
time_t now = time(NULL);
struct ao2_iterator i;
sessions = ao2_global_obj_ref(mgr_sessions);
if (!sessions) {
return;
}
i = ao2_iterator_init(sessions, 0);
ao2_ref(sessions, -1);
while ((session = ao2_iterator_next(&i)) && n_max > 0) {
ao2_lock(session);
if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
if (session->authenticated
&& VERBOSITY_ATLEAST(2)
&& manager_displayconnects(session)) {
ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
session->username, ast_sockaddr_stringify_addr(&session->addr));
}
ao2_unlock(session);
session_destroy(session);
n_max--;
} else {
ao2_unlock(session);
unref_mansession(session);
}
}
ao2_iterator_destroy(&i);
}
| static void report_auth_success | ( | const struct mansession * | s | ) | [static] |
Definition at line 2458 of file manager.c.
References mansession_session::addr, AST_SEC_EVT, ast_security_event_report(), AST_SECURITY_EVENT_SUCCESSFUL_AUTH, AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION, ast_security_event_successful_auth::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, mansession::session, mansession_session::sessionstart_tv, mansession::tcptls_session, and mansession_session::username.
Referenced by authenticate().
{
char session_id[32];
struct ast_security_event_successful_auth successful_auth = {
.common.event_type = AST_SECURITY_EVENT_SUCCESSFUL_AUTH,
.common.version = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION,
.common.service = "AMI",
.common.account_id = s->session->username,
.common.session_tv = &s->session->sessionstart_tv,
.common.local_addr = {
.addr = &s->tcptls_session->parent->local_address,
.transport = mansession_get_transport(s),
},
.common.remote_addr = {
.addr = &s->session->addr,
.transport = mansession_get_transport(s),
},
.common.session_id = session_id,
};
snprintf(session_id, sizeof(session_id), "%p", s->session);
ast_security_event_report(AST_SEC_EVT(&successful_auth));
}
| static void report_failed_acl | ( | const struct mansession * | s, |
| const char * | username | ||
| ) | [static] |
Definition at line 2408 of file manager.c.
References mansession_session::addr, AST_SEC_EVT, AST_SECURITY_EVENT_FAILED_ACL, AST_SECURITY_EVENT_FAILED_ACL_VERSION, ast_security_event_report(), ast_security_event_failed_acl::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, mansession::session, mansession_session::sessionstart_tv, and mansession::tcptls_session.
Referenced by authenticate().
{
char session_id[32];
struct ast_security_event_failed_acl failed_acl_event = {
.common.event_type = AST_SECURITY_EVENT_FAILED_ACL,
.common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
.common.service = "AMI",
.common.account_id = username,
.common.session_tv = &s->session->sessionstart_tv,
.common.local_addr = {
.addr = &s->tcptls_session->parent->local_address,
.transport = mansession_get_transport(s),
},
.common.remote_addr = {
.addr = &s->session->addr,
.transport = mansession_get_transport(s),
},
.common.session_id = session_id,
};
snprintf(session_id, sizeof(session_id), "%p", s->session);
ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
}
| static void report_failed_challenge_response | ( | const struct mansession * | s, |
| const char * | response, | ||
| const char * | expected_response | ||
| ) | [static] |
Definition at line 2541 of file manager.c.
References mansession_session::addr, AST_SEC_EVT, AST_SECURITY_EVENT_CHAL_RESP_FAILED, AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION, ast_security_event_report(), mansession_session::challenge, ast_security_event_chal_resp_failed::common, ast_security_event_common::event_type, ast_security_event_chal_resp_failed::expected_response, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, ast_security_event_chal_resp_failed::response, mansession::session, mansession_session::sessionstart_tv, mansession::tcptls_session, and mansession_session::username.
Referenced by authenticate().
{
char session_id[32];
struct ast_security_event_chal_resp_failed chal_resp_failed = {
.common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED,
.common.version = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION,
.common.service = "AMI",
.common.account_id = s->session->username,
.common.session_tv = &s->session->sessionstart_tv,
.common.local_addr = {
.addr = &s->tcptls_session->parent->local_address,
.transport = mansession_get_transport(s),
},
.common.remote_addr = {
.addr = &s->session->addr,
.transport = mansession_get_transport(s),
},
.common.session_id = session_id,
.challenge = s->session->challenge,
.response = response,
.expected_response = expected_response,
};
snprintf(session_id, sizeof(session_id), "%p", s->session);
ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
}
| static void report_inval_password | ( | const struct mansession * | s, |
| const char * | username | ||
| ) | [static] |
Definition at line 2433 of file manager.c.
References mansession_session::addr, AST_SEC_EVT, AST_SECURITY_EVENT_INVAL_PASSWORD, AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION, ast_security_event_report(), ast_security_event_inval_password::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, mansession::session, mansession_session::sessionstart_tv, and mansession::tcptls_session.
Referenced by authenticate().
{
char session_id[32];
struct ast_security_event_inval_password inval_password = {
.common.event_type = AST_SECURITY_EVENT_INVAL_PASSWORD,
.common.version = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION,
.common.service = "AMI",
.common.account_id = username,
.common.session_tv = &s->session->sessionstart_tv,
.common.local_addr = {
.addr = &s->tcptls_session->parent->local_address,
.transport = mansession_get_transport(s),
},
.common.remote_addr = {
.addr = &s->session->addr,
.transport = mansession_get_transport(s),
},
.common.session_id = session_id,
};
snprintf(session_id, sizeof(session_id), "%p", s->session);
ast_security_event_report(AST_SEC_EVT(&inval_password));
}
| static void report_invalid_user | ( | const struct mansession * | s, |
| const char * | username | ||
| ) | [static] |
Definition at line 2383 of file manager.c.
References mansession_session::addr, AST_SEC_EVT, AST_SECURITY_EVENT_INVAL_ACCT_ID, AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION, ast_security_event_report(), ast_security_event_inval_acct_id::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, mansession::session, mansession_session::sessionstart_tv, and mansession::tcptls_session.
Referenced by authenticate().
{
char session_id[32];
struct ast_security_event_inval_acct_id inval_acct_id = {
.common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID,
.common.version = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION,
.common.service = "AMI",
.common.account_id = username,
.common.session_tv = &s->session->sessionstart_tv,
.common.local_addr = {
.addr = &s->tcptls_session->parent->local_address,
.transport = mansession_get_transport(s),
},
.common.remote_addr = {
.addr = &s->session->addr,
.transport = mansession_get_transport(s),
},
.common.session_id = session_id,
};
snprintf(session_id, sizeof(session_id), "%p", s);
ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
}
| static void report_req_bad_format | ( | const struct mansession * | s, |
| const char * | action | ||
| ) | [static] |
Definition at line 2512 of file manager.c.
References mansession_session::addr, AST_SEC_EVT, ast_security_event_report(), AST_SECURITY_EVENT_REQ_BAD_FORMAT, AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION, ast_security_event_req_bad_format::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, ast_security_event_req_not_allowed::request_type, ast_security_event_req_bad_format::request_type, mansession::session, mansession_session::sessionstart_tv, mansession::tcptls_session, and mansession_session::username.
Referenced by process_message().
{
char session_id[32];
char request_type[64];
struct ast_security_event_req_bad_format req_bad_format = {
.common.event_type = AST_SECURITY_EVENT_REQ_BAD_FORMAT,
.common.version = AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION,
.common.service = "AMI",
.common.account_id = s->session->username,
.common.session_tv = &s->session->sessionstart_tv,
.common.local_addr = {
.addr = &s->tcptls_session->parent->local_address,
.transport = mansession_get_transport(s),
},
.common.remote_addr = {
.addr = &s->session->addr,
.transport = mansession_get_transport(s),
},
.common.session_id = session_id,
.request_type = request_type,
};
snprintf(session_id, sizeof(session_id), "%p", s->session);
snprintf(request_type, sizeof(request_type), "Action: %s", action);
ast_security_event_report(AST_SEC_EVT(&req_bad_format));
}
| static void report_req_not_allowed | ( | const struct mansession * | s, |
| const char * | action | ||
| ) | [static] |
Definition at line 2483 of file manager.c.
References mansession_session::addr, AST_SEC_EVT, ast_security_event_report(), AST_SECURITY_EVENT_REQ_NOT_ALLOWED, AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION, ast_security_event_req_not_allowed::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, ast_security_event_req_not_allowed::request_type, mansession::session, mansession_session::sessionstart_tv, mansession::tcptls_session, and mansession_session::username.
Referenced by process_message().
{
char session_id[32];
char request_type[64];
struct ast_security_event_req_not_allowed req_not_allowed = {
.common.event_type = AST_SECURITY_EVENT_REQ_NOT_ALLOWED,
.common.version = AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION,
.common.service = "AMI",
.common.account_id = s->session->username,
.common.session_tv = &s->session->sessionstart_tv,
.common.local_addr = {
.addr = &s->tcptls_session->parent->local_address,
.transport = mansession_get_transport(s),
},
.common.remote_addr = {
.addr = &s->session->addr,
.transport = mansession_get_transport(s),
},
.common.session_id = session_id,
.request_type = request_type,
};
snprintf(session_id, sizeof(session_id), "%p", s->session);
snprintf(request_type, sizeof(request_type), "Action: %s", action);
ast_security_event_report(AST_SEC_EVT(&req_not_allowed));
}
| static void report_session_limit | ( | const struct mansession * | s | ) | [static] |
Definition at line 2571 of file manager.c.
References mansession_session::addr, AST_SEC_EVT, ast_security_event_report(), AST_SECURITY_EVENT_SESSION_LIMIT, AST_SECURITY_EVENT_SESSION_LIMIT_VERSION, ast_security_event_session_limit::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, mansession::session, mansession_session::sessionstart_tv, mansession::tcptls_session, and mansession_session::username.
Referenced by process_message().
{
char session_id[32];
struct ast_security_event_session_limit session_limit = {
.common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
.common.version = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION,
.common.service = "AMI",
.common.account_id = s->session->username,
.common.session_tv = &s->session->sessionstart_tv,
.common.local_addr = {
.addr = &s->tcptls_session->parent->local_address,
.transport = mansession_get_transport(s),
},
.common.remote_addr = {
.addr = &s->session->addr,
.transport = mansession_get_transport(s),
},
.common.session_id = session_id,
};
snprintf(session_id, sizeof(session_id), "%p", s->session);
ast_security_event_report(AST_SEC_EVT(&session_limit));
}
| static int send_string | ( | struct mansession * | s, |
| char * | string | ||
| ) | [static] |
helper function to send a string to the socket. Return -1 on error (e.g. buffer full).
Definition at line 2201 of file manager.c.
References ast_careful_fwrite(), EVENT_FLAG_HOOKRESPONSE, f, mansession_session::f, mansession::f, mansession_session::fd, mansession::fd, manager_custom_hook::helper, mansession::hook, mansession::session, mansession::write_error, and mansession_session::writetimeout.
Referenced by astman_append(), and process_events().
{
int res;
FILE *f = s->f ? s->f : s->session->f;
int fd = s->f ? s->fd : s->session->fd;
/* It's a result from one of the hook's action invocation */
if (s->hook) {
/*
* to send responses, we're using the same function
* as for receiving events. We call the event "HookResponse"
*/
s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string);
return 0;
}
if ((res = ast_careful_fwrite(f, fd, string, strlen(string), s->session->writetimeout))) {
s->write_error = 1;
}
return res;
}
| static void session_destroy | ( | struct mansession_session * | s | ) | [static] |
Definition at line 1561 of file manager.c.
References ao2_global_obj_ref, ao2_ref, ao2_unlink, sessions, and unref_mansession().
Referenced by auth_http_callback(), generic_http_callback(), purge_sessions(), and session_do().
{
struct ao2_container *sessions;
sessions = ao2_global_obj_ref(mgr_sessions);
if (sessions) {
ao2_unlink(sessions, s);
ao2_ref(sessions, -1);
}
unref_mansession(s);
}
| static void session_destructor | ( | void * | obj | ) | [static] |
Definition at line 1481 of file manager.c.
References ao2_t_ref, ast_atomic_fetchadd_int(), ast_datastore_free(), AST_LIST_REMOVE_HEAD, ast_variables_destroy(), mansession_session::blackfilters, mansession_session::chanvars, mansession_session::datastores, mansession_session::f, mansession_session::fd, mansession_session::last_ev, eventqent::usecount, and mansession_session::whitefilters.
Referenced by build_mansession().
{
struct mansession_session *session = obj;
struct eventqent *eqe = session->last_ev;
struct ast_datastore *datastore;
/* Get rid of each of the data stores on the session */
while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
/* Free the data store */
ast_datastore_free(datastore);
}
if (session->f != NULL) {
/*
* Issuing shutdown() is necessary here to avoid a race
* condition where the last data written may not appear
* in the the TCP stream. See ASTERISK-23548
*/
fflush(session->f);
if (session->fd != -1) {
shutdown(session->fd, SHUT_RDWR);
}
fclose(session->f);
}
if (eqe) {
ast_atomic_fetchadd_int(&eqe->usecount, -1);
}
if (session->chanvars) {
ast_variables_destroy(session->chanvars);
}
if (session->whitefilters) {
ao2_t_ref(session->whitefilters, -1, "decrement ref for white container, should be last one");
}
if (session->blackfilters) {
ao2_t_ref(session->blackfilters, -1, "decrement ref for black container, should be last one");
}
}
| static void* session_do | ( | void * | data | ) | [static] |
The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). )
Definition at line 5510 of file manager.c.
References mansession_session::addr, AMI_VERSION, ao2_lock, ao2_ref, ao2_unlock, ast_atomic_fetchadd_int(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_sockaddr_copy(), ast_sockaddr_stringify_addr(), ast_verb, astman_append(), mansession_session::authenticated, mansession_session::authstart, block_sockets, build_mansession(), ast_frame::data, mansession_session::datastores, do_message(), errno, ast_tcptls_session_instance::f, mansession_session::f, mansession::f, ast_tcptls_session_instance::fd, mansession_session::fd, mansession::fd, ast_frame::flags, grab_last(), mansession_session::last_ev, mansession::lock, LOG_ERROR, LOG_WARNING, manager_displayconnects(), ast_tcptls_session_instance::remote_address, mansession::session, session_destroy(), mansession::tcptls_session, unauth_sessions, mansession_session::username, and mansession::write_error.
{
struct ast_tcptls_session_instance *ser = data;
struct mansession_session *session;
struct mansession s = {
.tcptls_session = data,
};
int flags;
int res;
struct ast_sockaddr ser_remote_address_tmp;
struct protoent *p;
if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
fclose(ser->f);
ast_atomic_fetchadd_int(&unauth_sessions, -1);
goto done;
}
ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
session = build_mansession(&ser_remote_address_tmp);
if (session == NULL) {
fclose(ser->f);
ast_atomic_fetchadd_int(&unauth_sessions, -1);
goto done;
}
/* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
* This is necessary to prevent delays (caused by buffering) as we
* write to the socket in bits and peices. */
p = getprotobyname("tcp");
if (p) {
int arg = 1;
if( setsockopt(ser->fd, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\nSome manager actions may be slow to respond.\n", strerror(errno));
}
} else {
ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY, getprotobyname(\"tcp\") failed\nSome manager actions may be slow to respond.\n");
}
flags = fcntl(ser->fd, F_GETFL);
if (!block_sockets) { /* make sure socket is non-blocking */
flags |= O_NONBLOCK;
} else {
flags &= ~O_NONBLOCK;
}
fcntl(ser->fd, F_SETFL, flags);
ao2_lock(session);
/* Hook to the tail of the event queue */
session->last_ev = grab_last();
ast_mutex_init(&s.lock);
/* these fields duplicate those in the 'ser' structure */
session->fd = s.fd = ser->fd;
session->f = s.f = ser->f;
ast_sockaddr_copy(&session->addr, &ser_remote_address_tmp);
s.session = session;
AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
if(time(&session->authstart) == -1) {
ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
ast_atomic_fetchadd_int(&unauth_sessions, -1);
ao2_unlock(session);
session_destroy(session);
goto done;
}
ao2_unlock(session);
astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */
for (;;) {
if ((res = do_message(&s)) < 0 || s.write_error) {
break;
}
}
/* session is over, explain why and terminate */
if (session->authenticated) {
if (manager_displayconnects(session)) {
ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_sockaddr_stringify_addr(&session->addr));
}
} else {
ast_atomic_fetchadd_int(&unauth_sessions, -1);
if (displayconnects) {
ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
}
}
session_destroy(session);
ast_mutex_destroy(&s.lock);
done:
ao2_ref(ser, -1);
ser = NULL;
return NULL;
}
| static int set_eventmask | ( | struct mansession * | s, |
| const char * | eventmask | ||
| ) | [static] |
Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm.
Definition at line 2364 of file manager.c.
References ao2_lock, ao2_unlock, mansession_session::send_events, mansession::session, and strings_to_mask().
Referenced by action_events(), and authenticate().
{
int maskint = strings_to_mask(eventmask);
ao2_lock(s->session);
if (maskint >= 0) {
s->session->send_events = maskint;
}
ao2_unlock(s->session);
return maskint;
}
| static int strings_to_mask | ( | const char * | string | ) | [static] |
A number returns itself, false returns 0, true returns all flags, other strings return the flags that are set.
Definition at line 1435 of file manager.c.
References ARRAY_LEN, ast_false(), ast_strlen_zero(), ast_true(), get_perm(), permalias::num, and perms.
Referenced by set_eventmask().
{
const char *p;
if (ast_strlen_zero(string)) {
return -1;
}
for (p = string; *p; p++) {
if (*p < '0' || *p > '9') {
break;
}
}
if (!*p) { /* all digits */
return atoi(string);
}
if (ast_false(string)) {
return 0;
}
if (ast_true(string)) { /* all permissions */
int x, ret = 0;
for (x = 0; x < ARRAY_LEN(perms); x++) {
ret |= perms[x].num;
}
return ret;
}
return get_perm(string);
}
| static struct mansession_session* unref_mansession | ( | struct mansession_session * | s | ) | [static, read] |
Unreference manager session object. If no more references, then go ahead and delete it.
Definition at line 1466 of file manager.c.
References ao2_ref, and ast_debug.
Referenced by __ast_manager_event_multichan(), astman_is_authed(), astman_verify_session_readpermissions(), astman_verify_session_writepermissions(), check_manager_session_inuse(), find_session(), find_session_by_nonce(), handle_showmanconn(), purge_sessions(), and session_destroy().
{
int refcount = ao2_ref(s, -1);
if (manager_debug) {
ast_debug(1, "Mansession: %p refcount now %d\n", s, refcount - 1);
}
return NULL;
}
| static const char* user_authority_to_str | ( | int | authority, |
| struct ast_str ** | res | ||
| ) | [static] |
Convert authority code to a list of options for a user. This will only display those authority codes that have an explicit match on authority.
Definition at line 1349 of file manager.c.
References ARRAY_LEN, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), permalias::num, and perms.
Referenced by handle_showmanager().
{
int i;
char *sep = "";
ast_str_reset(*res);
for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
if ((authority & perms[i].num) == perms[i].num) {
ast_str_append(res, 0, "%s%s", sep, perms[i].label);
sep = ",";
}
}
if (ast_str_strlen(*res) == 0) /* replace empty string with something sensible */
ast_str_append(res, 0, "<none>");
return ast_str_buffer(*res);
}
| static int whitefilter_cmp_fn | ( | void * | obj, |
| void * | arg, | ||
| void * | data, | ||
| int | flags | ||
| ) | [static] |
Definition at line 4712 of file manager.c.
References CMP_MATCH, CMP_STOP, and ast_frame::data.
Referenced by match_filter().
struct ast_event_sub* acl_change_event_subscription [static] |
Definition at line 1028 of file manager.c.
Referenced by acl_change_event_subscribe(), and acl_change_event_unsubscribe().
struct all_events all_events [static] |
int allowmultiplelogin = 1 [static] |
struct ast_threadstorage astman_append_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_astman_append_buf , .custom_init = NULL , } [static] |
Definition at line 2231 of file manager.c.
Referenced by astman_append(), and astman_send_error_va().
int authtimeout [static] |
int block_sockets [static] |
Definition at line 1026 of file manager.c.
Referenced by __init_manager(), handle_manager_show_settings(), and session_do().
int broken_events_action = 0 [static] |
struct channelvars channelvars [static] |
struct { ... } command_blacklist[] [static] |
Referenced by check_blacklist().
int displayconnects = 1 [static] |
Definition at line 1011 of file manager.c.
Referenced by __init_manager().
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 1024 of file manager.c.
Referenced by __init_manager(), auth_http_callback(), and manager_set_defaults().
int httptimeout = 60 [static] |
char* manager_channelvars [static] |
int manager_debug = 0 [static] |
int manager_enabled = 0 [static] |
Definition at line 1016 of file manager.c.
Referenced by check_manager_enabled().
struct ast_threadstorage manager_event_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_buf , .custom_init = NULL , } [static] |
Definition at line 5697 of file manager.c.
Referenced by __ast_manager_event_multichan().
struct ast_threadstorage manager_event_funcbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_funcbuf , .custom_init = NULL , } [static] |
Definition at line 5670 of file manager.c.
Referenced by append_channel_vars().
struct manager_hooks manager_hooks [static] |
Referenced by action_events(), authority_to_str(), get_perm(), strings_to_mask(), and user_authority_to_str().
int timestampevents [static] |
int unauth_sessions = 0 [static] |
Definition at line 1027 of file manager.c.
Referenced by action_login(), and session_do().
struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , } [static] |
Definition at line 2233 of file manager.c.
Referenced by action_userevent().
int webmanager_enabled = 0 [static] |
| const char* words[AST_MAX_CMD_LEN] |