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 void | destroy_fast_originate_helper (struct fast_originate_helper *doomed) |
static int | do_message (struct mansession *s) |
static void | event_filter_destructor (void *obj) |
static void * | fast_originate (void *data) |
static void | free_channelvars (void) |
static int | function_capable_string_allowed_with_auths (const char *evaluating, int writepermlist) |
Checks to see if a string which can be used to evaluate functions should be rejected. | |
static int | get_input (struct mansession *s, char *output) |
static struct ast_manager_user * | get_manager_by_name_locked (const char *name) |
static int | get_perm (const char *instr) |
static struct eventqent * | grab_last (void) |
static char * | handle_manager_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI command manager reload. | |
static char * | handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static 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 2006 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 1765 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 2047 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 5113 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().
05115 { 05116 struct mansession_session *session; 05117 struct manager_custom_hook *hook; 05118 struct ast_str *auth = ast_str_alloca(80); 05119 const char *cat_str; 05120 va_list ap; 05121 struct timeval now; 05122 struct ast_str *buf; 05123 int i; 05124 05125 if (!(sessions && ao2_container_count(sessions)) && AST_RWLIST_EMPTY(&manager_hooks)) { 05126 return 0; 05127 } 05128 05129 if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) { 05130 return -1; 05131 } 05132 05133 cat_str = authority_to_str(category, &auth); 05134 ast_str_set(&buf, 0, 05135 "Event: %s\r\nPrivilege: %s\r\n", 05136 event, cat_str); 05137 05138 if (timestampevents) { 05139 now = ast_tvnow(); 05140 ast_str_append(&buf, 0, 05141 "Timestamp: %ld.%06lu\r\n", 05142 (long)now.tv_sec, (unsigned long) now.tv_usec); 05143 } 05144 if (manager_debug) { 05145 static int seq; 05146 ast_str_append(&buf, 0, 05147 "SequenceNumber: %d\r\n", 05148 ast_atomic_fetchadd_int(&seq, 1)); 05149 ast_str_append(&buf, 0, 05150 "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func); 05151 } 05152 05153 va_start(ap, fmt); 05154 ast_str_append_va(&buf, 0, fmt, ap); 05155 va_end(ap); 05156 for (i = 0; i < chancount; i++) { 05157 append_channel_vars(&buf, chans[i]); 05158 } 05159 05160 ast_str_append(&buf, 0, "\r\n"); 05161 05162 append_event(ast_str_buffer(buf), category); 05163 05164 /* Wake up any sleeping sessions */ 05165 if (sessions) { 05166 struct ao2_iterator i; 05167 i = ao2_iterator_init(sessions, 0); 05168 while ((session = ao2_iterator_next(&i))) { 05169 ao2_lock(session); 05170 if (session->waiting_thread != AST_PTHREADT_NULL) { 05171 pthread_kill(session->waiting_thread, SIGURG); 05172 } else { 05173 /* We have an event to process, but the mansession is 05174 * not waiting for it. We still need to indicate that there 05175 * is an event waiting so that get_input processes the pending 05176 * event instead of polling. 05177 */ 05178 session->pending_event = 1; 05179 } 05180 ao2_unlock(session); 05181 unref_mansession(session); 05182 } 05183 ao2_iterator_destroy(&i); 05184 } 05185 05186 if (!AST_RWLIST_EMPTY(&manager_hooks)) { 05187 AST_RWLIST_RDLOCK(&manager_hooks); 05188 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) { 05189 hook->helper(category, event, ast_str_buffer(buf)); 05190 } 05191 AST_RWLIST_UNLOCK(&manager_hooks); 05192 } 05193 05194 return 0; 05195 }
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 1780 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().
01781 { 01782 int x, l = strlen(var); 01783 const char *result = ""; 01784 01785 for (x = 0; x < m->hdrcount; x++) { 01786 const char *h = m->headers[x]; 01787 if (!strncasecmp(var, h, l) && h[l] == ':') { 01788 const char *value = h + l + 1; 01789 value = ast_skip_blanks(value); /* ignore leading spaces in the value */ 01790 /* found a potential candidate */ 01791 if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) { 01792 continue; /* not interesting */ 01793 } 01794 if (mode & GET_HEADER_LAST_MATCH) { 01795 result = value; /* record the last match so far */ 01796 } else { 01797 return value; 01798 } 01799 } 01800 } 01801 01802 return result; 01803 }
static void __init_astman_append_buf | ( | void | ) | [static] |
thread local buffer for astman_append
Definition at line 2002 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 3803 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().
03804 { 03805 const char *channel = astman_get_header(m, "Channel"); 03806 const char *pchannel = astman_get_header(m, "ChannelPrefix"); 03807 const char *msgtype = astman_get_header(m, "MsgType"); 03808 const char *chargetype = astman_get_header(m, "ChargeType"); 03809 const char *currencyname = astman_get_header(m, "CurrencyName"); 03810 const char *currencyamount = astman_get_header(m, "CurrencyAmount"); 03811 const char *mult = astman_get_header(m, "CurrencyMultiplier"); 03812 const char *totaltype = astman_get_header(m, "TotalType"); 03813 const char *aocbillingid = astman_get_header(m, "AOCBillingId"); 03814 const char *association_id= astman_get_header(m, "ChargingAssociationId"); 03815 const char *association_num = astman_get_header(m, "ChargingAssociationNumber"); 03816 const char *association_plan = astman_get_header(m, "ChargingAssociationPlan"); 03817 03818 enum ast_aoc_type _msgtype; 03819 enum ast_aoc_charge_type _chargetype; 03820 enum ast_aoc_currency_multiplier _mult = AST_AOC_MULT_ONE; 03821 enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL; 03822 enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA; 03823 unsigned int _currencyamount = 0; 03824 int _association_id = 0; 03825 unsigned int _association_plan = 0; 03826 struct ast_channel *chan = NULL; 03827 03828 struct ast_aoc_decoded *decoded = NULL; 03829 struct ast_aoc_encoded *encoded = NULL; 03830 size_t encoded_size = 0; 03831 03832 if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) { 03833 astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these."); 03834 goto aocmessage_cleanup; 03835 } 03836 03837 if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) { 03838 chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel)); 03839 } 03840 03841 if (!chan) { 03842 astman_send_error(s, m, "No such channel"); 03843 goto aocmessage_cleanup; 03844 } 03845 03846 if (ast_strlen_zero(msgtype) || (strcasecmp(msgtype, "d") && strcasecmp(msgtype, "e"))) { 03847 astman_send_error(s, m, "Invalid MsgType"); 03848 goto aocmessage_cleanup; 03849 } 03850 03851 if (ast_strlen_zero(chargetype)) { 03852 astman_send_error(s, m, "ChargeType not specified"); 03853 goto aocmessage_cleanup; 03854 } 03855 03856 _msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D; 03857 03858 if (!strcasecmp(chargetype, "NA")) { 03859 _chargetype = AST_AOC_CHARGE_NA; 03860 } else if (!strcasecmp(chargetype, "Free")) { 03861 _chargetype = AST_AOC_CHARGE_FREE; 03862 } else if (!strcasecmp(chargetype, "Currency")) { 03863 _chargetype = AST_AOC_CHARGE_CURRENCY; 03864 } else if (!strcasecmp(chargetype, "Unit")) { 03865 _chargetype = AST_AOC_CHARGE_UNIT; 03866 } else { 03867 astman_send_error(s, m, "Invalid ChargeType"); 03868 goto aocmessage_cleanup; 03869 } 03870 03871 if (_chargetype == AST_AOC_CHARGE_CURRENCY) { 03872 03873 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) { 03874 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency"); 03875 goto aocmessage_cleanup; 03876 } 03877 03878 if (ast_strlen_zero(mult)) { 03879 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency."); 03880 goto aocmessage_cleanup; 03881 } else if (!strcasecmp(mult, "onethousandth")) { 03882 _mult = AST_AOC_MULT_ONETHOUSANDTH; 03883 } else if (!strcasecmp(mult, "onehundredth")) { 03884 _mult = AST_AOC_MULT_ONEHUNDREDTH; 03885 } else if (!strcasecmp(mult, "onetenth")) { 03886 _mult = AST_AOC_MULT_ONETENTH; 03887 } else if (!strcasecmp(mult, "one")) { 03888 _mult = AST_AOC_MULT_ONE; 03889 } else if (!strcasecmp(mult, "ten")) { 03890 _mult = AST_AOC_MULT_TEN; 03891 } else if (!strcasecmp(mult, "hundred")) { 03892 _mult = AST_AOC_MULT_HUNDRED; 03893 } else if (!strcasecmp(mult, "thousand")) { 03894 _mult = AST_AOC_MULT_THOUSAND; 03895 } else { 03896 astman_send_error(s, m, "Invalid ChargeMultiplier"); 03897 goto aocmessage_cleanup; 03898 } 03899 } 03900 03901 /* create decoded object and start setting values */ 03902 if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) { 03903 astman_send_error(s, m, "Message Creation Failed"); 03904 goto aocmessage_cleanup; 03905 } 03906 03907 if (_msgtype == AST_AOC_D) { 03908 if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) { 03909 _totaltype = AST_AOC_SUBTOTAL; 03910 } 03911 03912 if (ast_strlen_zero(aocbillingid)) { 03913 /* ignore this is optional */ 03914 } else if (!strcasecmp(aocbillingid, "Normal")) { 03915 _billingid = AST_AOC_BILLING_NORMAL; 03916 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) { 03917 _billingid = AST_AOC_BILLING_REVERSE_CHARGE; 03918 } else if (!strcasecmp(aocbillingid, "CreditCard")) { 03919 _billingid = AST_AOC_BILLING_CREDIT_CARD; 03920 } else { 03921 astman_send_error(s, m, "Invalid AOC-D AOCBillingId"); 03922 goto aocmessage_cleanup; 03923 } 03924 } else { 03925 if (ast_strlen_zero(aocbillingid)) { 03926 /* ignore this is optional */ 03927 } else if (!strcasecmp(aocbillingid, "Normal")) { 03928 _billingid = AST_AOC_BILLING_NORMAL; 03929 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) { 03930 _billingid = AST_AOC_BILLING_REVERSE_CHARGE; 03931 } else if (!strcasecmp(aocbillingid, "CreditCard")) { 03932 _billingid = AST_AOC_BILLING_CREDIT_CARD; 03933 } else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) { 03934 _billingid = AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL; 03935 } else if (!strcasecmp(aocbillingid, "CallFwdBusy")) { 03936 _billingid = AST_AOC_BILLING_CALL_FWD_BUSY; 03937 } else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) { 03938 _billingid = AST_AOC_BILLING_CALL_FWD_NO_REPLY; 03939 } else if (!strcasecmp(aocbillingid, "CallDeflection")) { 03940 _billingid = AST_AOC_BILLING_CALL_DEFLECTION; 03941 } else if (!strcasecmp(aocbillingid, "CallTransfer")) { 03942 _billingid = AST_AOC_BILLING_CALL_TRANSFER; 03943 } else { 03944 astman_send_error(s, m, "Invalid AOC-E AOCBillingId"); 03945 goto aocmessage_cleanup; 03946 } 03947 03948 if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) { 03949 astman_send_error(s, m, "Invalid ChargingAssociationId"); 03950 goto aocmessage_cleanup; 03951 } 03952 if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) { 03953 astman_send_error(s, m, "Invalid ChargingAssociationPlan"); 03954 goto aocmessage_cleanup; 03955 } 03956 03957 if (_association_id) { 03958 ast_aoc_set_association_id(decoded, _association_id); 03959 } else if (!ast_strlen_zero(association_num)) { 03960 ast_aoc_set_association_number(decoded, association_num, _association_plan); 03961 } 03962 } 03963 03964 if (_chargetype == AST_AOC_CHARGE_CURRENCY) { 03965 ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname); 03966 } else if (_chargetype == AST_AOC_CHARGE_UNIT) { 03967 struct ast_aoc_unit_entry entry; 03968 int i; 03969 03970 /* multiple unit entries are possible, lets get them all */ 03971 for (i = 0; i < 32; i++) { 03972 if (aocmessage_get_unit_entry(m, &entry, i)) { 03973 break; /* that's the end then */ 03974 } 03975 03976 ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type); 03977 } 03978 03979 /* at least one unit entry is required */ 03980 if (!i) { 03981 astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit"); 03982 goto aocmessage_cleanup; 03983 } 03984 03985 } 03986 03987 ast_aoc_set_billing_id(decoded, _billingid); 03988 ast_aoc_set_total_type(decoded, _totaltype); 03989 03990 03991 if ((encoded = ast_aoc_encode(decoded, &encoded_size, NULL)) && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) { 03992 astman_send_ack(s, m, "AOC Message successfully queued on channel"); 03993 } else { 03994 astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel"); 03995 } 03996 03997 aocmessage_cleanup: 03998 03999 ast_aoc_destroy_decoded(decoded); 04000 ast_aoc_destroy_encoded(encoded); 04001 04002 if (chan) { 04003 chan = ast_channel_unref(chan); 04004 } 04005 return 0; 04006 }
static int action_atxfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3531 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().
03532 { 03533 const char *name = astman_get_header(m, "Channel"); 03534 const char *exten = astman_get_header(m, "Exten"); 03535 const char *context = astman_get_header(m, "Context"); 03536 struct ast_channel *chan = NULL; 03537 struct ast_call_feature *atxfer_feature = NULL; 03538 char *feature_code = NULL; 03539 03540 if (ast_strlen_zero(name)) { 03541 astman_send_error(s, m, "No channel specified"); 03542 return 0; 03543 } 03544 if (ast_strlen_zero(exten)) { 03545 astman_send_error(s, m, "No extension specified"); 03546 return 0; 03547 } 03548 03549 if (!(atxfer_feature = ast_find_call_feature("atxfer"))) { 03550 astman_send_error(s, m, "No attended transfer feature found"); 03551 return 0; 03552 } 03553 03554 if (!(chan = ast_channel_get_by_name(name))) { 03555 astman_send_error(s, m, "Channel specified does not exist"); 03556 return 0; 03557 } 03558 03559 if (!ast_strlen_zero(context)) { 03560 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context); 03561 } 03562 03563 for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) { 03564 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *feature_code }; 03565 ast_queue_frame(chan, &f); 03566 } 03567 03568 for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) { 03569 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *feature_code }; 03570 ast_queue_frame(chan, &f); 03571 } 03572 03573 chan = ast_channel_unref(chan); 03574 03575 astman_send_ack(s, m, "Atxfer successfully queued"); 03576 03577 return 0; 03578 }
static int action_challenge | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3086 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().
03087 { 03088 const char *authtype = astman_get_header(m, "AuthType"); 03089 03090 if (!strcasecmp(authtype, "MD5")) { 03091 if (ast_strlen_zero(s->session->challenge)) { 03092 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random()); 03093 } 03094 mansession_lock(s); 03095 astman_start_ack(s, m); 03096 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge); 03097 mansession_unlock(s); 03098 } else { 03099 astman_send_error(s, m, "Must specify AuthType"); 03100 } 03101 return 0; 03102 }
static int action_command | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager command "command" - execute CLI command.
Definition at line 3616 of file manager.c.
References ast_cli_command, ast_free, ast_log(), AST_LOG_WARNING, ast_malloc, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), check_blacklist(), errno, LOG_WARNING, and term_strip().
Referenced by __init_manager().
03617 { 03618 const char *cmd = astman_get_header(m, "Command"); 03619 const char *id = astman_get_header(m, "ActionID"); 03620 char *buf = NULL, *final_buf = NULL; 03621 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 03622 int fd; 03623 off_t l; 03624 03625 if (ast_strlen_zero(cmd)) { 03626 astman_send_error(s, m, "No command provided"); 03627 return 0; 03628 } 03629 03630 if (check_blacklist(cmd)) { 03631 astman_send_error(s, m, "Command blacklisted"); 03632 return 0; 03633 } 03634 03635 if ((fd = mkstemp(template)) < 0) { 03636 ast_log(AST_LOG_WARNING, "Failed to create temporary file for command: %s\n", strerror(errno)); 03637 astman_send_error(s, m, "Command response construction error"); 03638 return 0; 03639 } 03640 03641 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 03642 if (!ast_strlen_zero(id)) { 03643 astman_append(s, "ActionID: %s\r\n", id); 03644 } 03645 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 03646 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 03647 /* Determine number of characters available */ 03648 if ((l = lseek(fd, 0, SEEK_END)) < 0) { 03649 ast_log(LOG_WARNING, "Failed to determine number of characters for command: %s\n", strerror(errno)); 03650 goto action_command_cleanup; 03651 } 03652 03653 /* This has a potential to overflow the stack. Hence, use the heap. */ 03654 buf = ast_malloc(l + 1); 03655 final_buf = ast_malloc(l + 1); 03656 03657 if (!buf || !final_buf) { 03658 ast_log(LOG_WARNING, "Failed to allocate memory for temporary buffer\n"); 03659 goto action_command_cleanup; 03660 } 03661 03662 if (lseek(fd, 0, SEEK_SET) < 0) { 03663 ast_log(LOG_WARNING, "Failed to set position on temporary file for command: %s\n", strerror(errno)); 03664 goto action_command_cleanup; 03665 } 03666 03667 if (read(fd, buf, l) < 0) { 03668 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 03669 goto action_command_cleanup; 03670 } 03671 03672 buf[l] = '\0'; 03673 term_strip(final_buf, buf, l); 03674 final_buf[l] = '\0'; 03675 astman_append(s, "%s", final_buf); 03676 03677 action_command_cleanup: 03678 03679 close(fd); 03680 unlink(template); 03681 astman_append(s, "--END COMMAND--\r\n\r\n"); 03682 03683 ast_free(buf); 03684 ast_free(final_buf); 03685 03686 return 0; 03687 }
static int action_coresettings | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core settings information.
Definition at line 4352 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().
04353 { 04354 const char *actionid = astman_get_header(m, "ActionID"); 04355 char idText[150]; 04356 04357 if (!ast_strlen_zero(actionid)) { 04358 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 04359 } else { 04360 idText[0] = '\0'; 04361 } 04362 04363 astman_append(s, "Response: Success\r\n" 04364 "%s" 04365 "AMIversion: %s\r\n" 04366 "AsteriskVersion: %s\r\n" 04367 "SystemName: %s\r\n" 04368 "CoreMaxCalls: %d\r\n" 04369 "CoreMaxLoadAvg: %f\r\n" 04370 "CoreRunUser: %s\r\n" 04371 "CoreRunGroup: %s\r\n" 04372 "CoreMaxFilehandles: %d\r\n" 04373 "CoreRealTimeEnabled: %s\r\n" 04374 "CoreCDRenabled: %s\r\n" 04375 "CoreHTTPenabled: %s\r\n" 04376 "\r\n", 04377 idText, 04378 AMI_VERSION, 04379 ast_get_version(), 04380 ast_config_AST_SYSTEM_NAME, 04381 option_maxcalls, 04382 option_maxload, 04383 ast_config_AST_RUN_USER, 04384 ast_config_AST_RUN_GROUP, 04385 option_maxfiles, 04386 AST_CLI_YESNO(ast_realtime_enabled()), 04387 AST_CLI_YESNO(check_cdr_enabled()), 04388 AST_CLI_YESNO(check_webmanager_enabled()) 04389 ); 04390 return 0; 04391 }
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 4461 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().
04462 { 04463 const char *actionid = astman_get_header(m, "ActionID"); 04464 char idText[256]; 04465 struct ast_channel *c = NULL; 04466 int numchans = 0; 04467 int duration, durh, durm, durs; 04468 struct ast_channel_iterator *iter; 04469 04470 if (!ast_strlen_zero(actionid)) { 04471 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 04472 } else { 04473 idText[0] = '\0'; 04474 } 04475 04476 if (!(iter = ast_channel_iterator_all_new())) { 04477 astman_send_error(s, m, "Memory Allocation Failure"); 04478 return 1; 04479 } 04480 04481 astman_send_listack(s, m, "Channels will follow", "start"); 04482 04483 for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) { 04484 struct ast_channel *bc; 04485 char durbuf[10] = ""; 04486 04487 ast_channel_lock(c); 04488 04489 bc = ast_bridged_channel(c); 04490 if (c->cdr && !ast_tvzero(c->cdr->start)) { 04491 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 04492 durh = duration / 3600; 04493 durm = (duration % 3600) / 60; 04494 durs = duration % 60; 04495 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 04496 } 04497 04498 astman_append(s, 04499 "Event: CoreShowChannel\r\n" 04500 "%s" 04501 "Channel: %s\r\n" 04502 "UniqueID: %s\r\n" 04503 "Context: %s\r\n" 04504 "Extension: %s\r\n" 04505 "Priority: %d\r\n" 04506 "ChannelState: %d\r\n" 04507 "ChannelStateDesc: %s\r\n" 04508 "Application: %s\r\n" 04509 "ApplicationData: %s\r\n" 04510 "CallerIDnum: %s\r\n" 04511 "CallerIDname: %s\r\n" 04512 "ConnectedLineNum: %s\r\n" 04513 "ConnectedLineName: %s\r\n" 04514 "Duration: %s\r\n" 04515 "AccountCode: %s\r\n" 04516 "BridgedChannel: %s\r\n" 04517 "BridgedUniqueID: %s\r\n" 04518 "\r\n", idText, c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, 04519 ast_state2str(c->_state), c->appl ? c->appl : "", c->data ? S_OR(c->data, "") : "", 04520 S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""), 04521 S_COR(c->caller.id.name.valid, c->caller.id.name.str, ""), 04522 S_COR(c->connected.id.number.valid, c->connected.id.number.str, ""), 04523 S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""), 04524 durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : ""); 04525 04526 ast_channel_unlock(c); 04527 04528 numchans++; 04529 } 04530 04531 astman_append(s, 04532 "Event: CoreShowChannelsComplete\r\n" 04533 "EventList: Complete\r\n" 04534 "ListItems: %d\r\n" 04535 "%s" 04536 "\r\n", numchans, idText); 04537 04538 ast_channel_iterator_destroy(iter); 04539 04540 return 0; 04541 }
static int action_corestatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core status information.
Definition at line 4394 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().
04395 { 04396 const char *actionid = astman_get_header(m, "ActionID"); 04397 char idText[150]; 04398 char startuptime[150], startupdate[150]; 04399 char reloadtime[150], reloaddate[150]; 04400 struct ast_tm tm; 04401 04402 if (!ast_strlen_zero(actionid)) { 04403 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 04404 } else { 04405 idText[0] = '\0'; 04406 } 04407 04408 ast_localtime(&ast_startuptime, &tm, NULL); 04409 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm); 04410 ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm); 04411 ast_localtime(&ast_lastreloadtime, &tm, NULL); 04412 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm); 04413 ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm); 04414 04415 astman_append(s, "Response: Success\r\n" 04416 "%s" 04417 "CoreStartupDate: %s\r\n" 04418 "CoreStartupTime: %s\r\n" 04419 "CoreReloadDate: %s\r\n" 04420 "CoreReloadTime: %s\r\n" 04421 "CoreCurrentCalls: %d\r\n" 04422 "\r\n", 04423 idText, 04424 startupdate, 04425 startuptime, 04426 reloaddate, 04427 reloadtime, 04428 ast_active_channels() 04429 ); 04430 return 0; 04431 }
static int action_createconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2862 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().
02863 { 02864 int fd; 02865 const char *fn = astman_get_header(m, "Filename"); 02866 struct ast_str *filepath = ast_str_alloca(PATH_MAX); 02867 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR); 02868 ast_str_append(&filepath, 0, "%s", fn); 02869 02870 if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) { 02871 close(fd); 02872 astman_send_ack(s, m, "New configuration file created successfully"); 02873 } else { 02874 astman_send_error(s, m, strerror(errno)); 02875 } 02876 02877 return 0; 02878 }
static void action_destroy | ( | void * | obj | ) | [static] |
Definition at line 5302 of file manager.c.
References ast_string_field_free_memory.
Referenced by ast_manager_register2().
05303 { 05304 struct manager_action *doomed = obj; 05305 05306 if (doomed->synopsis) { 05307 /* The string fields were initialized. */ 05308 ast_string_field_free_memory(doomed); 05309 } 05310 }
static int action_events | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3005 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().
03006 { 03007 const char *mask = astman_get_header(m, "EventMask"); 03008 int res, x; 03009 const char *id = astman_get_header(m, "ActionID"); 03010 char id_text[256]; 03011 03012 if (!ast_strlen_zero(id)) { 03013 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id); 03014 } else { 03015 id_text[0] = '\0'; 03016 } 03017 03018 res = set_eventmask(s, mask); 03019 if (broken_events_action) { 03020 /* if this option is set we should not return a response on 03021 * error, or when all events are set */ 03022 03023 if (res > 0) { 03024 for (x = 0; x < ARRAY_LEN(perms); x++) { 03025 if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) { 03026 return 0; 03027 } 03028 } 03029 astman_append(s, "Response: Success\r\n%s" 03030 "Events: On\r\n\r\n", id_text); 03031 } else if (res == 0) 03032 astman_append(s, "Response: Success\r\n%s" 03033 "Events: Off\r\n\r\n", id_text); 03034 return 0; 03035 } 03036 03037 if (res > 0) 03038 astman_append(s, "Response: Success\r\n%s" 03039 "Events: On\r\n\r\n", id_text); 03040 else if (res == 0) 03041 astman_append(s, "Response: Success\r\n%s" 03042 "Events: Off\r\n\r\n", id_text); 03043 else 03044 astman_send_error(s, m, "Invalid event mask"); 03045 03046 return 0; 03047 }
static int action_extensionstate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4190 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().
04191 { 04192 const char *exten = astman_get_header(m, "Exten"); 04193 const char *context = astman_get_header(m, "Context"); 04194 char hint[256] = ""; 04195 int status; 04196 if (ast_strlen_zero(exten)) { 04197 astman_send_error(s, m, "Extension not specified"); 04198 return 0; 04199 } 04200 if (ast_strlen_zero(context)) { 04201 context = "default"; 04202 } 04203 status = ast_extension_state(NULL, context, exten); 04204 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 04205 astman_start_ack(s, m); 04206 astman_append(s, "Message: Extension Status\r\n" 04207 "Exten: %s\r\n" 04208 "Context: %s\r\n" 04209 "Hint: %s\r\n" 04210 "Status: %d\r\n\r\n", 04211 exten, context, hint, status); 04212 return 0; 04213 }
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 2480 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_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __init_manager().
02481 { 02482 struct ast_config *cfg; 02483 const char *fn = astman_get_header(m, "Filename"); 02484 const char *category = astman_get_header(m, "Category"); 02485 int catcount = 0; 02486 int lineno = 0; 02487 char *cur_category = NULL; 02488 struct ast_variable *v; 02489 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 02490 02491 if (ast_strlen_zero(fn)) { 02492 astman_send_error(s, m, "Filename not specified"); 02493 return 0; 02494 } 02495 cfg = ast_config_load2(fn, "manager", config_flags); 02496 if (cfg == CONFIG_STATUS_FILEMISSING) { 02497 astman_send_error(s, m, "Config file not found"); 02498 return 0; 02499 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02500 astman_send_error(s, m, "Config file has invalid format"); 02501 return 0; 02502 } 02503 02504 astman_start_ack(s, m); 02505 while ((cur_category = ast_category_browse(cfg, cur_category))) { 02506 if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) { 02507 lineno = 0; 02508 astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category); 02509 for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) { 02510 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 02511 } 02512 catcount++; 02513 } 02514 } 02515 if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */ 02516 astman_append(s, "No categories found\r\n"); 02517 } 02518 ast_config_destroy(cfg); 02519 astman_append(s, "\r\n"); 02520 02521 return 0; 02522 }
static int action_getconfigjson | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2590 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_STATUS_FILEINVALID, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __init_manager().
02591 { 02592 struct ast_config *cfg; 02593 const char *fn = astman_get_header(m, "Filename"); 02594 char *category = NULL; 02595 struct ast_variable *v; 02596 int comma1 = 0; 02597 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 02598 02599 if (ast_strlen_zero(fn)) { 02600 astman_send_error(s, m, "Filename not specified"); 02601 return 0; 02602 } 02603 02604 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 02605 astman_send_error(s, m, "Config file not found"); 02606 return 0; 02607 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02608 astman_send_error(s, m, "Config file has invalid format"); 02609 return 0; 02610 } 02611 02612 astman_start_ack(s, m); 02613 astman_append(s, "JSON: {"); 02614 while ((category = ast_category_browse(cfg, category))) { 02615 int comma2 = 0; 02616 02617 astman_append(s, "%s\"", comma1 ? "," : ""); 02618 astman_append_json(s, category); 02619 astman_append(s, "\":["); 02620 comma1 = 1; 02621 for (v = ast_variable_browse(cfg, category); v; v = v->next) { 02622 astman_append(s, "%s\"", comma2 ? "," : ""); 02623 astman_append_json(s, v->name); 02624 astman_append(s, "\":\""); 02625 astman_append_json(s, v->value); 02626 astman_append(s, "\""); 02627 comma2 = 1; 02628 } 02629 astman_append(s, "]"); 02630 } 02631 astman_append(s, "}\r\n\r\n"); 02632 02633 ast_config_destroy(cfg); 02634 02635 return 0; 02636 }
static int action_getvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3180 of file manager.c.
References ast_channel_get_by_name(), ast_channel_unref, ast_dummy_channel_alloc(), ast_func_read(), ast_log(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), function_capable_string_allowed_with_auths(), LOG_ERROR, name, pbx_retrieve_variable(), S_OR, mansession::session, and mansession_session::writeperm.
Referenced by __init_manager().
03181 { 03182 struct ast_channel *c = NULL; 03183 const char *name = astman_get_header(m, "Channel"); 03184 const char *varname = astman_get_header(m, "Variable"); 03185 char *varval; 03186 char workspace[1024]; 03187 03188 if (ast_strlen_zero(varname)) { 03189 astman_send_error(s, m, "No variable specified"); 03190 return 0; 03191 } 03192 03193 /* We don't want users with insufficient permissions using certain functions. */ 03194 if (!(function_capable_string_allowed_with_auths(varname, s->session->writeperm))) { 03195 astman_send_error(s, m, "GetVar Access Forbidden: Variable"); 03196 return 0; 03197 } 03198 03199 if (!ast_strlen_zero(name)) { 03200 if (!(c = ast_channel_get_by_name(name))) { 03201 astman_send_error(s, m, "No such channel"); 03202 return 0; 03203 } 03204 } 03205 03206 workspace[0] = '\0'; 03207 if (varname[strlen(varname) - 1] == ')') { 03208 if (!c) { 03209 c = ast_dummy_channel_alloc(); 03210 if (c) { 03211 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 03212 } else 03213 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 03214 } else { 03215 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 03216 } 03217 varval = workspace; 03218 } else { 03219 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 03220 } 03221 03222 if (c) { 03223 c = ast_channel_unref(c); 03224 } 03225 03226 astman_start_ack(s, m); 03227 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, "")); 03228 03229 return 0; 03230 }
static int action_hangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3104 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().
03105 { 03106 struct ast_channel *c = NULL; 03107 int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */ 03108 const char *name = astman_get_header(m, "Channel"); 03109 const char *cause = astman_get_header(m, "Cause"); 03110 03111 if (ast_strlen_zero(name)) { 03112 astman_send_error(s, m, "No channel specified"); 03113 return 0; 03114 } 03115 03116 if (!ast_strlen_zero(cause)) { 03117 char *endptr; 03118 causecode = strtol(cause, &endptr, 10); 03119 if (causecode < 0 || causecode > 127 || *endptr != '\0') { 03120 ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause); 03121 /* keep going, better to hangup without cause than to not hang up at all */ 03122 causecode = 0; /* do not set channel's hangupcause */ 03123 } 03124 } 03125 03126 if (!(c = ast_channel_get_by_name(name))) { 03127 astman_send_error(s, m, "No such channel"); 03128 return 0; 03129 } 03130 03131 ast_channel_lock(c); 03132 if (causecode > 0) { 03133 ast_debug(1, "Setting hangupcause of channel %s to %d (is %d now)\n", 03134 c->name, causecode, c->hangupcause); 03135 c->hangupcause = causecode; 03136 } 03137 ast_softhangup_nolock(c, AST_SOFTHANGUP_EXPLICIT); 03138 ast_channel_unlock(c); 03139 03140 c = ast_channel_unref(c); 03141 03142 astman_send_ack(s, m, "Channel Hungup"); 03143 03144 return 0; 03145 }
static int action_listcategories | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2524 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, and CONFIG_STATUS_FILEINVALID.
Referenced by __init_manager().
02525 { 02526 struct ast_config *cfg; 02527 const char *fn = astman_get_header(m, "Filename"); 02528 char *category = NULL; 02529 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 02530 int catcount = 0; 02531 02532 if (ast_strlen_zero(fn)) { 02533 astman_send_error(s, m, "Filename not specified"); 02534 return 0; 02535 } 02536 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 02537 astman_send_error(s, m, "Config file not found"); 02538 return 0; 02539 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02540 astman_send_error(s, m, "Config file has invalid format"); 02541 return 0; 02542 } 02543 astman_start_ack(s, m); 02544 while ((category = ast_category_browse(cfg, category))) { 02545 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 02546 catcount++; 02547 } 02548 if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */ 02549 astman_append(s, "Error: no categories found\r\n"); 02550 } 02551 ast_config_destroy(cfg); 02552 astman_append(s, "\r\n"); 02553 02554 return 0; 02555 }
static int action_listcommands | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2986 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().
02987 { 02988 struct manager_action *cur; 02989 struct ast_str *temp = ast_str_alloca(256); 02990 02991 astman_start_ack(s, m); 02992 AST_RWLIST_RDLOCK(&actions); 02993 AST_RWLIST_TRAVERSE(&actions, cur, list) { 02994 if ((s->session->writeperm & cur->authority) || cur->authority == 0) { 02995 astman_append(s, "%s: %s (Priv: %s)\r\n", 02996 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp)); 02997 } 02998 } 02999 AST_RWLIST_UNLOCK(&actions); 03000 astman_append(s, "\r\n"); 03001 03002 return 0; 03003 }
static int action_login | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3055 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().
03056 { 03057 03058 /* still authenticated - don't process again */ 03059 if (s->session->authenticated) { 03060 astman_send_ack(s, m, "Already authenticated"); 03061 return 0; 03062 } 03063 03064 if (authenticate(s, m)) { 03065 sleep(1); 03066 astman_send_error(s, m, "Authentication failed"); 03067 return -1; 03068 } 03069 s->session->authenticated = 1; 03070 ast_atomic_fetchadd_int(&unauth_sessions, -1); 03071 if (manager_displayconnects(s->session)) { 03072 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)); 03073 } 03074 astman_send_ack(s, m, "Authentication accepted"); 03075 if ((s->session->send_events & EVENT_FLAG_SYSTEM) 03076 && ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) { 03077 struct ast_str *auth = ast_str_alloca(80); 03078 const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth); 03079 astman_append(s, "Event: FullyBooted\r\n" 03080 "Privilege: %s\r\n" 03081 "Status: Fully Booted\r\n\r\n", cat_str); 03082 } 03083 return 0; 03084 }
static int action_logoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3049 of file manager.c.
References astman_send_response().
Referenced by __init_manager().
03050 { 03051 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 03052 return -1; 03053 }
static int action_mailboxcount | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4169 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().
04170 { 04171 const char *mailbox = astman_get_header(m, "Mailbox"); 04172 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;; 04173 04174 if (ast_strlen_zero(mailbox)) { 04175 astman_send_error(s, m, "Mailbox not specified"); 04176 return 0; 04177 } 04178 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs); 04179 astman_start_ack(s, m); 04180 astman_append(s, "Message: Mailbox Message Count\r\n" 04181 "Mailbox: %s\r\n" 04182 "UrgMessages: %d\r\n" 04183 "NewMessages: %d\r\n" 04184 "OldMessages: %d\r\n" 04185 "\r\n", 04186 mailbox, urgentmsgs, newmsgs, oldmsgs); 04187 return 0; 04188 }
static int action_mailboxstatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4152 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().
04153 { 04154 const char *mailbox = astman_get_header(m, "Mailbox"); 04155 int ret; 04156 04157 if (ast_strlen_zero(mailbox)) { 04158 astman_send_error(s, m, "Mailbox not specified"); 04159 return 0; 04160 } 04161 ret = ast_app_has_voicemail(mailbox, NULL); 04162 astman_start_ack(s, m); 04163 astman_append(s, "Message: Mailbox Status\r\n" 04164 "Mailbox: %s\r\n" 04165 "Waiting: %d\r\n\r\n", mailbox, ret); 04166 return 0; 04167 }
static int action_originate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4008 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_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, ast_frame::data, destroy_fast_originate_helper(), EVENT_FLAG_SYSTEM, exten, fast_originate(), name, mansession::session, strcasestr(), and mansession_session::writeperm.
Referenced by __init_manager().
04009 { 04010 const char *name = astman_get_header(m, "Channel"); 04011 const char *exten = astman_get_header(m, "Exten"); 04012 const char *context = astman_get_header(m, "Context"); 04013 const char *priority = astman_get_header(m, "Priority"); 04014 const char *timeout = astman_get_header(m, "Timeout"); 04015 const char *callerid = astman_get_header(m, "CallerID"); 04016 const char *account = astman_get_header(m, "Account"); 04017 const char *app = astman_get_header(m, "Application"); 04018 const char *appdata = astman_get_header(m, "Data"); 04019 const char *async = astman_get_header(m, "Async"); 04020 const char *id = astman_get_header(m, "ActionID"); 04021 const char *codecs = astman_get_header(m, "Codecs"); 04022 struct ast_variable *vars; 04023 char *tech, *data; 04024 char *l = NULL, *n = NULL; 04025 int pi = 0; 04026 int res; 04027 int to = 30000; 04028 int reason = 0; 04029 char tmp[256]; 04030 char tmp2[256]; 04031 format_t format = AST_FORMAT_SLINEAR; 04032 04033 pthread_t th; 04034 if (ast_strlen_zero(name)) { 04035 astman_send_error(s, m, "Channel not specified"); 04036 return 0; 04037 } 04038 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 04039 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 04040 astman_send_error(s, m, "Invalid priority"); 04041 return 0; 04042 } 04043 } 04044 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) { 04045 astman_send_error(s, m, "Invalid timeout"); 04046 return 0; 04047 } 04048 ast_copy_string(tmp, name, sizeof(tmp)); 04049 tech = tmp; 04050 data = strchr(tmp, '/'); 04051 if (!data) { 04052 astman_send_error(s, m, "Invalid channel"); 04053 return 0; 04054 } 04055 *data++ = '\0'; 04056 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 04057 ast_callerid_parse(tmp2, &n, &l); 04058 if (n) { 04059 if (ast_strlen_zero(n)) { 04060 n = NULL; 04061 } 04062 } 04063 if (l) { 04064 ast_shrink_phone_number(l); 04065 if (ast_strlen_zero(l)) { 04066 l = NULL; 04067 } 04068 } 04069 if (!ast_strlen_zero(codecs)) { 04070 format = 0; 04071 ast_parse_allow_disallow(NULL, &format, codecs, 1); 04072 } 04073 if (!ast_strlen_zero(app) && s->session) { 04074 int bad_appdata = 0; 04075 /* To run the System application (or anything else that goes to 04076 * shell), you must have the additional System privilege */ 04077 if (!(s->session->writeperm & EVENT_FLAG_SYSTEM) 04078 && ( 04079 strcasestr(app, "system") || /* System(rm -rf /) 04080 TrySystem(rm -rf /) */ 04081 strcasestr(app, "exec") || /* Exec(System(rm -rf /)) 04082 TryExec(System(rm -rf /)) */ 04083 strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /) 04084 EAGI(/bin/rm,-rf /) */ 04085 strcasestr(app, "mixmonitor") || /* MixMonitor(blah,,rm -rf) */ 04086 strcasestr(app, "externalivr") || /* ExternalIVR(rm -rf) */ 04087 (strstr(appdata, "SHELL") && (bad_appdata = 1)) || /* NoOp(${SHELL(rm -rf /)}) */ 04088 (strstr(appdata, "EVAL") && (bad_appdata = 1)) /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ 04089 )) { 04090 char error_buf[64]; 04091 snprintf(error_buf, sizeof(error_buf), "Originate Access Forbidden: %s", bad_appdata ? "Data" : "Application"); 04092 astman_send_error(s, m, error_buf); 04093 return 0; 04094 } 04095 } 04096 /* Allocate requested channel variables */ 04097 vars = astman_get_variables(m); 04098 04099 if (ast_true(async)) { 04100 struct fast_originate_helper *fast; 04101 04102 fast = ast_calloc(1, sizeof(*fast)); 04103 if (!fast || ast_string_field_init(fast, 252)) { 04104 ast_free(fast); 04105 ast_variables_destroy(vars); 04106 res = -1; 04107 } else { 04108 if (!ast_strlen_zero(id)) { 04109 ast_string_field_build(fast, idtext, "ActionID: %s\r\n", id); 04110 } 04111 ast_string_field_set(fast, tech, tech); 04112 ast_string_field_set(fast, data, data); 04113 ast_string_field_set(fast, app, app); 04114 ast_string_field_set(fast, appdata, appdata); 04115 ast_string_field_set(fast, cid_num, l); 04116 ast_string_field_set(fast, cid_name, n); 04117 ast_string_field_set(fast, context, context); 04118 ast_string_field_set(fast, exten, exten); 04119 ast_string_field_set(fast, account, account); 04120 fast->vars = vars; 04121 fast->format = format; 04122 fast->timeout = to; 04123 fast->priority = pi; 04124 if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) { 04125 destroy_fast_originate_helper(fast); 04126 res = -1; 04127 } else { 04128 res = 0; 04129 } 04130 } 04131 } else if (!ast_strlen_zero(app)) { 04132 res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 04133 /* Any vars memory was passed to ast_pbx_outgoing_app(). */ 04134 } else { 04135 if (exten && context && pi) { 04136 res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 04137 /* Any vars memory was passed to ast_pbx_outgoing_exten(). */ 04138 } else { 04139 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 04140 ast_variables_destroy(vars); 04141 return 0; 04142 } 04143 } 04144 if (!res) { 04145 astman_send_ack(s, m, "Originate successfully queued"); 04146 } else { 04147 astman_send_error(s, m, "Originate failed"); 04148 } 04149 return 0; 04150 }
static int action_ping | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2462 of file manager.c.
References ast_strlen_zero(), ast_tvnow(), astman_append(), and astman_get_header().
Referenced by __init_manager().
02463 { 02464 const char *actionid = astman_get_header(m, "ActionID"); 02465 struct timeval now = ast_tvnow(); 02466 02467 astman_append(s, "Response: Success\r\n"); 02468 if (!ast_strlen_zero(actionid)){ 02469 astman_append(s, "ActionID: %s\r\n", actionid); 02470 } 02471 astman_append( 02472 s, 02473 "Ping: Pong\r\n" 02474 "Timestamp: %ld.%06lu\r\n" 02475 "\r\n", 02476 (long) now.tv_sec, (unsigned long) now.tv_usec); 02477 return 0; 02478 }
static int action_redirect | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_redirect: The redirect manager command
Definition at line 3431 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().
03432 { 03433 const char *name = astman_get_header(m, "Channel"); 03434 const char *name2 = astman_get_header(m, "ExtraChannel"); 03435 const char *exten = astman_get_header(m, "Exten"); 03436 const char *exten2 = astman_get_header(m, "ExtraExten"); 03437 const char *context = astman_get_header(m, "Context"); 03438 const char *context2 = astman_get_header(m, "ExtraContext"); 03439 const char *priority = astman_get_header(m, "Priority"); 03440 const char *priority2 = astman_get_header(m, "ExtraPriority"); 03441 struct ast_channel *chan, *chan2 = NULL; 03442 int pi, pi2 = 0; 03443 int res; 03444 03445 if (ast_strlen_zero(name)) { 03446 astman_send_error(s, m, "Channel not specified"); 03447 return 0; 03448 } 03449 03450 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 03451 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 03452 astman_send_error(s, m, "Invalid priority"); 03453 return 0; 03454 } 03455 } 03456 03457 if (!ast_strlen_zero(priority2) && (sscanf(priority2, "%30d", &pi2) != 1)) { 03458 if ((pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL)) < 1) { 03459 astman_send_error(s, m, "Invalid ExtraPriority"); 03460 return 0; 03461 } 03462 } 03463 03464 if (!(chan = ast_channel_get_by_name(name))) { 03465 char buf[256]; 03466 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 03467 astman_send_error(s, m, buf); 03468 return 0; 03469 } 03470 03471 if (ast_check_hangup_locked(chan)) { 03472 astman_send_error(s, m, "Redirect failed, channel not up."); 03473 chan = ast_channel_unref(chan); 03474 return 0; 03475 } 03476 03477 if (!ast_strlen_zero(name2)) { 03478 chan2 = ast_channel_get_by_name(name2); 03479 } 03480 03481 if (chan2 && ast_check_hangup_locked(chan2)) { 03482 astman_send_error(s, m, "Redirect failed, extra channel not up."); 03483 chan = ast_channel_unref(chan); 03484 chan2 = ast_channel_unref(chan2); 03485 return 0; 03486 } 03487 03488 if (chan->pbx) { 03489 ast_channel_lock(chan); 03490 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 03491 ast_channel_unlock(chan); 03492 } 03493 03494 res = ast_async_goto(chan, context, exten, pi); 03495 if (!res) { 03496 if (!ast_strlen_zero(name2)) { 03497 if (chan2) { 03498 if (chan2->pbx) { 03499 ast_channel_lock(chan2); 03500 ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 03501 ast_channel_unlock(chan2); 03502 } 03503 if (!ast_strlen_zero(context2)) { 03504 res = ast_async_goto(chan2, context2, exten2, pi2); 03505 } else { 03506 res = ast_async_goto(chan2, context, exten, pi); 03507 } 03508 } else { 03509 res = -1; 03510 } 03511 if (!res) { 03512 astman_send_ack(s, m, "Dual Redirect successful"); 03513 } else { 03514 astman_send_error(s, m, "Secondary redirect failed"); 03515 } 03516 } else { 03517 astman_send_ack(s, m, "Redirect successful"); 03518 } 03519 } else { 03520 astman_send_error(s, m, "Redirect failed"); 03521 } 03522 03523 chan = ast_channel_unref(chan); 03524 if (chan2) { 03525 chan2 = ast_channel_unref(chan2); 03526 } 03527 03528 return 0; 03529 }
static int action_reload | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Send a reload event.
Definition at line 4434 of file manager.c.
References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.
Referenced by __init_manager().
04435 { 04436 const char *module = astman_get_header(m, "Module"); 04437 int res = ast_module_reload(S_OR(module, NULL)); 04438 04439 switch (res) { 04440 case -1: 04441 astman_send_error(s, m, "A reload is in progress"); 04442 break; 04443 case 0: 04444 astman_send_error(s, m, "No such module"); 04445 break; 04446 case 1: 04447 astman_send_error(s, m, "Module does not support reload"); 04448 break; 04449 case 2: 04450 astman_send_ack(s, m, "Module Reloaded"); 04451 break; 04452 default: 04453 astman_send_error(s, m, "An unknown error occurred"); 04454 break; 04455 } 04456 return 0; 04457 }
static int action_sendtext | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3396 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().
03397 { 03398 struct ast_channel *c = NULL; 03399 const char *name = astman_get_header(m, "Channel"); 03400 const char *textmsg = astman_get_header(m, "Message"); 03401 int res = 0; 03402 03403 if (ast_strlen_zero(name)) { 03404 astman_send_error(s, m, "No channel specified"); 03405 return 0; 03406 } 03407 03408 if (ast_strlen_zero(textmsg)) { 03409 astman_send_error(s, m, "No Message specified"); 03410 return 0; 03411 } 03412 03413 if (!(c = ast_channel_get_by_name(name))) { 03414 astman_send_error(s, m, "No such channel"); 03415 return 0; 03416 } 03417 03418 res = ast_sendtext(c, textmsg); 03419 c = ast_channel_unref(c); 03420 03421 if (res >= 0) { 03422 astman_send_ack(s, m, "Success"); 03423 } else { 03424 astman_send_error(s, m, "Failure"); 03425 } 03426 03427 return res; 03428 }
static int action_setvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 3147 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().
03148 { 03149 struct ast_channel *c = NULL; 03150 const char *name = astman_get_header(m, "Channel"); 03151 const char *varname = astman_get_header(m, "Variable"); 03152 const char *varval = astman_get_header(m, "Value"); 03153 int res = 0; 03154 03155 if (ast_strlen_zero(varname)) { 03156 astman_send_error(s, m, "No variable specified"); 03157 return 0; 03158 } 03159 03160 if (!ast_strlen_zero(name)) { 03161 if (!(c = ast_channel_get_by_name(name))) { 03162 astman_send_error(s, m, "No such channel"); 03163 return 0; 03164 } 03165 } 03166 03167 res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 03168 03169 if (c) { 03170 c = ast_channel_unref(c); 03171 } 03172 if (res == 0) { 03173 astman_send_ack(s, m, "Variable Set"); 03174 } else { 03175 astman_send_error(s, m, "Variable not set"); 03176 } 03177 return 0; 03178 }
static int action_status | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager "status" command to show channels.
Definition at line 3234 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, function_capable_string_allowed_with_auths(), ast_channel::name, name, pbx_retrieve_variable(), S_OR, mansession::session, str, and mansession_session::writeperm.
Referenced by __init_manager().
03235 { 03236 const char *name = astman_get_header(m, "Channel"); 03237 const char *cvariables = astman_get_header(m, "Variables"); 03238 char *variables = ast_strdupa(S_OR(cvariables, "")); 03239 struct ast_channel *c; 03240 char bridge[256]; 03241 struct timeval now = ast_tvnow(); 03242 long elapsed_seconds = 0; 03243 int channels = 0; 03244 int all = ast_strlen_zero(name); /* set if we want all channels */ 03245 const char *id = astman_get_header(m, "ActionID"); 03246 char idText[256]; 03247 AST_DECLARE_APP_ARGS(vars, 03248 AST_APP_ARG(name)[100]; 03249 ); 03250 struct ast_str *str = ast_str_create(1000); 03251 struct ast_channel_iterator *iter = NULL; 03252 03253 if (!ast_strlen_zero(id)) { 03254 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 03255 } else { 03256 idText[0] = '\0'; 03257 } 03258 03259 if (!(function_capable_string_allowed_with_auths(variables, s->session->writeperm))) { 03260 astman_send_error(s, m, "Status Access Forbidden: Variables"); 03261 return 0; 03262 } 03263 03264 if (all) { 03265 if (!(iter = ast_channel_iterator_all_new())) { 03266 ast_free(str); 03267 astman_send_error(s, m, "Memory Allocation Failure"); 03268 return 1; 03269 } 03270 c = ast_channel_iterator_next(iter); 03271 } else { 03272 if (!(c = ast_channel_get_by_name(name))) { 03273 astman_send_error(s, m, "No such channel"); 03274 ast_free(str); 03275 return 0; 03276 } 03277 } 03278 03279 astman_send_ack(s, m, "Channel status will follow"); 03280 03281 if (!ast_strlen_zero(cvariables)) { 03282 AST_STANDARD_APP_ARGS(vars, variables); 03283 } 03284 03285 /* if we look by name, we break after the first iteration */ 03286 for (; c; c = ast_channel_iterator_next(iter)) { 03287 ast_channel_lock(c); 03288 03289 if (!ast_strlen_zero(cvariables)) { 03290 int i; 03291 ast_str_reset(str); 03292 for (i = 0; i < vars.argc; i++) { 03293 char valbuf[512], *ret = NULL; 03294 03295 if (vars.name[i][strlen(vars.name[i]) - 1] == ')') { 03296 if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) { 03297 valbuf[0] = '\0'; 03298 } 03299 ret = valbuf; 03300 } else { 03301 pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL); 03302 } 03303 03304 ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret); 03305 } 03306 } 03307 03308 channels++; 03309 if (c->_bridge) { 03310 snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid); 03311 } else { 03312 bridge[0] = '\0'; 03313 } 03314 if (c->pbx) { 03315 if (c->cdr) { 03316 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 03317 } 03318 astman_append(s, 03319 "Event: Status\r\n" 03320 "Privilege: Call\r\n" 03321 "Channel: %s\r\n" 03322 "CallerIDNum: %s\r\n" 03323 "CallerIDName: %s\r\n" 03324 "ConnectedLineNum: %s\r\n" 03325 "ConnectedLineName: %s\r\n" 03326 "Accountcode: %s\r\n" 03327 "ChannelState: %d\r\n" 03328 "ChannelStateDesc: %s\r\n" 03329 "Context: %s\r\n" 03330 "Extension: %s\r\n" 03331 "Priority: %d\r\n" 03332 "Seconds: %ld\r\n" 03333 "%s" 03334 "Uniqueid: %s\r\n" 03335 "%s" 03336 "%s" 03337 "\r\n", 03338 c->name, 03339 S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<unknown>"), 03340 S_COR(c->caller.id.name.valid, c->caller.id.name.str, "<unknown>"), 03341 S_COR(c->connected.id.number.valid, c->connected.id.number.str, "<unknown>"), 03342 S_COR(c->connected.id.name.valid, c->connected.id.name.str, "<unknown>"), 03343 c->accountcode, 03344 c->_state, 03345 ast_state2str(c->_state), c->context, 03346 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, ast_str_buffer(str), idText); 03347 } else { 03348 astman_append(s, 03349 "Event: Status\r\n" 03350 "Privilege: Call\r\n" 03351 "Channel: %s\r\n" 03352 "CallerIDNum: %s\r\n" 03353 "CallerIDName: %s\r\n" 03354 "ConnectedLineNum: %s\r\n" 03355 "ConnectedLineName: %s\r\n" 03356 "Account: %s\r\n" 03357 "State: %s\r\n" 03358 "%s" 03359 "Uniqueid: %s\r\n" 03360 "%s" 03361 "%s" 03362 "\r\n", 03363 c->name, 03364 S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<unknown>"), 03365 S_COR(c->caller.id.name.valid, c->caller.id.name.str, "<unknown>"), 03366 S_COR(c->connected.id.number.valid, c->connected.id.number.str, "<unknown>"), 03367 S_COR(c->connected.id.name.valid, c->connected.id.name.str, "<unknown>"), 03368 c->accountcode, 03369 ast_state2str(c->_state), bridge, c->uniqueid, 03370 ast_str_buffer(str), idText); 03371 } 03372 03373 ast_channel_unlock(c); 03374 c = ast_channel_unref(c); 03375 03376 if (!all) { 03377 break; 03378 } 03379 } 03380 03381 if (iter) { 03382 ast_channel_iterator_destroy(iter); 03383 } 03384 03385 astman_append(s, 03386 "Event: StatusComplete\r\n" 03387 "%s" 03388 "Items: %d\r\n" 03389 "\r\n", idText, channels); 03390 03391 ast_free(str); 03392 03393 return 0; 03394 }
static int action_timeout | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4215 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().
04216 { 04217 struct ast_channel *c; 04218 const char *name = astman_get_header(m, "Channel"); 04219 double timeout = atof(astman_get_header(m, "Timeout")); 04220 struct timeval when = { timeout, 0 }; 04221 04222 if (ast_strlen_zero(name)) { 04223 astman_send_error(s, m, "No channel specified"); 04224 return 0; 04225 } 04226 04227 if (!timeout || timeout < 0) { 04228 astman_send_error(s, m, "No timeout specified"); 04229 return 0; 04230 } 04231 04232 if (!(c = ast_channel_get_by_name(name))) { 04233 astman_send_error(s, m, "No such channel"); 04234 return 0; 04235 } 04236 04237 when.tv_usec = (timeout - when.tv_sec) * 1000000.0; 04238 04239 ast_channel_lock(c); 04240 ast_channel_setwhentohangup_tv(c, when); 04241 ast_channel_unlock(c); 04242 c = ast_channel_unref(c); 04243 04244 astman_send_ack(s, m, "Timeout Set"); 04245 04246 return 0; 04247 }
static int action_updateconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2784 of file manager.c.
References ast_config_destroy(), ast_config_load2(), ast_config_text_file_save(), ast_include_rename(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, FAILURE_ALLOCATION, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, handle_updates(), UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.
Referenced by __init_manager().
02785 { 02786 struct ast_config *cfg; 02787 const char *sfn = astman_get_header(m, "SrcFilename"); 02788 const char *dfn = astman_get_header(m, "DstFilename"); 02789 int res; 02790 const char *rld = astman_get_header(m, "Reload"); 02791 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 02792 enum error_type result; 02793 02794 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 02795 astman_send_error(s, m, "Filename not specified"); 02796 return 0; 02797 } 02798 if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) { 02799 astman_send_error(s, m, "Config file not found"); 02800 return 0; 02801 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02802 astman_send_error(s, m, "Config file has invalid format"); 02803 return 0; 02804 } 02805 result = handle_updates(s, m, cfg, dfn); 02806 if (!result) { 02807 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */ 02808 res = ast_config_text_file_save(dfn, cfg, "Manager"); 02809 ast_config_destroy(cfg); 02810 if (res) { 02811 astman_send_error(s, m, "Save of config failed"); 02812 return 0; 02813 } 02814 astman_send_ack(s, m, NULL); 02815 if (!ast_strlen_zero(rld)) { 02816 if (ast_true(rld)) { 02817 rld = NULL; 02818 } 02819 ast_module_reload(rld); 02820 } 02821 } else { 02822 ast_config_destroy(cfg); 02823 switch(result) { 02824 case UNKNOWN_ACTION: 02825 astman_send_error(s, m, "Unknown action command"); 02826 break; 02827 case UNKNOWN_CATEGORY: 02828 astman_send_error(s, m, "Given category does not exist"); 02829 break; 02830 case UNSPECIFIED_CATEGORY: 02831 astman_send_error(s, m, "Category not specified"); 02832 break; 02833 case UNSPECIFIED_ARGUMENT: 02834 astman_send_error(s, m, "Problem with category, value, or line (if required)"); 02835 break; 02836 case FAILURE_ALLOCATION: 02837 astman_send_error(s, m, "Memory allocation failure, this should not happen"); 02838 break; 02839 case FAILURE_NEWCAT: 02840 astman_send_error(s, m, "Create category did not complete successfully"); 02841 break; 02842 case FAILURE_DELCAT: 02843 astman_send_error(s, m, "Delete category did not complete successfully"); 02844 break; 02845 case FAILURE_EMPTYCAT: 02846 astman_send_error(s, m, "Empty category did not complete successfully"); 02847 break; 02848 case FAILURE_UPDATE: 02849 astman_send_error(s, m, "Update did not complete successfully"); 02850 break; 02851 case FAILURE_DELETE: 02852 astman_send_error(s, m, "Delete did not complete successfully"); 02853 break; 02854 case FAILURE_APPEND: 02855 astman_send_error(s, m, "Append did not complete successfully"); 02856 break; 02857 } 02858 } 02859 return 0; 02860 }
static int action_userevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4332 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().
04333 { 04334 const char *event = astman_get_header(m, "UserEvent"); 04335 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16); 04336 int x; 04337 04338 ast_str_reset(body); 04339 04340 for (x = 0; x < m->hdrcount; x++) { 04341 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 04342 ast_str_append(&body, 0, "%s\r\n", m->headers[x]); 04343 } 04344 } 04345 04346 astman_send_ack(s, m, "Event Sent"); 04347 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body)); 04348 return 0; 04349 }
static int action_waitevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2880 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().
02881 { 02882 const char *timeouts = astman_get_header(m, "Timeout"); 02883 int timeout = -1; 02884 int x; 02885 int needexit = 0; 02886 const char *id = astman_get_header(m, "ActionID"); 02887 char idText[256]; 02888 02889 if (!ast_strlen_zero(id)) { 02890 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02891 } else { 02892 idText[0] = '\0'; 02893 } 02894 02895 if (!ast_strlen_zero(timeouts)) { 02896 sscanf(timeouts, "%30i", &timeout); 02897 if (timeout < -1) { 02898 timeout = -1; 02899 } 02900 /* XXX maybe put an upper bound, or prevent the use of 0 ? */ 02901 } 02902 02903 ao2_lock(s->session); 02904 if (s->session->waiting_thread != AST_PTHREADT_NULL) { 02905 pthread_kill(s->session->waiting_thread, SIGURG); 02906 } 02907 02908 if (s->session->managerid) { /* AMI-over-HTTP session */ 02909 /* 02910 * Make sure the timeout is within the expire time of the session, 02911 * as the client will likely abort the request if it does not see 02912 * data coming after some amount of time. 02913 */ 02914 time_t now = time(NULL); 02915 int max = s->session->sessiontimeout - now - 10; 02916 02917 if (max < 0) { /* We are already late. Strange but possible. */ 02918 max = 0; 02919 } 02920 if (timeout < 0 || timeout > max) { 02921 timeout = max; 02922 } 02923 if (!s->session->send_events) { /* make sure we record events */ 02924 s->session->send_events = -1; 02925 } 02926 } 02927 ao2_unlock(s->session); 02928 02929 /* XXX should this go inside the lock ? */ 02930 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */ 02931 ast_debug(1, "Starting waiting for an event!\n"); 02932 02933 for (x = 0; x < timeout || timeout < 0; x++) { 02934 ao2_lock(s->session); 02935 if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) { 02936 needexit = 1; 02937 } 02938 /* We can have multiple HTTP session point to the same mansession entry. 02939 * The way we deal with it is not very nice: newcomers kick out the previous 02940 * HTTP session. XXX this needs to be improved. 02941 */ 02942 if (s->session->waiting_thread != pthread_self()) { 02943 needexit = 1; 02944 } 02945 if (s->session->needdestroy) { 02946 needexit = 1; 02947 } 02948 ao2_unlock(s->session); 02949 if (needexit) { 02950 break; 02951 } 02952 if (s->session->managerid == 0) { /* AMI session */ 02953 if (ast_wait_for_input(s->session->fd, 1000)) { 02954 break; 02955 } 02956 } else { /* HTTP session */ 02957 sleep(1); 02958 } 02959 } 02960 ast_debug(1, "Finished waiting for an event!\n"); 02961 02962 ao2_lock(s->session); 02963 if (s->session->waiting_thread == pthread_self()) { 02964 struct eventqent *eqe = s->session->last_ev; 02965 astman_send_response(s, m, "Success", "Waiting for Event completed."); 02966 while ((eqe = advance_event(eqe))) { 02967 if (((s->session->readperm & eqe->category) == eqe->category) && 02968 ((s->session->send_events & eqe->category) == eqe->category)) { 02969 astman_append(s, "%s", eqe->eventdata); 02970 } 02971 s->session->last_ev = eqe; 02972 } 02973 astman_append(s, 02974 "Event: WaitEventComplete\r\n" 02975 "%s" 02976 "\r\n", idText); 02977 s->session->waiting_thread = AST_PTHREADT_NULL; 02978 } else { 02979 ast_debug(1, "Abandoning event request!\n"); 02980 } 02981 ao2_unlock(s->session); 02982 02983 return 0; 02984 }
Definition at line 1750 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().
01751 { 01752 struct eventqent *next; 01753 01754 AST_RWLIST_RDLOCK(&all_events); 01755 if ((next = AST_RWLIST_NEXT(e, eq_next))) { 01756 ast_atomic_fetchadd_int(&next->usecount, 1); 01757 ast_atomic_fetchadd_int(&e->usecount, -1); 01758 } 01759 AST_RWLIST_UNLOCK(&all_events); 01760 return next; 01761 }
static int aocmessage_get_unit_entry | ( | const struct message * | m, | |
struct ast_aoc_unit_entry * | entry, | |||
unsigned int | entry_num | |||
) | [static] |
Definition at line 3778 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().
03779 { 03780 const char *unitamount; 03781 const char *unittype; 03782 struct ast_str *str = ast_str_alloca(32); 03783 03784 memset(entry, 0, sizeof(*entry)); 03785 03786 ast_str_set(&str, 0, "UnitAmount(%u)", entry_num); 03787 unitamount = astman_get_header(m, ast_str_buffer(str)); 03788 03789 ast_str_set(&str, 0, "UnitType(%u)", entry_num); 03790 unittype = astman_get_header(m, ast_str_buffer(str)); 03791 03792 if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) { 03793 entry->valid_amount = 1; 03794 } 03795 03796 if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) { 03797 entry->valid_type = 1; 03798 } 03799 03800 return 0; 03801 }
static void append_channel_vars | ( | struct ast_str ** | pbuf, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 5085 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().
05086 { 05087 struct manager_channel_variable *var; 05088 05089 AST_RWLIST_RDLOCK(&channelvars); 05090 AST_LIST_TRAVERSE(&channelvars, var, entry) { 05091 const char *val; 05092 struct ast_str *res; 05093 05094 if (var->isfunc) { 05095 res = ast_str_thread_get(&manager_event_funcbuf, 16); 05096 if (res && ast_func_read2(chan, var->name, &res, 0) == 0) { 05097 val = ast_str_buffer(res); 05098 } else { 05099 val = NULL; 05100 } 05101 } else { 05102 val = pbx_builtin_getvar_helper(chan, var->name); 05103 } 05104 ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", chan->name, var->name, val ? val : ""); 05105 } 05106 AST_RWLIST_UNLOCK(&channelvars); 05107 }
static int append_event | ( | const char * | str, | |
int | category | |||
) | [static] |
Definition at line 5059 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().
05060 { 05061 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 05062 static int seq; /* sequence number */ 05063 05064 if (!tmp) { 05065 return -1; 05066 } 05067 05068 /* need to init all fields, because ast_malloc() does not */ 05069 tmp->usecount = 0; 05070 tmp->category = category; 05071 tmp->seq = ast_atomic_fetchadd_int(&seq, 1); 05072 tmp->tv = ast_tvnow(); 05073 AST_RWLIST_NEXT(tmp, eq_next) = NULL; 05074 strcpy(tmp->eventdata, str); 05075 05076 AST_RWLIST_WRLOCK(&all_events); 05077 AST_RWLIST_INSERT_TAIL(&all_events, tmp, eq_next); 05078 AST_RWLIST_UNLOCK(&all_events); 05079 05080 return 0; 05081 }
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 1893 of file manager.c.
References ARRAY_LEN, ast_strdup, message::hdrcount, message::headers, and mansession::session.
01894 { 01895 const char *action; 01896 int ret = 0; 01897 struct manager_action *act_found; 01898 struct mansession s = {.session = NULL, }; 01899 struct message m = { 0 }; 01900 char *dup_str; 01901 char *src; 01902 int x = 0; 01903 int curlen; 01904 01905 if (hook == NULL) { 01906 return -1; 01907 } 01908 01909 /* Create our own copy of the AMI action msg string. */ 01910 src = dup_str = ast_strdup(msg); 01911 if (!dup_str) { 01912 return -1; 01913 } 01914 01915 /* convert msg string to message struct */ 01916 curlen = strlen(src); 01917 for (x = 0; x < curlen; x++) { 01918 int cr; /* set if we have \r */ 01919 if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n') 01920 cr = 2; /* Found. Update length to include \r\n */ 01921 else if (src[x] == '\n') 01922 cr = 1; /* also accept \n only */ 01923 else 01924 continue; 01925 /* don't keep empty lines */ 01926 if (x && m.hdrcount < ARRAY_LEN(m.headers)) { 01927 /* ... but trim \r\n and terminate the header string */ 01928 src[x] = '\0'; 01929 m.headers[m.hdrcount++] = src; 01930 } 01931 x += cr; 01932 curlen -= x; /* remaining size */ 01933 src += x; /* update pointer */ 01934 x = -1; /* reset loop */ 01935 } 01936 01937 action = astman_get_header(&m, "Action"); 01938 if (strcasecmp(action, "login")) { 01939 act_found = action_find(action); 01940 if (act_found) { 01941 /* 01942 * we have to simulate a session for this action request 01943 * to be able to pass it down for processing 01944 * This is necessary to meet the previous design of manager.c 01945 */ 01946 s.hook = hook; 01947 s.f = (void*)1; /* set this to something so our request will make it through all functions that test it*/ 01948 01949 ao2_lock(act_found); 01950 if (act_found->registered && act_found->func) { 01951 ++act_found->active_count; 01952 ao2_unlock(act_found); 01953 ret = act_found->func(&s, &m); 01954 ao2_lock(act_found); 01955 --act_found->active_count; 01956 } else { 01957 ret = -1; 01958 } 01959 ao2_unlock(act_found); 01960 ao2_t_ref(act_found, -1, "done with found action object"); 01961 } 01962 } 01963 ast_free(dup_str); 01964 return ret; 01965 }
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 1220 of file manager.c.
References eventqent::next.
Referenced by get_perm().
01221 { 01222 const char *val = bigstr, *next; 01223 01224 do { 01225 if ((next = strchr(val, delim))) { 01226 if (!strncmp(val, smallstr, (next - val))) { 01227 return 1; 01228 } else { 01229 continue; 01230 } 01231 } else { 01232 return !strcmp(smallstr, val); 01233 } 01234 } while (*(val = (next + 1))); 01235 01236 return 0; 01237 }
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 5314 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().
05315 { 05316 struct manager_action *cur; 05317 05318 cur = ao2_alloc(sizeof(*cur), action_destroy); 05319 if (!cur) { 05320 return -1; 05321 } 05322 if (ast_string_field_init(cur, 128)) { 05323 ao2_t_ref(cur, -1, "action object creation failed"); 05324 return -1; 05325 } 05326 05327 cur->action = action; 05328 cur->authority = auth; 05329 cur->func = func; 05330 #ifdef AST_XML_DOCS 05331 if (ast_strlen_zero(synopsis) && ast_strlen_zero(description)) { 05332 char *tmpxml; 05333 05334 tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL); 05335 ast_string_field_set(cur, synopsis, tmpxml); 05336 ast_free(tmpxml); 05337 05338 tmpxml = ast_xmldoc_build_syntax("manager", action, NULL); 05339 ast_string_field_set(cur, syntax, tmpxml); 05340 ast_free(tmpxml); 05341 05342 tmpxml = ast_xmldoc_build_description("manager", action, NULL); 05343 ast_string_field_set(cur, description, tmpxml); 05344 ast_free(tmpxml); 05345 05346 tmpxml = ast_xmldoc_build_seealso("manager", action, NULL); 05347 ast_string_field_set(cur, seealso, tmpxml); 05348 ast_free(tmpxml); 05349 05350 tmpxml = ast_xmldoc_build_arguments("manager", action, NULL); 05351 ast_string_field_set(cur, arguments, tmpxml); 05352 ast_free(tmpxml); 05353 05354 cur->docsrc = AST_XML_DOC; 05355 } else 05356 #endif 05357 { 05358 ast_string_field_set(cur, synopsis, synopsis); 05359 ast_string_field_set(cur, description, description); 05360 #ifdef AST_XML_DOCS 05361 cur->docsrc = AST_STATIC_DOC; 05362 #endif 05363 } 05364 if (ast_manager_register_struct(cur)) { 05365 ao2_t_ref(cur, -1, "action object registration failed"); 05366 return -1; 05367 } 05368 05369 ao2_t_ref(cur, -1, "action object registration successful"); 05370 return 0; 05371 }
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 5259 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().
05260 { 05261 struct manager_action *cur, *prev = NULL; 05262 05263 AST_RWLIST_WRLOCK(&actions); 05264 AST_RWLIST_TRAVERSE(&actions, cur, list) { 05265 int ret; 05266 05267 ret = strcasecmp(cur->action, act->action); 05268 if (ret == 0) { 05269 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 05270 AST_RWLIST_UNLOCK(&actions); 05271 return -1; 05272 } 05273 if (ret > 0) { /* Insert these alphabetically */ 05274 prev = cur; 05275 break; 05276 } 05277 } 05278 05279 ao2_t_ref(act, +1, "action object added to list"); 05280 act->registered = 1; 05281 if (prev) { 05282 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list); 05283 } else { 05284 AST_RWLIST_INSERT_HEAD(&actions, act, list); 05285 } 05286 05287 ast_verb(2, "Manager registered action %s\n", act->action); 05288 05289 AST_RWLIST_UNLOCK(&actions); 05290 05291 return 0; 05292 }
int ast_manager_unregister | ( | char * | action | ) |
Unregister a registered manager command.
action | Name of registered Action: |
Definition at line 5200 of file manager.c.
References manager_action::action, manager_action::active_count, ao2_lock, ao2_t_ref, ao2_unlock, ast_debug, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and manager_action::registered.
Referenced by __unload_module(), and unload_module().
05201 { 05202 struct manager_action *cur; 05203 05204 AST_RWLIST_WRLOCK(&actions); 05205 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) { 05206 if (!strcasecmp(action, cur->action)) { 05207 AST_RWLIST_REMOVE_CURRENT(list); 05208 break; 05209 } 05210 } 05211 AST_RWLIST_TRAVERSE_SAFE_END; 05212 AST_RWLIST_UNLOCK(&actions); 05213 05214 if (cur) { 05215 time_t now; 05216 05217 /* 05218 * We have removed the action object from the container so we 05219 * are no longer in a hurry. 05220 */ 05221 ao2_lock(cur); 05222 cur->registered = 0; 05223 ao2_unlock(cur); 05224 05225 /* 05226 * Wait up to 5 seconds for any active invocations to complete 05227 * before returning. We have to wait instead of blocking 05228 * because we may be waiting for ourself to complete. 05229 */ 05230 now = time(NULL); 05231 while (cur->active_count) { 05232 if (5 <= time(NULL) - now) { 05233 ast_debug(1, 05234 "Unregister manager action %s timed out waiting for %d active instances to complete\n", 05235 action, cur->active_count); 05236 break; 05237 } 05238 05239 sched_yield(); 05240 } 05241 05242 ao2_t_ref(cur, -1, "action object removed from list"); 05243 ast_verb(2, "Manager unregistered action %s\n", action); 05244 } 05245 05246 return 0; 05247 }
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 2011 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_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(), and session_do().
02012 { 02013 va_list ap; 02014 struct ast_str *buf; 02015 02016 if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) { 02017 return; 02018 } 02019 02020 va_start(ap, fmt); 02021 ast_str_set_va(&buf, 0, fmt, ap); 02022 va_end(ap); 02023 02024 if (s->f != NULL || s->session->f != NULL) { 02025 send_string(s, ast_str_buffer(buf)); 02026 } else { 02027 ast_verbose("fd == -1 in astman_append, should not happen\n"); 02028 } 02029 }
static void astman_append_json | ( | struct mansession * | s, | |
const char * | str | |||
) | [static] |
Definition at line 2581 of file manager.c.
References astman_append(), and json_escape().
Referenced by action_getconfigjson().
02582 { 02583 char *buf; 02584 02585 buf = alloca(2 * strlen(str) + 1); 02586 json_escape(buf, str); 02587 astman_append(s, "%s", buf); 02588 }
const char* astman_get_header | ( | const struct message * | m, | |
char * | var | |||
) |
Get header from mananger transaction.
Never returns NULL.
Definition at line 1813 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_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(), start_monitor_action(), and stop_monitor_action().
01814 { 01815 return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH); 01816 }
struct ast_variable* astman_get_variables | ( | const struct message * | m | ) |
Get a linked list of the Variable: headers.
Definition at line 1871 of file manager.c.
References message::hdrcount, message::headers, and man_do_variable_value().
Referenced by action_originate(), and manager_sipnotify().
01872 { 01873 int varlen; 01874 int x; 01875 struct ast_variable *head = NULL; 01876 01877 static const char var_hdr[] = "Variable:"; 01878 01879 /* Process all "Variable:" headers. */ 01880 varlen = strlen(var_hdr); 01881 for (x = 0; x < m->hdrcount; x++) { 01882 if (strncasecmp(var_hdr, m->headers[x], varlen)) { 01883 continue; 01884 } 01885 head = man_do_variable_value(head, m->headers[x] + varlen); 01886 } 01887 01888 return head; 01889 }
void astman_send_ack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg | |||
) |
Send ack in manager transaction.
Definition at line 2078 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().
02079 { 02080 astman_send_response_full(s, m, "Success", msg, NULL); 02081 }
void astman_send_error | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | error | |||
) |
Send error in manager transaction.
Definition at line 2073 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_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().
02074 { 02075 astman_send_response_full(s, m, "Error", error, NULL); 02076 }
void astman_send_listack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg, | |||
char * | listflag | |||
) |
Send ack in manager list transaction.
Definition at line 2088 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().
02089 { 02090 astman_send_response_full(s, m, "Success", msg, listflag); 02091 }
void astman_send_response | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg | |||
) |
Send response in manager transaction.
Definition at line 2068 of file manager.c.
References astman_send_response_full().
Referenced by action_logoff().
02069 { 02070 astman_send_response_full(s, m, resp, msg, NULL); 02071 }
static void astman_send_response_full | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg, | |||
char * | listflag | |||
) | [static] |
Definition at line 2048 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().
02049 { 02050 const char *id = astman_get_header(m, "ActionID"); 02051 02052 astman_append(s, "Response: %s\r\n", resp); 02053 if (!ast_strlen_zero(id)) { 02054 astman_append(s, "ActionID: %s\r\n", id); 02055 } 02056 if (listflag) { 02057 astman_append(s, "EventList: %s\r\n", listflag); /* Start, complete, cancelled */ 02058 } 02059 if (msg == MSG_MOREDATA) { 02060 return; 02061 } else if (msg) { 02062 astman_append(s, "Message: %s\r\n\r\n", msg); 02063 } else { 02064 astman_append(s, "\r\n"); 02065 } 02066 }
static void astman_start_ack | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2083 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().
02084 { 02085 astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL); 02086 }
static int authenticate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2365 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.
02366 { 02367 const char *username = astman_get_header(m, "Username"); 02368 const char *password = astman_get_header(m, "Secret"); 02369 int error = -1; 02370 struct ast_manager_user *user = NULL; 02371 regex_t *regex_filter; 02372 struct ao2_iterator filter_iter; 02373 struct ast_sockaddr addr; 02374 02375 if (ast_strlen_zero(username)) { /* missing username */ 02376 return -1; 02377 } 02378 02379 /* locate user in locked state */ 02380 AST_RWLIST_WRLOCK(&users); 02381 02382 ast_sockaddr_from_sin(&addr, &s->session->sin); 02383 02384 if (!(user = get_manager_by_name_locked(username))) { 02385 report_invalid_user(s, username); 02386 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 02387 } else if (user->ha && !ast_apply_ha(user->ha, &addr)) { 02388 report_failed_acl(s, username); 02389 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 02390 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { 02391 const char *key = astman_get_header(m, "Key"); 02392 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) { 02393 int x; 02394 int len = 0; 02395 char md5key[256] = ""; 02396 struct MD5Context md5; 02397 unsigned char digest[16]; 02398 02399 MD5Init(&md5); 02400 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge)); 02401 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret)); 02402 MD5Final(digest, &md5); 02403 for (x = 0; x < 16; x++) 02404 len += sprintf(md5key + len, "%2.2x", digest[x]); 02405 if (!strcmp(md5key, key)) { 02406 error = 0; 02407 } else { 02408 report_failed_challenge_response(s, key, md5key); 02409 } 02410 } else { 02411 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n", 02412 S_OR(s->session->challenge, "")); 02413 } 02414 } else if (user->secret) { 02415 if (!strcmp(password, user->secret)) { 02416 error = 0; 02417 } else { 02418 report_inval_password(s, username); 02419 } 02420 } 02421 02422 if (error) { 02423 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 02424 AST_RWLIST_UNLOCK(&users); 02425 return -1; 02426 } 02427 02428 /* auth complete */ 02429 02430 /* All of the user parameters are copied to the session so that in the event 02431 * of a reload and a configuration change, the session parameters are not 02432 * changed. */ 02433 ast_copy_string(s->session->username, username, sizeof(s->session->username)); 02434 s->session->readperm = user->readperm; 02435 s->session->writeperm = user->writeperm; 02436 s->session->writetimeout = user->writetimeout; 02437 02438 filter_iter = ao2_iterator_init(user->whitefilters, 0); 02439 while ((regex_filter = ao2_iterator_next(&filter_iter))) { 02440 ao2_t_link(s->session->whitefilters, regex_filter, "add white user filter to session"); 02441 ao2_t_ref(regex_filter, -1, "remove iterator ref"); 02442 } 02443 ao2_iterator_destroy(&filter_iter); 02444 02445 filter_iter = ao2_iterator_init(user->blackfilters, 0); 02446 while ((regex_filter = ao2_iterator_next(&filter_iter))) { 02447 ao2_t_link(s->session->blackfilters, regex_filter, "add black user filter to session"); 02448 ao2_t_ref(regex_filter, -1, "remove iterator ref"); 02449 } 02450 ao2_iterator_destroy(&filter_iter); 02451 02452 s->session->sessionstart = time(NULL); 02453 s->session->sessionstart_tv = ast_tvnow(); 02454 set_eventmask(s, astman_get_header(m, "Events")); 02455 02456 report_auth_success(s); 02457 02458 AST_RWLIST_UNLOCK(&users); 02459 return 0; 02460 }
static const char* authority_to_str | ( | int | authority, | |
struct ast_str ** | res | |||
) | [static] |
Convert authority code to a list of options.
Definition at line 1196 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().
01197 { 01198 int i; 01199 char *sep = ""; 01200 01201 ast_str_reset(*res); 01202 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) { 01203 if (authority & perms[i].num) { 01204 ast_str_append(res, 0, "%s%s", sep, perms[i].label); 01205 sep = ","; 01206 } 01207 } 01208 01209 if (ast_str_strlen(*res) == 0) /* replace empty string with something sensible */ 01210 ast_str_append(res, 0, "<none>"); 01211 01212 return ast_str_buffer(*res); 01213 }
static int blackfilter_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
void * | data, | |||
int | flags | |||
) | [static] |
Definition at line 4263 of file manager.c.
References CMP_MATCH, and CMP_STOP.
Referenced by match_filter().
04264 { 04265 regex_t *regex_filter = obj; 04266 const char *eventdata = arg; 04267 int *result = data; 04268 04269 if (!regexec(regex_filter, eventdata, 0, NULL, 0)) { 04270 *result = 0; 04271 return (CMP_MATCH | CMP_STOP); 04272 } 04273 04274 *result = 1; 04275 return 0; 04276 }
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 1337 of file manager.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, AST_PTHREADT_NULL, and session_destructor().
Referenced by session_do().
01338 { 01339 struct mansession_session *newsession; 01340 01341 if (!(newsession = ao2_alloc(sizeof(*newsession), session_destructor))) { 01342 return NULL; 01343 } 01344 01345 if (!(newsession->whitefilters = ao2_container_alloc(1, NULL, NULL))) { 01346 ao2_ref(newsession, -1); 01347 return NULL; 01348 } 01349 01350 if (!(newsession->blackfilters = ao2_container_alloc(1, NULL, NULL))) { 01351 ao2_ref(newsession, -1); /* session_destructor will cleanup the other filter */ 01352 return NULL; 01353 } 01354 01355 newsession->fd = -1; 01356 newsession->waiting_thread = AST_PTHREADT_NULL; 01357 newsession->writetimeout = 100; 01358 newsession->send_events = -1; 01359 newsession->sin = sin; 01360 01361 ao2_link(sessions, newsession); 01362 01363 return newsession; 01364 }
static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 3580 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().
03581 { 03582 char *cmd_copy, *cur_cmd; 03583 char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, }; 03584 int i; 03585 03586 cmd_copy = ast_strdupa(cmd); 03587 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) { 03588 cur_cmd = ast_strip(cur_cmd); 03589 if (ast_strlen_zero(cur_cmd)) { 03590 i--; 03591 continue; 03592 } 03593 03594 cmd_words[i] = cur_cmd; 03595 } 03596 03597 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) { 03598 int j, match = 1; 03599 03600 for (j = 0; command_blacklist[i].words[j]; j++) { 03601 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) { 03602 match = 0; 03603 break; 03604 } 03605 } 03606 03607 if (match) { 03608 return 1; 03609 } 03610 } 03611 03612 return 0; 03613 }
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 1380 of file manager.c.
References ao2_find, mansession_session::inuse, and unref_mansession().
Referenced by process_message().
01381 { 01382 struct mansession_session *session = ao2_find(sessions, (char *) name, 0); 01383 int inuse = 0; 01384 01385 if (session) { 01386 inuse = 1; 01387 unref_mansession(session); 01388 } 01389 return inuse; 01390 }
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 void destroy_fast_originate_helper | ( | struct fast_originate_helper * | doomed | ) | [static] |
Definition at line 3717 of file manager.c.
References ast_free, ast_string_field_free_memory, ast_variables_destroy(), and fast_originate_helper::vars.
Referenced by action_originate(), and fast_originate().
03718 { 03719 ast_variables_destroy(doomed->vars); 03720 ast_string_field_free_memory(doomed); 03721 ast_free(doomed); 03722 }
static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 4851 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().
04852 { 04853 struct message m = { 0 }; 04854 char header_buf[sizeof(s->session->inbuf)] = { '\0' }; 04855 int res; 04856 int idx; 04857 int hdr_loss; 04858 time_t now; 04859 04860 hdr_loss = 0; 04861 for (;;) { 04862 /* Check if any events are pending and do them if needed */ 04863 if (process_events(s)) { 04864 res = -1; 04865 break; 04866 } 04867 res = get_input(s, header_buf); 04868 if (res == 0) { 04869 /* No input line received. */ 04870 if (!s->session->authenticated) { 04871 if (time(&now) == -1) { 04872 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 04873 res = -1; 04874 break; 04875 } 04876 04877 if (now - s->session->authstart > authtimeout) { 04878 if (displayconnects) { 04879 ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_inet_ntoa(s->session->sin.sin_addr), authtimeout); 04880 } 04881 res = -1; 04882 break; 04883 } 04884 } 04885 continue; 04886 } else if (res > 0) { 04887 /* Input line received. */ 04888 if (ast_strlen_zero(header_buf)) { 04889 if (hdr_loss) { 04890 mansession_lock(s); 04891 astman_send_error(s, &m, "Too many lines in message or allocation failure"); 04892 mansession_unlock(s); 04893 res = 0; 04894 } else { 04895 res = process_message(s, &m) ? -1 : 0; 04896 } 04897 break; 04898 } else if (m.hdrcount < ARRAY_LEN(m.headers)) { 04899 m.headers[m.hdrcount] = ast_strdup(header_buf); 04900 if (!m.headers[m.hdrcount]) { 04901 /* Allocation failure. */ 04902 hdr_loss = 1; 04903 } else { 04904 ++m.hdrcount; 04905 } 04906 } else { 04907 /* Too many lines in message. */ 04908 hdr_loss = 1; 04909 } 04910 } else { 04911 /* Input error. */ 04912 break; 04913 } 04914 } 04915 04916 /* Free AMI request headers. */ 04917 for (idx = 0; idx < m.hdrcount; ++idx) { 04918 ast_free((void *) m.headers[idx]); 04919 } 04920 return res; 04921 }
static void event_filter_destructor | ( | void * | obj | ) | [static] |
static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 3724 of file manager.c.
References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_unlock, ast_manager_event_multichan, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, fast_originate_helper::data, destroy_fast_originate_helper(), 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().
03725 { 03726 struct fast_originate_helper *in = data; 03727 int res; 03728 int reason = 0; 03729 struct ast_channel *chan = NULL, *chans[1]; 03730 char requested_channel[AST_CHANNEL_NAME]; 03731 03732 if (!ast_strlen_zero(in->app)) { 03733 res = ast_pbx_outgoing_app(in->tech, in->format, (char *) in->data, 03734 in->timeout, in->app, in->appdata, &reason, 1, 03735 S_OR(in->cid_num, NULL), 03736 S_OR(in->cid_name, NULL), 03737 in->vars, in->account, &chan); 03738 } else { 03739 res = ast_pbx_outgoing_exten(in->tech, in->format, (char *) in->data, 03740 in->timeout, in->context, in->exten, in->priority, &reason, 1, 03741 S_OR(in->cid_num, NULL), 03742 S_OR(in->cid_name, NULL), 03743 in->vars, in->account, &chan); 03744 } 03745 /* Any vars memory was passed to the ast_pbx_outgoing_xxx() calls. */ 03746 in->vars = NULL; 03747 03748 if (!chan) { 03749 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 03750 } 03751 /* Tell the manager what happened with the channel */ 03752 chans[0] = chan; 03753 ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans, 03754 "%s" 03755 "Response: %s\r\n" 03756 "Channel: %s\r\n" 03757 "Context: %s\r\n" 03758 "Exten: %s\r\n" 03759 "Reason: %d\r\n" 03760 "Uniqueid: %s\r\n" 03761 "CallerIDNum: %s\r\n" 03762 "CallerIDName: %s\r\n", 03763 in->idtext, res ? "Failure" : "Success", 03764 chan ? chan->name : requested_channel, in->context, in->exten, reason, 03765 chan ? chan->uniqueid : "<null>", 03766 S_OR(in->cid_num, "<unknown>"), 03767 S_OR(in->cid_name, "<unknown>") 03768 ); 03769 03770 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 03771 if (chan) { 03772 ast_channel_unlock(chan); 03773 } 03774 destroy_fast_originate_helper(in); 03775 return NULL; 03776 }
static void free_channelvars | ( | void | ) | [static] |
Definition at line 7012 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().
07013 { 07014 struct manager_channel_variable *var; 07015 AST_RWLIST_WRLOCK(&channelvars); 07016 while ((var = AST_RWLIST_REMOVE_HEAD(&channelvars, entry))) { 07017 ast_free(var); 07018 } 07019 AST_RWLIST_UNLOCK(&channelvars); 07020 }
static int function_capable_string_allowed_with_auths | ( | const char * | evaluating, | |
int | writepermlist | |||
) | [static] |
Checks to see if a string which can be used to evaluate functions should be rejected.
Definition at line 1183 of file manager.c.
References EVENT_FLAG_SYSTEM.
Referenced by action_getvar(), and action_status().
01184 { 01185 if (!(writepermlist & EVENT_FLAG_SYSTEM) 01186 && ( 01187 strstr(evaluating, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */ 01188 strstr(evaluating, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ 01189 )) { 01190 return 0; 01191 } 01192 return 1; 01193 }
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 4754 of file manager.c.
References mansession_session::inbuf, mansession_session::inlen, mansession::session, and ast_frame::src.
04755 { 04756 int res, x; 04757 int maxlen = sizeof(s->session->inbuf) - 1; 04758 char *src = s->session->inbuf; 04759 int timeout = -1; 04760 time_t now; 04761 04762 /* 04763 * Look for \r\n within the buffer. If found, copy to the output 04764 * buffer and return, trimming the \r\n (not used afterwards). 04765 */ 04766 for (x = 0; x < s->session->inlen; x++) { 04767 int cr; /* set if we have \r */ 04768 if (src[x] == '\r' && x+1 < s->session->inlen && src[x + 1] == '\n') { 04769 cr = 2; /* Found. Update length to include \r\n */ 04770 } else if (src[x] == '\n') { 04771 cr = 1; /* also accept \n only */ 04772 } else { 04773 continue; 04774 } 04775 memmove(output, src, x); /*... but trim \r\n */ 04776 output[x] = '\0'; /* terminate the string */ 04777 x += cr; /* number of bytes used */ 04778 s->session->inlen -= x; /* remaining size */ 04779 memmove(src, src + x, s->session->inlen); /* remove used bytes */ 04780 return 1; 04781 } 04782 if (s->session->inlen >= maxlen) { 04783 /* no crlf found, and buffer full - sorry, too long for us */ 04784 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src); 04785 s->session->inlen = 0; 04786 } 04787 res = 0; 04788 while (res == 0) { 04789 /* calculate a timeout if we are not authenticated */ 04790 if (!s->session->authenticated) { 04791 if(time(&now) == -1) { 04792 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno)); 04793 return -1; 04794 } 04795 04796 timeout = (authtimeout - (now - s->session->authstart)) * 1000; 04797 if (timeout < 0) { 04798 /* we have timed out */ 04799 return 0; 04800 } 04801 } 04802 04803 ao2_lock(s->session); 04804 if (s->session->pending_event) { 04805 s->session->pending_event = 0; 04806 ao2_unlock(s->session); 04807 return 0; 04808 } 04809 s->session->waiting_thread = pthread_self(); 04810 ao2_unlock(s->session); 04811 04812 res = ast_wait_for_input(s->session->fd, timeout); 04813 04814 ao2_lock(s->session); 04815 s->session->waiting_thread = AST_PTHREADT_NULL; 04816 ao2_unlock(s->session); 04817 } 04818 if (res < 0) { 04819 /* If we get a signal from some other thread (typically because 04820 * there are new events queued), return 0 to notify the caller. 04821 */ 04822 if (errno == EINTR || errno == EAGAIN) { 04823 return 0; 04824 } 04825 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno)); 04826 return -1; 04827 } 04828 04829 ao2_lock(s->session); 04830 res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f); 04831 if (res < 1) { 04832 res = -1; /* error return */ 04833 } else { 04834 s->session->inlen += res; 04835 src[s->session->inlen] = '\0'; 04836 res = 0; 04837 } 04838 ao2_unlock(s->session); 04839 return res; 04840 }
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 1397 of file manager.c.
References AST_RWLIST_TRAVERSE, ast_manager_user::list, and user.
Referenced by authenticate(), handle_showmanager(), and manager_displayconnects().
01398 { 01399 struct ast_manager_user *user = NULL; 01400 01401 AST_RWLIST_TRAVERSE(&users, user, list) { 01402 if (!strcasecmp(user->username, name)) { 01403 break; 01404 } 01405 } 01406 01407 return user; 01408 }
static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 1239 of file manager.c.
References ARRAY_LEN, ast_instring(), permalias::num, and perms.
Referenced by strings_to_mask().
01240 { 01241 int x = 0, ret = 0; 01242 01243 if (!instr) { 01244 return 0; 01245 } 01246 01247 for (x = 0; x < ARRAY_LEN(perms); x++) { 01248 if (ast_instring(instr, perms[x].label, ',')) { 01249 ret |= perms[x].num; 01250 } 01251 } 01252 01253 return ret; 01254 }
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 1731 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.
01732 { 01733 switch (cmd) { 01734 case CLI_INIT: 01735 e->command = "manager reload"; 01736 e->usage = 01737 "Usage: manager reload\n" 01738 " Reloads the manager configuration.\n"; 01739 return NULL; 01740 case CLI_GENERATE: 01741 return NULL; 01742 } 01743 if (a->argc > 2) { 01744 return CLI_SHOWUSAGE; 01745 } 01746 reload_manager(); 01747 return CLI_SUCCESS; 01748 }
static char* handle_mandebug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1505 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.
01506 { 01507 switch (cmd) { 01508 case CLI_INIT: 01509 e->command = "manager set debug [on|off]"; 01510 e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n"; 01511 return NULL; 01512 case CLI_GENERATE: 01513 return NULL; 01514 } 01515 01516 if (a->argc == 3) { 01517 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off"); 01518 } else if (a->argc == 4) { 01519 if (!strcasecmp(a->argv[3], "on")) { 01520 manager_debug = 1; 01521 } else if (!strcasecmp(a->argv[3], "off")) { 01522 manager_debug = 0; 01523 } else { 01524 return CLI_SHOWUSAGE; 01525 } 01526 } 01527 return CLI_SUCCESS; 01528 }
static char* handle_showmanager | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1530 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.
01531 { 01532 struct ast_manager_user *user = NULL; 01533 int l, which; 01534 char *ret = NULL; 01535 struct ast_str *rauthority = ast_str_alloca(128); 01536 struct ast_str *wauthority = ast_str_alloca(128); 01537 01538 switch (cmd) { 01539 case CLI_INIT: 01540 e->command = "manager show user"; 01541 e->usage = 01542 " Usage: manager show user <user>\n" 01543 " Display all information related to the manager user specified.\n"; 01544 return NULL; 01545 case CLI_GENERATE: 01546 l = strlen(a->word); 01547 which = 0; 01548 if (a->pos != 3) { 01549 return NULL; 01550 } 01551 AST_RWLIST_RDLOCK(&users); 01552 AST_RWLIST_TRAVERSE(&users, user, list) { 01553 if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) { 01554 ret = ast_strdup(user->username); 01555 break; 01556 } 01557 } 01558 AST_RWLIST_UNLOCK(&users); 01559 return ret; 01560 } 01561 01562 if (a->argc != 4) { 01563 return CLI_SHOWUSAGE; 01564 } 01565 01566 AST_RWLIST_RDLOCK(&users); 01567 01568 if (!(user = get_manager_by_name_locked(a->argv[3]))) { 01569 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]); 01570 AST_RWLIST_UNLOCK(&users); 01571 return CLI_SUCCESS; 01572 } 01573 01574 ast_cli(a->fd, "\n"); 01575 ast_cli(a->fd, 01576 " username: %s\n" 01577 " secret: %s\n" 01578 " acl: %s\n" 01579 " read perm: %s\n" 01580 " write perm: %s\n" 01581 "displayconnects: %s\n", 01582 (user->username ? user->username : "(N/A)"), 01583 (user->secret ? "<Set>" : "(N/A)"), 01584 (user->ha ? "yes" : "no"), 01585 authority_to_str(user->readperm, &rauthority), 01586 authority_to_str(user->writeperm, &wauthority), 01587 (user->displayconnects ? "yes" : "no")); 01588 01589 AST_RWLIST_UNLOCK(&users); 01590 01591 return CLI_SUCCESS; 01592 }
static char* handle_showmanagers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1594 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.
01595 { 01596 struct ast_manager_user *user = NULL; 01597 int count_amu = 0; 01598 switch (cmd) { 01599 case CLI_INIT: 01600 e->command = "manager show users"; 01601 e->usage = 01602 "Usage: manager show users\n" 01603 " Prints a listing of all managers that are currently configured on that\n" 01604 " system.\n"; 01605 return NULL; 01606 case CLI_GENERATE: 01607 return NULL; 01608 } 01609 if (a->argc != 3) { 01610 return CLI_SHOWUSAGE; 01611 } 01612 01613 AST_RWLIST_RDLOCK(&users); 01614 01615 /* If there are no users, print out something along those lines */ 01616 if (AST_RWLIST_EMPTY(&users)) { 01617 ast_cli(a->fd, "There are no manager users.\n"); 01618 AST_RWLIST_UNLOCK(&users); 01619 return CLI_SUCCESS; 01620 } 01621 01622 ast_cli(a->fd, "\nusername\n--------\n"); 01623 01624 AST_RWLIST_TRAVERSE(&users, user, list) { 01625 ast_cli(a->fd, "%s\n", user->username); 01626 count_amu++; 01627 } 01628 01629 AST_RWLIST_UNLOCK(&users); 01630 01631 ast_cli(a->fd,"-------------------\n" 01632 "%d manager users configured.\n", count_amu); 01633 return CLI_SUCCESS; 01634 }
static char* handle_showmancmd | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1428 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.
01429 { 01430 struct manager_action *cur; 01431 struct ast_str *authority; 01432 int num, l, which; 01433 char *ret = NULL; 01434 #ifdef AST_XML_DOCS 01435 char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64]; 01436 #endif 01437 01438 switch (cmd) { 01439 case CLI_INIT: 01440 e->command = "manager show command"; 01441 e->usage = 01442 "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n" 01443 " Shows the detailed description for a specific Asterisk manager interface command.\n"; 01444 return NULL; 01445 case CLI_GENERATE: 01446 l = strlen(a->word); 01447 which = 0; 01448 AST_RWLIST_RDLOCK(&actions); 01449 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01450 if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) { 01451 ret = ast_strdup(cur->action); 01452 break; /* make sure we exit even if ast_strdup() returns NULL */ 01453 } 01454 } 01455 AST_RWLIST_UNLOCK(&actions); 01456 return ret; 01457 } 01458 authority = ast_str_alloca(80); 01459 if (a->argc < 4) { 01460 return CLI_SHOWUSAGE; 01461 } 01462 01463 #ifdef AST_XML_DOCS 01464 /* setup the titles */ 01465 term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); 01466 term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40); 01467 term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40); 01468 term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40); 01469 term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40); 01470 #endif 01471 01472 AST_RWLIST_RDLOCK(&actions); 01473 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01474 for (num = 3; num < a->argc; num++) { 01475 if (!strcasecmp(cur->action, a->argv[num])) { 01476 #ifdef AST_XML_DOCS 01477 if (cur->docsrc == AST_XML_DOC) { 01478 ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n", 01479 syntax_title, 01480 ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1), 01481 synopsis_title, 01482 ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1), 01483 description_title, 01484 ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1), 01485 arguments_title, 01486 ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1), 01487 seealso_title, 01488 ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1)); 01489 } else 01490 #endif 01491 { 01492 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", 01493 cur->action, cur->synopsis, 01494 authority_to_str(cur->authority, &authority), 01495 S_OR(cur->description, "")); 01496 } 01497 } 01498 } 01499 } 01500 AST_RWLIST_UNLOCK(&actions); 01501 01502 return CLI_SUCCESS; 01503 }
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 1637 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.
01638 { 01639 struct manager_action *cur; 01640 struct ast_str *authority; 01641 #define HSMC_FORMAT " %-15.15s %-15.15s %-55.55s\n" 01642 switch (cmd) { 01643 case CLI_INIT: 01644 e->command = "manager show commands"; 01645 e->usage = 01646 "Usage: manager show commands\n" 01647 " Prints a listing of all the available Asterisk manager interface commands.\n"; 01648 return NULL; 01649 case CLI_GENERATE: 01650 return NULL; 01651 } 01652 authority = ast_str_alloca(80); 01653 ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis"); 01654 ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------"); 01655 01656 AST_RWLIST_RDLOCK(&actions); 01657 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01658 ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis); 01659 } 01660 AST_RWLIST_UNLOCK(&actions); 01661 01662 return CLI_SUCCESS; 01663 }
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 1666 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.
01667 { 01668 struct mansession_session *session; 01669 time_t now = time(NULL); 01670 #define HSMCONN_FORMAT1 " %-15.15s %-15.15s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n" 01671 #define HSMCONN_FORMAT2 " %-15.15s %-15.15s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n" 01672 int count = 0; 01673 struct ao2_iterator i; 01674 01675 switch (cmd) { 01676 case CLI_INIT: 01677 e->command = "manager show connected"; 01678 e->usage = 01679 "Usage: manager show connected\n" 01680 " Prints a listing of the users that are currently connected to the\n" 01681 "Asterisk manager interface.\n"; 01682 return NULL; 01683 case CLI_GENERATE: 01684 return NULL; 01685 } 01686 01687 ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write"); 01688 01689 i = ao2_iterator_init(sessions, 0); 01690 while ((session = ao2_iterator_next(&i))) { 01691 ao2_lock(session); 01692 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); 01693 count++; 01694 ao2_unlock(session); 01695 unref_mansession(session); 01696 } 01697 ao2_iterator_destroy(&i); 01698 ast_cli(a->fd, "%d users connected.\n", count); 01699 01700 return CLI_SUCCESS; 01701 }
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 1705 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.
01706 { 01707 struct eventqent *s; 01708 switch (cmd) { 01709 case CLI_INIT: 01710 e->command = "manager show eventq"; 01711 e->usage = 01712 "Usage: manager show eventq\n" 01713 " Prints a listing of all events pending in the Asterisk manger\n" 01714 "event queue.\n"; 01715 return NULL; 01716 case CLI_GENERATE: 01717 return NULL; 01718 } 01719 AST_RWLIST_RDLOCK(&all_events); 01720 AST_RWLIST_TRAVERSE(&all_events, s, eq_next) { 01721 ast_cli(a->fd, "Usecount: %d\n", s->usecount); 01722 ast_cli(a->fd, "Category: %d\n", s->category); 01723 ast_cli(a->fd, "Event:\n%s", s->eventdata); 01724 } 01725 AST_RWLIST_UNLOCK(&all_events); 01726 01727 return CLI_SUCCESS; 01728 }
static enum error_type handle_updates | ( | struct mansession * | s, | |
const struct message * | m, | |||
struct ast_config * | cfg, | |||
const char * | dfn | |||
) | [static] |
Definition at line 2639 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().
02640 { 02641 int x; 02642 char hdr[40]; 02643 const char *action, *cat, *var, *value, *match, *line; 02644 struct ast_category *category; 02645 struct ast_variable *v; 02646 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 02647 enum error_type result = 0; 02648 02649 for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */ 02650 unsigned int object = 0; 02651 02652 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 02653 action = astman_get_header(m, hdr); 02654 if (ast_strlen_zero(action)) /* breaks the for loop if no action header */ 02655 break; /* this could cause problems if actions come in misnumbered */ 02656 02657 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 02658 cat = astman_get_header(m, hdr); 02659 if (ast_strlen_zero(cat)) { /* every action needs a category */ 02660 result = UNSPECIFIED_CATEGORY; 02661 break; 02662 } 02663 02664 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 02665 var = astman_get_header(m, hdr); 02666 02667 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 02668 value = astman_get_header(m, hdr); 02669 02670 if (!ast_strlen_zero(value) && *value == '>') { 02671 object = 1; 02672 value++; 02673 } 02674 02675 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 02676 match = astman_get_header(m, hdr); 02677 02678 snprintf(hdr, sizeof(hdr), "Line-%06d", x); 02679 line = astman_get_header(m, hdr); 02680 02681 if (!strcasecmp(action, "newcat")) { 02682 if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */ 02683 result = FAILURE_NEWCAT; /* already exist */ 02684 break; 02685 } 02686 if (!(category = ast_category_new(cat, dfn, -1))) { 02687 result = FAILURE_ALLOCATION; 02688 break; 02689 } 02690 if (ast_strlen_zero(match)) { 02691 ast_category_append(cfg, category); 02692 } else { 02693 ast_category_insert(cfg, category, match); 02694 } 02695 } else if (!strcasecmp(action, "renamecat")) { 02696 if (ast_strlen_zero(value)) { 02697 result = UNSPECIFIED_ARGUMENT; 02698 break; 02699 } 02700 if (!(category = ast_category_get(cfg, cat))) { 02701 result = UNKNOWN_CATEGORY; 02702 break; 02703 } 02704 ast_category_rename(category, value); 02705 } else if (!strcasecmp(action, "delcat")) { 02706 if (ast_category_delete(cfg, cat)) { 02707 result = FAILURE_DELCAT; 02708 break; 02709 } 02710 } else if (!strcasecmp(action, "emptycat")) { 02711 if (ast_category_empty(cfg, cat)) { 02712 result = FAILURE_EMPTYCAT; 02713 break; 02714 } 02715 } else if (!strcasecmp(action, "update")) { 02716 if (ast_strlen_zero(var)) { 02717 result = UNSPECIFIED_ARGUMENT; 02718 break; 02719 } 02720 if (!(category = ast_category_get(cfg,cat))) { 02721 result = UNKNOWN_CATEGORY; 02722 break; 02723 } 02724 if (ast_variable_update(category, var, value, match, object)) { 02725 result = FAILURE_UPDATE; 02726 break; 02727 } 02728 } else if (!strcasecmp(action, "delete")) { 02729 if ((ast_strlen_zero(var) && ast_strlen_zero(line))) { 02730 result = UNSPECIFIED_ARGUMENT; 02731 break; 02732 } 02733 if (!(category = ast_category_get(cfg, cat))) { 02734 result = UNKNOWN_CATEGORY; 02735 break; 02736 } 02737 if (ast_variable_delete(category, var, match, line)) { 02738 result = FAILURE_DELETE; 02739 break; 02740 } 02741 } else if (!strcasecmp(action, "append")) { 02742 if (ast_strlen_zero(var)) { 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 if (object || (match && !strcasecmp(match, "object"))) { 02755 v->object = 1; 02756 } 02757 ast_variable_append(category, v); 02758 } else if (!strcasecmp(action, "insert")) { 02759 if (ast_strlen_zero(var) || ast_strlen_zero(line)) { 02760 result = UNSPECIFIED_ARGUMENT; 02761 break; 02762 } 02763 if (!(category = ast_category_get(cfg, cat))) { 02764 result = UNKNOWN_CATEGORY; 02765 break; 02766 } 02767 if (!(v = ast_variable_new(var, value, dfn))) { 02768 result = FAILURE_ALLOCATION; 02769 break; 02770 } 02771 ast_variable_insert(category, v, line); 02772 } 02773 else { 02774 ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action); 02775 result = UNKNOWN_ACTION; 02776 break; 02777 } 02778 } 02779 ast_free(str1); 02780 ast_free(str2); 02781 return result; 02782 }
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 2561 of file manager.c.
Referenced by astman_append_json().
02562 { 02563 for (; *in; in++) { 02564 if (*in == '\\' || *in == '\"') { 02565 *out++ = '\\'; 02566 } 02567 *out++ = *in; 02568 } 02569 *out = '\0'; 02570 }
static struct ast_variable* man_do_variable_value | ( | struct ast_variable * | head, | |
const char * | hdr_val | |||
) | [static] |
Definition at line 1827 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().
01828 { 01829 char *parse; 01830 AST_DECLARE_APP_ARGS(args, 01831 AST_APP_ARG(vars)[64]; 01832 ); 01833 01834 hdr_val = ast_skip_blanks(hdr_val); /* ignore leading spaces in the value */ 01835 parse = ast_strdupa(hdr_val); 01836 01837 /* Break the header value string into name=val pair items. */ 01838 AST_STANDARD_APP_ARGS(args, parse); 01839 if (args.argc) { 01840 int y; 01841 01842 /* Process each name=val pair item. */ 01843 for (y = 0; y < args.argc; y++) { 01844 struct ast_variable *cur; 01845 char *var; 01846 char *val; 01847 01848 if (!args.vars[y]) { 01849 continue; 01850 } 01851 var = val = args.vars[y]; 01852 strsep(&val, "="); 01853 01854 /* XXX We may wish to trim whitespace from the strings. */ 01855 if (!val || ast_strlen_zero(var)) { 01856 continue; 01857 } 01858 01859 /* Create new variable list node and prepend it to the list. */ 01860 cur = ast_variable_new(var, val, ""); 01861 if (cur) { 01862 cur->next = head; 01863 head = cur; 01864 } 01865 } 01866 } 01867 01868 return head; 01869 }
static int manager_displayconnects | ( | struct mansession_session * | session | ) | [static] |
Get displayconnects config option.
session | manager session to get parameter from. |
Definition at line 1414 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().
01415 { 01416 struct ast_manager_user *user = NULL; 01417 int ret = 0; 01418 01419 AST_RWLIST_RDLOCK(&users); 01420 if ((user = get_manager_by_name_locked (session->username))) { 01421 ret = user->displayconnects; 01422 } 01423 AST_RWLIST_UNLOCK(&users); 01424 01425 return ret; 01426 }
static int manager_modulecheck | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4544 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().
04545 { 04546 int res; 04547 const char *module = astman_get_header(m, "Module"); 04548 const char *id = astman_get_header(m, "ActionID"); 04549 char idText[256]; 04550 #if !defined(LOW_MEMORY) 04551 const char *version; 04552 #endif 04553 char filename[PATH_MAX]; 04554 char *cut; 04555 04556 ast_copy_string(filename, module, sizeof(filename)); 04557 if ((cut = strchr(filename, '.'))) { 04558 *cut = '\0'; 04559 } else { 04560 cut = filename + strlen(filename); 04561 } 04562 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so"); 04563 ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename); 04564 res = ast_module_check(filename); 04565 if (!res) { 04566 astman_send_error(s, m, "Module not loaded"); 04567 return 0; 04568 } 04569 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c"); 04570 ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename); 04571 #if !defined(LOW_MEMORY) 04572 version = ast_file_version_find(filename); 04573 #endif 04574 04575 if (!ast_strlen_zero(id)) { 04576 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 04577 } else { 04578 idText[0] = '\0'; 04579 } 04580 astman_append(s, "Response: Success\r\n%s", idText); 04581 #if !defined(LOW_MEMORY) 04582 astman_append(s, "Version: %s\r\n\r\n", version ? version : ""); 04583 #endif 04584 return 0; 04585 }
static int manager_moduleload | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4587 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().
04588 { 04589 int res; 04590 const char *module = astman_get_header(m, "Module"); 04591 const char *loadtype = astman_get_header(m, "LoadType"); 04592 04593 if (!loadtype || strlen(loadtype) == 0) { 04594 astman_send_error(s, m, "Incomplete ModuleLoad action."); 04595 } 04596 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) { 04597 astman_send_error(s, m, "Need module name"); 04598 } 04599 04600 if (!strcasecmp(loadtype, "load")) { 04601 res = ast_load_resource(module); 04602 if (res) { 04603 astman_send_error(s, m, "Could not load module."); 04604 } else { 04605 astman_send_ack(s, m, "Module loaded."); 04606 } 04607 } else if (!strcasecmp(loadtype, "unload")) { 04608 res = ast_unload_resource(module, AST_FORCE_SOFT); 04609 if (res) { 04610 astman_send_error(s, m, "Could not unload module."); 04611 } else { 04612 astman_send_ack(s, m, "Module unloaded."); 04613 } 04614 } else if (!strcasecmp(loadtype, "reload")) { 04615 if (!ast_strlen_zero(module)) { 04616 res = ast_module_reload(module); 04617 if (res == 0) { 04618 astman_send_error(s, m, "No such module."); 04619 } else if (res == 1) { 04620 astman_send_error(s, m, "Module does not support reload action."); 04621 } else { 04622 astman_send_ack(s, m, "Module reloaded."); 04623 } 04624 } else { 04625 ast_module_reload(NULL); /* Reload all modules */ 04626 astman_send_ack(s, m, "All modules reloaded"); 04627 } 04628 } else 04629 astman_send_error(s, m, "Incomplete ModuleLoad action."); 04630 return 0; 04631 }
static int manager_state_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 5249 of file manager.c.
References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.
Referenced by __init_manager().
05250 { 05251 /* Notify managers of change */ 05252 char hint[512]; 05253 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten); 05254 05255 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state); 05256 return 0; 05257 }
static int mansession_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1366 of file manager.c.
References CMP_MATCH, str, and mansession_session::username.
01367 { 01368 struct mansession_session *s = obj; 01369 char *str = arg; 01370 return !strcasecmp(s->username, str) ? CMP_MATCH : 0; 01371 }
static struct sockaddr_in* mansession_encode_sin_local | ( | const struct mansession * | s, | |
struct sockaddr_in * | sin_local | |||
) | [static] |
Definition at line 2128 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().
02130 { 02131 ast_sockaddr_to_sin(&s->tcptls_session->parent->local_address, 02132 sin_local); 02133 02134 return sin_local; 02135 }
static enum ast_security_event_transport_type mansession_get_transport | ( | const struct mansession * | s | ) | [static] |
Definition at line 2122 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().
02123 { 02124 return s->tcptls_session->parent->tls_cfg ? AST_SECURITY_EVENT_TRANSPORT_TLS : 02125 AST_SECURITY_EVENT_TRANSPORT_TCP; 02126 }
static void mansession_lock | ( | struct mansession * | s | ) | [static] |
Lock the 'mansession' structure.
Definition at line 2094 of file manager.c.
References ast_mutex_lock, and mansession::lock.
Referenced by action_challenge(), do_message(), and process_message().
02095 { 02096 ast_mutex_lock(&s->lock); 02097 }
static void mansession_unlock | ( | struct mansession * | s | ) | [static] |
Unlock the 'mansession' structure.
Definition at line 2100 of file manager.c.
References ast_mutex_unlock, and mansession::lock.
Referenced by action_challenge(), do_message(), and process_message().
02101 { 02102 ast_mutex_unlock(&s->lock); 02103 }
static int match_filter | ( | struct mansession * | s, | |
char * | eventdata | |||
) | [static] |
Definition at line 4278 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().
04279 { 04280 int result = 0; 04281 04282 ast_debug(3, "Examining event:\n%s\n", eventdata); 04283 if (!ao2_container_count(s->session->whitefilters) && !ao2_container_count(s->session->blackfilters)) { 04284 return 1; /* no filtering means match all */ 04285 } else if (ao2_container_count(s->session->whitefilters) && !ao2_container_count(s->session->blackfilters)) { 04286 /* white filters only: implied black all filter processed first, then white filters */ 04287 ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 04288 } else if (!ao2_container_count(s->session->whitefilters) && ao2_container_count(s->session->blackfilters)) { 04289 /* black filters only: implied white all filter processed first, then black filters */ 04290 ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 04291 } else { 04292 /* white and black filters: implied black all filter processed first, then white filters, and lastly black filters */ 04293 ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 04294 if (result) { 04295 result = 0; 04296 ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 04297 } 04298 } 04299 04300 return result; 04301 }
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 4308 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().
04309 { 04310 int ret = 0; 04311 04312 ao2_lock(s->session); 04313 if (s->session->f != NULL) { 04314 struct eventqent *eqe = s->session->last_ev; 04315 04316 while ((eqe = advance_event(eqe))) { 04317 if (!ret && s->session->authenticated && 04318 (s->session->readperm & eqe->category) == eqe->category && 04319 (s->session->send_events & eqe->category) == eqe->category) { 04320 if (match_filter(s, eqe->eventdata)) { 04321 if (send_string(s, eqe->eventdata) < 0) 04322 ret = -1; /* don't send more */ 04323 } 04324 } 04325 s->session->last_ev = eqe; 04326 } 04327 } 04328 ao2_unlock(s->session); 04329 return ret; 04330 }
static int process_message | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4646 of file manager.c.
References __astman_get_header(), manager_action::action, action_find(), manager_action::active_count, 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().
04647 { 04648 int ret = 0; 04649 struct manager_action *act_found; 04650 const char *user; 04651 const char *action; 04652 04653 action = __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY); 04654 if (ast_strlen_zero(action)) { 04655 report_req_bad_format(s, "NONE"); 04656 mansession_lock(s); 04657 astman_send_error(s, m, "Missing action in request"); 04658 mansession_unlock(s); 04659 return 0; 04660 } 04661 04662 if (!s->session->authenticated 04663 && strcasecmp(action, "Login") 04664 && strcasecmp(action, "Logoff") 04665 && strcasecmp(action, "Challenge")) { 04666 if (!s->session->authenticated) { 04667 report_req_not_allowed(s, action); 04668 } 04669 mansession_lock(s); 04670 astman_send_error(s, m, "Permission denied"); 04671 mansession_unlock(s); 04672 return 0; 04673 } 04674 04675 if (!allowmultiplelogin 04676 && !s->session->authenticated 04677 && (!strcasecmp(action, "Login") 04678 || !strcasecmp(action, "Challenge"))) { 04679 user = astman_get_header(m, "Username"); 04680 04681 if (check_manager_session_inuse(user)) { 04682 report_session_limit(s); 04683 sleep(1); 04684 mansession_lock(s); 04685 astman_send_error(s, m, "Login Already In Use"); 04686 mansession_unlock(s); 04687 return -1; 04688 } 04689 } 04690 04691 act_found = action_find(action); 04692 if (act_found) { 04693 /* Found the requested AMI action. */ 04694 int acted = 0; 04695 04696 if ((s->session->writeperm & act_found->authority) 04697 || act_found->authority == 0) { 04698 /* We have the authority to execute the action. */ 04699 ao2_lock(act_found); 04700 if (act_found->registered && act_found->func) { 04701 ast_debug(1, "Running action '%s'\n", act_found->action); 04702 ++act_found->active_count; 04703 ao2_unlock(act_found); 04704 ret = act_found->func(s, m); 04705 acted = 1; 04706 ao2_lock(act_found); 04707 --act_found->active_count; 04708 } 04709 ao2_unlock(act_found); 04710 } 04711 if (!acted) { 04712 /* 04713 * We did not execute the action because access was denied, it 04714 * was no longer registered, or no action was really registered. 04715 * Complain about it and leave. 04716 */ 04717 report_req_not_allowed(s, action); 04718 mansession_lock(s); 04719 astman_send_error(s, m, "Permission denied"); 04720 mansession_unlock(s); 04721 } 04722 ao2_t_ref(act_found, -1, "done with found action object"); 04723 } else { 04724 char buf[512]; 04725 04726 report_req_bad_format(s, action); 04727 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action); 04728 mansession_lock(s); 04729 astman_send_error(s, m, buf); 04730 mansession_unlock(s); 04731 } 04732 if (ret) { 04733 return ret; 04734 } 04735 /* Once done with our message, deliver any pending events unless the 04736 requester doesn't want them as part of this response. 04737 */ 04738 if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) { 04739 return process_events(s); 04740 } else { 04741 return ret; 04742 } 04743 }
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 5030 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().
05031 { 05032 struct mansession_session *session; 05033 time_t now = time(NULL); 05034 struct ao2_iterator i; 05035 05036 i = ao2_iterator_init(sessions, 0); 05037 while ((session = ao2_iterator_next(&i)) && n_max > 0) { 05038 ao2_lock(session); 05039 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) { 05040 if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) { 05041 ast_verb(2, "HTTP Manager '%s' timed out from %s\n", 05042 session->username, ast_inet_ntoa(session->sin.sin_addr)); 05043 } 05044 ao2_unlock(session); 05045 session_destroy(session); 05046 n_max--; 05047 } else { 05048 ao2_unlock(session); 05049 unref_mansession(session); 05050 } 05051 } 05052 ao2_iterator_destroy(&i); 05053 }
static void report_auth_success | ( | const struct mansession * | s | ) | [static] |
Definition at line 2215 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().
02216 { 02217 struct sockaddr_in sin_local; 02218 char session_id[32]; 02219 struct ast_security_event_successful_auth successful_auth = { 02220 .common.event_type = AST_SECURITY_EVENT_SUCCESSFUL_AUTH, 02221 .common.version = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION, 02222 .common.service = "AMI", 02223 .common.account_id = s->session->username, 02224 .common.session_tv = &s->session->sessionstart_tv, 02225 .common.local_addr = { 02226 .sin = mansession_encode_sin_local(s, &sin_local), 02227 .transport = mansession_get_transport(s), 02228 }, 02229 .common.remote_addr = { 02230 .sin = &s->session->sin, 02231 .transport = mansession_get_transport(s), 02232 }, 02233 .common.session_id = session_id, 02234 }; 02235 02236 snprintf(session_id, sizeof(session_id), "%p", s->session); 02237 02238 ast_security_event_report(AST_SEC_EVT(&successful_auth)); 02239 }
static void report_failed_acl | ( | const struct mansession * | s, | |
const char * | username | |||
) | [static] |
Definition at line 2163 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().
02164 { 02165 struct sockaddr_in sin_local; 02166 char session_id[32]; 02167 struct ast_security_event_failed_acl failed_acl_event = { 02168 .common.event_type = AST_SECURITY_EVENT_FAILED_ACL, 02169 .common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION, 02170 .common.service = "AMI", 02171 .common.account_id = username, 02172 .common.session_tv = &s->session->sessionstart_tv, 02173 .common.local_addr = { 02174 .sin = mansession_encode_sin_local(s, &sin_local), 02175 .transport = mansession_get_transport(s), 02176 }, 02177 .common.remote_addr = { 02178 .sin = &s->session->sin, 02179 .transport = mansession_get_transport(s), 02180 }, 02181 .common.session_id = session_id, 02182 }; 02183 02184 snprintf(session_id, sizeof(session_id), "%p", s->session); 02185 02186 ast_security_event_report(AST_SEC_EVT(&failed_acl_event)); 02187 }
static void report_failed_challenge_response | ( | const struct mansession * | s, | |
const char * | response, | |||
const char * | expected_response | |||
) | [static] |
Definition at line 2301 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().
02303 { 02304 struct sockaddr_in sin_local; 02305 char session_id[32]; 02306 struct ast_security_event_chal_resp_failed chal_resp_failed = { 02307 .common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED, 02308 .common.version = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION, 02309 .common.service = "AMI", 02310 .common.account_id = s->session->username, 02311 .common.session_tv = &s->session->sessionstart_tv, 02312 .common.local_addr = { 02313 .sin = mansession_encode_sin_local(s, &sin_local), 02314 .transport = mansession_get_transport(s), 02315 }, 02316 .common.remote_addr = { 02317 .sin = &s->session->sin, 02318 .transport = mansession_get_transport(s), 02319 }, 02320 .common.session_id = session_id, 02321 02322 .challenge = s->session->challenge, 02323 .response = response, 02324 .expected_response = expected_response, 02325 }; 02326 02327 snprintf(session_id, sizeof(session_id), "%p", s->session); 02328 02329 ast_security_event_report(AST_SEC_EVT(&chal_resp_failed)); 02330 }
static void report_inval_password | ( | const struct mansession * | s, | |
const char * | username | |||
) | [static] |
Definition at line 2189 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().
02190 { 02191 struct sockaddr_in sin_local; 02192 char session_id[32]; 02193 struct ast_security_event_inval_password inval_password = { 02194 .common.event_type = AST_SECURITY_EVENT_INVAL_PASSWORD, 02195 .common.version = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION, 02196 .common.service = "AMI", 02197 .common.account_id = username, 02198 .common.session_tv = &s->session->sessionstart_tv, 02199 .common.local_addr = { 02200 .sin = mansession_encode_sin_local(s, &sin_local), 02201 .transport = mansession_get_transport(s), 02202 }, 02203 .common.remote_addr = { 02204 .sin = &s->session->sin, 02205 .transport = mansession_get_transport(s), 02206 }, 02207 .common.session_id = session_id, 02208 }; 02209 02210 snprintf(session_id, sizeof(session_id), "%p", s->session); 02211 02212 ast_security_event_report(AST_SEC_EVT(&inval_password)); 02213 }
static void report_invalid_user | ( | const struct mansession * | s, | |
const char * | username | |||
) | [static] |
Definition at line 2137 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().
02138 { 02139 struct sockaddr_in sin_local; 02140 char session_id[32]; 02141 struct ast_security_event_inval_acct_id inval_acct_id = { 02142 .common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID, 02143 .common.version = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION, 02144 .common.service = "AMI", 02145 .common.account_id = username, 02146 .common.session_tv = &s->session->sessionstart_tv, 02147 .common.local_addr = { 02148 .sin = mansession_encode_sin_local(s, &sin_local), 02149 .transport = mansession_get_transport(s), 02150 }, 02151 .common.remote_addr = { 02152 .sin = &s->session->sin, 02153 .transport = mansession_get_transport(s), 02154 }, 02155 .common.session_id = session_id, 02156 }; 02157 02158 snprintf(session_id, sizeof(session_id), "%p", s); 02159 02160 ast_security_event_report(AST_SEC_EVT(&inval_acct_id)); 02161 }
static void report_req_bad_format | ( | const struct mansession * | s, | |
const char * | action | |||
) | [static] |
Definition at line 2271 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().
02272 { 02273 struct sockaddr_in sin_local; 02274 char session_id[32]; 02275 char request_type[64]; 02276 struct ast_security_event_req_bad_format req_bad_format = { 02277 .common.event_type = AST_SECURITY_EVENT_REQ_BAD_FORMAT, 02278 .common.version = AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION, 02279 .common.service = "AMI", 02280 .common.account_id = s->session->username, 02281 .common.session_tv = &s->session->sessionstart_tv, 02282 .common.local_addr = { 02283 .sin = mansession_encode_sin_local(s, &sin_local), 02284 .transport = mansession_get_transport(s), 02285 }, 02286 .common.remote_addr = { 02287 .sin = &s->session->sin, 02288 .transport = mansession_get_transport(s), 02289 }, 02290 .common.session_id = session_id, 02291 02292 .request_type = request_type, 02293 }; 02294 02295 snprintf(session_id, sizeof(session_id), "%p", s->session); 02296 snprintf(request_type, sizeof(request_type), "Action: %s", action); 02297 02298 ast_security_event_report(AST_SEC_EVT(&req_bad_format)); 02299 }
static void report_req_not_allowed | ( | const struct mansession * | s, | |
const char * | action | |||
) | [static] |
Definition at line 2241 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().
02242 { 02243 struct sockaddr_in sin_local; 02244 char session_id[32]; 02245 char request_type[64]; 02246 struct ast_security_event_req_not_allowed req_not_allowed = { 02247 .common.event_type = AST_SECURITY_EVENT_REQ_NOT_ALLOWED, 02248 .common.version = AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION, 02249 .common.service = "AMI", 02250 .common.account_id = s->session->username, 02251 .common.session_tv = &s->session->sessionstart_tv, 02252 .common.local_addr = { 02253 .sin = mansession_encode_sin_local(s, &sin_local), 02254 .transport = mansession_get_transport(s), 02255 }, 02256 .common.remote_addr = { 02257 .sin = &s->session->sin, 02258 .transport = mansession_get_transport(s), 02259 }, 02260 .common.session_id = session_id, 02261 02262 .request_type = request_type, 02263 }; 02264 02265 snprintf(session_id, sizeof(session_id), "%p", s->session); 02266 snprintf(request_type, sizeof(request_type), "Action: %s", action); 02267 02268 ast_security_event_report(AST_SEC_EVT(&req_not_allowed)); 02269 }
static void report_session_limit | ( | const struct mansession * | s | ) | [static] |
Definition at line 2332 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().
02333 { 02334 struct sockaddr_in sin_local; 02335 char session_id[32]; 02336 struct ast_security_event_session_limit session_limit = { 02337 .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT, 02338 .common.version = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION, 02339 .common.service = "AMI", 02340 .common.account_id = s->session->username, 02341 .common.session_tv = &s->session->sessionstart_tv, 02342 .common.local_addr = { 02343 .sin = mansession_encode_sin_local(s, &sin_local), 02344 .transport = mansession_get_transport(s), 02345 }, 02346 .common.remote_addr = { 02347 .sin = &s->session->sin, 02348 .transport = mansession_get_transport(s), 02349 }, 02350 .common.session_id = session_id, 02351 }; 02352 02353 snprintf(session_id, sizeof(session_id), "%p", s->session); 02354 02355 ast_security_event_report(AST_SEC_EVT(&session_limit)); 02356 }
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 1972 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().
01973 { 01974 int res; 01975 FILE *f = s->f ? s->f : s->session->f; 01976 int fd = s->f ? s->fd : s->session->fd; 01977 01978 /* It's a result from one of the hook's action invocation */ 01979 if (s->hook) { 01980 /* 01981 * to send responses, we're using the same function 01982 * as for receiving events. We call the event "HookResponse" 01983 */ 01984 s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string); 01985 return 0; 01986 } 01987 01988 if ((res = ast_careful_fwrite(f, fd, string, strlen(string), s->session->writetimeout))) { 01989 s->write_error = 1; 01990 } 01991 01992 return res; 01993 }
static void session_destroy | ( | struct mansession_session * | s | ) | [static] |
Definition at line 1373 of file manager.c.
References ao2_unlink, and unref_mansession().
Referenced by purge_sessions(), session_do(), and spandsp_fax_destroy().
01374 { 01375 unref_mansession(s); 01376 ao2_unlink(sessions, s); 01377 }
static void session_destructor | ( | void * | obj | ) | [static] |
Definition at line 1306 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().
01307 { 01308 struct mansession_session *session = obj; 01309 struct eventqent *eqe = session->last_ev; 01310 struct ast_datastore *datastore; 01311 01312 /* Get rid of each of the data stores on the session */ 01313 while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) { 01314 /* Free the data store */ 01315 ast_datastore_free(datastore); 01316 } 01317 01318 if (session->f != NULL) { 01319 fclose(session->f); 01320 } 01321 if (eqe) { 01322 ast_atomic_fetchadd_int(&eqe->usecount, -1); 01323 } 01324 01325 if (session->whitefilters) { 01326 ao2_t_callback(session->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters"); 01327 ao2_t_ref(session->whitefilters, -1 , "decrement ref for white container, should be last one"); 01328 } 01329 01330 if (session->blackfilters) { 01331 ao2_t_callback(session->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters"); 01332 ao2_t_ref(session->blackfilters, -1 , "decrement ref for black container, should be last one"); 01333 } 01334 }
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 4931 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.
04932 { 04933 struct ast_tcptls_session_instance *ser = data; 04934 struct mansession_session *session; 04935 struct mansession s = { 04936 .tcptls_session = data, 04937 }; 04938 int flags; 04939 int res; 04940 struct sockaddr_in ser_remote_address_tmp; 04941 struct protoent *p; 04942 04943 if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) { 04944 fclose(ser->f); 04945 ast_atomic_fetchadd_int(&unauth_sessions, -1); 04946 goto done; 04947 } 04948 04949 ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp); 04950 session = build_mansession(ser_remote_address_tmp); 04951 04952 if (session == NULL) { 04953 fclose(ser->f); 04954 ast_atomic_fetchadd_int(&unauth_sessions, -1); 04955 goto done; 04956 } 04957 04958 /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm. 04959 * This is necessary to prevent delays (caused by buffering) as we 04960 * write to the socket in bits and peices. */ 04961 p = getprotobyname("tcp"); 04962 if (p) { 04963 int arg = 1; 04964 if( setsockopt(ser->fd, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 04965 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)); 04966 } 04967 } else { 04968 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"); 04969 } 04970 04971 flags = fcntl(ser->fd, F_GETFL); 04972 if (!block_sockets) { /* make sure socket is non-blocking */ 04973 flags |= O_NONBLOCK; 04974 } else { 04975 flags &= ~O_NONBLOCK; 04976 } 04977 fcntl(ser->fd, F_SETFL, flags); 04978 04979 ao2_lock(session); 04980 /* Hook to the tail of the event queue */ 04981 session->last_ev = grab_last(); 04982 04983 ast_mutex_init(&s.lock); 04984 04985 /* these fields duplicate those in the 'ser' structure */ 04986 session->fd = s.fd = ser->fd; 04987 session->f = s.f = ser->f; 04988 session->sin = ser_remote_address_tmp; 04989 s.session = session; 04990 04991 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores); 04992 04993 if(time(&session->authstart) == -1) { 04994 ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno)); 04995 ast_atomic_fetchadd_int(&unauth_sessions, -1); 04996 ao2_unlock(session); 04997 session_destroy(session); 04998 goto done; 04999 } 05000 ao2_unlock(session); 05001 05002 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */ 05003 for (;;) { 05004 if ((res = do_message(&s)) < 0 || s.write_error) { 05005 break; 05006 } 05007 } 05008 /* session is over, explain why and terminate */ 05009 if (session->authenticated) { 05010 if (manager_displayconnects(session)) { 05011 ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 05012 } 05013 } else { 05014 ast_atomic_fetchadd_int(&unauth_sessions, -1); 05015 if (displayconnects) { 05016 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); 05017 } 05018 } 05019 05020 session_destroy(session); 05021 05022 ast_mutex_destroy(&s.lock); 05023 done: 05024 ao2_ref(ser, -1); 05025 ser = NULL; 05026 return NULL; 05027 }
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 2109 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().
02110 { 02111 int maskint = strings_to_mask(eventmask); 02112 02113 ao2_lock(s->session); 02114 if (maskint >= 0) { 02115 s->session->send_events = maskint; 02116 } 02117 ao2_unlock(s->session); 02118 02119 return maskint; 02120 }
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 1260 of file manager.c.
References ARRAY_LEN, ast_false(), ast_strlen_zero(), ast_true(), get_perm(), and perms.
Referenced by set_eventmask().
01261 { 01262 const char *p; 01263 01264 if (ast_strlen_zero(string)) { 01265 return -1; 01266 } 01267 01268 for (p = string; *p; p++) { 01269 if (*p < '0' || *p > '9') { 01270 break; 01271 } 01272 } 01273 if (!*p) { /* all digits */ 01274 return atoi(string); 01275 } 01276 if (ast_false(string)) { 01277 return 0; 01278 } 01279 if (ast_true(string)) { /* all permissions */ 01280 int x, ret = 0; 01281 for (x = 0; x < ARRAY_LEN(perms); x++) { 01282 ret |= perms[x].num; 01283 } 01284 return ret; 01285 } 01286 return get_perm(string); 01287 }
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 1291 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().
01292 { 01293 int refcount = ao2_ref(s, -1); 01294 if (manager_debug) { 01295 ast_log(LOG_DEBUG, "Mansession: %p refcount now %d\n", s, refcount - 1); 01296 } 01297 return s; 01298 }
static int whitefilter_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
void * | data, | |||
int | flags | |||
) | [static] |
Definition at line 4249 of file manager.c.
References CMP_MATCH, and CMP_STOP.
Referenced by match_filter().
04250 { 04251 regex_t *regex_filter = obj; 04252 const char *eventdata = arg; 04253 int *result = data; 04254 04255 if (!regexec(regex_filter, eventdata, 0, NULL, 0)) { 04256 *result = 1; 04257 return (CMP_MATCH | CMP_STOP); 04258 } 04259 04260 return 0; 04261 }
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().