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 |
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 | |
#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) |
send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. | |
Enumerations | |
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 } |
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 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 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_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 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) |
int | ast_hook_send_action (struct manager_custom_hook *hook, const char *msg) |
Registered hooks can call this function to invoke actions and they will receive responses through registered callback. | |
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), const char *synopsis, const char *description) |
Register a manager command with the manager interface. | |
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 (char *action) |
Unregister a registered manager command. | |
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) |
Get header from mananger transaction. | |
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_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) |
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. | |
static int | blackfilter_cmp_fn (void *obj, void *arg, void *data, int flags) |
static struct mansession_session * | build_mansession (struct sockaddr_in sin) |
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 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 | 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 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) |
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 int | manager_displayconnects (struct mansession_session *session) |
Get displayconnects config option. | |
static int | manager_modulecheck (struct mansession *s, const struct message *m) |
static int | manager_moduleload (struct mansession *s, const struct message *m) |
static int | manager_state_cb (char *context, char *exten, int state, void *data) |
static int | mansession_cmp_fn (void *obj, void *arg, int flags) |
static struct sockaddr_in * | mansession_encode_sin_local (const struct mansession *s, struct sockaddr_in *sin_local) |
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) |
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 int | whitefilter_cmp_fn (void *obj, void *arg, void *data, int flags) |
Variables | |
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 |
struct { | |
const char * words [AST_MAX_CMD_LEN] | |
} | command_blacklist [] |
static const int | DEFAULT_AUTHLIMIT = 50 |
static const int | DEFAULT_AUTHTIMEOUT = 30 |
static const int | DEFAULT_BLOCKSOCKETS = 0 |
static const int | DEFAULT_BROKENEVENTSACTION = 0 |
static const int | DEFAULT_DISPLAYCONNECTS = 1 |
static const int | DEFAULT_ENABLED = 0 |
static const int | DEFAULT_HTTPTIMEOUT = 60 |
static const int | DEFAULT_MANAGERDEBUG = 0 |
static const int | DEFAULT_TIMESTAMPEVENTS = 0 |
static const int | DEFAULT_WEBENABLED = 0 |
static int | displayconnects |
static char | global_realm [MAXHOSTNAMELEN] |
static int | httptimeout |
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 permalias | perms [] |
static struct ao2_container * | sessions = NULL |
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 int | webmanager_enabled = 0 |
#define ASTMAN_APPEND_BUF_INITSIZE 256 |
initial allocated size for the astman_append_buf
Definition at line 1989 of file manager.c.
Referenced by astman_append().
#define DEFAULT_REALM "asterisk" |
#define GET_HEADER_FIRST_MATCH 0 |
#define GET_HEADER_LAST_MATCH 1 |
#define GET_HEADER_SKIP_EMPTY 2 |
Definition at line 1752 of file manager.c.
Referenced by __astman_get_header(), and process_message().
#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.
Definition at line 919 of file manager.c.
Referenced by check_blacklist().
#define MSG_MOREDATA ((char *)astman_send_response) |
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 2030 of file manager.c.
Referenced by astman_send_response_full(), and astman_start_ack().
enum error_type |
Doxygen group
UNKNOWN_ACTION | |
UNKNOWN_CATEGORY | |
UNSPECIFIED_CATEGORY | |
UNSPECIFIED_ARGUMENT | |
FAILURE_ALLOCATION | |
FAILURE_NEWCAT | |
FAILURE_DELCAT | |
FAILURE_EMPTYCAT | |
FAILURE_UPDATE | |
FAILURE_DELETE | |
FAILURE_APPEND |
Definition at line 834 of file manager.c.
00834 { 00835 UNKNOWN_ACTION = 1, 00836 UNKNOWN_CATEGORY, 00837 UNSPECIFIED_CATEGORY, 00838 UNSPECIFIED_ARGUMENT, 00839 FAILURE_ALLOCATION, 00840 FAILURE_NEWCAT, 00841 FAILURE_DELCAT, 00842 FAILURE_EMPTYCAT, 00843 FAILURE_UPDATE, 00844 FAILURE_DELETE, 00845 FAILURE_APPEND 00846 };
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 5031 of file manager.c.
References ao2_container_count(), 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(), manager_custom_hook::helper, manager_debug, manager_event_buf, MANAGER_EVENT_BUF_INITSIZE, seq, timestampevents, and unref_mansession().
05033 { 05034 struct mansession_session *session; 05035 struct manager_custom_hook *hook; 05036 struct ast_str *auth = ast_str_alloca(80); 05037 const char *cat_str; 05038 va_list ap; 05039 struct timeval now; 05040 struct ast_str *buf; 05041 int i; 05042 05043 if (!(sessions && ao2_container_count(sessions)) && AST_RWLIST_EMPTY(&manager_hooks)) { 05044 return 0; 05045 } 05046 05047 if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) { 05048 return -1; 05049 } 05050 05051 cat_str = authority_to_str(category, &auth); 05052 ast_str_set(&buf, 0, 05053 "Event: %s\r\nPrivilege: %s\r\n", 05054 event, cat_str); 05055 05056 if (timestampevents) { 05057 now = ast_tvnow(); 05058 ast_str_append(&buf, 0, 05059 "Timestamp: %ld.%06lu\r\n", 05060 (long)now.tv_sec, (unsigned long) now.tv_usec); 05061 } 05062 if (manager_debug) { 05063 static int seq; 05064 ast_str_append(&buf, 0, 05065 "SequenceNumber: %d\r\n", 05066 ast_atomic_fetchadd_int(&seq, 1)); 05067 ast_str_append(&buf, 0, 05068 "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func); 05069 } 05070 05071 va_start(ap, fmt); 05072 ast_str_append_va(&buf, 0, fmt, ap); 05073 va_end(ap); 05074 for (i = 0; i < chancount; i++) { 05075 append_channel_vars(&buf, chans[i]); 05076 } 05077 05078 ast_str_append(&buf, 0, "\r\n"); 05079 05080 append_event(ast_str_buffer(buf), category); 05081 05082 /* Wake up any sleeping sessions */ 05083 if (sessions) { 05084 struct ao2_iterator i; 05085 i = ao2_iterator_init(sessions, 0); 05086 while ((session = ao2_iterator_next(&i))) { 05087 ao2_lock(session); 05088 if (session->waiting_thread != AST_PTHREADT_NULL) { 05089 pthread_kill(session->waiting_thread, SIGURG); 05090 } else { 05091 /* We have an event to process, but the mansession is 05092 * not waiting for it. We still need to indicate that there 05093 * is an event waiting so that get_input processes the pending 05094 * event instead of polling. 05095 */ 05096 session->pending_event = 1; 05097 } 05098 ao2_unlock(session); 05099 unref_mansession(session); 05100 } 05101 ao2_iterator_destroy(&i); 05102 } 05103 05104 if (!AST_RWLIST_EMPTY(&manager_hooks)) { 05105 AST_RWLIST_RDLOCK(&manager_hooks); 05106 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) { 05107 hook->helper(category, event, ast_str_buffer(buf)); 05108 } 05109 AST_RWLIST_UNLOCK(&manager_hooks); 05110 } 05111 05112 return 0; 05113 }
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.
Never returns NULL.
Definition at line 1767 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().
01768 { 01769 int x, l = strlen(var); 01770 const char *result = ""; 01771 01772 for (x = 0; x < m->hdrcount; x++) { 01773 const char *h = m->headers[x]; 01774 if (!strncasecmp(var, h, l) && h[l] == ':') { 01775 const char *value = h + l + 1; 01776 value = ast_skip_blanks(value); /* ignore leading spaces in the value */ 01777 /* found a potential candidate */ 01778 if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) { 01779 continue; /* not interesting */ 01780 } 01781 if (mode & GET_HEADER_LAST_MATCH) { 01782 result = value; /* record the last match so far */ 01783 } else { 01784 return value; 01785 } 01786 } 01787 } 01788 01789 return result; 01790 }
static void __init_astman_append_buf | ( | void | ) | [static] |
thread local buffer for astman_append
Definition at line 1985 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 int action_aocmessage | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3742 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().
03743 { 03744 const char *channel = astman_get_header(m, "Channel"); 03745 const char *pchannel = astman_get_header(m, "ChannelPrefix"); 03746 const char *msgtype = astman_get_header(m, "MsgType"); 03747 const char *chargetype = astman_get_header(m, "ChargeType"); 03748 const char *currencyname = astman_get_header(m, "CurrencyName"); 03749 const char *currencyamount = astman_get_header(m, "CurrencyAmount"); 03750 const char *mult = astman_get_header(m, "CurrencyMultiplier"); 03751 const char *totaltype = astman_get_header(m, "TotalType"); 03752 const char *aocbillingid = astman_get_header(m, "AOCBillingId"); 03753 const char *association_id= astman_get_header(m, "ChargingAssociationId"); 03754 const char *association_num = astman_get_header(m, "ChargingAssociationNumber"); 03755 const char *association_plan = astman_get_header(m, "ChargingAssociationPlan"); 03756 03757 enum ast_aoc_type _msgtype; 03758 enum ast_aoc_charge_type _chargetype; 03759 enum ast_aoc_currency_multiplier _mult = AST_AOC_MULT_ONE; 03760 enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL; 03761 enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA; 03762 unsigned int _currencyamount = 0; 03763 int _association_id = 0; 03764 unsigned int _association_plan = 0; 03765 struct ast_channel *chan = NULL; 03766 03767 struct ast_aoc_decoded *decoded = NULL; 03768 struct ast_aoc_encoded *encoded = NULL; 03769 size_t encoded_size = 0; 03770 03771 if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) { 03772 astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these."); 03773 goto aocmessage_cleanup; 03774 } 03775 03776 if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) { 03777 chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel)); 03778 } 03779 03780 if (!chan) { 03781 astman_send_error(s, m, "No such channel"); 03782 goto aocmessage_cleanup; 03783 } 03784 03785 if (ast_strlen_zero(msgtype) || (strcasecmp(msgtype, "d") && strcasecmp(msgtype, "e"))) { 03786 astman_send_error(s, m, "Invalid MsgType"); 03787 goto aocmessage_cleanup; 03788 } 03789 03790 if (ast_strlen_zero(chargetype)) { 03791 astman_send_error(s, m, "ChargeType not specified"); 03792 goto aocmessage_cleanup; 03793 } 03794 03795 _msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D; 03796 03797 if (!strcasecmp(chargetype, "NA")) { 03798 _chargetype = AST_AOC_CHARGE_NA; 03799 } else if (!strcasecmp(chargetype, "Free")) { 03800 _chargetype = AST_AOC_CHARGE_FREE; 03801 } else if (!strcasecmp(chargetype, "Currency")) { 03802 _chargetype = AST_AOC_CHARGE_CURRENCY; 03803 } else if (!strcasecmp(chargetype, "Unit")) { 03804 _chargetype = AST_AOC_CHARGE_UNIT; 03805 } else { 03806 astman_send_error(s, m, "Invalid ChargeType"); 03807 goto aocmessage_cleanup; 03808 } 03809 03810 if (_chargetype == AST_AOC_CHARGE_CURRENCY) { 03811 03812 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) { 03813 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency"); 03814 goto aocmessage_cleanup; 03815 } 03816 03817 if (ast_strlen_zero(mult)) { 03818 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency."); 03819 goto aocmessage_cleanup; 03820 } else if (!strcasecmp(mult, "onethousandth")) { 03821 _mult = AST_AOC_MULT_ONETHOUSANDTH; 03822 } else if (!strcasecmp(mult, "onehundredth")) { 03823 _mult = AST_AOC_MULT_ONEHUNDREDTH; 03824 } else if (!strcasecmp(mult, "onetenth")) { 03825 _mult = AST_AOC_MULT_ONETENTH; 03826 } else if (!strcasecmp(mult, "one")) { 03827 _mult = AST_AOC_MULT_ONE; 03828 } else if (!strcasecmp(mult, "ten")) { 03829 _mult = AST_AOC_MULT_TEN; 03830 } else if (!strcasecmp(mult, "hundred")) { 03831 _mult = AST_AOC_MULT_HUNDRED; 03832 } else if (!strcasecmp(mult, "thousand")) { 03833 _mult = AST_AOC_MULT_THOUSAND; 03834 } else { 03835 astman_send_error(s, m, "Invalid ChargeMultiplier"); 03836 goto aocmessage_cleanup; 03837 } 03838 } 03839 03840 /* create decoded object and start setting values */ 03841 if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) { 03842 astman_send_error(s, m, "Message Creation Failed"); 03843 goto aocmessage_cleanup; 03844 } 03845 03846 if (_msgtype == AST_AOC_D) { 03847 if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) { 03848 _totaltype = AST_AOC_SUBTOTAL; 03849 } 03850 03851 if (ast_strlen_zero(aocbillingid)) { 03852 /* ignore this is optional */ 03853 } else if (!strcasecmp(aocbillingid, "Normal")) { 03854 _billingid = AST_AOC_BILLING_NORMAL; 03855 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) { 03856 _billingid = AST_AOC_BILLING_REVERSE_CHARGE; 03857 } else if (!strcasecmp(aocbillingid, "CreditCard")) { 03858 _billingid = AST_AOC_BILLING_CREDIT_CARD; 03859 } else { 03860 astman_send_error(s, m, "Invalid AOC-D AOCBillingId"); 03861 goto aocmessage_cleanup; 03862 } 03863 } else { 03864 if (ast_strlen_zero(aocbillingid)) { 03865 /* ignore this is optional */ 03866 } else if (!strcasecmp(aocbillingid, "Normal")) { 03867 _billingid = AST_AOC_BILLING_NORMAL; 03868 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) { 03869 _billingid = AST_AOC_BILLING_REVERSE_CHARGE; 03870 } else if (!strcasecmp(aocbillingid, "CreditCard")) { 03871 _billingid = AST_AOC_BILLING_CREDIT_CARD; 03872 } else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) { 03873 _billingid = AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL; 03874 } else if (!strcasecmp(aocbillingid, "CallFwdBusy")) { 03875 _billingid = AST_AOC_BILLING_CALL_FWD_BUSY; 03876 } else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) { 03877 _billingid = AST_AOC_BILLING_CALL_FWD_NO_REPLY; 03878 } else if (!strcasecmp(aocbillingid, "CallDeflection")) { 03879 _billingid = AST_AOC_BILLING_CALL_DEFLECTION; 03880 } else if (!strcasecmp(aocbillingid, "CallTransfer")) { 03881 _billingid = AST_AOC_BILLING_CALL_TRANSFER; 03882 } else { 03883 astman_send_error(s, m, "Invalid AOC-E AOCBillingId"); 03884 goto aocmessage_cleanup; 03885 } 03886 03887 if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) { 03888 astman_send_error(s, m, "Invalid ChargingAssociationId"); 03889 goto aocmessage_cleanup; 03890 } 03891 if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) { 03892 astman_send_error(s, m, "Invalid ChargingAssociationPlan"); 03893 goto aocmessage_cleanup; 03894 } 03895 03896 if (_association_id) { 03897 ast_aoc_set_association_id(decoded, _association_id); 03898 } else if (!ast_strlen_zero(association_num)) { 03899 ast_aoc_set_association_number(decoded, association_num, _association_plan); 03900 } 03901 } 03902 03903 if (_chargetype == AST_AOC_CHARGE_CURRENCY) { 03904 ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname); 03905 } else if (_chargetype == AST_AOC_CHARGE_UNIT) { 03906 struct ast_aoc_unit_entry entry; 03907 int i; 03908 03909 /* multiple unit entries are possible, lets get them all */ 03910 for (i = 0; i < 32; i++) { 03911 if (aocmessage_get_unit_entry(m, &entry, i)) { 03912 break; /* that's the end then */ 03913 } 03914 03915 ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type); 03916 } 03917 03918 /* at least one unit entry is required */ 03919 if (!i) { 03920 astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit"); 03921 goto aocmessage_cleanup; 03922 } 03923 03924 } 03925 03926 ast_aoc_set_billing_id(decoded, _billingid); 03927 ast_aoc_set_total_type(decoded, _totaltype); 03928 03929 03930 if ((encoded = ast_aoc_encode(decoded, &encoded_size, NULL)) && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) { 03931 astman_send_ack(s, m, "AOC Message successfully queued on channel"); 03932 } else { 03933 astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel"); 03934 } 03935 03936 aocmessage_cleanup: 03937 03938 ast_aoc_destroy_decoded(decoded); 03939 ast_aoc_destroy_encoded(encoded); 03940 03941 if (chan) { 03942 chan = ast_channel_unref(chan); 03943 } 03944 return 0; 03945 }
static int action_atxfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3506 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, f, ast_frame_subclass::integer, name, pbx_builtin_setvar_helper(), and ast_frame::subclass.
Referenced by __init_manager().
03507 { 03508 const char *name = astman_get_header(m, "Channel"); 03509 const char *exten = astman_get_header(m, "Exten"); 03510 const char *context = astman_get_header(m, "Context"); 03511 struct ast_channel *chan = NULL; 03512 struct ast_call_feature *atxfer_feature = NULL; 03513 char *feature_code = NULL; 03514 03515 if (ast_strlen_zero(name)) { 03516 astman_send_error(s, m, "No channel specified"); 03517 return 0; 03518 } 03519 if (ast_strlen_zero(exten)) { 03520 astman_send_error(s, m, "No extension specified"); 03521 return 0; 03522 } 03523 03524 if (!(atxfer_feature = ast_find_call_feature("atxfer"))) { 03525 astman_send_error(s, m, "No attended transfer feature found"); 03526 return 0; 03527 } 03528 03529 if (!(chan = ast_channel_get_by_name(name))) { 03530 astman_send_error(s, m, "Channel specified does not exist"); 03531 return 0; 03532 } 03533 03534 if (!ast_strlen_zero(context)) { 03535 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context); 03536 } 03537 03538 for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) { 03539 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *feature_code }; 03540 ast_queue_frame(chan, &f); 03541 } 03542 03543 for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) { 03544 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *feature_code }; 03545 ast_queue_frame(chan, &f); 03546 } 03547 03548 chan = ast_channel_unref(chan); 03549 03550 astman_send_ack(s, m, "Atxfer successfully queued"); 03551 03552 return 0; 03553 }
static int action_challenge | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3069 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().
03070 { 03071 const char *authtype = astman_get_header(m, "AuthType"); 03072 03073 if (!strcasecmp(authtype, "MD5")) { 03074 if (ast_strlen_zero(s->session->challenge)) { 03075 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random()); 03076 } 03077 mansession_lock(s); 03078 astman_start_ack(s, m); 03079 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge); 03080 mansession_unlock(s); 03081 } else { 03082 astman_send_error(s, m, "Must specify AuthType"); 03083 } 03084 return 0; 03085 }
static int action_command | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager command "command" - execute CLI command.
Definition at line 3591 of file manager.c.
References ast_calloc, ast_cli_command, ast_free, ast_log(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), check_blacklist(), errno, LOG_WARNING, S_OR, and term_strip().
Referenced by __init_manager().
03592 { 03593 const char *cmd = astman_get_header(m, "Command"); 03594 const char *id = astman_get_header(m, "ActionID"); 03595 char *buf, *final_buf; 03596 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 03597 int fd; 03598 off_t l; 03599 03600 if (ast_strlen_zero(cmd)) { 03601 astman_send_error(s, m, "No command provided"); 03602 return 0; 03603 } 03604 03605 if (check_blacklist(cmd)) { 03606 astman_send_error(s, m, "Command blacklisted"); 03607 return 0; 03608 } 03609 03610 fd = mkstemp(template); 03611 03612 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 03613 if (!ast_strlen_zero(id)) { 03614 astman_append(s, "ActionID: %s\r\n", id); 03615 } 03616 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 03617 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 03618 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 03619 03620 /* This has a potential to overflow the stack. Hence, use the heap. */ 03621 buf = ast_calloc(1, l + 1); 03622 final_buf = ast_calloc(1, l + 1); 03623 if (buf) { 03624 lseek(fd, 0, SEEK_SET); 03625 if (read(fd, buf, l) < 0) { 03626 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 03627 } 03628 buf[l] = '\0'; 03629 if (final_buf) { 03630 term_strip(final_buf, buf, l); 03631 final_buf[l] = '\0'; 03632 } 03633 astman_append(s, "%s", S_OR(final_buf, buf)); 03634 ast_free(buf); 03635 } 03636 close(fd); 03637 unlink(template); 03638 astman_append(s, "--END COMMAND--\r\n\r\n"); 03639 if (final_buf) { 03640 ast_free(final_buf); 03641 } 03642 return 0; 03643 }
static int action_coresettings | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core settings information.
Definition at line 4286 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().
04287 { 04288 const char *actionid = astman_get_header(m, "ActionID"); 04289 char idText[150]; 04290 04291 if (!ast_strlen_zero(actionid)) { 04292 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 04293 } else { 04294 idText[0] = '\0'; 04295 } 04296 04297 astman_append(s, "Response: Success\r\n" 04298 "%s" 04299 "AMIversion: %s\r\n" 04300 "AsteriskVersion: %s\r\n" 04301 "SystemName: %s\r\n" 04302 "CoreMaxCalls: %d\r\n" 04303 "CoreMaxLoadAvg: %f\r\n" 04304 "CoreRunUser: %s\r\n" 04305 "CoreRunGroup: %s\r\n" 04306 "CoreMaxFilehandles: %d\r\n" 04307 "CoreRealTimeEnabled: %s\r\n" 04308 "CoreCDRenabled: %s\r\n" 04309 "CoreHTTPenabled: %s\r\n" 04310 "\r\n", 04311 idText, 04312 AMI_VERSION, 04313 ast_get_version(), 04314 ast_config_AST_SYSTEM_NAME, 04315 option_maxcalls, 04316 option_maxload, 04317 ast_config_AST_RUN_USER, 04318 ast_config_AST_RUN_GROUP, 04319 option_maxfiles, 04320 AST_CLI_YESNO(ast_realtime_enabled()), 04321 AST_CLI_YESNO(check_cdr_enabled()), 04322 AST_CLI_YESNO(check_webmanager_enabled()) 04323 ); 04324 return 0; 04325 }
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 4383 of file manager.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::appl, ast_bridged_channel(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, 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(), ast_channel::caller, ast_channel::cdr, ast_channel::connected, ast_channel::context, ast_channel::data, ast_channel::exten, ast_party_connected_line::id, ast_party_caller::id, ast_party_id::name, ast_channel::name, ast_party_id::number, ast_channel::priority, S_COR, S_OR, ast_cdr::start, ast_party_name::str, ast_party_number::str, ast_channel::uniqueid, ast_party_name::valid, and ast_party_number::valid.
Referenced by __init_manager().
04384 { 04385 const char *actionid = astman_get_header(m, "ActionID"); 04386 char idText[256]; 04387 struct ast_channel *c = NULL; 04388 int numchans = 0; 04389 int duration, durh, durm, durs; 04390 struct ast_channel_iterator *iter; 04391 04392 if (!ast_strlen_zero(actionid)) { 04393 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 04394 } else { 04395 idText[0] = '\0'; 04396 } 04397 04398 if (!(iter = ast_channel_iterator_all_new())) { 04399 astman_send_error(s, m, "Memory Allocation Failure"); 04400 return 1; 04401 } 04402 04403 astman_send_listack(s, m, "Channels will follow", "start"); 04404 04405 for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) { 04406 struct ast_channel *bc; 04407 char durbuf[10] = ""; 04408 04409 ast_channel_lock(c); 04410 04411 bc = ast_bridged_channel(c); 04412 if (c->cdr && !ast_tvzero(c->cdr->start)) { 04413 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 04414 durh = duration / 3600; 04415 durm = (duration % 3600) / 60; 04416 durs = duration % 60; 04417 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 04418 } 04419 04420 astman_append(s, 04421 "Event: CoreShowChannel\r\n" 04422 "%s" 04423 "Channel: %s\r\n" 04424 "UniqueID: %s\r\n" 04425 "Context: %s\r\n" 04426 "Extension: %s\r\n" 04427 "Priority: %d\r\n" 04428 "ChannelState: %d\r\n" 04429 "ChannelStateDesc: %s\r\n" 04430 "Application: %s\r\n" 04431 "ApplicationData: %s\r\n" 04432 "CallerIDnum: %s\r\n" 04433 "CallerIDname: %s\r\n" 04434 "ConnectedLineNum: %s\r\n" 04435 "ConnectedLineName: %s\r\n" 04436 "Duration: %s\r\n" 04437 "AccountCode: %s\r\n" 04438 "BridgedChannel: %s\r\n" 04439 "BridgedUniqueID: %s\r\n" 04440 "\r\n", idText, c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, 04441 ast_state2str(c->_state), c->appl ? c->appl : "", c->data ? S_OR(c->data, "") : "", 04442 S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""), 04443 S_COR(c->caller.id.name.valid, c->caller.id.name.str, ""), 04444 S_COR(c->connected.id.number.valid, c->connected.id.number.str, ""), 04445 S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""), 04446 durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : ""); 04447 04448 ast_channel_unlock(c); 04449 04450 numchans++; 04451 } 04452 04453 astman_append(s, 04454 "Event: CoreShowChannelsComplete\r\n" 04455 "EventList: Complete\r\n" 04456 "ListItems: %d\r\n" 04457 "%s" 04458 "\r\n", numchans, idText); 04459 04460 ast_channel_iterator_destroy(iter); 04461 04462 return 0; 04463 }
static int action_corestatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core status information.
Definition at line 4328 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().
04329 { 04330 const char *actionid = astman_get_header(m, "ActionID"); 04331 char idText[150]; 04332 char startuptime[150], startupdate[150]; 04333 char reloadtime[150], reloaddate[150]; 04334 struct ast_tm tm; 04335 04336 if (!ast_strlen_zero(actionid)) { 04337 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 04338 } else { 04339 idText[0] = '\0'; 04340 } 04341 04342 ast_localtime(&ast_startuptime, &tm, NULL); 04343 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm); 04344 ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm); 04345 ast_localtime(&ast_lastreloadtime, &tm, NULL); 04346 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm); 04347 ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm); 04348 04349 astman_append(s, "Response: Success\r\n" 04350 "%s" 04351 "CoreStartupDate: %s\r\n" 04352 "CoreStartupTime: %s\r\n" 04353 "CoreReloadDate: %s\r\n" 04354 "CoreReloadTime: %s\r\n" 04355 "CoreCurrentCalls: %d\r\n" 04356 "\r\n", 04357 idText, 04358 startupdate, 04359 startuptime, 04360 reloaddate, 04361 reloadtime, 04362 ast_active_channels() 04363 ); 04364 return 0; 04365 }
static int action_createconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2845 of file manager.c.
References ast_config_AST_CONFIG_DIR, AST_FILE_MODE, 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().
02846 { 02847 int fd; 02848 const char *fn = astman_get_header(m, "Filename"); 02849 struct ast_str *filepath = ast_str_alloca(PATH_MAX); 02850 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR); 02851 ast_str_append(&filepath, 0, "%s", fn); 02852 02853 if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) { 02854 close(fd); 02855 astman_send_ack(s, m, "New configuration file created successfully"); 02856 } else { 02857 astman_send_error(s, m, strerror(errno)); 02858 } 02859 02860 return 0; 02861 }
static void action_destroy | ( | void * | obj | ) | [static] |
Definition at line 5201 of file manager.c.
References ast_string_field_free_memory.
Referenced by ast_manager_register2().
05202 { 05203 struct manager_action *doomed = obj; 05204 05205 if (doomed->synopsis) { 05206 /* The string fields were initialized. */ 05207 ast_string_field_free_memory(doomed); 05208 } 05209 }
static int action_events | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2988 of file manager.c.
References ARRAY_LEN, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), broken_events_action, perms, and set_eventmask().
Referenced by __init_manager().
02989 { 02990 const char *mask = astman_get_header(m, "EventMask"); 02991 int res, x; 02992 const char *id = astman_get_header(m, "ActionID"); 02993 char id_text[256]; 02994 02995 if (!ast_strlen_zero(id)) { 02996 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id); 02997 } else { 02998 id_text[0] = '\0'; 02999 } 03000 03001 res = set_eventmask(s, mask); 03002 if (broken_events_action) { 03003 /* if this option is set we should not return a response on 03004 * error, or when all events are set */ 03005 03006 if (res > 0) { 03007 for (x = 0; x < ARRAY_LEN(perms); x++) { 03008 if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) { 03009 return 0; 03010 } 03011 } 03012 astman_append(s, "Response: Success\r\n%s" 03013 "Events: On\r\n\r\n", id_text); 03014 } else if (res == 0) 03015 astman_append(s, "Response: Success\r\n%s" 03016 "Events: Off\r\n\r\n", id_text); 03017 return 0; 03018 } 03019 03020 if (res > 0) 03021 astman_append(s, "Response: Success\r\n%s" 03022 "Events: On\r\n\r\n", id_text); 03023 else if (res == 0) 03024 astman_append(s, "Response: Success\r\n%s" 03025 "Events: Off\r\n\r\n", id_text); 03026 else 03027 astman_send_error(s, m, "Invalid event mask"); 03028 03029 return 0; 03030 }
static int action_extensionstate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4124 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().
04125 { 04126 const char *exten = astman_get_header(m, "Exten"); 04127 const char *context = astman_get_header(m, "Context"); 04128 char hint[256] = ""; 04129 int status; 04130 if (ast_strlen_zero(exten)) { 04131 astman_send_error(s, m, "Extension not specified"); 04132 return 0; 04133 } 04134 if (ast_strlen_zero(context)) { 04135 context = "default"; 04136 } 04137 status = ast_extension_state(NULL, context, exten); 04138 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 04139 astman_start_ack(s, m); 04140 astman_append(s, "Message: Extension Status\r\n" 04141 "Exten: %s\r\n" 04142 "Context: %s\r\n" 04143 "Hint: %s\r\n" 04144 "Status: %d\r\n\r\n", 04145 exten, context, hint, status); 04146 return 0; 04147 }
static struct manager_action* action_find | ( | const char * | name | ) | [static] |
Definition at line 1059 of file manager.c.
References manager_action::action, ao2_t_ref, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and manager_action::list.
Referenced by process_message().
01060 { 01061 struct manager_action *act; 01062 01063 AST_RWLIST_RDLOCK(&actions); 01064 AST_RWLIST_TRAVERSE(&actions, act, list) { 01065 if (!strcasecmp(name, act->action)) { 01066 ao2_t_ref(act, +1, "found action object"); 01067 break; 01068 } 01069 } 01070 AST_RWLIST_UNLOCK(&actions); 01071 01072 return act; 01073 }
static int action_getconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2463 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(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __init_manager().
02464 { 02465 struct ast_config *cfg; 02466 const char *fn = astman_get_header(m, "Filename"); 02467 const char *category = astman_get_header(m, "Category"); 02468 int catcount = 0; 02469 int lineno = 0; 02470 char *cur_category = NULL; 02471 struct ast_variable *v; 02472 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 02473 02474 if (ast_strlen_zero(fn)) { 02475 astman_send_error(s, m, "Filename not specified"); 02476 return 0; 02477 } 02478 cfg = ast_config_load2(fn, "manager", config_flags); 02479 if (cfg == CONFIG_STATUS_FILEMISSING) { 02480 astman_send_error(s, m, "Config file not found"); 02481 return 0; 02482 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02483 astman_send_error(s, m, "Config file has invalid format"); 02484 return 0; 02485 } 02486 02487 astman_start_ack(s, m); 02488 while ((cur_category = ast_category_browse(cfg, cur_category))) { 02489 if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) { 02490 lineno = 0; 02491 astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category); 02492 for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) { 02493 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 02494 } 02495 catcount++; 02496 } 02497 } 02498 if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */ 02499 astman_append(s, "No categories found\r\n"); 02500 } 02501 ast_config_destroy(cfg); 02502 astman_append(s, "\r\n"); 02503 02504 return 0; 02505 }
static int action_getconfigjson | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2573 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(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, config_flags, CONFIG_STATUS_FILEINVALID, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __init_manager().
02574 { 02575 struct ast_config *cfg; 02576 const char *fn = astman_get_header(m, "Filename"); 02577 char *category = NULL; 02578 struct ast_variable *v; 02579 int comma1 = 0; 02580 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 02581 02582 if (ast_strlen_zero(fn)) { 02583 astman_send_error(s, m, "Filename not specified"); 02584 return 0; 02585 } 02586 02587 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 02588 astman_send_error(s, m, "Config file not found"); 02589 return 0; 02590 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02591 astman_send_error(s, m, "Config file has invalid format"); 02592 return 0; 02593 } 02594 02595 astman_start_ack(s, m); 02596 astman_append(s, "JSON: {"); 02597 while ((category = ast_category_browse(cfg, category))) { 02598 int comma2 = 0; 02599 02600 astman_append(s, "%s\"", comma1 ? "," : ""); 02601 astman_append_json(s, category); 02602 astman_append(s, "\":["); 02603 comma1 = 1; 02604 for (v = ast_variable_browse(cfg, category); v; v = v->next) { 02605 astman_append(s, "%s\"", comma2 ? "," : ""); 02606 astman_append_json(s, v->name); 02607 astman_append(s, "\":\""); 02608 astman_append_json(s, v->value); 02609 astman_append(s, "\""); 02610 comma2 = 1; 02611 } 02612 astman_append(s, "]"); 02613 } 02614 astman_append(s, "}\r\n\r\n"); 02615 02616 ast_config_destroy(cfg); 02617 02618 return 0; 02619 }
static int action_getvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3163 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(), LOG_ERROR, name, pbx_retrieve_variable(), and S_OR.
Referenced by __init_manager().
03164 { 03165 struct ast_channel *c = NULL; 03166 const char *name = astman_get_header(m, "Channel"); 03167 const char *varname = astman_get_header(m, "Variable"); 03168 char *varval; 03169 char workspace[1024]; 03170 03171 if (ast_strlen_zero(varname)) { 03172 astman_send_error(s, m, "No variable specified"); 03173 return 0; 03174 } 03175 03176 if (!ast_strlen_zero(name)) { 03177 if (!(c = ast_channel_get_by_name(name))) { 03178 astman_send_error(s, m, "No such channel"); 03179 return 0; 03180 } 03181 } 03182 03183 workspace[0] = '\0'; 03184 if (varname[strlen(varname) - 1] == ')') { 03185 if (!c) { 03186 c = ast_dummy_channel_alloc(); 03187 if (c) { 03188 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 03189 } else 03190 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 03191 } else { 03192 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 03193 } 03194 varval = workspace; 03195 } else { 03196 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 03197 } 03198 03199 if (c) { 03200 c = ast_channel_unref(c); 03201 } 03202 03203 astman_start_ack(s, m); 03204 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, "")); 03205 03206 return 0; 03207 }
static int action_hangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3087 of file manager.c.
References ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_debug, ast_log(), AST_SOFTHANGUP_EXPLICIT, ast_softhangup_nolock(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), cause, ast_channel::hangupcause, LOG_NOTICE, ast_channel::name, and name.
Referenced by __init_manager().
03088 { 03089 struct ast_channel *c = NULL; 03090 int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */ 03091 const char *name = astman_get_header(m, "Channel"); 03092 const char *cause = astman_get_header(m, "Cause"); 03093 03094 if (ast_strlen_zero(name)) { 03095 astman_send_error(s, m, "No channel specified"); 03096 return 0; 03097 } 03098 03099 if (!ast_strlen_zero(cause)) { 03100 char *endptr; 03101 causecode = strtol(cause, &endptr, 10); 03102 if (causecode < 0 || causecode > 127 || *endptr != '\0') { 03103 ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause); 03104 /* keep going, better to hangup without cause than to not hang up at all */ 03105 causecode = 0; /* do not set channel's hangupcause */ 03106 } 03107 } 03108 03109 if (!(c = ast_channel_get_by_name(name))) { 03110 astman_send_error(s, m, "No such channel"); 03111 return 0; 03112 } 03113 03114 ast_channel_lock(c); 03115 if (causecode > 0) { 03116 ast_debug(1, "Setting hangupcause of channel %s to %d (is %d now)\n", 03117 c->name, causecode, c->hangupcause); 03118 c->hangupcause = causecode; 03119 } 03120 ast_softhangup_nolock(c, AST_SOFTHANGUP_EXPLICIT); 03121 ast_channel_unlock(c); 03122 03123 c = ast_channel_unref(c); 03124 03125 astman_send_ack(s, m, "Channel Hungup"); 03126 03127 return 0; 03128 }
static int action_listcategories | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2507 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(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, config_flags, and CONFIG_STATUS_FILEINVALID.
Referenced by __init_manager().
02508 { 02509 struct ast_config *cfg; 02510 const char *fn = astman_get_header(m, "Filename"); 02511 char *category = NULL; 02512 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 02513 int catcount = 0; 02514 02515 if (ast_strlen_zero(fn)) { 02516 astman_send_error(s, m, "Filename not specified"); 02517 return 0; 02518 } 02519 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 02520 astman_send_error(s, m, "Config file not found"); 02521 return 0; 02522 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02523 astman_send_error(s, m, "Config file has invalid format"); 02524 return 0; 02525 } 02526 astman_start_ack(s, m); 02527 while ((category = ast_category_browse(cfg, category))) { 02528 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 02529 catcount++; 02530 } 02531 if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */ 02532 astman_append(s, "Error: no categories found\r\n"); 02533 } 02534 ast_config_destroy(cfg); 02535 astman_append(s, "\r\n"); 02536 02537 return 0; 02538 }
static int action_listcommands | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2969 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, and mansession_session::writeperm.
Referenced by __init_manager().
02970 { 02971 struct manager_action *cur; 02972 struct ast_str *temp = ast_str_alloca(256); 02973 02974 astman_start_ack(s, m); 02975 AST_RWLIST_RDLOCK(&actions); 02976 AST_RWLIST_TRAVERSE(&actions, cur, list) { 02977 if ((s->session->writeperm & cur->authority) || cur->authority == 0) { 02978 astman_append(s, "%s: %s (Priv: %s)\r\n", 02979 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp)); 02980 } 02981 } 02982 AST_RWLIST_UNLOCK(&actions); 02983 astman_append(s, "\r\n"); 02984 02985 return 0; 02986 }
static int action_login | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3038 of file manager.c.
References ast_atomic_fetchadd_int(), ast_inet_ntoa(), AST_OPT_FLAG_FULLY_BOOTED, ast_options, 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, mansession_session::sin, unauth_sessions, and mansession_session::username.
Referenced by __init_manager().
03039 { 03040 03041 /* still authenticated - don't process again */ 03042 if (s->session->authenticated) { 03043 astman_send_ack(s, m, "Already authenticated"); 03044 return 0; 03045 } 03046 03047 if (authenticate(s, m)) { 03048 sleep(1); 03049 astman_send_error(s, m, "Authentication failed"); 03050 return -1; 03051 } 03052 s->session->authenticated = 1; 03053 ast_atomic_fetchadd_int(&unauth_sessions, -1); 03054 if (manager_displayconnects(s->session)) { 03055 ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_inet_ntoa(s->session->sin.sin_addr)); 03056 } 03057 astman_send_ack(s, m, "Authentication accepted"); 03058 if ((s->session->send_events & EVENT_FLAG_SYSTEM) 03059 && ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) { 03060 struct ast_str *auth = ast_str_alloca(80); 03061 const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth); 03062 astman_append(s, "Event: FullyBooted\r\n" 03063 "Privilege: %s\r\n" 03064 "Status: Fully Booted\r\n\r\n", cat_str); 03065 } 03066 return 0; 03067 }
static int action_logoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3032 of file manager.c.
References astman_send_response().
Referenced by __init_manager().
03033 { 03034 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 03035 return -1; 03036 }
static int action_mailboxcount | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4103 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().
04104 { 04105 const char *mailbox = astman_get_header(m, "Mailbox"); 04106 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;; 04107 04108 if (ast_strlen_zero(mailbox)) { 04109 astman_send_error(s, m, "Mailbox not specified"); 04110 return 0; 04111 } 04112 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs); 04113 astman_start_ack(s, m); 04114 astman_append(s, "Message: Mailbox Message Count\r\n" 04115 "Mailbox: %s\r\n" 04116 "UrgMessages: %d\r\n" 04117 "NewMessages: %d\r\n" 04118 "OldMessages: %d\r\n" 04119 "\r\n", 04120 mailbox, urgentmsgs, newmsgs, oldmsgs); 04121 return 0; 04122 }
static int action_mailboxstatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4086 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().
04087 { 04088 const char *mailbox = astman_get_header(m, "Mailbox"); 04089 int ret; 04090 04091 if (ast_strlen_zero(mailbox)) { 04092 astman_send_error(s, m, "Mailbox not specified"); 04093 return 0; 04094 } 04095 ret = ast_app_has_voicemail(mailbox, NULL); 04096 astman_start_ack(s, m); 04097 astman_append(s, "Message: Mailbox Status\r\n" 04098 "Mailbox: %s\r\n" 04099 "Waiting: %d\r\n\r\n", mailbox, ret); 04100 return 0; 04101 }
static int action_originate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3947 of file manager.c.
References app, ast_callerid_parse(), ast_calloc, ast_copy_string(), ast_findlabel_extension(), 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_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_true(), ast_variables_destroy(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), cid_name, cid_num, context, EVENT_FLAG_SYSTEM, exten, fast_originate(), name, mansession::session, strcasestr(), and mansession_session::writeperm.
Referenced by __init_manager().
03948 { 03949 const char *name = astman_get_header(m, "Channel"); 03950 const char *exten = astman_get_header(m, "Exten"); 03951 const char *context = astman_get_header(m, "Context"); 03952 const char *priority = astman_get_header(m, "Priority"); 03953 const char *timeout = astman_get_header(m, "Timeout"); 03954 const char *callerid = astman_get_header(m, "CallerID"); 03955 const char *account = astman_get_header(m, "Account"); 03956 const char *app = astman_get_header(m, "Application"); 03957 const char *appdata = astman_get_header(m, "Data"); 03958 const char *async = astman_get_header(m, "Async"); 03959 const char *id = astman_get_header(m, "ActionID"); 03960 const char *codecs = astman_get_header(m, "Codecs"); 03961 struct ast_variable *vars; 03962 char *tech, *data; 03963 char *l = NULL, *n = NULL; 03964 int pi = 0; 03965 int res; 03966 int to = 30000; 03967 int reason = 0; 03968 char tmp[256]; 03969 char tmp2[256]; 03970 format_t format = AST_FORMAT_SLINEAR; 03971 03972 pthread_t th; 03973 if (ast_strlen_zero(name)) { 03974 astman_send_error(s, m, "Channel not specified"); 03975 return 0; 03976 } 03977 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 03978 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 03979 astman_send_error(s, m, "Invalid priority"); 03980 return 0; 03981 } 03982 } 03983 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) { 03984 astman_send_error(s, m, "Invalid timeout"); 03985 return 0; 03986 } 03987 ast_copy_string(tmp, name, sizeof(tmp)); 03988 tech = tmp; 03989 data = strchr(tmp, '/'); 03990 if (!data) { 03991 astman_send_error(s, m, "Invalid channel"); 03992 return 0; 03993 } 03994 *data++ = '\0'; 03995 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 03996 ast_callerid_parse(tmp2, &n, &l); 03997 if (n) { 03998 if (ast_strlen_zero(n)) { 03999 n = NULL; 04000 } 04001 } 04002 if (l) { 04003 ast_shrink_phone_number(l); 04004 if (ast_strlen_zero(l)) { 04005 l = NULL; 04006 } 04007 } 04008 if (!ast_strlen_zero(codecs)) { 04009 format = 0; 04010 ast_parse_allow_disallow(NULL, &format, codecs, 1); 04011 } 04012 if (!ast_strlen_zero(app)) { 04013 /* To run the System application (or anything else that goes to 04014 * shell), you must have the additional System privilege */ 04015 if (!(s->session->writeperm & EVENT_FLAG_SYSTEM) 04016 && ( 04017 strcasestr(app, "system") || /* System(rm -rf /) 04018 TrySystem(rm -rf /) */ 04019 strcasestr(app, "exec") || /* Exec(System(rm -rf /)) 04020 TryExec(System(rm -rf /)) */ 04021 strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /) 04022 EAGI(/bin/rm,-rf /) */ 04023 strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */ 04024 strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ 04025 )) { 04026 astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have."); 04027 return 0; 04028 } 04029 } 04030 /* Allocate requested channel variables */ 04031 vars = astman_get_variables(m); 04032 04033 if (ast_true(async)) { 04034 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 04035 if (!fast || ast_string_field_init(fast, 252)) { 04036 if (fast) { 04037 ast_free(fast); 04038 } 04039 res = -1; 04040 } else { 04041 if (!ast_strlen_zero(id)) { 04042 ast_string_field_build(fast, idtext, "ActionID: %s", id); 04043 } 04044 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 04045 ast_copy_string(fast->data, data, sizeof(fast->data)); 04046 ast_string_field_set(fast, app, app); 04047 ast_string_field_set(fast, appdata, appdata); 04048 ast_string_field_set(fast, cid_num, l); 04049 ast_string_field_set(fast, cid_name, n); 04050 ast_string_field_set(fast, context, context); 04051 ast_string_field_set(fast, exten, exten); 04052 ast_string_field_set(fast, account, account); 04053 fast->vars = vars; 04054 fast->format = format; 04055 fast->timeout = to; 04056 fast->priority = pi; 04057 if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) { 04058 ast_string_field_free_memory(fast); 04059 ast_free(fast); 04060 res = -1; 04061 } else { 04062 res = 0; 04063 } 04064 } 04065 } else if (!ast_strlen_zero(app)) { 04066 res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 04067 } else { 04068 if (exten && context && pi) { 04069 res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 04070 } else { 04071 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 04072 if (vars) { 04073 ast_variables_destroy(vars); 04074 } 04075 return 0; 04076 } 04077 } 04078 if (!res) { 04079 astman_send_ack(s, m, "Originate successfully queued"); 04080 } else { 04081 astman_send_error(s, m, "Originate failed"); 04082 } 04083 return 0; 04084 }
static int action_ping | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2445 of file manager.c.
References ast_strlen_zero(), ast_tvnow(), astman_append(), and astman_get_header().
Referenced by __init_manager().
02446 { 02447 const char *actionid = astman_get_header(m, "ActionID"); 02448 struct timeval now = ast_tvnow(); 02449 02450 astman_append(s, "Response: Success\r\n"); 02451 if (!ast_strlen_zero(actionid)){ 02452 astman_append(s, "ActionID: %s\r\n", actionid); 02453 } 02454 astman_append( 02455 s, 02456 "Ping: Pong\r\n" 02457 "Timestamp: %ld.%06lu\r\n" 02458 "\r\n", 02459 (long) now.tv_sec, (unsigned long) now.tv_usec); 02460 return 0; 02461 }
static int action_redirect | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_redirect: The redirect manager command
Definition at line 3403 of file manager.c.
References ast_async_goto(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_check_hangup_locked(), ast_findlabel_extension(), AST_FLAG_BRIDGE_HANGUP_DONT, ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, name, ast_channel::pbx, and ast_channel::priority.
Referenced by __init_manager().
03404 { 03405 const char *name = astman_get_header(m, "Channel"); 03406 const char *name2 = astman_get_header(m, "ExtraChannel"); 03407 const char *exten = astman_get_header(m, "Exten"); 03408 const char *exten2 = astman_get_header(m, "ExtraExten"); 03409 const char *context = astman_get_header(m, "Context"); 03410 const char *context2 = astman_get_header(m, "ExtraContext"); 03411 const char *priority = astman_get_header(m, "Priority"); 03412 const char *priority2 = astman_get_header(m, "ExtraPriority"); 03413 struct ast_channel *chan, *chan2 = NULL; 03414 int pi, pi2 = 0; 03415 int res; 03416 03417 if (ast_strlen_zero(name)) { 03418 astman_send_error(s, m, "Channel not specified"); 03419 return 0; 03420 } 03421 03422 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 03423 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 03424 astman_send_error(s, m, "Invalid priority"); 03425 return 0; 03426 } 03427 } 03428 03429 if (!ast_strlen_zero(priority2) && (sscanf(priority2, "%30d", &pi2) != 1)) { 03430 if ((pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL)) < 1) { 03431 astman_send_error(s, m, "Invalid ExtraPriority"); 03432 return 0; 03433 } 03434 } 03435 03436 if (!(chan = ast_channel_get_by_name(name))) { 03437 char buf[256]; 03438 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 03439 astman_send_error(s, m, buf); 03440 return 0; 03441 } 03442 03443 if (ast_check_hangup_locked(chan)) { 03444 astman_send_error(s, m, "Redirect failed, channel not up."); 03445 chan = ast_channel_unref(chan); 03446 return 0; 03447 } 03448 03449 if (!ast_strlen_zero(name2)) { 03450 chan2 = ast_channel_get_by_name(name2); 03451 } 03452 03453 if (chan2 && ast_check_hangup_locked(chan2)) { 03454 astman_send_error(s, m, "Redirect failed, extra channel not up."); 03455 chan = ast_channel_unref(chan); 03456 chan2 = ast_channel_unref(chan2); 03457 return 0; 03458 } 03459 03460 if (chan->pbx) { 03461 ast_channel_lock(chan); 03462 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 03463 ast_channel_unlock(chan); 03464 } 03465 03466 res = ast_async_goto(chan, context, exten, pi); 03467 if (!res) { 03468 if (!ast_strlen_zero(name2)) { 03469 if (chan2) { 03470 if (chan2->pbx) { 03471 ast_channel_lock(chan2); 03472 ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 03473 ast_channel_unlock(chan2); 03474 } 03475 if (context2) { 03476 res = ast_async_goto(chan2, context2, exten2, pi2); 03477 } else { 03478 res = ast_async_goto(chan2, context, exten, pi); 03479 } 03480 } else { 03481 res = -1; 03482 } 03483 if (!res) { 03484 astman_send_ack(s, m, "Dual Redirect successful"); 03485 } else { 03486 astman_send_error(s, m, "Secondary redirect failed"); 03487 } 03488 } else { 03489 astman_send_ack(s, m, "Redirect successful"); 03490 } 03491 } else { 03492 astman_send_error(s, m, "Redirect failed"); 03493 } 03494 03495 if (chan) { 03496 chan = ast_channel_unref(chan); 03497 } 03498 03499 if (chan2) { 03500 chan2 = ast_channel_unref(chan2); 03501 } 03502 03503 return 0; 03504 }
static int action_reload | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Send a reload event.
Definition at line 4368 of file manager.c.
References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.
Referenced by __init_manager().
04369 { 04370 const char *module = astman_get_header(m, "Module"); 04371 int res = ast_module_reload(S_OR(module, NULL)); 04372 04373 if (res == 2) { 04374 astman_send_ack(s, m, "Module Reloaded"); 04375 } else { 04376 astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload"); 04377 } 04378 return 0; 04379 }
static int action_sendtext | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3368 of file manager.c.
References ast_channel_get_by_name(), ast_channel_unref, ast_sendtext(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and name.
Referenced by __init_manager().
03369 { 03370 struct ast_channel *c = NULL; 03371 const char *name = astman_get_header(m, "Channel"); 03372 const char *textmsg = astman_get_header(m, "Message"); 03373 int res = 0; 03374 03375 if (ast_strlen_zero(name)) { 03376 astman_send_error(s, m, "No channel specified"); 03377 return 0; 03378 } 03379 03380 if (ast_strlen_zero(textmsg)) { 03381 astman_send_error(s, m, "No Message specified"); 03382 return 0; 03383 } 03384 03385 if (!(c = ast_channel_get_by_name(name))) { 03386 astman_send_error(s, m, "No such channel"); 03387 return 0; 03388 } 03389 03390 res = ast_sendtext(c, textmsg); 03391 c = ast_channel_unref(c); 03392 03393 if (res >= 0) { 03394 astman_send_ack(s, m, "Success"); 03395 } else { 03396 astman_send_error(s, m, "Failure"); 03397 } 03398 03399 return res; 03400 }
static int action_setvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3130 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(), name, pbx_builtin_setvar_helper(), and S_OR.
Referenced by __init_manager().
03131 { 03132 struct ast_channel *c = NULL; 03133 const char *name = astman_get_header(m, "Channel"); 03134 const char *varname = astman_get_header(m, "Variable"); 03135 const char *varval = astman_get_header(m, "Value"); 03136 int res = 0; 03137 03138 if (ast_strlen_zero(varname)) { 03139 astman_send_error(s, m, "No variable specified"); 03140 return 0; 03141 } 03142 03143 if (!ast_strlen_zero(name)) { 03144 if (!(c = ast_channel_get_by_name(name))) { 03145 astman_send_error(s, m, "No such channel"); 03146 return 0; 03147 } 03148 } 03149 03150 res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 03151 03152 if (c) { 03153 c = ast_channel_unref(c); 03154 } 03155 if (res == 0) { 03156 astman_send_ack(s, m, "Variable Set"); 03157 } else { 03158 astman_send_error(s, m, "Variable not set"); 03159 } 03160 return 0; 03161 }
static int action_status | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager "status" command to show channels.
Definition at line 3211 of file manager.c.
References AST_APP_ARG, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_next(), ast_channel_lock, AST_DECLARE_APP_ARGS, ast_free, ast_func_read(), AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_create(), ast_str_reset(), ast_strdupa, ast_strlen_zero(), ast_tvnow(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::bridge, channels, ast_channel::name, name, pbx_retrieve_variable(), S_OR, and str.
Referenced by __init_manager().
03212 { 03213 const char *name = astman_get_header(m, "Channel"); 03214 const char *cvariables = astman_get_header(m, "Variables"); 03215 char *variables = ast_strdupa(S_OR(cvariables, "")); 03216 struct ast_channel *c; 03217 char bridge[256]; 03218 struct timeval now = ast_tvnow(); 03219 long elapsed_seconds = 0; 03220 int channels = 0; 03221 int all = ast_strlen_zero(name); /* set if we want all channels */ 03222 const char *id = astman_get_header(m, "ActionID"); 03223 char idText[256]; 03224 AST_DECLARE_APP_ARGS(vars, 03225 AST_APP_ARG(name)[100]; 03226 ); 03227 struct ast_str *str = ast_str_create(1000); 03228 struct ast_channel_iterator *iter = NULL; 03229 03230 if (!ast_strlen_zero(id)) { 03231 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 03232 } else { 03233 idText[0] = '\0'; 03234 } 03235 03236 if (all) { 03237 if (!(iter = ast_channel_iterator_all_new())) { 03238 ast_free(str); 03239 astman_send_error(s, m, "Memory Allocation Failure"); 03240 return 1; 03241 } 03242 c = ast_channel_iterator_next(iter); 03243 } else { 03244 if (!(c = ast_channel_get_by_name(name))) { 03245 astman_send_error(s, m, "No such channel"); 03246 ast_free(str); 03247 return 0; 03248 } 03249 } 03250 03251 astman_send_ack(s, m, "Channel status will follow"); 03252 03253 if (!ast_strlen_zero(cvariables)) { 03254 AST_STANDARD_APP_ARGS(vars, variables); 03255 } 03256 03257 /* if we look by name, we break after the first iteration */ 03258 for (; c; c = ast_channel_iterator_next(iter)) { 03259 ast_channel_lock(c); 03260 03261 if (!ast_strlen_zero(cvariables)) { 03262 int i; 03263 ast_str_reset(str); 03264 for (i = 0; i < vars.argc; i++) { 03265 char valbuf[512], *ret = NULL; 03266 03267 if (vars.name[i][strlen(vars.name[i]) - 1] == ')') { 03268 if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) { 03269 valbuf[0] = '\0'; 03270 } 03271 ret = valbuf; 03272 } else { 03273 pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL); 03274 } 03275 03276 ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret); 03277 } 03278 } 03279 03280 channels++; 03281 if (c->_bridge) { 03282 snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid); 03283 } else { 03284 bridge[0] = '\0'; 03285 } 03286 if (c->pbx) { 03287 if (c->cdr) { 03288 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 03289 } 03290 astman_append(s, 03291 "Event: Status\r\n" 03292 "Privilege: Call\r\n" 03293 "Channel: %s\r\n" 03294 "CallerIDNum: %s\r\n" 03295 "CallerIDName: %s\r\n" 03296 "ConnectedLineNum: %s\r\n" 03297 "ConnectedLineName: %s\r\n" 03298 "Accountcode: %s\r\n" 03299 "ChannelState: %d\r\n" 03300 "ChannelStateDesc: %s\r\n" 03301 "Context: %s\r\n" 03302 "Extension: %s\r\n" 03303 "Priority: %d\r\n" 03304 "Seconds: %ld\r\n" 03305 "%s" 03306 "Uniqueid: %s\r\n" 03307 "%s" 03308 "%s" 03309 "\r\n", 03310 c->name, 03311 S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<unknown>"), 03312 S_COR(c->caller.id.name.valid, c->caller.id.name.str, "<unknown>"), 03313 S_COR(c->connected.id.number.valid, c->connected.id.number.str, "<unknown>"), 03314 S_COR(c->connected.id.name.valid, c->connected.id.name.str, "<unknown>"), 03315 c->accountcode, 03316 c->_state, 03317 ast_state2str(c->_state), c->context, 03318 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, ast_str_buffer(str), idText); 03319 } else { 03320 astman_append(s, 03321 "Event: Status\r\n" 03322 "Privilege: Call\r\n" 03323 "Channel: %s\r\n" 03324 "CallerIDNum: %s\r\n" 03325 "CallerIDName: %s\r\n" 03326 "ConnectedLineNum: %s\r\n" 03327 "ConnectedLineName: %s\r\n" 03328 "Account: %s\r\n" 03329 "State: %s\r\n" 03330 "%s" 03331 "Uniqueid: %s\r\n" 03332 "%s" 03333 "%s" 03334 "\r\n", 03335 c->name, 03336 S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<unknown>"), 03337 S_COR(c->caller.id.name.valid, c->caller.id.name.str, "<unknown>"), 03338 S_COR(c->connected.id.number.valid, c->connected.id.number.str, "<unknown>"), 03339 S_COR(c->connected.id.name.valid, c->connected.id.name.str, "<unknown>"), 03340 c->accountcode, 03341 ast_state2str(c->_state), bridge, c->uniqueid, 03342 ast_str_buffer(str), idText); 03343 } 03344 03345 ast_channel_unlock(c); 03346 c = ast_channel_unref(c); 03347 03348 if (!all) { 03349 break; 03350 } 03351 } 03352 03353 if (iter) { 03354 ast_channel_iterator_destroy(iter); 03355 } 03356 03357 astman_append(s, 03358 "Event: StatusComplete\r\n" 03359 "%s" 03360 "Items: %d\r\n" 03361 "\r\n", idText, channels); 03362 03363 ast_free(str); 03364 03365 return 0; 03366 }
static int action_timeout | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4149 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(), astman_send_error(), and name.
Referenced by __init_manager().
04150 { 04151 struct ast_channel *c; 04152 const char *name = astman_get_header(m, "Channel"); 04153 double timeout = atof(astman_get_header(m, "Timeout")); 04154 struct timeval when = { timeout, 0 }; 04155 04156 if (ast_strlen_zero(name)) { 04157 astman_send_error(s, m, "No channel specified"); 04158 return 0; 04159 } 04160 04161 if (!timeout || timeout < 0) { 04162 astman_send_error(s, m, "No timeout specified"); 04163 return 0; 04164 } 04165 04166 if (!(c = ast_channel_get_by_name(name))) { 04167 astman_send_error(s, m, "No such channel"); 04168 return 0; 04169 } 04170 04171 when.tv_usec = (timeout - when.tv_sec) * 1000000.0; 04172 04173 ast_channel_lock(c); 04174 ast_channel_setwhentohangup_tv(c, when); 04175 ast_channel_unlock(c); 04176 c = ast_channel_unref(c); 04177 04178 astman_send_ack(s, m, "Timeout Set"); 04179 04180 return 0; 04181 }
static int action_updateconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2767 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_flags, CONFIG_STATUS_FILEINVALID, FAILURE_ALLOCATION, 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().
02768 { 02769 struct ast_config *cfg; 02770 const char *sfn = astman_get_header(m, "SrcFilename"); 02771 const char *dfn = astman_get_header(m, "DstFilename"); 02772 int res; 02773 const char *rld = astman_get_header(m, "Reload"); 02774 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 02775 enum error_type result; 02776 02777 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 02778 astman_send_error(s, m, "Filename not specified"); 02779 return 0; 02780 } 02781 if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) { 02782 astman_send_error(s, m, "Config file not found"); 02783 return 0; 02784 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02785 astman_send_error(s, m, "Config file has invalid format"); 02786 return 0; 02787 } 02788 result = handle_updates(s, m, cfg, dfn); 02789 if (!result) { 02790 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */ 02791 res = ast_config_text_file_save(dfn, cfg, "Manager"); 02792 ast_config_destroy(cfg); 02793 if (res) { 02794 astman_send_error(s, m, "Save of config failed"); 02795 return 0; 02796 } 02797 astman_send_ack(s, m, NULL); 02798 if (!ast_strlen_zero(rld)) { 02799 if (ast_true(rld)) { 02800 rld = NULL; 02801 } 02802 ast_module_reload(rld); 02803 } 02804 } else { 02805 ast_config_destroy(cfg); 02806 switch(result) { 02807 case UNKNOWN_ACTION: 02808 astman_send_error(s, m, "Unknown action command"); 02809 break; 02810 case UNKNOWN_CATEGORY: 02811 astman_send_error(s, m, "Given category does not exist"); 02812 break; 02813 case UNSPECIFIED_CATEGORY: 02814 astman_send_error(s, m, "Category not specified"); 02815 break; 02816 case UNSPECIFIED_ARGUMENT: 02817 astman_send_error(s, m, "Problem with category, value, or line (if required)"); 02818 break; 02819 case FAILURE_ALLOCATION: 02820 astman_send_error(s, m, "Memory allocation failure, this should not happen"); 02821 break; 02822 case FAILURE_NEWCAT: 02823 astman_send_error(s, m, "Create category did not complete successfully"); 02824 break; 02825 case FAILURE_DELCAT: 02826 astman_send_error(s, m, "Delete category did not complete successfully"); 02827 break; 02828 case FAILURE_EMPTYCAT: 02829 astman_send_error(s, m, "Empty category did not complete successfully"); 02830 break; 02831 case FAILURE_UPDATE: 02832 astman_send_error(s, m, "Update did not complete successfully"); 02833 break; 02834 case FAILURE_DELETE: 02835 astman_send_error(s, m, "Delete did not complete successfully"); 02836 break; 02837 case FAILURE_APPEND: 02838 astman_send_error(s, m, "Append did not complete successfully"); 02839 break; 02840 } 02841 } 02842 return 0; 02843 }
static int action_userevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4266 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().
04267 { 04268 const char *event = astman_get_header(m, "UserEvent"); 04269 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16); 04270 int x; 04271 04272 ast_str_reset(body); 04273 04274 for (x = 0; x < m->hdrcount; x++) { 04275 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 04276 ast_str_append(&body, 0, "%s\r\n", m->headers[x]); 04277 } 04278 } 04279 04280 astman_send_ack(s, m, "Event Sent"); 04281 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body)); 04282 return 0; 04283 }
static int action_waitevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2863 of file manager.c.
References ao2_lock, ao2_unlock, ast_debug, AST_PTHREADT_NULL, AST_RWLIST_NEXT, ast_strlen_zero(), astman_get_header(), mansession_session::last_ev, mansession_session::managerid, mansession_session::needdestroy, mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, and mansession_session::waiting_thread.
Referenced by __init_manager().
02864 { 02865 const char *timeouts = astman_get_header(m, "Timeout"); 02866 int timeout = -1; 02867 int x; 02868 int needexit = 0; 02869 const char *id = astman_get_header(m, "ActionID"); 02870 char idText[256]; 02871 02872 if (!ast_strlen_zero(id)) { 02873 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02874 } else { 02875 idText[0] = '\0'; 02876 } 02877 02878 if (!ast_strlen_zero(timeouts)) { 02879 sscanf(timeouts, "%30i", &timeout); 02880 if (timeout < -1) { 02881 timeout = -1; 02882 } 02883 /* XXX maybe put an upper bound, or prevent the use of 0 ? */ 02884 } 02885 02886 ao2_lock(s->session); 02887 if (s->session->waiting_thread != AST_PTHREADT_NULL) { 02888 pthread_kill(s->session->waiting_thread, SIGURG); 02889 } 02890 02891 if (s->session->managerid) { /* AMI-over-HTTP session */ 02892 /* 02893 * Make sure the timeout is within the expire time of the session, 02894 * as the client will likely abort the request if it does not see 02895 * data coming after some amount of time. 02896 */ 02897 time_t now = time(NULL); 02898 int max = s->session->sessiontimeout - now - 10; 02899 02900 if (max < 0) { /* We are already late. Strange but possible. */ 02901 max = 0; 02902 } 02903 if (timeout < 0 || timeout > max) { 02904 timeout = max; 02905 } 02906 if (!s->session->send_events) { /* make sure we record events */ 02907 s->session->send_events = -1; 02908 } 02909 } 02910 ao2_unlock(s->session); 02911 02912 /* XXX should this go inside the lock ? */ 02913 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */ 02914 ast_debug(1, "Starting waiting for an event!\n"); 02915 02916 for (x = 0; x < timeout || timeout < 0; x++) { 02917 ao2_lock(s->session); 02918 if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) { 02919 needexit = 1; 02920 } 02921 /* We can have multiple HTTP session point to the same mansession entry. 02922 * The way we deal with it is not very nice: newcomers kick out the previous 02923 * HTTP session. XXX this needs to be improved. 02924 */ 02925 if (s->session->waiting_thread != pthread_self()) { 02926 needexit = 1; 02927 } 02928 if (s->session->needdestroy) { 02929 needexit = 1; 02930 } 02931 ao2_unlock(s->session); 02932 if (needexit) { 02933 break; 02934 } 02935 if (s->session->managerid == 0) { /* AMI session */ 02936 if (ast_wait_for_input(s->session->fd, 1000)) { 02937 break; 02938 } 02939 } else { /* HTTP session */ 02940 sleep(1); 02941 } 02942 } 02943 ast_debug(1, "Finished waiting for an event!\n"); 02944 02945 ao2_lock(s->session); 02946 if (s->session->waiting_thread == pthread_self()) { 02947 struct eventqent *eqe = s->session->last_ev; 02948 astman_send_response(s, m, "Success", "Waiting for Event completed."); 02949 while ((eqe = advance_event(eqe))) { 02950 if (((s->session->readperm & eqe->category) == eqe->category) && 02951 ((s->session->send_events & eqe->category) == eqe->category)) { 02952 astman_append(s, "%s", eqe->eventdata); 02953 } 02954 s->session->last_ev = eqe; 02955 } 02956 astman_append(s, 02957 "Event: WaitEventComplete\r\n" 02958 "%s" 02959 "\r\n", idText); 02960 s->session->waiting_thread = AST_PTHREADT_NULL; 02961 } else { 02962 ast_debug(1, "Abandoning event request!\n"); 02963 } 02964 ao2_unlock(s->session); 02965 02966 return 0; 02967 }
Definition at line 1737 of file manager.c.
References ast_atomic_fetchadd_int(), AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, eventqent::eq_next, eventqent::next, and eventqent::usecount.
Referenced by process_events().
01738 { 01739 struct eventqent *next; 01740 01741 AST_RWLIST_RDLOCK(&all_events); 01742 if ((next = AST_RWLIST_NEXT(e, eq_next))) { 01743 ast_atomic_fetchadd_int(&next->usecount, 1); 01744 ast_atomic_fetchadd_int(&e->usecount, -1); 01745 } 01746 AST_RWLIST_UNLOCK(&all_events); 01747 return next; 01748 }
static int aocmessage_get_unit_entry | ( | const struct message * | m, | |
struct ast_aoc_unit_entry * | entry, | |||
unsigned int | entry_num | |||
) | [static] |
Definition at line 3717 of file manager.c.
References ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), astman_get_header(), and str.
Referenced by action_aocmessage().
03718 { 03719 const char *unitamount; 03720 const char *unittype; 03721 struct ast_str *str = ast_str_alloca(32); 03722 03723 memset(entry, 0, sizeof(*entry)); 03724 03725 ast_str_set(&str, 0, "UnitAmount(%u)", entry_num); 03726 unitamount = astman_get_header(m, ast_str_buffer(str)); 03727 03728 ast_str_set(&str, 0, "UnitType(%u)", entry_num); 03729 unittype = astman_get_header(m, ast_str_buffer(str)); 03730 03731 if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) { 03732 entry->valid_amount = 1; 03733 } 03734 03735 if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) { 03736 entry->valid_type = 1; 03737 } 03738 03739 return 0; 03740 }
static void append_channel_vars | ( | struct ast_str ** | pbuf, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 5003 of file manager.c.
References ast_func_read2(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_str_append(), ast_str_buffer(), ast_str_thread_get(), manager_event_funcbuf, ast_channel::name, pbx_builtin_getvar_helper(), and var.
Referenced by __ast_manager_event_multichan().
05004 { 05005 struct manager_channel_variable *var; 05006 05007 AST_RWLIST_RDLOCK(&channelvars); 05008 AST_LIST_TRAVERSE(&channelvars, var, entry) { 05009 const char *val; 05010 struct ast_str *res; 05011 05012 if (var->isfunc) { 05013 res = ast_str_thread_get(&manager_event_funcbuf, 16); 05014 if (res && ast_func_read2(chan, var->name, &res, 0) == 0) { 05015 val = ast_str_buffer(res); 05016 } else { 05017 val = NULL; 05018 } 05019 } else { 05020 val = pbx_builtin_getvar_helper(chan, var->name); 05021 } 05022 ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", chan->name, var->name, val ? val : ""); 05023 } 05024 AST_RWLIST_UNLOCK(&channelvars); 05025 }
static int append_event | ( | const char * | str, | |
int | category | |||
) | [static] |
Definition at line 4977 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(), and seq.
Referenced by __ast_manager_event_multichan(), and __init_manager().
04978 { 04979 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 04980 static int seq; /* sequence number */ 04981 04982 if (!tmp) { 04983 return -1; 04984 } 04985 04986 /* need to init all fields, because ast_malloc() does not */ 04987 tmp->usecount = 0; 04988 tmp->category = category; 04989 tmp->seq = ast_atomic_fetchadd_int(&seq, 1); 04990 tmp->tv = ast_tvnow(); 04991 AST_RWLIST_NEXT(tmp, eq_next) = NULL; 04992 strcpy(tmp->eventdata, str); 04993 04994 AST_RWLIST_WRLOCK(&all_events); 04995 AST_RWLIST_INSERT_TAIL(&all_events, tmp, eq_next); 04996 AST_RWLIST_UNLOCK(&all_events); 04997 04998 return 0; 04999 }
int ast_hook_send_action | ( | struct manager_custom_hook * | hook, | |
const char * | msg | |||
) |
Registered hooks can call this function to invoke actions and they will receive responses through registered callback.
hook | the file identifier specified in manager_custom_hook struct when registering a hook | |
msg | ami action mesage string e.g. "Action: SipPeers\r\n" |
0 | on Success | |
non-zero | on Failure |
Definition at line 1880 of file manager.c.
References ARRAY_LEN, ast_strdup, message::hdrcount, message::headers, and mansession::session.
01881 { 01882 const char *action; 01883 int ret = 0; 01884 struct manager_action *act_found; 01885 struct mansession s = {.session = NULL, }; 01886 struct message m = { 0 }; 01887 char *dup_str; 01888 char *src; 01889 int x = 0; 01890 int curlen; 01891 01892 if (hook == NULL) { 01893 return -1; 01894 } 01895 01896 /* Create our own copy of the AMI action msg string. */ 01897 src = dup_str = ast_strdup(msg); 01898 if (!dup_str) { 01899 return -1; 01900 } 01901 01902 /* convert msg string to message struct */ 01903 curlen = strlen(src); 01904 for (x = 0; x < curlen; x++) { 01905 int cr; /* set if we have \r */ 01906 if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n') 01907 cr = 2; /* Found. Update length to include \r\n */ 01908 else if (src[x] == '\n') 01909 cr = 1; /* also accept \n only */ 01910 else 01911 continue; 01912 /* don't keep empty lines */ 01913 if (x && m.hdrcount < ARRAY_LEN(m.headers)) { 01914 /* ... but trim \r\n and terminate the header string */ 01915 src[x] = '\0'; 01916 m.headers[m.hdrcount++] = src; 01917 } 01918 x += cr; 01919 curlen -= x; /* remaining size */ 01920 src += x; /* update pointer */ 01921 x = -1; /* reset loop */ 01922 } 01923 01924 action = astman_get_header(&m, "Action"); 01925 if (strcasecmp(action, "login")) { 01926 act_found = action_find(action); 01927 if (act_found) { 01928 /* 01929 * we have to simulate a session for this action request 01930 * to be able to pass it down for processing 01931 * This is necessary to meet the previous design of manager.c 01932 */ 01933 s.hook = hook; 01934 s.f = (void*)1; /* set this to something so our request will make it through all functions that test it*/ 01935 01936 ao2_lock(act_found); 01937 if (act_found->registered && act_found->func) { 01938 ret = act_found->func(&s, &m); 01939 } else { 01940 ret = -1; 01941 } 01942 ao2_unlock(act_found); 01943 ao2_t_ref(act_found, -1, "done with found action object"); 01944 } 01945 } 01946 ast_free(dup_str); 01947 return ret; 01948 }
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 1207 of file manager.c.
References eventqent::next.
Referenced by get_perm().
01208 { 01209 const char *val = bigstr, *next; 01210 01211 do { 01212 if ((next = strchr(val, delim))) { 01213 if (!strncmp(val, smallstr, (next - val))) { 01214 return 1; 01215 } else { 01216 continue; 01217 } 01218 } else { 01219 return !strcmp(smallstr, val); 01220 } 01221 } while (*(val = (next + 1))); 01222 01223 return 0; 01224 }
int ast_manager_register2 | ( | const char * | action, | |
int | authority, | |||
int(*)(struct mansession *s, const struct message *m) | func, | |||
const char * | synopsis, | |||
const char * | description | |||
) |
Register a manager command with the manager interface.
action | Name of the requested Action: | |
authority | Required authority for this command | |
func | Function to call for this command | |
synopsis | Help text (one line, up to 30 chars) for CLI manager show commands | |
description | Help text, several lines |
Definition at line 5213 of file manager.c.
References 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(), and ast_xmldoc_build_syntax().
Referenced by load_module().
05214 { 05215 struct manager_action *cur; 05216 05217 cur = ao2_alloc(sizeof(*cur), action_destroy); 05218 if (!cur) { 05219 return -1; 05220 } 05221 if (ast_string_field_init(cur, 128)) { 05222 ao2_t_ref(cur, -1, "action object creation failed"); 05223 return -1; 05224 } 05225 05226 cur->action = action; 05227 cur->authority = auth; 05228 cur->func = func; 05229 #ifdef AST_XML_DOCS 05230 if (ast_strlen_zero(synopsis) && ast_strlen_zero(description)) { 05231 char *tmpxml; 05232 05233 tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL); 05234 ast_string_field_set(cur, synopsis, tmpxml); 05235 ast_free(tmpxml); 05236 05237 tmpxml = ast_xmldoc_build_syntax("manager", action, NULL); 05238 ast_string_field_set(cur, syntax, tmpxml); 05239 ast_free(tmpxml); 05240 05241 tmpxml = ast_xmldoc_build_description("manager", action, NULL); 05242 ast_string_field_set(cur, description, tmpxml); 05243 ast_free(tmpxml); 05244 05245 tmpxml = ast_xmldoc_build_seealso("manager", action, NULL); 05246 ast_string_field_set(cur, seealso, tmpxml); 05247 ast_free(tmpxml); 05248 05249 tmpxml = ast_xmldoc_build_arguments("manager", action, NULL); 05250 ast_string_field_set(cur, arguments, tmpxml); 05251 ast_free(tmpxml); 05252 05253 cur->docsrc = AST_XML_DOC; 05254 } else 05255 #endif 05256 { 05257 ast_string_field_set(cur, synopsis, synopsis); 05258 ast_string_field_set(cur, description, description); 05259 #ifdef AST_XML_DOCS 05260 cur->docsrc = AST_STATIC_DOC; 05261 #endif 05262 } 05263 if (ast_manager_register_struct(cur)) { 05264 ao2_t_ref(cur, -1, "action object registration failed"); 05265 return -1; 05266 } 05267 05268 ao2_t_ref(cur, -1, "action object registration successful"); 05269 return 0; 05270 }
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 1076 of file manager.c.
References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and manager_action::list.
01077 { 01078 AST_RWLIST_WRLOCK(&manager_hooks); 01079 AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list); 01080 AST_RWLIST_UNLOCK(&manager_hooks); 01081 }
static int ast_manager_register_struct | ( | struct manager_action * | act | ) | [static] |
Definition at line 5158 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().
05159 { 05160 struct manager_action *cur, *prev = NULL; 05161 05162 AST_RWLIST_WRLOCK(&actions); 05163 AST_RWLIST_TRAVERSE(&actions, cur, list) { 05164 int ret; 05165 05166 ret = strcasecmp(cur->action, act->action); 05167 if (ret == 0) { 05168 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 05169 AST_RWLIST_UNLOCK(&actions); 05170 return -1; 05171 } 05172 if (ret > 0) { /* Insert these alphabetically */ 05173 prev = cur; 05174 break; 05175 } 05176 } 05177 05178 ao2_t_ref(act, +1, "action object added to list"); 05179 act->registered = 1; 05180 if (prev) { 05181 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list); 05182 } else { 05183 AST_RWLIST_INSERT_HEAD(&actions, act, list); 05184 } 05185 05186 ast_verb(2, "Manager registered action %s\n", act->action); 05187 05188 AST_RWLIST_UNLOCK(&actions); 05189 05190 return 0; 05191 }
int ast_manager_unregister | ( | char * | action | ) |
Unregister a registered manager command.
action | Name of registered Action: |
Definition at line 5118 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, and ast_verb.
Referenced by __unload_module(), and unload_module().
05119 { 05120 struct manager_action *cur; 05121 05122 AST_RWLIST_WRLOCK(&actions); 05123 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) { 05124 if (!strcasecmp(action, cur->action)) { 05125 AST_RWLIST_REMOVE_CURRENT(list); 05126 break; 05127 } 05128 } 05129 AST_RWLIST_TRAVERSE_SAFE_END; 05130 AST_RWLIST_UNLOCK(&actions); 05131 05132 if (cur) { 05133 /* 05134 * We have removed the action object from the container so we 05135 * are no longer in a hurry. 05136 */ 05137 ao2_lock(cur); 05138 cur->registered = 0; 05139 ao2_unlock(cur); 05140 05141 ao2_t_ref(cur, -1, "action object removed from list"); 05142 ast_verb(2, "Manager unregistered action %s\n", action); 05143 } 05144 05145 return 0; 05146 }
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 1084 of file manager.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and manager_action::list.
01085 { 01086 AST_RWLIST_WRLOCK(&manager_hooks); 01087 AST_RWLIST_REMOVE(&manager_hooks, hook, list); 01088 AST_RWLIST_UNLOCK(&manager_hooks); 01089 }
void astman_append | ( | struct mansession * | s, | |
const char * | fmt, | |||
... | ||||
) |
utility functions for creating AMI replies
Definition at line 1994 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(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), _skinny_show_lines(), action_agents(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_ping(), 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_modulecheck(), manager_mute_mixmonitor(), manager_mutestream(), manager_parking_status(), manager_queue_rule_show(), manager_queues_show(), manager_queues_status(), manager_queues_summary(), manager_rpt_local_nodes(), manager_rpt_status(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_show_registry(), 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(), rpt_manager_do_stats(), rpt_manager_success(), and session_do().
01995 { 01996 va_list ap; 01997 struct ast_str *buf; 01998 01999 if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) { 02000 return; 02001 } 02002 02003 va_start(ap, fmt); 02004 ast_str_set_va(&buf, 0, fmt, ap); 02005 va_end(ap); 02006 02007 if (s->f != NULL || s->session->f != NULL) { 02008 send_string(s, ast_str_buffer(buf)); 02009 } else { 02010 ast_verbose("fd == -1 in astman_append, should not happen\n"); 02011 } 02012 }
static void astman_append_json | ( | struct mansession * | s, | |
const char * | str | |||
) | [static] |
Definition at line 2564 of file manager.c.
References astman_append(), and json_escape().
Referenced by action_getconfigjson().
02565 { 02566 char *buf; 02567 02568 buf = alloca(2 * strlen(str) + 1); 02569 json_escape(buf, str); 02570 astman_append(s, "%s", buf); 02571 }
const char* astman_get_header | ( | const struct message * | m, | |
char * | var | |||
) |
Get header from mananger transaction.
Never returns NULL.
Definition at line 1800 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_coresettings(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_ping(), 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(), 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_modulecheck(), manager_moduleload(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_reload(), manager_queue_reset(), manager_queue_rule_show(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_registry(), 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(), meetmemute(), process_message(), rpt_manager_do_stats(), rpt_manager_success(), start_monitor_action(), and stop_monitor_action().
01801 { 01802 return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH); 01803 }
struct ast_variable* astman_get_variables | ( | const struct message * | m | ) |
Get a linked list of the Variable: headers.
Definition at line 1858 of file manager.c.
References message::hdrcount, message::headers, and man_do_variable_value().
Referenced by action_originate(), and manager_sipnotify().
01859 { 01860 int varlen; 01861 int x; 01862 struct ast_variable *head = NULL; 01863 01864 static const char var_hdr[] = "Variable:"; 01865 01866 /* Process all "Variable:" headers. */ 01867 varlen = strlen(var_hdr); 01868 for (x = 0; x < m->hdrcount; x++) { 01869 if (strncasecmp(var_hdr, m->headers[x], varlen)) { 01870 continue; 01871 } 01872 head = man_do_variable_value(head, m->headers[x] + varlen); 01873 } 01874 01875 return head; 01876 }
void astman_send_ack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg | |||
) |
Send ack in manager transaction.
Definition at line 2061 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_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_dahdishowchannels(), action_hangup(), action_login(), action_originate(), 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_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_reload(), manager_queue_reset(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), meetmemute(), start_monitor_action(), and stop_monitor_action().
02062 { 02063 astman_send_response_full(s, m, "Success", msg, NULL); 02064 }
void astman_send_error | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | error | |||
) |
Send error in manager transaction.
Definition at line 2056 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_coreshowchannels(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), 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(), manager_add_queue_member(), manager_data_get(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), 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_reload(), manager_queue_reset(), manager_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sipnotify(), manager_skinny_show_device(), manager_skinny_show_line(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
02057 { 02058 astman_send_response_full(s, m, "Error", error, NULL); 02059 }
void astman_send_listack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg, | |||
char * | listflag | |||
) |
Send ack in manager list transaction.
Definition at line 2071 of file manager.c.
References astman_send_response_full().
Referenced by action_coreshowchannels(), action_meetmelist(), 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().
02072 { 02073 astman_send_response_full(s, m, "Success", msg, listflag); 02074 }
void astman_send_response | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg | |||
) |
Send response in manager transaction.
Definition at line 2051 of file manager.c.
References astman_send_response_full().
Referenced by action_logoff().
02052 { 02053 astman_send_response_full(s, m, resp, msg, NULL); 02054 }
static void astman_send_response_full | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg, | |||
char * | listflag | |||
) | [static] |
Definition at line 2031 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_listack(), astman_send_response(), and astman_start_ack().
02032 { 02033 const char *id = astman_get_header(m, "ActionID"); 02034 02035 astman_append(s, "Response: %s\r\n", resp); 02036 if (!ast_strlen_zero(id)) { 02037 astman_append(s, "ActionID: %s\r\n", id); 02038 } 02039 if (listflag) { 02040 astman_append(s, "EventList: %s\r\n", listflag); /* Start, complete, cancelled */ 02041 } 02042 if (msg == MSG_MOREDATA) { 02043 return; 02044 } else if (msg) { 02045 astman_append(s, "Message: %s\r\n\r\n", msg); 02046 } else { 02047 astman_append(s, "\r\n"); 02048 } 02049 }
static void astman_start_ack | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2066 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().
02067 { 02068 astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL); 02069 }
static int authenticate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2348 of file manager.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_t_link, ao2_t_ref, ast_apply_ha(), ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_sockaddr_from_sin, ast_strlen_zero(), ast_tvnow(), astman_get_header(), mansession_session::blackfilters, mansession_session::challenge, get_manager_by_name_locked(), len(), LOG_NOTICE, md5(), MD5Final(), MD5Init(), MD5Update(), mansession_session::readperm, report_auth_success(), report_failed_acl(), report_failed_challenge_response(), report_inval_password(), report_invalid_user(), S_OR, mansession::session, mansession_session::sessionstart, mansession_session::sessionstart_tv, set_eventmask(), mansession_session::sin, user, mansession_session::username, mansession_session::whitefilters, mansession_session::writeperm, and mansession_session::writetimeout.
02349 { 02350 const char *username = astman_get_header(m, "Username"); 02351 const char *password = astman_get_header(m, "Secret"); 02352 int error = -1; 02353 struct ast_manager_user *user = NULL; 02354 regex_t *regex_filter; 02355 struct ao2_iterator filter_iter; 02356 struct ast_sockaddr addr; 02357 02358 if (ast_strlen_zero(username)) { /* missing username */ 02359 return -1; 02360 } 02361 02362 /* locate user in locked state */ 02363 AST_RWLIST_WRLOCK(&users); 02364 02365 ast_sockaddr_from_sin(&addr, &s->session->sin); 02366 02367 if (!(user = get_manager_by_name_locked(username))) { 02368 report_invalid_user(s, username); 02369 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 02370 } else if (user->ha && !ast_apply_ha(user->ha, &addr)) { 02371 report_failed_acl(s, username); 02372 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 02373 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { 02374 const char *key = astman_get_header(m, "Key"); 02375 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) { 02376 int x; 02377 int len = 0; 02378 char md5key[256] = ""; 02379 struct MD5Context md5; 02380 unsigned char digest[16]; 02381 02382 MD5Init(&md5); 02383 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge)); 02384 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret)); 02385 MD5Final(digest, &md5); 02386 for (x = 0; x < 16; x++) 02387 len += sprintf(md5key + len, "%2.2x", digest[x]); 02388 if (!strcmp(md5key, key)) { 02389 error = 0; 02390 } else { 02391 report_failed_challenge_response(s, key, md5key); 02392 } 02393 } else { 02394 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n", 02395 S_OR(s->session->challenge, "")); 02396 } 02397 } else if (user->secret) { 02398 if (!strcmp(password, user->secret)) { 02399 error = 0; 02400 } else { 02401 report_inval_password(s, username); 02402 } 02403 } 02404 02405 if (error) { 02406 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 02407 AST_RWLIST_UNLOCK(&users); 02408 return -1; 02409 } 02410 02411 /* auth complete */ 02412 02413 /* All of the user parameters are copied to the session so that in the event 02414 * of a reload and a configuration change, the session parameters are not 02415 * changed. */ 02416 ast_copy_string(s->session->username, username, sizeof(s->session->username)); 02417 s->session->readperm = user->readperm; 02418 s->session->writeperm = user->writeperm; 02419 s->session->writetimeout = user->writetimeout; 02420 02421 filter_iter = ao2_iterator_init(user->whitefilters, 0); 02422 while ((regex_filter = ao2_iterator_next(&filter_iter))) { 02423 ao2_t_link(s->session->whitefilters, regex_filter, "add white user filter to session"); 02424 ao2_t_ref(regex_filter, -1, "remove iterator ref"); 02425 } 02426 ao2_iterator_destroy(&filter_iter); 02427 02428 filter_iter = ao2_iterator_init(user->blackfilters, 0); 02429 while ((regex_filter = ao2_iterator_next(&filter_iter))) { 02430 ao2_t_link(s->session->blackfilters, regex_filter, "add black user filter to session"); 02431 ao2_t_ref(regex_filter, -1, "remove iterator ref"); 02432 } 02433 ao2_iterator_destroy(&filter_iter); 02434 02435 s->session->sessionstart = time(NULL); 02436 s->session->sessionstart_tv = ast_tvnow(); 02437 set_eventmask(s, astman_get_header(m, "Events")); 02438 02439 report_auth_success(s); 02440 02441 AST_RWLIST_UNLOCK(&users); 02442 return 0; 02443 }
static const char* authority_to_str | ( | int | authority, | |
struct ast_str ** | res | |||
) | [static] |
Convert authority code to a list of options.
Definition at line 1183 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_showmanager(), handle_showmancmd(), and handle_showmancmds().
01184 { 01185 int i; 01186 char *sep = ""; 01187 01188 ast_str_reset(*res); 01189 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) { 01190 if (authority & perms[i].num) { 01191 ast_str_append(res, 0, "%s%s", sep, perms[i].label); 01192 sep = ","; 01193 } 01194 } 01195 01196 if (ast_str_strlen(*res) == 0) /* replace empty string with something sensible */ 01197 ast_str_append(res, 0, "<none>"); 01198 01199 return ast_str_buffer(*res); 01200 }
static int blackfilter_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
void * | data, | |||
int | flags | |||
) | [static] |
Definition at line 4197 of file manager.c.
References CMP_MATCH, and CMP_STOP.
Referenced by match_filter().
04198 { 04199 regex_t *regex_filter = obj; 04200 const char *eventdata = arg; 04201 int *result = data; 04202 04203 if (!regexec(regex_filter, eventdata, 0, NULL, 0)) { 04204 *result = 0; 04205 return (CMP_MATCH | CMP_STOP); 04206 } 04207 04208 *result = 1; 04209 return 0; 04210 }
static struct mansession_session* build_mansession | ( | struct sockaddr_in | sin | ) | [static] |
Allocate manager session structure and add it to the list of sessions.
Definition at line 1324 of file manager.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, AST_PTHREADT_NULL, and session_destructor().
Referenced by session_do().
01325 { 01326 struct mansession_session *newsession; 01327 01328 if (!(newsession = ao2_alloc(sizeof(*newsession), session_destructor))) { 01329 return NULL; 01330 } 01331 01332 if (!(newsession->whitefilters = ao2_container_alloc(1, NULL, NULL))) { 01333 ao2_ref(newsession, -1); 01334 return NULL; 01335 } 01336 01337 if (!(newsession->blackfilters = ao2_container_alloc(1, NULL, NULL))) { 01338 ao2_ref(newsession, -1); /* session_destructor will cleanup the other filter */ 01339 return NULL; 01340 } 01341 01342 newsession->fd = -1; 01343 newsession->waiting_thread = AST_PTHREADT_NULL; 01344 newsession->writetimeout = 100; 01345 newsession->send_events = -1; 01346 newsession->sin = sin; 01347 01348 ao2_link(sessions, newsession); 01349 01350 return newsession; 01351 }
static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 3555 of file manager.c.
References ARRAY_LEN, ast_strdupa, ast_strip(), ast_strlen_zero(), command_blacklist, match(), MAX_BLACKLIST_CMD_LEN, strsep(), and words.
Referenced by action_command().
03556 { 03557 char *cmd_copy, *cur_cmd; 03558 char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, }; 03559 int i; 03560 03561 cmd_copy = ast_strdupa(cmd); 03562 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) { 03563 cur_cmd = ast_strip(cur_cmd); 03564 if (ast_strlen_zero(cur_cmd)) { 03565 i--; 03566 continue; 03567 } 03568 03569 cmd_words[i] = cur_cmd; 03570 } 03571 03572 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) { 03573 int j, match = 1; 03574 03575 for (j = 0; command_blacklist[i].words[j]; j++) { 03576 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) { 03577 match = 0; 03578 break; 03579 } 03580 } 03581 03582 if (match) { 03583 return 1; 03584 } 03585 } 03586 03587 return 0; 03588 }
int check_manager_enabled | ( | void | ) |
Check if AMI is enabled.
Definition at line 1091 of file manager.c.
Referenced by handle_show_settings().
01092 { 01093 return manager_enabled; 01094 }
static int check_manager_session_inuse | ( | const char * | name | ) | [static] |
Definition at line 1367 of file manager.c.
References ao2_find, mansession_session::inuse, and unref_mansession().
Referenced by process_message().
01368 { 01369 struct mansession_session *session = ao2_find(sessions, (char *) name, 0); 01370 int inuse = 0; 01371 01372 if (session) { 01373 inuse = 1; 01374 unref_mansession(session); 01375 } 01376 return inuse; 01377 }
int check_webmanager_enabled | ( | void | ) |
Check if AMI/HTTP is enabled.
Definition at line 1096 of file manager.c.
Referenced by action_coresettings(), and handle_show_settings().
01097 { 01098 return (webmanager_enabled && manager_enabled); 01099 }
static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 4769 of file manager.c.
References ARRAY_LEN, ast_free, ast_inet_ntoa(), ast_log(), ast_strdup, ast_strlen_zero(), ast_verb, astman_send_error(), authtimeout, displayconnects, errno, get_input(), message::hdrcount, message::headers, mansession_session::inbuf, LOG_ERROR, mansession_lock(), mansession_unlock(), process_events(), process_message(), and mansession::session.
Referenced by session_do().
04770 { 04771 struct message m = { 0 }; 04772 char header_buf[sizeof(s->session->inbuf)] = { '\0' }; 04773 int res; 04774 int idx; 04775 int hdr_loss; 04776 time_t now; 04777 04778 hdr_loss = 0; 04779 for (;;) { 04780 /* Check if any events are pending and do them if needed */ 04781 if (process_events(s)) { 04782 res = -1; 04783 break; 04784 } 04785 res = get_input(s, header_buf); 04786 if (res == 0) { 04787 /* No input line received. */ 04788 if (!s->session->authenticated) { 04789 if (time(&now) == -1) { 04790 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 04791 res = -1; 04792 break; 04793 } 04794 04795 if (now - s->session->authstart > authtimeout) { 04796 if (displayconnects) { 04797 ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_inet_ntoa(s->session->sin.sin_addr), authtimeout); 04798 } 04799 res = -1; 04800 break; 04801 } 04802 } 04803 continue; 04804 } else if (res > 0) { 04805 /* Input line received. */ 04806 if (ast_strlen_zero(header_buf)) { 04807 if (hdr_loss) { 04808 mansession_lock(s); 04809 astman_send_error(s, &m, "Too many lines in message or allocation failure"); 04810 mansession_unlock(s); 04811 res = 0; 04812 } else { 04813 res = process_message(s, &m) ? -1 : 0; 04814 } 04815 break; 04816 } else if (m.hdrcount < ARRAY_LEN(m.headers)) { 04817 m.headers[m.hdrcount] = ast_strdup(header_buf); 04818 if (!m.headers[m.hdrcount]) { 04819 /* Allocation failure. */ 04820 hdr_loss = 1; 04821 } else { 04822 ++m.hdrcount; 04823 } 04824 } else { 04825 /* Too many lines in message. */ 04826 hdr_loss = 1; 04827 } 04828 } else { 04829 /* Input error. */ 04830 break; 04831 } 04832 } 04833 04834 /* Free AMI request headers. */ 04835 for (idx = 0; idx < m.hdrcount; ++idx) { 04836 ast_free((void *) m.headers[idx]); 04837 } 04838 return res; 04839 }
static void event_filter_destructor | ( | void * | obj | ) | [static] |
static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 3666 of file manager.c.
References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_unlock, ast_free, ast_manager_event_multichan, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_string_field_free_memory, ast_strlen_zero(), fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, fast_originate_helper::data, EVENT_FLAG_CALL, fast_originate_helper::exten, fast_originate_helper::format, fast_originate_helper::idtext, ast_channel::name, fast_originate_helper::priority, S_OR, fast_originate_helper::tech, fast_originate_helper::timeout, ast_channel::uniqueid, and fast_originate_helper::vars.
Referenced by action_originate().
03667 { 03668 struct fast_originate_helper *in = data; 03669 int res; 03670 int reason = 0; 03671 struct ast_channel *chan = NULL, *chans[1]; 03672 char requested_channel[AST_CHANNEL_NAME]; 03673 03674 if (!ast_strlen_zero(in->app)) { 03675 res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1, 03676 S_OR(in->cid_num, NULL), 03677 S_OR(in->cid_name, NULL), 03678 in->vars, in->account, &chan); 03679 } else { 03680 res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 03681 S_OR(in->cid_num, NULL), 03682 S_OR(in->cid_name, NULL), 03683 in->vars, in->account, &chan); 03684 } 03685 03686 if (!chan) { 03687 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 03688 } 03689 /* Tell the manager what happened with the channel */ 03690 chans[0] = chan; 03691 ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans, 03692 "%s%s" 03693 "Response: %s\r\n" 03694 "Channel: %s\r\n" 03695 "Context: %s\r\n" 03696 "Exten: %s\r\n" 03697 "Reason: %d\r\n" 03698 "Uniqueid: %s\r\n" 03699 "CallerIDNum: %s\r\n" 03700 "CallerIDName: %s\r\n", 03701 in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 03702 chan ? chan->name : requested_channel, in->context, in->exten, reason, 03703 chan ? chan->uniqueid : "<null>", 03704 S_OR(in->cid_num, "<unknown>"), 03705 S_OR(in->cid_name, "<unknown>") 03706 ); 03707 03708 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 03709 if (chan) { 03710 ast_channel_unlock(chan); 03711 } 03712 ast_string_field_free_memory(in); 03713 ast_free(in); 03714 return NULL; 03715 }
static void free_channelvars | ( | void | ) | [static] |
Definition at line 6890 of file manager.c.
References ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, manager_channel_variable::entry, and var.
Referenced by __init_manager(), and load_channelvars().
06891 { 06892 struct manager_channel_variable *var; 06893 AST_RWLIST_WRLOCK(&channelvars); 06894 while ((var = AST_RWLIST_REMOVE_HEAD(&channelvars, entry))) { 06895 ast_free(var); 06896 } 06897 AST_RWLIST_UNLOCK(&channelvars); 06898 }
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 4672 of file manager.c.
References mansession_session::inbuf, mansession_session::inlen, mansession::session, and ast_frame::src.
04673 { 04674 int res, x; 04675 int maxlen = sizeof(s->session->inbuf) - 1; 04676 char *src = s->session->inbuf; 04677 int timeout = -1; 04678 time_t now; 04679 04680 /* 04681 * Look for \r\n within the buffer. If found, copy to the output 04682 * buffer and return, trimming the \r\n (not used afterwards). 04683 */ 04684 for (x = 0; x < s->session->inlen; x++) { 04685 int cr; /* set if we have \r */ 04686 if (src[x] == '\r' && x+1 < s->session->inlen && src[x + 1] == '\n') { 04687 cr = 2; /* Found. Update length to include \r\n */ 04688 } else if (src[x] == '\n') { 04689 cr = 1; /* also accept \n only */ 04690 } else { 04691 continue; 04692 } 04693 memmove(output, src, x); /*... but trim \r\n */ 04694 output[x] = '\0'; /* terminate the string */ 04695 x += cr; /* number of bytes used */ 04696 s->session->inlen -= x; /* remaining size */ 04697 memmove(src, src + x, s->session->inlen); /* remove used bytes */ 04698 return 1; 04699 } 04700 if (s->session->inlen >= maxlen) { 04701 /* no crlf found, and buffer full - sorry, too long for us */ 04702 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src); 04703 s->session->inlen = 0; 04704 } 04705 res = 0; 04706 while (res == 0) { 04707 /* calculate a timeout if we are not authenticated */ 04708 if (!s->session->authenticated) { 04709 if(time(&now) == -1) { 04710 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 04711 return -1; 04712 } 04713 04714 timeout = (authtimeout - (now - s->session->authstart)) * 1000; 04715 if (timeout < 0) { 04716 /* we have timed out */ 04717 return 0; 04718 } 04719 } 04720 04721 ao2_lock(s->session); 04722 if (s->session->pending_event) { 04723 s->session->pending_event = 0; 04724 ao2_unlock(s->session); 04725 return 0; 04726 } 04727 s->session->waiting_thread = pthread_self(); 04728 ao2_unlock(s->session); 04729 04730 res = ast_wait_for_input(s->session->fd, timeout); 04731 04732 ao2_lock(s->session); 04733 s->session->waiting_thread = AST_PTHREADT_NULL; 04734 ao2_unlock(s->session); 04735 } 04736 if (res < 0) { 04737 /* If we get a signal from some other thread (typically because 04738 * there are new events queued), return 0 to notify the caller. 04739 */ 04740 if (errno == EINTR || errno == EAGAIN) { 04741 return 0; 04742 } 04743 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno)); 04744 return -1; 04745 } 04746 04747 ao2_lock(s->session); 04748 res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f); 04749 if (res < 1) { 04750 res = -1; /* error return */ 04751 } else { 04752 s->session->inlen += res; 04753 src[s->session->inlen] = '\0'; 04754 res = 0; 04755 } 04756 ao2_unlock(s->session); 04757 return res; 04758 }
static struct ast_manager_user* get_manager_by_name_locked | ( | const char * | name | ) | [static] |
lookup an entry in the list of registered users. must be called with the list lock held.
Definition at line 1384 of file manager.c.
References AST_RWLIST_TRAVERSE, ast_manager_user::list, and user.
Referenced by authenticate(), handle_showmanager(), and manager_displayconnects().
01385 { 01386 struct ast_manager_user *user = NULL; 01387 01388 AST_RWLIST_TRAVERSE(&users, user, list) { 01389 if (!strcasecmp(user->username, name)) { 01390 break; 01391 } 01392 } 01393 01394 return user; 01395 }
static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 1226 of file manager.c.
References ARRAY_LEN, ast_instring(), permalias::num, and perms.
Referenced by strings_to_mask().
01227 { 01228 int x = 0, ret = 0; 01229 01230 if (!instr) { 01231 return 0; 01232 } 01233 01234 for (x = 0; x < ARRAY_LEN(perms); x++) { 01235 if (ast_instring(instr, perms[x].label, ',')) { 01236 ret |= perms[x].num; 01237 } 01238 } 01239 01240 return ret; 01241 }
static struct eventqent* grab_last | ( | void | ) | [static] |
Grab a reference to the last event, update usecount as needed. Can handle a NULL pointer.
Definition at line 1105 of file manager.c.
References ast_atomic_fetchadd_int(), AST_RWLIST_LAST, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and eventqent::usecount.
Referenced by session_do().
01106 { 01107 struct eventqent *ret; 01108 01109 AST_RWLIST_WRLOCK(&all_events); 01110 ret = AST_RWLIST_LAST(&all_events); 01111 /* the list is never empty now, but may become so when 01112 * we optimize it in the future, so be prepared. 01113 */ 01114 if (ret) { 01115 ast_atomic_fetchadd_int(&ret->usecount, 1); 01116 } 01117 AST_RWLIST_UNLOCK(&all_events); 01118 return ret; 01119 }
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 1718 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.
01719 { 01720 switch (cmd) { 01721 case CLI_INIT: 01722 e->command = "manager reload"; 01723 e->usage = 01724 "Usage: manager reload\n" 01725 " Reloads the manager configuration.\n"; 01726 return NULL; 01727 case CLI_GENERATE: 01728 return NULL; 01729 } 01730 if (a->argc > 2) { 01731 return CLI_SHOWUSAGE; 01732 } 01733 reload_manager(); 01734 return CLI_SUCCESS; 01735 }
static char* handle_mandebug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1492 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.
01493 { 01494 switch (cmd) { 01495 case CLI_INIT: 01496 e->command = "manager set debug [on|off]"; 01497 e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n"; 01498 return NULL; 01499 case CLI_GENERATE: 01500 return NULL; 01501 } 01502 01503 if (a->argc == 3) { 01504 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off"); 01505 } else if (a->argc == 4) { 01506 if (!strcasecmp(a->argv[3], "on")) { 01507 manager_debug = 1; 01508 } else if (!strcasecmp(a->argv[3], "off")) { 01509 manager_debug = 0; 01510 } else { 01511 return CLI_SHOWUSAGE; 01512 } 01513 } 01514 return CLI_SUCCESS; 01515 }
static char* handle_showmanager | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1517 of file manager.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_manager_by_name_locked(), ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, user, and ast_cli_args::word.
01518 { 01519 struct ast_manager_user *user = NULL; 01520 int l, which; 01521 char *ret = NULL; 01522 struct ast_str *rauthority = ast_str_alloca(128); 01523 struct ast_str *wauthority = ast_str_alloca(128); 01524 01525 switch (cmd) { 01526 case CLI_INIT: 01527 e->command = "manager show user"; 01528 e->usage = 01529 " Usage: manager show user <user>\n" 01530 " Display all information related to the manager user specified.\n"; 01531 return NULL; 01532 case CLI_GENERATE: 01533 l = strlen(a->word); 01534 which = 0; 01535 if (a->pos != 3) { 01536 return NULL; 01537 } 01538 AST_RWLIST_RDLOCK(&users); 01539 AST_RWLIST_TRAVERSE(&users, user, list) { 01540 if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) { 01541 ret = ast_strdup(user->username); 01542 break; 01543 } 01544 } 01545 AST_RWLIST_UNLOCK(&users); 01546 return ret; 01547 } 01548 01549 if (a->argc != 4) { 01550 return CLI_SHOWUSAGE; 01551 } 01552 01553 AST_RWLIST_RDLOCK(&users); 01554 01555 if (!(user = get_manager_by_name_locked(a->argv[3]))) { 01556 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]); 01557 AST_RWLIST_UNLOCK(&users); 01558 return CLI_SUCCESS; 01559 } 01560 01561 ast_cli(a->fd, "\n"); 01562 ast_cli(a->fd, 01563 " username: %s\n" 01564 " secret: %s\n" 01565 " acl: %s\n" 01566 " read perm: %s\n" 01567 " write perm: %s\n" 01568 "displayconnects: %s\n", 01569 (user->username ? user->username : "(N/A)"), 01570 (user->secret ? "<Set>" : "(N/A)"), 01571 (user->ha ? "yes" : "no"), 01572 authority_to_str(user->readperm, &rauthority), 01573 authority_to_str(user->writeperm, &wauthority), 01574 (user->displayconnects ? "yes" : "no")); 01575 01576 AST_RWLIST_UNLOCK(&users); 01577 01578 return CLI_SUCCESS; 01579 }
static char* handle_showmanagers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1581 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_manager_user::list, ast_cli_entry::usage, and user.
01582 { 01583 struct ast_manager_user *user = NULL; 01584 int count_amu = 0; 01585 switch (cmd) { 01586 case CLI_INIT: 01587 e->command = "manager show users"; 01588 e->usage = 01589 "Usage: manager show users\n" 01590 " Prints a listing of all managers that are currently configured on that\n" 01591 " system.\n"; 01592 return NULL; 01593 case CLI_GENERATE: 01594 return NULL; 01595 } 01596 if (a->argc != 3) { 01597 return CLI_SHOWUSAGE; 01598 } 01599 01600 AST_RWLIST_RDLOCK(&users); 01601 01602 /* If there are no users, print out something along those lines */ 01603 if (AST_RWLIST_EMPTY(&users)) { 01604 ast_cli(a->fd, "There are no manager users.\n"); 01605 AST_RWLIST_UNLOCK(&users); 01606 return CLI_SUCCESS; 01607 } 01608 01609 ast_cli(a->fd, "\nusername\n--------\n"); 01610 01611 AST_RWLIST_TRAVERSE(&users, user, list) { 01612 ast_cli(a->fd, "%s\n", user->username); 01613 count_amu++; 01614 } 01615 01616 AST_RWLIST_UNLOCK(&users); 01617 01618 ast_cli(a->fd,"-------------------\n" 01619 "%d manager users configured.\n", count_amu); 01620 return CLI_SUCCESS; 01621 }
static char* handle_showmancmd | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1415 of file manager.c.
References manager_action::action, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), 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, COLOR_MAGENTA, ast_cli_entry::command, manager_action::docsrc, ast_cli_args::fd, ast_cli_args::n, S_OR, term_color(), ast_cli_entry::usage, and ast_cli_args::word.
01416 { 01417 struct manager_action *cur; 01418 struct ast_str *authority; 01419 int num, l, which; 01420 char *ret = NULL; 01421 #ifdef AST_XML_DOCS 01422 char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64]; 01423 #endif 01424 01425 switch (cmd) { 01426 case CLI_INIT: 01427 e->command = "manager show command"; 01428 e->usage = 01429 "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n" 01430 " Shows the detailed description for a specific Asterisk manager interface command.\n"; 01431 return NULL; 01432 case CLI_GENERATE: 01433 l = strlen(a->word); 01434 which = 0; 01435 AST_RWLIST_RDLOCK(&actions); 01436 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01437 if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) { 01438 ret = ast_strdup(cur->action); 01439 break; /* make sure we exit even if ast_strdup() returns NULL */ 01440 } 01441 } 01442 AST_RWLIST_UNLOCK(&actions); 01443 return ret; 01444 } 01445 authority = ast_str_alloca(80); 01446 if (a->argc < 4) { 01447 return CLI_SHOWUSAGE; 01448 } 01449 01450 #ifdef AST_XML_DOCS 01451 /* setup the titles */ 01452 term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01453 term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40); 01454 term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01455 term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40); 01456 term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40); 01457 #endif 01458 01459 AST_RWLIST_RDLOCK(&actions); 01460 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01461 for (num = 3; num < a->argc; num++) { 01462 if (!strcasecmp(cur->action, a->argv[num])) { 01463 #ifdef AST_XML_DOCS 01464 if (cur->docsrc == AST_XML_DOC) { 01465 ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n", 01466 syntax_title, 01467 ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1), 01468 synopsis_title, 01469 ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1), 01470 description_title, 01471 ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1), 01472 arguments_title, 01473 ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1), 01474 seealso_title, 01475 ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1)); 01476 } else 01477 #endif 01478 { 01479 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", 01480 cur->action, cur->synopsis, 01481 authority_to_str(cur->authority, &authority), 01482 S_OR(cur->description, "")); 01483 } 01484 } 01485 } 01486 } 01487 AST_RWLIST_UNLOCK(&actions); 01488 01489 return CLI_SUCCESS; 01490 }
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 1624 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, and ast_cli_entry::usage.
01625 { 01626 struct manager_action *cur; 01627 struct ast_str *authority; 01628 #define HSMC_FORMAT " %-15.15s %-15.15s %-55.55s\n" 01629 switch (cmd) { 01630 case CLI_INIT: 01631 e->command = "manager show commands"; 01632 e->usage = 01633 "Usage: manager show commands\n" 01634 " Prints a listing of all the available Asterisk manager interface commands.\n"; 01635 return NULL; 01636 case CLI_GENERATE: 01637 return NULL; 01638 } 01639 authority = ast_str_alloca(80); 01640 ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis"); 01641 ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------"); 01642 01643 AST_RWLIST_RDLOCK(&actions); 01644 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01645 ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis); 01646 } 01647 AST_RWLIST_UNLOCK(&actions); 01648 01649 return CLI_SUCCESS; 01650 }
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 1653 of file manager.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_cli(), ast_inet_ntoa(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HSMCONN_FORMAT1, HSMCONN_FORMAT2, unref_mansession(), and ast_cli_entry::usage.
01654 { 01655 struct mansession_session *session; 01656 time_t now = time(NULL); 01657 #define HSMCONN_FORMAT1 " %-15.15s %-15.15s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n" 01658 #define HSMCONN_FORMAT2 " %-15.15s %-15.15s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n" 01659 int count = 0; 01660 struct ao2_iterator i; 01661 01662 switch (cmd) { 01663 case CLI_INIT: 01664 e->command = "manager show connected"; 01665 e->usage = 01666 "Usage: manager show connected\n" 01667 " Prints a listing of the users that are currently connected to the\n" 01668 "Asterisk manager interface.\n"; 01669 return NULL; 01670 case CLI_GENERATE: 01671 return NULL; 01672 } 01673 01674 ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write"); 01675 01676 i = ao2_iterator_init(sessions, 0); 01677 while ((session = ao2_iterator_next(&i))) { 01678 ao2_lock(session); 01679 ast_cli(a->fd, HSMCONN_FORMAT2, session->username, ast_inet_ntoa(session->sin.sin_addr), (int)(session->sessionstart), (int)(now - session->sessionstart), session->fd, session->inuse, session->readperm, session->writeperm); 01680 count++; 01681 ao2_unlock(session); 01682 unref_mansession(session); 01683 } 01684 ao2_iterator_destroy(&i); 01685 ast_cli(a->fd, "%d users connected.\n", count); 01686 01687 return CLI_SUCCESS; 01688 }
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 1692 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, eventqent::eq_next, eventqent::eventdata, ast_cli_args::fd, ast_cli_entry::usage, and eventqent::usecount.
01693 { 01694 struct eventqent *s; 01695 switch (cmd) { 01696 case CLI_INIT: 01697 e->command = "manager show eventq"; 01698 e->usage = 01699 "Usage: manager show eventq\n" 01700 " Prints a listing of all events pending in the Asterisk manger\n" 01701 "event queue.\n"; 01702 return NULL; 01703 case CLI_GENERATE: 01704 return NULL; 01705 } 01706 AST_RWLIST_RDLOCK(&all_events); 01707 AST_RWLIST_TRAVERSE(&all_events, s, eq_next) { 01708 ast_cli(a->fd, "Usecount: %d\n", s->usecount); 01709 ast_cli(a->fd, "Category: %d\n", s->category); 01710 ast_cli(a->fd, "Event:\n%s", s->eventdata); 01711 } 01712 AST_RWLIST_UNLOCK(&all_events); 01713 01714 return CLI_SUCCESS; 01715 }
static enum error_type handle_updates | ( | struct mansession * | s, | |
const struct message * | m, | |||
struct ast_config * | cfg, | |||
const char * | dfn | |||
) | [static] |
Definition at line 2622 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(), 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().
02623 { 02624 int x; 02625 char hdr[40]; 02626 const char *action, *cat, *var, *value, *match, *line; 02627 struct ast_category *category; 02628 struct ast_variable *v; 02629 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 02630 enum error_type result = 0; 02631 02632 for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */ 02633 unsigned int object = 0; 02634 02635 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 02636 action = astman_get_header(m, hdr); 02637 if (ast_strlen_zero(action)) /* breaks the for loop if no action header */ 02638 break; /* this could cause problems if actions come in misnumbered */ 02639 02640 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 02641 cat = astman_get_header(m, hdr); 02642 if (ast_strlen_zero(cat)) { /* every action needs a category */ 02643 result = UNSPECIFIED_CATEGORY; 02644 break; 02645 } 02646 02647 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 02648 var = astman_get_header(m, hdr); 02649 02650 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 02651 value = astman_get_header(m, hdr); 02652 02653 if (!ast_strlen_zero(value) && *value == '>') { 02654 object = 1; 02655 value++; 02656 } 02657 02658 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 02659 match = astman_get_header(m, hdr); 02660 02661 snprintf(hdr, sizeof(hdr), "Line-%06d", x); 02662 line = astman_get_header(m, hdr); 02663 02664 if (!strcasecmp(action, "newcat")) { 02665 if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */ 02666 result = FAILURE_NEWCAT; /* already exist */ 02667 break; 02668 } 02669 if (!(category = ast_category_new(cat, dfn, -1))) { 02670 result = FAILURE_ALLOCATION; 02671 break; 02672 } 02673 if (ast_strlen_zero(match)) { 02674 ast_category_append(cfg, category); 02675 } else { 02676 ast_category_insert(cfg, category, match); 02677 } 02678 } else if (!strcasecmp(action, "renamecat")) { 02679 if (ast_strlen_zero(value)) { 02680 result = UNSPECIFIED_ARGUMENT; 02681 break; 02682 } 02683 if (!(category = ast_category_get(cfg, cat))) { 02684 result = UNKNOWN_CATEGORY; 02685 break; 02686 } 02687 ast_category_rename(category, value); 02688 } else if (!strcasecmp(action, "delcat")) { 02689 if (ast_category_delete(cfg, cat)) { 02690 result = FAILURE_DELCAT; 02691 break; 02692 } 02693 } else if (!strcasecmp(action, "emptycat")) { 02694 if (ast_category_empty(cfg, cat)) { 02695 result = FAILURE_EMPTYCAT; 02696 break; 02697 } 02698 } else if (!strcasecmp(action, "update")) { 02699 if (ast_strlen_zero(var)) { 02700 result = UNSPECIFIED_ARGUMENT; 02701 break; 02702 } 02703 if (!(category = ast_category_get(cfg,cat))) { 02704 result = UNKNOWN_CATEGORY; 02705 break; 02706 } 02707 if (ast_variable_update(category, var, value, match, object)) { 02708 result = FAILURE_UPDATE; 02709 break; 02710 } 02711 } else if (!strcasecmp(action, "delete")) { 02712 if ((ast_strlen_zero(var) && ast_strlen_zero(line))) { 02713 result = UNSPECIFIED_ARGUMENT; 02714 break; 02715 } 02716 if (!(category = ast_category_get(cfg, cat))) { 02717 result = UNKNOWN_CATEGORY; 02718 break; 02719 } 02720 if (ast_variable_delete(category, var, match, line)) { 02721 result = FAILURE_DELETE; 02722 break; 02723 } 02724 } else if (!strcasecmp(action, "append")) { 02725 if (ast_strlen_zero(var)) { 02726 result = UNSPECIFIED_ARGUMENT; 02727 break; 02728 } 02729 if (!(category = ast_category_get(cfg, cat))) { 02730 result = UNKNOWN_CATEGORY; 02731 break; 02732 } 02733 if (!(v = ast_variable_new(var, value, dfn))) { 02734 result = FAILURE_ALLOCATION; 02735 break; 02736 } 02737 if (object || (match && !strcasecmp(match, "object"))) { 02738 v->object = 1; 02739 } 02740 ast_variable_append(category, v); 02741 } else if (!strcasecmp(action, "insert")) { 02742 if (ast_strlen_zero(var) || ast_strlen_zero(line)) { 02743 result = UNSPECIFIED_ARGUMENT; 02744 break; 02745 } 02746 if (!(category = ast_category_get(cfg, cat))) { 02747 result = UNKNOWN_CATEGORY; 02748 break; 02749 } 02750 if (!(v = ast_variable_new(var, value, dfn))) { 02751 result = FAILURE_ALLOCATION; 02752 break; 02753 } 02754 ast_variable_insert(category, v, line); 02755 } 02756 else { 02757 ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action); 02758 result = UNKNOWN_ACTION; 02759 break; 02760 } 02761 } 02762 ast_free(str1); 02763 ast_free(str2); 02764 return result; 02765 }
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 2544 of file manager.c.
Referenced by astman_append_json().
02545 { 02546 for (; *in; in++) { 02547 if (*in == '\\' || *in == '\"') { 02548 *out++ = '\\'; 02549 } 02550 *out++ = *in; 02551 } 02552 *out = '\0'; 02553 }
static struct ast_variable* man_do_variable_value | ( | struct ast_variable * | head, | |
const char * | hdr_val | |||
) | [static] |
Definition at line 1814 of file manager.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_skip_blanks(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_variable_new(), parse(), strsep(), and var.
Referenced by astman_get_variables().
01815 { 01816 char *parse; 01817 AST_DECLARE_APP_ARGS(args, 01818 AST_APP_ARG(vars)[64]; 01819 ); 01820 01821 hdr_val = ast_skip_blanks(hdr_val); /* ignore leading spaces in the value */ 01822 parse = ast_strdupa(hdr_val); 01823 01824 /* Break the header value string into name=val pair items. */ 01825 AST_STANDARD_APP_ARGS(args, parse); 01826 if (args.argc) { 01827 int y; 01828 01829 /* Process each name=val pair item. */ 01830 for (y = 0; y < args.argc; y++) { 01831 struct ast_variable *cur; 01832 char *var; 01833 char *val; 01834 01835 if (!args.vars[y]) { 01836 continue; 01837 } 01838 var = val = args.vars[y]; 01839 strsep(&val, "="); 01840 01841 /* XXX We may wish to trim whitespace from the strings. */ 01842 if (!val || ast_strlen_zero(var)) { 01843 continue; 01844 } 01845 01846 /* Create new variable list node and prepend it to the list. */ 01847 cur = ast_variable_new(var, val, ""); 01848 if (cur) { 01849 cur->next = head; 01850 head = cur; 01851 } 01852 } 01853 } 01854 01855 return head; 01856 }
static int manager_displayconnects | ( | struct mansession_session * | session | ) | [static] |
Get displayconnects config option.
session | manager session to get parameter from. |
Definition at line 1401 of file manager.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, get_manager_by_name_locked(), user, and mansession_session::username.
Referenced by action_login(), and purge_sessions().
01402 { 01403 struct ast_manager_user *user = NULL; 01404 int ret = 0; 01405 01406 AST_RWLIST_RDLOCK(&users); 01407 if ((user = get_manager_by_name_locked (session->username))) { 01408 ret = user->displayconnects; 01409 } 01410 AST_RWLIST_UNLOCK(&users); 01411 01412 return ret; 01413 }
static int manager_modulecheck | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4466 of file manager.c.
References ast_copy_string(), ast_file_version_find(), ast_log(), ast_module_check(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), LOG_DEBUG, and version.
Referenced by __init_manager().
04467 { 04468 int res; 04469 const char *module = astman_get_header(m, "Module"); 04470 const char *id = astman_get_header(m, "ActionID"); 04471 char idText[256]; 04472 #if !defined(LOW_MEMORY) 04473 const char *version; 04474 #endif 04475 char filename[PATH_MAX]; 04476 char *cut; 04477 04478 ast_copy_string(filename, module, sizeof(filename)); 04479 if ((cut = strchr(filename, '.'))) { 04480 *cut = '\0'; 04481 } else { 04482 cut = filename + strlen(filename); 04483 } 04484 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so"); 04485 ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename); 04486 res = ast_module_check(filename); 04487 if (!res) { 04488 astman_send_error(s, m, "Module not loaded"); 04489 return 0; 04490 } 04491 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c"); 04492 ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename); 04493 #if !defined(LOW_MEMORY) 04494 version = ast_file_version_find(filename); 04495 #endif 04496 04497 if (!ast_strlen_zero(id)) { 04498 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 04499 } else { 04500 idText[0] = '\0'; 04501 } 04502 astman_append(s, "Response: Success\r\n%s", idText); 04503 #if !defined(LOW_MEMORY) 04504 astman_append(s, "Version: %s\r\n\r\n", version ? version : ""); 04505 #endif 04506 return 0; 04507 }
static int manager_moduleload | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4509 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().
04510 { 04511 int res; 04512 const char *module = astman_get_header(m, "Module"); 04513 const char *loadtype = astman_get_header(m, "LoadType"); 04514 04515 if (!loadtype || strlen(loadtype) == 0) { 04516 astman_send_error(s, m, "Incomplete ModuleLoad action."); 04517 } 04518 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) { 04519 astman_send_error(s, m, "Need module name"); 04520 } 04521 04522 if (!strcasecmp(loadtype, "load")) { 04523 res = ast_load_resource(module); 04524 if (res) { 04525 astman_send_error(s, m, "Could not load module."); 04526 } else { 04527 astman_send_ack(s, m, "Module loaded."); 04528 } 04529 } else if (!strcasecmp(loadtype, "unload")) { 04530 res = ast_unload_resource(module, AST_FORCE_SOFT); 04531 if (res) { 04532 astman_send_error(s, m, "Could not unload module."); 04533 } else { 04534 astman_send_ack(s, m, "Module unloaded."); 04535 } 04536 } else if (!strcasecmp(loadtype, "reload")) { 04537 if (!ast_strlen_zero(module)) { 04538 res = ast_module_reload(module); 04539 if (res == 0) { 04540 astman_send_error(s, m, "No such module."); 04541 } else if (res == 1) { 04542 astman_send_error(s, m, "Module does not support reload action."); 04543 } else { 04544 astman_send_ack(s, m, "Module reloaded."); 04545 } 04546 } else { 04547 ast_module_reload(NULL); /* Reload all modules */ 04548 astman_send_ack(s, m, "All modules reloaded"); 04549 } 04550 } else 04551 astman_send_error(s, m, "Incomplete ModuleLoad action."); 04552 return 0; 04553 }
static int manager_state_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 5148 of file manager.c.
References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.
Referenced by __init_manager().
05149 { 05150 /* Notify managers of change */ 05151 char hint[512]; 05152 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten); 05153 05154 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state); 05155 return 0; 05156 }
static int mansession_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1353 of file manager.c.
References CMP_MATCH, str, and mansession_session::username.
01354 { 01355 struct mansession_session *s = obj; 01356 char *str = arg; 01357 return !strcasecmp(s->username, str) ? CMP_MATCH : 0; 01358 }
static struct sockaddr_in* mansession_encode_sin_local | ( | const struct mansession * | s, | |
struct sockaddr_in * | sin_local | |||
) | [static] |
Definition at line 2111 of file manager.c.
References ast_sockaddr_to_sin, ast_tcptls_session_args::local_address, ast_tcptls_session_instance::parent, and mansession::tcptls_session.
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().
02113 { 02114 ast_sockaddr_to_sin(&s->tcptls_session->parent->local_address, 02115 sin_local); 02116 02117 return sin_local; 02118 }
static enum ast_security_event_transport_type mansession_get_transport | ( | const struct mansession * | s | ) | [static] |
Definition at line 2105 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().
02106 { 02107 return s->tcptls_session->parent->tls_cfg ? AST_SECURITY_EVENT_TRANSPORT_TLS : 02108 AST_SECURITY_EVENT_TRANSPORT_TCP; 02109 }
static void mansession_lock | ( | struct mansession * | s | ) | [static] |
Lock the 'mansession' structure.
Definition at line 2077 of file manager.c.
References ast_mutex_lock, and mansession::lock.
Referenced by action_challenge(), do_message(), and process_message().
02078 { 02079 ast_mutex_lock(&s->lock); 02080 }
static void mansession_unlock | ( | struct mansession * | s | ) | [static] |
Unlock the 'mansession' structure.
Definition at line 2083 of file manager.c.
References ast_mutex_unlock, and mansession::lock.
Referenced by action_challenge(), do_message(), and process_message().
02084 { 02085 ast_mutex_unlock(&s->lock); 02086 }
static int match_filter | ( | struct mansession * | s, | |
char * | eventdata | |||
) | [static] |
Definition at line 4212 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().
04213 { 04214 int result = 0; 04215 04216 ast_debug(3, "Examining event:\n%s\n", eventdata); 04217 if (!ao2_container_count(s->session->whitefilters) && !ao2_container_count(s->session->blackfilters)) { 04218 return 1; /* no filtering means match all */ 04219 } else if (ao2_container_count(s->session->whitefilters) && !ao2_container_count(s->session->blackfilters)) { 04220 /* white filters only: implied black all filter processed first, then white filters */ 04221 ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 04222 } else if (!ao2_container_count(s->session->whitefilters) && ao2_container_count(s->session->blackfilters)) { 04223 /* black filters only: implied white all filter processed first, then black filters */ 04224 ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 04225 } else { 04226 /* white and black filters: implied black all filter processed first, then white filters, and lastly black filters */ 04227 ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 04228 if (result) { 04229 result = 0; 04230 ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 04231 } 04232 } 04233 04234 return result; 04235 }
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 4242 of file manager.c.
References advance_event(), ao2_lock, ao2_unlock, mansession_session::authenticated, eventqent::category, eventqent::eventdata, 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().
04243 { 04244 int ret = 0; 04245 04246 ao2_lock(s->session); 04247 if (s->session->f != NULL) { 04248 struct eventqent *eqe = s->session->last_ev; 04249 04250 while ((eqe = advance_event(eqe))) { 04251 if (!ret && s->session->authenticated && 04252 (s->session->readperm & eqe->category) == eqe->category && 04253 (s->session->send_events & eqe->category) == eqe->category) { 04254 if (match_filter(s, eqe->eventdata)) { 04255 if (send_string(s, eqe->eventdata) < 0) 04256 ret = -1; /* don't send more */ 04257 } 04258 } 04259 s->session->last_ev = eqe; 04260 } 04261 } 04262 ao2_unlock(s->session); 04263 return ret; 04264 }
static int process_message | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4568 of file manager.c.
References __astman_get_header(), manager_action::action, action_find(), allowmultiplelogin, ao2_lock, ao2_t_ref, ao2_unlock, ast_debug, 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(), process_events(), manager_action::registered, report_req_bad_format(), report_req_not_allowed(), report_session_limit(), mansession::session, and mansession_session::writeperm.
Referenced by do_message().
04569 { 04570 int ret = 0; 04571 struct manager_action *act_found; 04572 const char *user; 04573 const char *action; 04574 04575 action = __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY); 04576 if (ast_strlen_zero(action)) { 04577 report_req_bad_format(s, "NONE"); 04578 mansession_lock(s); 04579 astman_send_error(s, m, "Missing action in request"); 04580 mansession_unlock(s); 04581 return 0; 04582 } 04583 04584 if (!s->session->authenticated 04585 && strcasecmp(action, "Login") 04586 && strcasecmp(action, "Logoff") 04587 && strcasecmp(action, "Challenge")) { 04588 if (!s->session->authenticated) { 04589 report_req_not_allowed(s, action); 04590 } 04591 mansession_lock(s); 04592 astman_send_error(s, m, "Permission denied"); 04593 mansession_unlock(s); 04594 return 0; 04595 } 04596 04597 if (!allowmultiplelogin 04598 && !s->session->authenticated 04599 && (!strcasecmp(action, "Login") 04600 || !strcasecmp(action, "Challenge"))) { 04601 user = astman_get_header(m, "Username"); 04602 04603 if (check_manager_session_inuse(user)) { 04604 report_session_limit(s); 04605 sleep(1); 04606 mansession_lock(s); 04607 astman_send_error(s, m, "Login Already In Use"); 04608 mansession_unlock(s); 04609 return -1; 04610 } 04611 } 04612 04613 act_found = action_find(action); 04614 if (act_found) { 04615 /* Found the requested AMI action. */ 04616 int acted = 0; 04617 04618 if ((s->session->writeperm & act_found->authority) 04619 || act_found->authority == 0) { 04620 /* We have the authority to execute the action. */ 04621 ao2_lock(act_found); 04622 if (act_found->registered && act_found->func) { 04623 ast_debug(1, "Running action '%s'\n", act_found->action); 04624 ret = act_found->func(s, m); 04625 acted = 1; 04626 } 04627 ao2_unlock(act_found); 04628 } 04629 if (!acted) { 04630 /* 04631 * We did not execute the action because access was denied, it 04632 * was no longer registered, or no action was really registered. 04633 * Complain about it and leave. 04634 */ 04635 report_req_not_allowed(s, action); 04636 mansession_lock(s); 04637 astman_send_error(s, m, "Permission denied"); 04638 mansession_unlock(s); 04639 } 04640 ao2_t_ref(act_found, -1, "done with found action object"); 04641 } else { 04642 char buf[512]; 04643 04644 report_req_bad_format(s, action); 04645 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action); 04646 mansession_lock(s); 04647 astman_send_error(s, m, buf); 04648 mansession_unlock(s); 04649 } 04650 if (ret) { 04651 return ret; 04652 } 04653 /* Once done with our message, deliver any pending events unless the 04654 requester doesn't want them as part of this response. 04655 */ 04656 if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) { 04657 return process_events(s); 04658 } else { 04659 return ret; 04660 } 04661 }
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 1125 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::eq_next, eventqent::tv, and eventqent::usecount.
Referenced by purge_old_stuff().
01126 { 01127 struct eventqent *ev; 01128 struct timeval now = ast_tvnow(); 01129 01130 AST_RWLIST_WRLOCK(&all_events); 01131 while ( (ev = AST_RWLIST_FIRST(&all_events)) && 01132 ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) { 01133 AST_RWLIST_REMOVE_HEAD(&all_events, eq_next); 01134 ast_free(ev); 01135 } 01136 01137 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&all_events, ev, eq_next) { 01138 /* Never release the last event */ 01139 if (!AST_RWLIST_NEXT(ev, eq_next)) { 01140 break; 01141 } 01142 01143 /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */ 01144 if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) { 01145 AST_RWLIST_REMOVE_CURRENT(eq_next); 01146 ast_free(ev); 01147 } 01148 } 01149 AST_RWLIST_TRAVERSE_SAFE_END; 01150 AST_RWLIST_UNLOCK(&all_events); 01151 }
static void purge_sessions | ( | int | n_max | ) | [static] |
remove at most n_max stale session from the list.
Definition at line 4948 of file manager.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_inet_ntoa(), ast_verb, mansession_session::authenticated, mansession_session::inuse, manager_displayconnects(), session_destroy(), mansession_session::sessiontimeout, mansession_session::sin, unref_mansession(), mansession_session::username, and VERBOSITY_ATLEAST.
Referenced by purge_old_stuff().
04949 { 04950 struct mansession_session *session; 04951 time_t now = time(NULL); 04952 struct ao2_iterator i; 04953 04954 i = ao2_iterator_init(sessions, 0); 04955 while ((session = ao2_iterator_next(&i)) && n_max > 0) { 04956 ao2_lock(session); 04957 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) { 04958 if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) { 04959 ast_verb(2, "HTTP Manager '%s' timed out from %s\n", 04960 session->username, ast_inet_ntoa(session->sin.sin_addr)); 04961 } 04962 ao2_unlock(session); 04963 session_destroy(session); 04964 n_max--; 04965 } else { 04966 ao2_unlock(session); 04967 unref_mansession(session); 04968 } 04969 } 04970 ao2_iterator_destroy(&i); 04971 }
static void report_auth_success | ( | const struct mansession * | s | ) | [static] |
Definition at line 2198 of file manager.c.
References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.
Referenced by authenticate().
02199 { 02200 struct sockaddr_in sin_local; 02201 char session_id[32]; 02202 struct ast_security_event_successful_auth successful_auth = { 02203 .common.event_type = AST_SECURITY_EVENT_SUCCESSFUL_AUTH, 02204 .common.version = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION, 02205 .common.service = "AMI", 02206 .common.account_id = s->session->username, 02207 .common.session_tv = &s->session->sessionstart_tv, 02208 .common.local_addr = { 02209 .sin = mansession_encode_sin_local(s, &sin_local), 02210 .transport = mansession_get_transport(s), 02211 }, 02212 .common.remote_addr = { 02213 .sin = &s->session->sin, 02214 .transport = mansession_get_transport(s), 02215 }, 02216 .common.session_id = session_id, 02217 }; 02218 02219 snprintf(session_id, sizeof(session_id), "%p", s->session); 02220 02221 ast_security_event_report(AST_SEC_EVT(&successful_auth)); 02222 }
static void report_failed_acl | ( | const struct mansession * | s, | |
const char * | username | |||
) | [static] |
Definition at line 2146 of file manager.c.
References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, and mansession_session::sin.
Referenced by authenticate().
02147 { 02148 struct sockaddr_in sin_local; 02149 char session_id[32]; 02150 struct ast_security_event_failed_acl failed_acl_event = { 02151 .common.event_type = AST_SECURITY_EVENT_FAILED_ACL, 02152 .common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION, 02153 .common.service = "AMI", 02154 .common.account_id = username, 02155 .common.session_tv = &s->session->sessionstart_tv, 02156 .common.local_addr = { 02157 .sin = mansession_encode_sin_local(s, &sin_local), 02158 .transport = mansession_get_transport(s), 02159 }, 02160 .common.remote_addr = { 02161 .sin = &s->session->sin, 02162 .transport = mansession_get_transport(s), 02163 }, 02164 .common.session_id = session_id, 02165 }; 02166 02167 snprintf(session_id, sizeof(session_id), "%p", s->session); 02168 02169 ast_security_event_report(AST_SEC_EVT(&failed_acl_event)); 02170 }
static void report_failed_challenge_response | ( | const struct mansession * | s, | |
const char * | response, | |||
const char * | expected_response | |||
) | [static] |
Definition at line 2284 of file manager.c.
References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.
Referenced by authenticate().
02286 { 02287 struct sockaddr_in sin_local; 02288 char session_id[32]; 02289 struct ast_security_event_chal_resp_failed chal_resp_failed = { 02290 .common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED, 02291 .common.version = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION, 02292 .common.service = "AMI", 02293 .common.account_id = s->session->username, 02294 .common.session_tv = &s->session->sessionstart_tv, 02295 .common.local_addr = { 02296 .sin = mansession_encode_sin_local(s, &sin_local), 02297 .transport = mansession_get_transport(s), 02298 }, 02299 .common.remote_addr = { 02300 .sin = &s->session->sin, 02301 .transport = mansession_get_transport(s), 02302 }, 02303 .common.session_id = session_id, 02304 02305 .challenge = s->session->challenge, 02306 .response = response, 02307 .expected_response = expected_response, 02308 }; 02309 02310 snprintf(session_id, sizeof(session_id), "%p", s->session); 02311 02312 ast_security_event_report(AST_SEC_EVT(&chal_resp_failed)); 02313 }
static void report_inval_password | ( | const struct mansession * | s, | |
const char * | username | |||
) | [static] |
Definition at line 2172 of file manager.c.
References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, and mansession_session::sin.
Referenced by authenticate().
02173 { 02174 struct sockaddr_in sin_local; 02175 char session_id[32]; 02176 struct ast_security_event_inval_password inval_password = { 02177 .common.event_type = AST_SECURITY_EVENT_INVAL_PASSWORD, 02178 .common.version = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION, 02179 .common.service = "AMI", 02180 .common.account_id = username, 02181 .common.session_tv = &s->session->sessionstart_tv, 02182 .common.local_addr = { 02183 .sin = mansession_encode_sin_local(s, &sin_local), 02184 .transport = mansession_get_transport(s), 02185 }, 02186 .common.remote_addr = { 02187 .sin = &s->session->sin, 02188 .transport = mansession_get_transport(s), 02189 }, 02190 .common.session_id = session_id, 02191 }; 02192 02193 snprintf(session_id, sizeof(session_id), "%p", s->session); 02194 02195 ast_security_event_report(AST_SEC_EVT(&inval_password)); 02196 }
static void report_invalid_user | ( | const struct mansession * | s, | |
const char * | username | |||
) | [static] |
Definition at line 2120 of file manager.c.
References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, and mansession_session::sin.
Referenced by authenticate().
02121 { 02122 struct sockaddr_in sin_local; 02123 char session_id[32]; 02124 struct ast_security_event_inval_acct_id inval_acct_id = { 02125 .common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID, 02126 .common.version = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION, 02127 .common.service = "AMI", 02128 .common.account_id = username, 02129 .common.session_tv = &s->session->sessionstart_tv, 02130 .common.local_addr = { 02131 .sin = mansession_encode_sin_local(s, &sin_local), 02132 .transport = mansession_get_transport(s), 02133 }, 02134 .common.remote_addr = { 02135 .sin = &s->session->sin, 02136 .transport = mansession_get_transport(s), 02137 }, 02138 .common.session_id = session_id, 02139 }; 02140 02141 snprintf(session_id, sizeof(session_id), "%p", s); 02142 02143 ast_security_event_report(AST_SEC_EVT(&inval_acct_id)); 02144 }
static void report_req_bad_format | ( | const struct mansession * | s, | |
const char * | action | |||
) | [static] |
Definition at line 2254 of file manager.c.
References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.
Referenced by process_message().
02255 { 02256 struct sockaddr_in sin_local; 02257 char session_id[32]; 02258 char request_type[64]; 02259 struct ast_security_event_req_bad_format req_bad_format = { 02260 .common.event_type = AST_SECURITY_EVENT_REQ_BAD_FORMAT, 02261 .common.version = AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION, 02262 .common.service = "AMI", 02263 .common.account_id = s->session->username, 02264 .common.session_tv = &s->session->sessionstart_tv, 02265 .common.local_addr = { 02266 .sin = mansession_encode_sin_local(s, &sin_local), 02267 .transport = mansession_get_transport(s), 02268 }, 02269 .common.remote_addr = { 02270 .sin = &s->session->sin, 02271 .transport = mansession_get_transport(s), 02272 }, 02273 .common.session_id = session_id, 02274 02275 .request_type = request_type, 02276 }; 02277 02278 snprintf(session_id, sizeof(session_id), "%p", s->session); 02279 snprintf(request_type, sizeof(request_type), "Action: %s", action); 02280 02281 ast_security_event_report(AST_SEC_EVT(&req_bad_format)); 02282 }
static void report_req_not_allowed | ( | const struct mansession * | s, | |
const char * | action | |||
) | [static] |
Definition at line 2224 of file manager.c.
References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.
Referenced by process_message().
02225 { 02226 struct sockaddr_in sin_local; 02227 char session_id[32]; 02228 char request_type[64]; 02229 struct ast_security_event_req_not_allowed req_not_allowed = { 02230 .common.event_type = AST_SECURITY_EVENT_REQ_NOT_ALLOWED, 02231 .common.version = AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION, 02232 .common.service = "AMI", 02233 .common.account_id = s->session->username, 02234 .common.session_tv = &s->session->sessionstart_tv, 02235 .common.local_addr = { 02236 .sin = mansession_encode_sin_local(s, &sin_local), 02237 .transport = mansession_get_transport(s), 02238 }, 02239 .common.remote_addr = { 02240 .sin = &s->session->sin, 02241 .transport = mansession_get_transport(s), 02242 }, 02243 .common.session_id = session_id, 02244 02245 .request_type = request_type, 02246 }; 02247 02248 snprintf(session_id, sizeof(session_id), "%p", s->session); 02249 snprintf(request_type, sizeof(request_type), "Action: %s", action); 02250 02251 ast_security_event_report(AST_SEC_EVT(&req_not_allowed)); 02252 }
static void report_session_limit | ( | const struct mansession * | s | ) | [static] |
Definition at line 2315 of file manager.c.
References AST_SEC_EVT, ast_security_event_report(), AST_SECURITY_EVENT_SESSION_LIMIT, AST_SECURITY_EVENT_SESSION_LIMIT_VERSION, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, session_limit, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.
Referenced by process_message().
02316 { 02317 struct sockaddr_in sin_local; 02318 char session_id[32]; 02319 struct ast_security_event_session_limit session_limit = { 02320 .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT, 02321 .common.version = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION, 02322 .common.service = "AMI", 02323 .common.account_id = s->session->username, 02324 .common.session_tv = &s->session->sessionstart_tv, 02325 .common.local_addr = { 02326 .sin = mansession_encode_sin_local(s, &sin_local), 02327 .transport = mansession_get_transport(s), 02328 }, 02329 .common.remote_addr = { 02330 .sin = &s->session->sin, 02331 .transport = mansession_get_transport(s), 02332 }, 02333 .common.session_id = session_id, 02334 }; 02335 02336 snprintf(session_id, sizeof(session_id), "%p", s->session); 02337 02338 ast_security_event_report(AST_SEC_EVT(&session_limit)); 02339 }
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 1955 of file manager.c.
References ast_careful_fwrite(), EVENT_FLAG_HOOKRESPONSE, mansession_session::f, mansession::f, 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().
01956 { 01957 int res; 01958 FILE *f = s->f ? s->f : s->session->f; 01959 int fd = s->f ? s->fd : s->session->fd; 01960 01961 /* It's a result from one of the hook's action invocation */ 01962 if (s->hook) { 01963 /* 01964 * to send responses, we're using the same function 01965 * as for receiving events. We call the event "HookResponse" 01966 */ 01967 s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string); 01968 return 0; 01969 } 01970 01971 if ((res = ast_careful_fwrite(f, fd, string, strlen(string), s->session->writetimeout))) { 01972 s->write_error = 1; 01973 } 01974 01975 return res; 01976 }
static void session_destroy | ( | struct mansession_session * | s | ) | [static] |
Definition at line 1360 of file manager.c.
References ao2_unlink, and unref_mansession().
Referenced by purge_sessions(), session_do(), and spandsp_fax_destroy().
01361 { 01362 unref_mansession(s); 01363 ao2_unlink(sessions, s); 01364 }
static void session_destructor | ( | void * | obj | ) | [static] |
Definition at line 1293 of file manager.c.
References ao2_t_callback, ao2_t_ref, ast_atomic_fetchadd_int(), ast_datastore_free(), AST_LIST_REMOVE_HEAD, mansession_session::blackfilters, mansession_session::datastores, ast_datastore::entry, mansession_session::f, mansession_session::last_ev, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, eventqent::usecount, and mansession_session::whitefilters.
Referenced by build_mansession().
01294 { 01295 struct mansession_session *session = obj; 01296 struct eventqent *eqe = session->last_ev; 01297 struct ast_datastore *datastore; 01298 01299 /* Get rid of each of the data stores on the session */ 01300 while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) { 01301 /* Free the data store */ 01302 ast_datastore_free(datastore); 01303 } 01304 01305 if (session->f != NULL) { 01306 fclose(session->f); 01307 } 01308 if (eqe) { 01309 ast_atomic_fetchadd_int(&eqe->usecount, -1); 01310 } 01311 01312 if (session->whitefilters) { 01313 ao2_t_callback(session->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters"); 01314 ao2_t_ref(session->whitefilters, -1 , "decrement ref for white container, should be last one"); 01315 } 01316 01317 if (session->blackfilters) { 01318 ao2_t_callback(session->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters"); 01319 ao2_t_ref(session->blackfilters, -1 , "decrement ref for black container, should be last one"); 01320 } 01321 }
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 4849 of file manager.c.
References AMI_VERSION, ao2_lock, ao2_unlock, ast_atomic_fetchadd_int(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_mutex_init, ast_sockaddr_to_sin, astman_append(), authlimit, mansession_session::authstart, block_sockets, build_mansession(), mansession_session::datastores, do_message(), errno, mansession::f, mansession_session::f, ast_tcptls_session_instance::f, mansession::fd, mansession_session::fd, ast_tcptls_session_instance::fd, ast_frame::flags, grab_last(), mansession_session::last_ev, mansession::lock, LOG_ERROR, LOG_WARNING, ast_tcptls_session_instance::remote_address, mansession::session, session_destroy(), mansession_session::sin, mansession::tcptls_session, unauth_sessions, and mansession::write_error.
04850 { 04851 struct ast_tcptls_session_instance *ser = data; 04852 struct mansession_session *session; 04853 struct mansession s = { 04854 .tcptls_session = data, 04855 }; 04856 int flags; 04857 int res; 04858 struct sockaddr_in ser_remote_address_tmp; 04859 struct protoent *p; 04860 04861 if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) { 04862 fclose(ser->f); 04863 ast_atomic_fetchadd_int(&unauth_sessions, -1); 04864 goto done; 04865 } 04866 04867 ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp); 04868 session = build_mansession(ser_remote_address_tmp); 04869 04870 if (session == NULL) { 04871 fclose(ser->f); 04872 ast_atomic_fetchadd_int(&unauth_sessions, -1); 04873 goto done; 04874 } 04875 04876 /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm. 04877 * This is necessary to prevent delays (caused by buffering) as we 04878 * write to the socket in bits and peices. */ 04879 p = getprotobyname("tcp"); 04880 if (p) { 04881 int arg = 1; 04882 if( setsockopt(ser->fd, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 04883 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)); 04884 } 04885 } else { 04886 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"); 04887 } 04888 04889 flags = fcntl(ser->fd, F_GETFL); 04890 if (!block_sockets) { /* make sure socket is non-blocking */ 04891 flags |= O_NONBLOCK; 04892 } else { 04893 flags &= ~O_NONBLOCK; 04894 } 04895 fcntl(ser->fd, F_SETFL, flags); 04896 04897 ao2_lock(session); 04898 /* Hook to the tail of the event queue */ 04899 session->last_ev = grab_last(); 04900 04901 ast_mutex_init(&s.lock); 04902 04903 /* these fields duplicate those in the 'ser' structure */ 04904 session->fd = s.fd = ser->fd; 04905 session->f = s.f = ser->f; 04906 session->sin = ser_remote_address_tmp; 04907 s.session = session; 04908 04909 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores); 04910 04911 if(time(&session->authstart) == -1) { 04912 ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno)); 04913 ast_atomic_fetchadd_int(&unauth_sessions, -1); 04914 ao2_unlock(session); 04915 session_destroy(session); 04916 goto done; 04917 } 04918 ao2_unlock(session); 04919 04920 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */ 04921 for (;;) { 04922 if ((res = do_message(&s)) < 0 || s.write_error) { 04923 break; 04924 } 04925 } 04926 /* session is over, explain why and terminate */ 04927 if (session->authenticated) { 04928 if (manager_displayconnects(session)) { 04929 ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 04930 } 04931 } else { 04932 ast_atomic_fetchadd_int(&unauth_sessions, -1); 04933 if (displayconnects) { 04934 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); 04935 } 04936 } 04937 04938 session_destroy(session); 04939 04940 ast_mutex_destroy(&s.lock); 04941 done: 04942 ao2_ref(ser, -1); 04943 ser = NULL; 04944 return NULL; 04945 }
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 2092 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().
02093 { 02094 int maskint = strings_to_mask(eventmask); 02095 02096 ao2_lock(s->session); 02097 if (maskint >= 0) { 02098 s->session->send_events = maskint; 02099 } 02100 ao2_unlock(s->session); 02101 02102 return maskint; 02103 }
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 1247 of file manager.c.
References ARRAY_LEN, ast_false(), ast_strlen_zero(), ast_true(), get_perm(), and perms.
Referenced by set_eventmask().
01248 { 01249 const char *p; 01250 01251 if (ast_strlen_zero(string)) { 01252 return -1; 01253 } 01254 01255 for (p = string; *p; p++) { 01256 if (*p < '0' || *p > '9') { 01257 break; 01258 } 01259 } 01260 if (!*p) { /* all digits */ 01261 return atoi(string); 01262 } 01263 if (ast_false(string)) { 01264 return 0; 01265 } 01266 if (ast_true(string)) { /* all permissions */ 01267 int x, ret = 0; 01268 for (x = 0; x < ARRAY_LEN(perms); x++) { 01269 ret |= perms[x].num; 01270 } 01271 return ret; 01272 } 01273 return get_perm(string); 01274 }
static struct mansession_session* unref_mansession | ( | struct mansession_session * | s | ) | [static] |
Unreference manager session object. If no more references, then go ahead and delete it.
Definition at line 1278 of file manager.c.
References ao2_ref, ast_log(), and LOG_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().
01279 { 01280 int refcount = ao2_ref(s, -1); 01281 if (manager_debug) { 01282 ast_log(LOG_DEBUG, "Mansession: %p refcount now %d\n", s, refcount - 1); 01283 } 01284 return s; 01285 }
static int whitefilter_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
void * | data, | |||
int | flags | |||
) | [static] |
Definition at line 4183 of file manager.c.
References CMP_MATCH, and CMP_STOP.
Referenced by match_filter().
04184 { 04185 regex_t *regex_filter = obj; 04186 const char *eventdata = arg; 04187 int *result = data; 04188 04189 if (!regexec(regex_filter, eventdata, 0, NULL, 0)) { 04190 *result = 1; 04191 return (CMP_MATCH | CMP_STOP); 04192 } 04193 04194 return 0; 04195 }
int allowmultiplelogin = 1 [static] |
Definition at line 891 of file manager.c.
Referenced by handle_manager_show_settings(), and process_message().
struct ast_threadstorage astman_append_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_astman_append_buf , .custom_init = NULL , } [static] |
int authtimeout [static] |
int block_sockets [static] |
Definition at line 905 of file manager.c.
Referenced by __init_manager(), handle_manager_show_settings(), and session_do().
int broken_events_action [static] |
struct { ... } command_blacklist[] [static] |
Referenced by check_blacklist().
const int DEFAULT_AUTHLIMIT = 50 [static] |
Default setting for authlimit
Definition at line 887 of file manager.c.
Referenced by __init_manager(), and reload_config().
const int DEFAULT_AUTHTIMEOUT = 30 [static] |
Default setting for authtimeout
Definition at line 886 of file manager.c.
Referenced by __init_manager(), and reload_config().
const int DEFAULT_BLOCKSOCKETS = 0 [static] |
Default setting for block-sockets
Definition at line 881 of file manager.c.
Referenced by __init_manager().
const int DEFAULT_BROKENEVENTSACTION = 0 [static] |
Default setting for brokeneventsaction
Definition at line 885 of file manager.c.
Referenced by __init_manager().
const int DEFAULT_DISPLAYCONNECTS = 1 [static] |
Default setting for displaying manager connections
Definition at line 882 of file manager.c.
Referenced by __init_manager().
const int DEFAULT_ENABLED = 0 [static] |
Default setting for manager to be enabled
Definition at line 879 of file manager.c.
Referenced by __init_manager().
const int DEFAULT_HTTPTIMEOUT = 60 [static] |
Default manager http timeout
Definition at line 884 of file manager.c.
Referenced by __init_manager().
const int DEFAULT_MANAGERDEBUG = 0 [static] |
Default setting for manager debug
Definition at line 888 of file manager.c.
Referenced by __init_manager().
const int DEFAULT_TIMESTAMPEVENTS = 0 [static] |
Default setting for timestampevents
Definition at line 883 of file manager.c.
Referenced by __init_manager().
const int DEFAULT_WEBENABLED = 0 [static] |
Default setting for the web interface to be enabled
Definition at line 880 of file manager.c.
Referenced by __init_manager().
int displayconnects [static] |
Definition at line 890 of file manager.c.
Referenced by __init_manager(), do_message(), and handle_manager_show_settings().
char global_realm[MAXHOSTNAMELEN] [static] |
int httptimeout [static] |
Definition at line 893 of file manager.c.
Referenced by __init_manager(), and handle_manager_show_settings().
char* manager_channelvars [static] |
Definition at line 900 of file manager.c.
Referenced by handle_manager_show_settings(), and load_channelvars().
int manager_debug = 0 [static] |
enable some debugging code in the manager
Definition at line 897 of file manager.c.
Referenced by __ast_manager_event_multichan(), __init_manager(), and handle_manager_show_settings().
int manager_enabled = 0 [static] |
Definition at line 895 of file manager.c.
Referenced by __init_manager(), and handle_manager_show_settings().
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] |
helper functions to convert back and forth between string and numeric representation of set of flags
Referenced by action_events(), authority_to_str(), get_perm(), and strings_to_mask().
struct ao2_container* sessions = NULL [static] |
int timestampevents [static] |
Definition at line 892 of file manager.c.
Referenced by __ast_manager_event_multichan(), __init_manager(), and handle_manager_show_settings().
int unauth_sessions = 0 [static] |
struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , } [static] |
int webmanager_enabled = 0 [static] |
Definition at line 896 of file manager.c.
Referenced by __init_manager(), and handle_manager_show_settings().