Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Enumerations | Functions | Variables
AMI functions

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  eventqent
 
struct  fast_originate_helper
 helper function for originate More...
 
struct  manager_hooks
 list of hooks registered More...
 
struct  mansession
 In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data. More...
 
struct  mansession_session
 
struct  permalias
 
struct  users
 list of users found in the config file More...
 

Macros

#define any_manager_listeners(sessions)    ((sessions && ao2_container_count(sessions)) || !AST_RWLIST_EMPTY(&manager_hooks))
 
#define ASTMAN_APPEND_BUF_INITSIZE   256
 initial allocated size for the astman_append_buf and astman_send_*_va More...
 
#define DEFAULT_REALM   "asterisk"
 
#define EVENT_FLAG_SHUTDOWN   -1
 Fake event class used to end sessions at shutdown. More...
 
#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 manager_event_sessions(sessions, category, event, contents, ...)    __manager_event_sessions(sessions, category, event, 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, contents , ## __VA_ARGS__)
 
#define MAX_AUTH_PERM_STRING   150
 
#define MAX_BLACKLIST_CMD_LEN   2
 Descriptor for a manager session, either on the AMI socket or over HTTP. More...
 
#define MAX_VARS   128
 
#define MGR_SHOW_TERMINAL_WIDTH   80
 
#define MSG_MOREDATA   ((char *)astman_send_response)
 

Enumerations

enum  add_filter_result { FILTER_SUCCESS , FILTER_ALLOC_FAILED , FILTER_COMPILE_FAIL }
 
enum  error_type {
  UNKNOWN_ACTION = 1 , UNKNOWN_CATEGORY , UNSPECIFIED_CATEGORY , UNSPECIFIED_ARGUMENT ,
  FAILURE_ALLOCATION , FAILURE_NEWCAT , FAILURE_DELCAT , FAILURE_EMPTYCAT ,
  FAILURE_UPDATE , FAILURE_DELETE , FAILURE_APPEND , FAILURE_TEMPLATE
}
 
enum  mansession_message_parsing { MESSAGE_OKAY , MESSAGE_LINE_TOO_LONG }
 

Functions

int __ast_manager_event_multichan (int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt,...)
 
static const char * __astman_get_header (const struct message *m, char *var, int mode)
 Return a matching header value. More...
 
static void __init_astman_append_buf (void)
 thread local buffer for astman_append More...
 
static void __init_manager_event_buf (void)
 
static void __init_userevent_buf (void)
 
static int __manager_event_sessions (struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt,...)
 
static int __manager_event_sessions_va (struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt, va_list ap)
 
static void acl_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void acl_change_stasis_subscribe (void)
 
static void acl_change_stasis_unsubscribe (void)
 
static struct ast_aoc_decodedaction_aoc_de_message (struct mansession *s, const struct message *m)
 
static struct ast_aoc_decodedaction_aoc_s_message (struct mansession *s, const struct message *m)
 
static int action_aoc_s_submessage (struct mansession *s, const struct message *m, struct ast_aoc_decoded *decoded)
 
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_blind_transfer (struct mansession *s, const struct message *m)
 
static int action_cancel_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. More...
 
static int action_coresettings (struct mansession *s, const struct message *m)
 Show PBX core settings information. More...
 
static int action_coreshowchannelmap (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannelMap" - Lists all channels connected to the specified channel. More...
 
static int action_coreshowchannels (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannels" - List currently defined channels and some information about them. More...
 
static int action_corestatus (struct mansession *s, const struct message *m)
 Show PBX core status information. More...
 
static int action_createconfig (struct mansession *s, const struct message *m)
 
static void action_destroy (void *obj)
 
static int action_events (struct mansession *s, const struct message *m)
 
static int action_extensionstate (struct mansession *s, const struct message *m)
 
static int action_filter (struct mansession *s, const struct message *m)
 Manager command to add an event filter to a manager session. More...
 
static struct manager_actionaction_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_loggerrotate (struct mansession *s, const struct message *m)
 Manager command "LoggerRotate" - reloads and rotates the logger in the same manner as the CLI command 'logger rotate'. More...
 
static int action_login (struct mansession *s, const struct message *m)
 
static int action_logoff (struct mansession *s, const struct message *m)
 
static int action_mailboxcount (struct mansession *s, const struct message *m)
 
static int action_mailboxstatus (struct mansession *s, const struct message *m)
 
static int action_originate (struct mansession *s, const struct message *m)
 
static int action_ping (struct mansession *s, const struct message *m)
 
static int action_presencestate (struct mansession *s, const struct message *m)
 
static int action_redirect (struct mansession *s, const struct message *m)
 action_redirect: The redirect manager command More...
 
static int action_reload (struct mansession *s, const struct message *m)
 Send a reload event. More...
 
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. More...
 
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 eventqentadvance_event (struct eventqent *e)
 
static AO2_GLOBAL_OBJ_STATIC (event_docs)
 A container of event documentation nodes. More...
 
static AO2_GLOBAL_OBJ_STATIC (mgr_sessions)
 
static int aocmessage_get_unit_entry (const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
 
static void append_channel_vars (struct ast_str **pbuf, struct ast_channel *chan)
 
static int append_event (const char *str, int category)
 events are appended to a queue from where they can be dispatched to clients. More...
 
int ast_hook_send_action (struct manager_custom_hook *hook, const char *msg)
 access for hooks to send action messages to ami More...
 
static int ast_instring (const char *bigstr, const char *smallstr, const char delim)
 
int ast_manager_check_enabled (void)
 Check if AMI is enabled. More...
 
struct stasis_message_routerast_manager_get_message_router (void)
 Get the stasis_message_router for AMI. More...
 
struct stasis_topicast_manager_get_topic (void)
 Get the Stasis Message Bus API topic for AMI. More...
 
int ast_manager_hangup_helper (struct mansession *s, const struct message *m, manager_hangup_handler_t hangup_handler, manager_hangup_cause_validator_t cause_validator)
 A manager helper function that hangs up a channel using a supplied channel type specific hangup function and cause code validator. More...
 
void ast_manager_publish_event (const char *type, int class_type, struct ast_json *obj)
 Publish an event to AMI. More...
 
int ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), struct ast_module *module, const char *synopsis, const char *description)
 register a new command with manager, including online help. This is the preferred way to register a manager command More...
 
void ast_manager_register_hook (struct manager_custom_hook *hook)
 Add a custom hook to be called when an event is fired. More...
 
static int ast_manager_register_struct (struct manager_action *act)
 
struct ast_strast_manager_str_from_json_object (struct ast_json *blob, key_exclusion_cb exclusion_cb)
 Convert a JSON object into an AMI compatible string. More...
 
int ast_manager_unregister (const char *action)
 support functions to register/unregister AMI action handlers, More...
 
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired. More...
 
int ast_webmanager_check_enabled (void)
 Check if AMI/HTTP is enabled. More...
 
void astman_append (struct mansession *s, const char *fmt,...)
 
static void astman_append_headers (struct message *m, const struct ast_variable *params)
 Append additional headers into the message structure from params. More...
 
static void astman_append_json (struct mansession *s, const char *str)
 
static void astman_flush (struct mansession *s, struct ast_str *buf)
 
static void astman_free_headers (struct message *m)
 Free headers inside message structure, but not the message structure itself. More...
 
const char * astman_get_header (const struct message *m, char *var)
 Return the first matching variable from an array. More...
 
struct ast_variableastman_get_variables (const struct message *m)
 Get a linked list of the Variable: headers. More...
 
struct ast_variableastman_get_variables_order (const struct message *m, enum variable_orders order)
 Get a linked list of the Variable: headers with order specified. More...
 
void astman_live_dangerously (int new_live_dangerously)
 Enable/disable the inclusion of 'dangerous' configurations outside of the ast_config_AST_CONFIG_DIR. More...
 
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
 Send ack in manager transaction. More...
 
void astman_send_error (struct mansession *s, const struct message *m, char *error)
 Send error in manager transaction. More...
 
void astman_send_error_va (struct mansession *s, const struct message *m, const char *fmt,...)
 Send error in manager transaction (with va_args support) More...
 
static void astman_send_list_complete (struct mansession *s, const struct message *m, const char *event_name, int count)
 
void astman_send_list_complete_end (struct mansession *s)
 End the list complete event. More...
 
void astman_send_list_complete_start (struct mansession *s, const struct message *m, const char *event_name, int count)
 Start the list complete event. More...
 
static struct ast_strastman_send_list_complete_start_common (struct mansession *s, const struct message *m, const char *event_name, int count)
 
void astman_send_listack (struct mansession *s, const struct message *m, char *msg, char *listflag)
 Send ack in manager transaction to begin a list. More...
 
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
 Send response in manager transaction. More...
 
static void astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
 send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. More...
 
static void astman_start_ack (struct mansession *s, const struct message *m)
 
static int authenticate (struct mansession *s, const struct message *m)
 
static const char * authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be returned. More...
 
static int blackfilter_cmp_fn (void *obj, void *arg, void *data, int flags)
 
static struct mansession_sessionbuild_mansession (const struct ast_sockaddr *addr)
 Allocate manager session structure and add it to the list of sessions. More...
 
static int check_blacklist (const char *cmd)
 
static int check_manager_session_inuse (const char *name)
 
static int coreshowchannelmap_add_connected_channels (struct ao2_container *channel_map, struct ast_channel_snapshot *channel_snapshot, struct ast_bridge_snapshot *bridge_snapshot)
 Recursive function to get all channels in a bridge. Follow local channels as well. More...
 
static int coreshowchannelmap_add_to_map (struct ao2_container *c, const char *s)
 Helper function to add a channel name to the vector. More...
 
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 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. More...
 
static void generate_status (struct mansession *s, struct ast_channel *chan, char **vars, int varc, int all_variables, char *id_text, int *count)
 
static int get_input (struct mansession *s, char *output)
 
static struct ast_manager_userget_manager_by_name_locked (const char *name)
 
static int get_perm (const char *instr)
 
static struct eventqentgrab_last (void)
 
static char * handle_kickmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager kick session. More...
 
static char * handle_manager_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager reload. More...
 
static char * handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void handle_parse_error (struct mansession *s, struct message *m, char *error)
 
static char * handle_showmanager (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmanagers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmancmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmancmds (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list commands. More...
 
static char * handle_showmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list connected. More...
 
static char * handle_showmaneventq (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list eventq. More...
 
static enum error_type handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
 helper function for action_updateconfig More...
 
static void json_escape (char *out, const char *in)
 
static void log_action (const struct message *m, const char *action)
 
static struct ast_variableman_do_variable_value (struct ast_variable *head, const char *hdr_val)
 
static enum add_filter_result manager_add_filter (const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters)
 Add an event filter to a manager session. More...
 
static void manager_default_msg_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int manager_displayconnects (struct mansession_session *session)
 Get displayconnects config option. More...
 
static void manager_generic_msg_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void manager_json_array_with_key (struct ast_json *obj, const char *key, size_t index, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_obj_with_key (struct ast_json *obj, const char *key, const char *parent_key, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_to_ast_str (struct ast_json *obj, const char *key, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_value_str_append (struct ast_json *value, const char *key, struct ast_str **res)
 
static int manager_modulecheck (struct mansession *s, const struct message *m)
 Manager function to check if module is loaded. More...
 
static int manager_moduleload (struct mansession *s, const struct message *m)
 
static int manager_state_cb (const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
 
static int mansession_cmp_fn (void *obj, void *arg, int flags)
 
static enum ast_transport mansession_get_transport (const struct mansession *s)
 
static void mansession_lock (struct mansession *s)
 Lock the 'mansession' structure. More...
 
static void mansession_unlock (struct mansession *s)
 Unlock the 'mansession' structure. More...
 
static int match_filter (struct mansession *s, char *eventdata)
 
static void print_event_instance (struct ast_cli_args *a, struct ast_xml_doc_item *instance)
 
static int process_events (struct mansession *s)
 
static int process_message (struct mansession *s, const struct message *m)
 Process an AMI message, performing desired action. Return 0 on success, -1 on error that require the session to be destroyed. More...
 
static void purge_events (void)
 
static int purge_sessions (int n_max)
 remove at most n_max stale session from the list. More...
 
static int queue_read_action_payload (struct ast_channel *chan, const unsigned char *payload, size_t payload_size, enum ast_frame_read_action action)
 Queue a given read action containing a payload onto a channel. More...
 
static int queue_sendtext (struct ast_channel *chan, const char *body)
 Queue a read action to send a text message. More...
 
static int queue_sendtext_data (struct ast_channel *chan, const char *body, const char *content_type)
 Queue a read action to send a text data message. More...
 
static int reload_module (void)
 
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 restrictedFile (const char *filename)
 Check if a file is restricted or not. More...
 
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(). ) More...
 
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. More...
 
static int strings_to_mask (const char *string)
 
static struct mansession_sessionunref_mansession (struct mansession_session *s)
 Unreference manager session object. If no more references, then go ahead and delete it. More...
 
static const char * user_authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options for a user. This will only display those authority codes that have an explicit match on authority. More...
 
static int whitefilter_cmp_fn (void *obj, void *arg, void *data, int flags)
 

Variables

static struct stasis_subscriptionacl_change_sub
 
static struct actions actions = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct all_events all_events = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
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 broken_events_action = 0
 
struct {
   const char *   words [AST_MAX_CMD_LEN]
 
command_blacklist []
 
static int displayconnects = 1
 
static char global_realm [MAXHOSTNAMELEN]
 
static int httptimeout = 60
 
static int live_dangerously
 Set to true (non-zero) to globally allow all dangerous AMI actions to run. More...
 
static char * manager_channelvars
 
static int manager_debug = 0
 
static char * manager_disabledevents
 
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 manager_hooks manager_hooks = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct stasis_topicmanager_topic
 A stasis_topic that all topics AMI cares about will be forwarded to. More...
 
static const struct permalias perms []
 
static struct stasis_forwardrtp_topic_forwarder
 The stasis_subscription for forwarding the RTP topic to the AMI topic. More...
 
static struct stasis_forwardsecurity_topic_forwarder
 The stasis_subscription for forwarding the Security topic to the AMI topic. More...
 
static struct stasis_message_routerstasis_router
 The stasis_message_router for all Stasis Message Bus API messages. More...
 
static int subscribed = 0
 
static int timestampevents
 
static int unauth_sessions = 0
 
static struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , }
 
static struct users users = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static int webmanager_enabled = 0
 
 STASIS_MESSAGE_TYPE_DEFN (ast_manager_get_generic_type)
 Define AMI message types. More...
 

Detailed Description

Macro Definition Documentation

◆ any_manager_listeners

#define any_manager_listeners (   sessions)     ((sessions && ao2_container_count(sessions)) || !AST_RWLIST_EMPTY(&manager_hooks))

Definition at line 1987 of file manager.c.

◆ ASTMAN_APPEND_BUF_INITSIZE

#define ASTMAN_APPEND_BUF_INITSIZE   256

initial allocated size for the astman_append_buf and astman_send_*_va

Definition at line 3288 of file manager.c.

◆ DEFAULT_REALM

#define DEFAULT_REALM   "asterisk"

Definition at line 1629 of file manager.c.

◆ EVENT_FLAG_SHUTDOWN

#define EVENT_FLAG_SHUTDOWN   -1

Fake event class used to end sessions at shutdown.

Definition at line 1662 of file manager.c.

◆ GET_HEADER_FIRST_MATCH

#define GET_HEADER_FIRST_MATCH   0

Definition at line 2988 of file manager.c.

◆ GET_HEADER_LAST_MATCH

#define GET_HEADER_LAST_MATCH   1

Definition at line 2989 of file manager.c.

◆ GET_HEADER_SKIP_EMPTY

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 2990 of file manager.c.

◆ MANAGER_EVENT_BUF_INITSIZE

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 7885 of file manager.c.

◆ manager_event_sessions

#define manager_event_sessions (   sessions,
  category,
  event,
  contents,
  ... 
)     __manager_event_sessions(sessions, category, event, 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, contents , ## __VA_ARGS__)

Definition at line 1984 of file manager.c.

◆ MAX_AUTH_PERM_STRING

#define MAX_AUTH_PERM_STRING   150

Maximum string length of the AMI authority permission string buildable from perms[].

Definition at line 2195 of file manager.c.

◆ MAX_BLACKLIST_CMD_LEN

#define MAX_BLACKLIST_CMD_LEN   2

Descriptor for a manager session, either on the AMI socket or over HTTP.

Note
AMI session have managerid == 0; the entry is created upon a connect, and destroyed with the socket. HTTP sessions have managerid != 0, the value is used as a search key to lookup sessions (using the mansession_id cookie, or nonce key from Digest Authentication http header).

Definition at line 1674 of file manager.c.

◆ MAX_VARS

#define MAX_VARS   128

Definition at line 1659 of file manager.c.

◆ MGR_SHOW_TERMINAL_WIDTH

#define MGR_SHOW_TERMINAL_WIDTH   80

Definition at line 1657 of file manager.c.

◆ MSG_MOREDATA

#define MSG_MOREDATA   ((char *)astman_send_response)
Note
NOTE: XXX this comment is unclear and possibly wrong. Callers of astman_send_error(), astman_send_response() or astman_send_ack() must EITHER hold the session lock or be running in an action callback (in which case s->session->busy will be non-zero). In either of these cases, there is no need to lock-protect the session's fd, since no other output will be sent (events will be queued), and no input will be read until either the current action finishes or get_input() obtains the session lock.
Todo:
XXX MSG_MOREDATA should go to a header file.

Definition at line 3336 of file manager.c.

Enumeration Type Documentation

◆ add_filter_result

Enumerator
FILTER_SUCCESS 
FILTER_ALLOC_FAILED 
FILTER_COMPILE_FAIL 

Definition at line 1579 of file manager.c.

1579 {
1583};
@ FILTER_SUCCESS
Definition: manager.c:1580
@ FILTER_COMPILE_FAIL
Definition: manager.c:1582
@ FILTER_ALLOC_FAILED
Definition: manager.c:1581

◆ error_type

enum error_type

Doxygen group

Enumerator
UNKNOWN_ACTION 
UNKNOWN_CATEGORY 
UNSPECIFIED_CATEGORY 
UNSPECIFIED_ARGUMENT 
FAILURE_ALLOCATION 
FAILURE_NEWCAT 
FAILURE_DELCAT 
FAILURE_EMPTYCAT 
FAILURE_UPDATE 
FAILURE_DELETE 
FAILURE_APPEND 
FAILURE_TEMPLATE 

Definition at line 1564 of file manager.c.

1564 {
1565 UNKNOWN_ACTION = 1,
1577};
@ FAILURE_EMPTYCAT
Definition: manager.c:1572
@ FAILURE_UPDATE
Definition: manager.c:1573
@ FAILURE_NEWCAT
Definition: manager.c:1570
@ FAILURE_DELETE
Definition: manager.c:1574
@ FAILURE_APPEND
Definition: manager.c:1575
@ UNKNOWN_CATEGORY
Definition: manager.c:1566
@ FAILURE_DELCAT
Definition: manager.c:1571
@ FAILURE_ALLOCATION
Definition: manager.c:1569
@ FAILURE_TEMPLATE
Definition: manager.c:1576
@ UNSPECIFIED_CATEGORY
Definition: manager.c:1567
@ UNSPECIFIED_ARGUMENT
Definition: manager.c:1568
@ UNKNOWN_ACTION
Definition: manager.c:1565

◆ mansession_message_parsing

Enumerator
MESSAGE_OKAY 
MESSAGE_LINE_TOO_LONG 

Definition at line 1767 of file manager.c.

1767 {
1770};
@ MESSAGE_OKAY
Definition: manager.c:1768
@ MESSAGE_LINE_TOO_LONG
Definition: manager.c:1769

Function Documentation

◆ __ast_manager_event_multichan()

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

Parameters
categoryEvent category, matches manager authorization
eventEvent name
chancountNumber of channels in chans parameter
chansA pointer to an array of channels involved in the event
file,line,func
contentsFormat string describing event
...
Since
1.8

Definition at line 8016 of file manager.c.

8019{
8020 struct ao2_container *sessions = ao2_global_obj_ref(mgr_sessions);
8021 va_list ap;
8022 int res;
8023
8025 /* Nobody is listening */
8027 return 0;
8028 }
8029
8030 va_start(ap, fmt);
8032 file, line, func, fmt, ap);
8033 va_end(ap);
8035 return res;
8036}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
static struct unistimsession * sessions
static int chancount
Definition: channel.c:93
#define any_manager_listeners(sessions)
Definition: manager.c:1987
static int __manager_event_sessions_va(struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt, va_list ap)
Definition: manager.c:7887
Generic container type.
Definition: astman.c:88
Definition: astman.c:222

References __manager_event_sessions_va(), any_manager_listeners, ao2_cleanup, ao2_global_obj_ref, chancount, make_ari_stubs::file, and sessions.

◆ __astman_get_header()

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.

Note
At the moment there is only one use of this function in this file, so we make it static.
Never returns NULL.

Definition at line 3005 of file manager.c.

3006{
3007 int x, l = strlen(var);
3008 const char *result = "";
3009
3010 if (!m) {
3011 return result;
3012 }
3013
3014 for (x = 0; x < m->hdrcount; x++) {
3015 const char *h = m->headers[x];
3016 if (!strncasecmp(var, h, l) && h[l] == ':') {
3017 const char *value = h + l + 1;
3018 value = ast_skip_blanks(value); /* ignore leading spaces in the value */
3019 /* found a potential candidate */
3020 if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
3021 continue; /* not interesting */
3022 }
3023 if (mode & GET_HEADER_LAST_MATCH) {
3024 result = value; /* record the last match so far */
3025 } else {
3026 return value;
3027 }
3028 }
3029 }
3030
3031 return result;
3032}
#define var
Definition: ast_expr2f.c:605
static PGresult * result
Definition: cel_pgsql.c:84
#define GET_HEADER_LAST_MATCH
Definition: manager.c:2989
#define GET_HEADER_SKIP_EMPTY
Definition: manager.c:2990
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
unsigned int hdrcount
Definition: manager.h:150
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:151
int value
Definition: syslog.c:37

References ast_skip_blanks(), ast_strlen_zero(), GET_HEADER_LAST_MATCH, GET_HEADER_SKIP_EMPTY, message::hdrcount, message::headers, result, value, and var.

Referenced by action_aoc_s_submessage(), astman_get_header(), and process_message().

◆ __init_astman_append_buf()

static void __init_astman_append_buf ( void  )
static

thread local buffer for astman_append

Note
This can not be defined within the astman_append() function because it declares a couple of functions that get used to initialize the thread local storage key.

Definition at line 3283 of file manager.c.

3291{

◆ __init_manager_event_buf()

static void __init_manager_event_buf ( void  )
static

Definition at line 7884 of file manager.c.

7898{

◆ __init_userevent_buf()

static void __init_userevent_buf ( void  )
static

Definition at line 3285 of file manager.c.

3291{

◆ __manager_event_sessions()

static int __manager_event_sessions ( struct ao2_container sessions,
int  category,
const char *  event,
int  chancount,
struct ast_channel **  chans,
const char *  file,
int  line,
const char *  func,
const char *  fmt,
  ... 
)
static

Definition at line 7994 of file manager.c.

8005{
8006 va_list ap;
8007 int res;
8008
8009 va_start(ap, fmt);
8011 file, line, func, fmt, ap);
8012 va_end(ap);
8013 return res;
8014}

References __manager_event_sessions_va(), chancount, make_ari_stubs::file, and sessions.

◆ __manager_event_sessions_va()

static int __manager_event_sessions_va ( struct ao2_container sessions,
int  category,
const char *  event,
int  chancount,
struct ast_channel **  chans,
const char *  file,
int  line,
const char *  func,
const char *  fmt,
va_list  ap 
)
static

Definition at line 7887 of file manager.c.

7898{
7900 const char *cat_str;
7901 struct timeval now;
7902 struct ast_str *buf;
7903 int i;
7904
7907 ast_debug(3, "AMI Event '%s' is globally disabled, skipping\n", event);
7908 /* Event is globally disabled */
7909 return -1;
7910 }
7911 }
7912
7914 if (!buf) {
7915 return -1;
7916 }
7917
7918 cat_str = authority_to_str(category, &auth);
7919 ast_str_set(&buf, 0,
7920 "Event: %s\r\n"
7921 "Privilege: %s\r\n",
7922 event, cat_str);
7923
7924 if (timestampevents) {
7925 now = ast_tvnow();
7926 ast_str_append(&buf, 0,
7927 "Timestamp: %ld.%06lu\r\n",
7928 (long)now.tv_sec, (unsigned long) now.tv_usec);
7929 }
7930 if (manager_debug) {
7931 static int seq;
7932
7933 ast_str_append(&buf, 0,
7934 "SequenceNumber: %d\r\n",
7936 ast_str_append(&buf, 0,
7937 "File: %s\r\n"
7938 "Line: %d\r\n"
7939 "Func: %s\r\n",
7940 file, line, func);
7941 }
7943 ast_str_append(&buf, 0,
7944 "SystemName: %s\r\n",
7946 }
7947
7948 ast_str_append_va(&buf, 0, fmt, ap);
7949 for (i = 0; i < chancount; i++) {
7951 }
7952
7953 ast_str_append(&buf, 0, "\r\n");
7954
7955 append_event(ast_str_buffer(buf), category);
7956
7957 /* Wake up any sleeping sessions */
7958 if (sessions) {
7959 struct ao2_iterator iter;
7961
7962 iter = ao2_iterator_init(sessions, 0);
7963 while ((session = ao2_iterator_next(&iter))) {
7964 ast_mutex_lock(&session->notify_lock);
7965 if (session->waiting_thread != AST_PTHREADT_NULL) {
7966 pthread_kill(session->waiting_thread, SIGURG);
7967 } else {
7968 /* We have an event to process, but the mansession is
7969 * not waiting for it. We still need to indicate that there
7970 * is an event waiting so that get_input processes the pending
7971 * event instead of polling.
7972 */
7973 session->pending_event = 1;
7974 }
7975 ast_mutex_unlock(&session->notify_lock);
7977 }
7978 ao2_iterator_destroy(&iter);
7979 }
7980
7981 if (category != EVENT_FLAG_SHUTDOWN && !AST_RWLIST_EMPTY(&manager_hooks)) {
7982 struct manager_custom_hook *hook;
7983
7985 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
7986 hook->helper(category, event, ast_str_buffer(buf));
7987 }
7989 }
7990
7991 return 0;
7992}
static volatile unsigned int seq
Definition: app_sms.c:120
static struct ast_mansession session
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static struct ast_threadstorage manager_event_buf
Definition: manager.c:7884
static int manager_debug
Definition: manager.c:1623
static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
Definition: manager.c:7867
static struct mansession_session * unref_mansession(struct mansession_session *s)
Unreference manager session object. If no more references, then go ahead and delete it.
Definition: manager.c:2335
static const char * authority_to_str(int authority, struct ast_str **res)
Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be re...
Definition: manager.c:2236
#define MAX_AUTH_PERM_STRING
Definition: manager.c:2195
static int timestampevents
Definition: manager.c:1617
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:1662
static int append_event(const char *str, int category)
events are appended to a queue from where they can be dispatched to clients.
Definition: manager.c:7843
#define MANAGER_EVENT_BUF_INITSIZE
Definition: manager.c:7885
static char * manager_disabledevents
Definition: manager.c:1627
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:452
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_mutex_unlock(a)
Definition: lock.h:190
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757
#define ast_mutex_lock(a)
Definition: lock.h:189
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_alloca(init_len)
Definition: strings.h:848
int ast_in_delimited_string(const char *needle, const char *haystack, char delim)
Check if there is an exact match for 'needle' between delimiters in 'haystack'.
Definition: strings.c:433
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
int ast_str_append_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Append to a dynamic string using a va_list.
Definition: strings.h:1048
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:909
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Support for dynamic strings.
Definition: strings.h:623
manager_hook_t helper
Definition: manager.h:117
list of hooks registered
Definition: manager.c:1820
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, append_channel_vars(), append_event(), ast_atomic_fetchadd_int(), ast_config_AST_SYSTEM_NAME, ast_debug, ast_in_delimited_string(), ast_mutex_lock, ast_mutex_unlock, 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_strlen_zero(), ast_tvnow(), authority_to_str(), buf, chancount, EVENT_FLAG_SHUTDOWN, make_ari_stubs::file, manager_custom_hook::helper, manager_debug, manager_disabledevents, manager_event_buf, MANAGER_EVENT_BUF_INITSIZE, MAX_AUTH_PERM_STRING, seq, session, sessions, timestampevents, and unref_mansession().

Referenced by __ast_manager_event_multichan(), and __manager_event_sessions().

◆ acl_change_stasis_cb()

static void acl_change_stasis_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 10458 of file manager.c.

10460{
10462 return;
10463 }
10464
10465 /* For now, this is going to be performed simply and just execute a forced reload. */
10466 ast_log(LOG_NOTICE, "Reloading manager in response to ACL change event.\n");
10467 __init_manager(1, 1);
10468}
struct stasis_message_type * ast_named_acl_change_type(void)
a stasis_message_type for changes against a named ACL or the set of all named ACLs
#define ast_log
Definition: astobj2.c:42
#define LOG_NOTICE
static int __init_manager(int reload, int by_external_config)
Definition: manager.c:9962
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.

References __init_manager(), ast_log, ast_named_acl_change_type(), LOG_NOTICE, and stasis_message_type().

Referenced by acl_change_stasis_subscribe().

◆ acl_change_stasis_subscribe()

static void acl_change_stasis_subscribe ( void  )
static

Definition at line 1685 of file manager.c.

1686{
1687 if (!acl_change_sub) {
1692 }
1693}
static struct stasis_subscription * acl_change_sub
Definition: manager.c:1633
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:10458
#define NULL
Definition: resample.c:96
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
Definition: stasis.h:297
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1023
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1077
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:649

References acl_change_stasis_cb(), acl_change_sub, ast_named_acl_change_type(), ast_security_topic(), NULL, stasis_subscribe, stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, and stasis_subscription_set_filter().

Referenced by __init_manager().

◆ acl_change_stasis_unsubscribe()

static void acl_change_stasis_unsubscribe ( void  )
static

Definition at line 1695 of file manager.c.

1696{
1698}
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1134

References acl_change_sub, and stasis_unsubscribe_and_join().

Referenced by __init_manager(), and manager_shutdown().

◆ action_aoc_de_message()

static struct ast_aoc_decoded * action_aoc_de_message ( struct mansession s,
const struct message m 
)
static

Definition at line 5823 of file manager.c.

5824{
5825 const char *msgtype = astman_get_header(m, "MsgType");
5826 const char *chargetype = astman_get_header(m, "ChargeType");
5827 const char *currencyname = astman_get_header(m, "CurrencyName");
5828 const char *currencyamount = astman_get_header(m, "CurrencyAmount");
5829 const char *mult = astman_get_header(m, "CurrencyMultiplier");
5830 const char *totaltype = astman_get_header(m, "TotalType");
5831 const char *aocbillingid = astman_get_header(m, "AOCBillingId");
5832 const char *association_id= astman_get_header(m, "ChargingAssociationId");
5833 const char *association_num = astman_get_header(m, "ChargingAssociationNumber");
5834 const char *association_plan = astman_get_header(m, "ChargingAssociationPlan");
5835
5836 enum ast_aoc_type _msgtype;
5837 enum ast_aoc_charge_type _chargetype;
5839 enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL;
5840 enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA;
5841 unsigned int _currencyamount = 0;
5842 int _association_id = 0;
5843 unsigned int _association_plan = 0;
5844
5845 struct ast_aoc_decoded *decoded = NULL;
5846
5847 if (ast_strlen_zero(chargetype)) {
5848 astman_send_error(s, m, "ChargeType not specified");
5849 goto aocmessage_cleanup;
5850 }
5851
5852 _msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D;
5853
5854 if (!strcasecmp(chargetype, "NA")) {
5855 _chargetype = AST_AOC_CHARGE_NA;
5856 } else if (!strcasecmp(chargetype, "Free")) {
5857 _chargetype = AST_AOC_CHARGE_FREE;
5858 } else if (!strcasecmp(chargetype, "Currency")) {
5859 _chargetype = AST_AOC_CHARGE_CURRENCY;
5860 } else if (!strcasecmp(chargetype, "Unit")) {
5861 _chargetype = AST_AOC_CHARGE_UNIT;
5862 } else {
5863 astman_send_error(s, m, "Invalid ChargeType");
5864 goto aocmessage_cleanup;
5865 }
5866
5867 if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
5868
5869 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) {
5870 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency");
5871 goto aocmessage_cleanup;
5872 }
5873
5874 if (ast_strlen_zero(mult)) {
5875 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
5876 goto aocmessage_cleanup;
5877 } else if (!strcasecmp(mult, "onethousandth")) {
5879 } else if (!strcasecmp(mult, "onehundredth")) {
5881 } else if (!strcasecmp(mult, "onetenth")) {
5882 _mult = AST_AOC_MULT_ONETENTH;
5883 } else if (!strcasecmp(mult, "one")) {
5884 _mult = AST_AOC_MULT_ONE;
5885 } else if (!strcasecmp(mult, "ten")) {
5886 _mult = AST_AOC_MULT_TEN;
5887 } else if (!strcasecmp(mult, "hundred")) {
5888 _mult = AST_AOC_MULT_HUNDRED;
5889 } else if (!strcasecmp(mult, "thousand")) {
5890 _mult = AST_AOC_MULT_THOUSAND;
5891 } else {
5892 astman_send_error(s, m, "Invalid ChargeMultiplier");
5893 goto aocmessage_cleanup;
5894 }
5895 }
5896
5897 /* create decoded object and start setting values */
5898 if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) {
5899 astman_send_error(s, m, "Message Creation Failed");
5900 goto aocmessage_cleanup;
5901 }
5902
5903 if (_msgtype == AST_AOC_D) {
5904 if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) {
5905 _totaltype = AST_AOC_SUBTOTAL;
5906 }
5907
5908 if (ast_strlen_zero(aocbillingid)) {
5909 /* ignore this is optional */
5910 } else if (!strcasecmp(aocbillingid, "Normal")) {
5911 _billingid = AST_AOC_BILLING_NORMAL;
5912 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
5913 _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
5914 } else if (!strcasecmp(aocbillingid, "CreditCard")) {
5915 _billingid = AST_AOC_BILLING_CREDIT_CARD;
5916 } else {
5917 astman_send_error(s, m, "Invalid AOC-D AOCBillingId");
5918 goto aocmessage_cleanup;
5919 }
5920 } else {
5921 if (ast_strlen_zero(aocbillingid)) {
5922 /* ignore this is optional */
5923 } else if (!strcasecmp(aocbillingid, "Normal")) {
5924 _billingid = AST_AOC_BILLING_NORMAL;
5925 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
5926 _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
5927 } else if (!strcasecmp(aocbillingid, "CreditCard")) {
5928 _billingid = AST_AOC_BILLING_CREDIT_CARD;
5929 } else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) {
5931 } else if (!strcasecmp(aocbillingid, "CallFwdBusy")) {
5932 _billingid = AST_AOC_BILLING_CALL_FWD_BUSY;
5933 } else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) {
5935 } else if (!strcasecmp(aocbillingid, "CallDeflection")) {
5937 } else if (!strcasecmp(aocbillingid, "CallTransfer")) {
5938 _billingid = AST_AOC_BILLING_CALL_TRANSFER;
5939 } else {
5940 astman_send_error(s, m, "Invalid AOC-E AOCBillingId");
5941 goto aocmessage_cleanup;
5942 }
5943
5944 if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) {
5945 astman_send_error(s, m, "Invalid ChargingAssociationId");
5946 goto aocmessage_cleanup;
5947 }
5948 if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) {
5949 astman_send_error(s, m, "Invalid ChargingAssociationPlan");
5950 goto aocmessage_cleanup;
5951 }
5952
5953 if (_association_id) {
5954 ast_aoc_set_association_id(decoded, _association_id);
5955 } else if (!ast_strlen_zero(association_num)) {
5956 ast_aoc_set_association_number(decoded, association_num, _association_plan);
5957 }
5958 }
5959
5960 if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
5961 ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname);
5962 } else if (_chargetype == AST_AOC_CHARGE_UNIT) {
5964 int i;
5965
5966 /* multiple unit entries are possible, lets get them all */
5967 for (i = 0; i < 32; i++) {
5968 if (aocmessage_get_unit_entry(m, &entry, i)) {
5969 break; /* that's the end then */
5970 }
5971
5972 ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type);
5973 }
5974
5975 /* at least one unit entry is required */
5976 if (!i) {
5977 astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit");
5978 goto aocmessage_cleanup;
5979 }
5980
5981 }
5982
5983 ast_aoc_set_billing_id(decoded, _billingid);
5984 ast_aoc_set_total_type(decoded, _totaltype);
5985
5986 return decoded;
5987
5988aocmessage_cleanup:
5989
5990 ast_aoc_destroy_decoded(decoded);
5991 return NULL;
5992}
ast_aoc_charge_type
Definition: aoc.h:69
@ AST_AOC_CHARGE_CURRENCY
Definition: aoc.h:72
@ AST_AOC_CHARGE_FREE
Definition: aoc.h:71
@ AST_AOC_CHARGE_UNIT
Definition: aoc.h:73
@ AST_AOC_CHARGE_NA
Definition: aoc.h:70
ast_aoc_currency_multiplier
Defines the currency multiplier for an aoc message.
Definition: aoc.h:34
@ AST_AOC_MULT_TEN
Definition: aoc.h:39
@ AST_AOC_MULT_ONEHUNDREDTH
Definition: aoc.h:36
@ AST_AOC_MULT_HUNDRED
Definition: aoc.h:40
@ AST_AOC_MULT_ONETENTH
Definition: aoc.h:37
@ AST_AOC_MULT_ONETHOUSANDTH
Definition: aoc.h:35
@ AST_AOC_MULT_THOUSAND
Definition: aoc.h:41
@ AST_AOC_MULT_ONE
Definition: aoc.h:38
struct ast_aoc_decoded * ast_aoc_create(const enum ast_aoc_type msg_type, const enum ast_aoc_charge_type charge_type, const enum ast_aoc_request requests)
creates a ast_aoc_decode object of a specific message type
Definition: aoc.c:276
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan)
set the charging association number for an AOC-E message
Definition: aoc.c:1056
int ast_aoc_add_unit_entry(struct ast_aoc_decoded *decoded, const unsigned int amount_is_present, const unsigned int amount, const unsigned int type_is_present, const unsigned int type)
Adds a unit entry into the list of units.
Definition: aoc.c:977
ast_aoc_billing_id
Defines the billing id options for an aoc message.
Definition: aoc.h:49
@ AST_AOC_BILLING_CALL_FWD_BUSY
Definition: aoc.h:55
@ AST_AOC_BILLING_CALL_FWD_NO_REPLY
Definition: aoc.h:56
@ AST_AOC_BILLING_NORMAL
Definition: aoc.h:51
@ AST_AOC_BILLING_CALL_DEFLECTION
Definition: aoc.h:57
@ AST_AOC_BILLING_CREDIT_CARD
Definition: aoc.h:53
@ AST_AOC_BILLING_CALL_TRANSFER
Definition: aoc.h:58
@ AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL
Definition: aoc.h:54
@ AST_AOC_BILLING_REVERSE_CHARGE
Definition: aoc.h:52
@ AST_AOC_BILLING_NA
Definition: aoc.h:50
int ast_aoc_set_billing_id(struct ast_aoc_decoded *decoded, const enum ast_aoc_billing_id id)
set the billing id for a AOC-D or AST_AOC_E message
Definition: aoc.c:1024
int ast_aoc_set_currency_info(struct ast_aoc_decoded *decoded, const unsigned int amount, const enum ast_aoc_currency_multiplier multiplier, const char *name)
Sets the currency values for a AOC-D or AOC-E message.
Definition: aoc.c:919
int ast_aoc_set_association_id(struct ast_aoc_decoded *decoded, const int id)
set the charging association id for an AST_AOC_E message
Definition: aoc.c:1040
int ast_aoc_set_total_type(struct ast_aoc_decoded *decoded, const enum ast_aoc_total_type type)
Sets the type of total for a AOC-D message.
Definition: aoc.c:907
ast_aoc_type
Definition: aoc.h:62
@ AST_AOC_D
Definition: aoc.h:65
@ AST_AOC_E
Definition: aoc.h:66
ast_aoc_total_type
Definition: aoc.h:82
@ AST_AOC_TOTAL
Definition: aoc.h:83
@ AST_AOC_SUBTOTAL
Definition: aoc.h:84
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3381
const char * astman_get_header(const struct message *m, char *var)
Return the first matching variable from an array.
Definition: manager.c:3042
static int aocmessage_get_unit_entry(const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
Definition: manager.c:5798
Definition: aoc.h:178
Definition: search.h:40

References 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_E, 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_strlen_zero(), astman_get_header(), astman_send_error(), and NULL.

Referenced by action_aocmessage().

◆ action_aoc_s_message()

static struct ast_aoc_decoded * action_aoc_s_message ( struct mansession s,
const struct message m 
)
static

Definition at line 6218 of file manager.c.

6220{
6221 struct ast_aoc_decoded *decoded = NULL;
6222 int hdrlen;
6223 int x;
6224 static const char hdr[] = "ChargedItem:";
6225 struct message sm = { 0 };
6226 int rates = 0;
6227
6228 if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
6229 astman_send_error(s, m, "Message Creation Failed");
6230 goto aocmessage_cleanup;
6231 }
6232
6233 hdrlen = strlen(hdr);
6234 for (x = 0; x < m->hdrcount; x++) {
6235 if (strncasecmp(hdr, m->headers[x], hdrlen) == 0) {
6236 if (rates > ast_aoc_s_get_count(decoded)) {
6237 if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
6238 goto aocmessage_cleanup;
6239 }
6240 }
6241 ++rates;
6242 }
6243
6244 sm.headers[sm.hdrcount] = m->headers[x];
6245 ++sm.hdrcount;
6246 }
6247 if (rates > ast_aoc_s_get_count(decoded)) {
6248 if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
6249 goto aocmessage_cleanup;
6250 }
6251 }
6252
6253 return decoded;
6254
6255aocmessage_cleanup:
6256
6257 ast_aoc_destroy_decoded(decoded);
6258 return NULL;
6259}
@ AST_AOC_S
Definition: aoc.h:64
unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded)
get the number rates associated with an AOC-S message
Definition: aoc.c:756
static int action_aoc_s_submessage(struct mansession *s, const struct message *m, struct ast_aoc_decoded *decoded)
Definition: manager.c:5994

References action_aoc_s_submessage(), ast_aoc_create(), ast_aoc_destroy_decoded(), AST_AOC_S, ast_aoc_s_get_count(), astman_send_error(), message::hdrcount, message::headers, and NULL.

Referenced by action_aocmessage().

◆ action_aoc_s_submessage()

static int action_aoc_s_submessage ( struct mansession s,
const struct message m,
struct ast_aoc_decoded decoded 
)
static

Definition at line 5994 of file manager.c.

5996{
5997 const char *chargeditem = __astman_get_header(m, "ChargedItem", GET_HEADER_LAST_MATCH);
5998 const char *ratetype = __astman_get_header(m, "RateType", GET_HEADER_LAST_MATCH);
5999 const char *currencyname = __astman_get_header(m, "CurrencyName", GET_HEADER_LAST_MATCH);
6000 const char *currencyamount = __astman_get_header(m, "CurrencyAmount", GET_HEADER_LAST_MATCH);
6001 const char *mult = __astman_get_header(m, "CurrencyMultiplier", GET_HEADER_LAST_MATCH);
6002 const char *time = __astman_get_header(m, "Time", GET_HEADER_LAST_MATCH);
6003 const char *timescale = __astman_get_header(m, "TimeScale", GET_HEADER_LAST_MATCH);
6004 const char *granularity = __astman_get_header(m, "Granularity", GET_HEADER_LAST_MATCH);
6005 const char *granularitytimescale = __astman_get_header(m, "GranularityTimeScale", GET_HEADER_LAST_MATCH);
6006 const char *chargingtype = __astman_get_header(m, "ChargingType", GET_HEADER_LAST_MATCH);
6007 const char *volumeunit = __astman_get_header(m, "VolumeUnit", GET_HEADER_LAST_MATCH);
6008 const char *code = __astman_get_header(m, "Code", GET_HEADER_LAST_MATCH);
6009
6010 enum ast_aoc_s_charged_item _chargeditem;
6011 enum ast_aoc_s_rate_type _ratetype;
6013 unsigned int _currencyamount = 0;
6014 unsigned int _code;
6015 unsigned int _time = 0;
6016 enum ast_aoc_time_scale _scale = 0;
6017 unsigned int _granularity = 0;
6018 enum ast_aoc_time_scale _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
6019 int _step = 0;
6020 enum ast_aoc_volume_unit _volumeunit = 0;
6021
6022 if (ast_strlen_zero(chargeditem)) {
6023 astman_send_error(s, m, "ChargedItem not specified");
6024 goto aocmessage_cleanup;
6025 }
6026
6027 if (ast_strlen_zero(ratetype)) {
6028 astman_send_error(s, m, "RateType not specified");
6029 goto aocmessage_cleanup;
6030 }
6031
6032 if (!strcasecmp(chargeditem, "NA")) {
6033 _chargeditem = AST_AOC_CHARGED_ITEM_NA;
6034 } else if (!strcasecmp(chargeditem, "SpecialArrangement")) {
6036 } else if (!strcasecmp(chargeditem, "BasicCommunication")) {
6038 } else if (!strcasecmp(chargeditem, "CallAttempt")) {
6039 _chargeditem = AST_AOC_CHARGED_ITEM_CALL_ATTEMPT;
6040 } else if (!strcasecmp(chargeditem, "CallSetup")) {
6041 _chargeditem = AST_AOC_CHARGED_ITEM_CALL_SETUP;
6042 } else if (!strcasecmp(chargeditem, "UserUserInfo")) {
6044 } else if (!strcasecmp(chargeditem, "SupplementaryService")) {
6046 } else {
6047 astman_send_error(s, m, "Invalid ChargedItem");
6048 goto aocmessage_cleanup;
6049 }
6050
6051 if (!strcasecmp(ratetype, "NA")) {
6052 _ratetype = AST_AOC_RATE_TYPE_NA;
6053 } else if (!strcasecmp(ratetype, "Free")) {
6054 _ratetype = AST_AOC_RATE_TYPE_FREE;
6055 } else if (!strcasecmp(ratetype, "FreeFromBeginning")) {
6057 } else if (!strcasecmp(ratetype, "Duration")) {
6058 _ratetype = AST_AOC_RATE_TYPE_DURATION;
6059 } else if (!strcasecmp(ratetype, "Flat")) {
6060 _ratetype = AST_AOC_RATE_TYPE_FLAT;
6061 } else if (!strcasecmp(ratetype, "Volume")) {
6062 _ratetype = AST_AOC_RATE_TYPE_VOLUME;
6063 } else if (!strcasecmp(ratetype, "SpecialCode")) {
6065 } else {
6066 astman_send_error(s, m, "Invalid RateType");
6067 goto aocmessage_cleanup;
6068 }
6069
6070 if (_ratetype > AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
6071 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u",
6072 &_currencyamount) != 1)) {
6073 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when RateType is non-free");
6074 goto aocmessage_cleanup;
6075 }
6076
6077 if (ast_strlen_zero(mult)) {
6078 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
6079 goto aocmessage_cleanup;
6080 } else if (!strcasecmp(mult, "onethousandth")) {
6082 } else if (!strcasecmp(mult, "onehundredth")) {
6084 } else if (!strcasecmp(mult, "onetenth")) {
6085 _mult = AST_AOC_MULT_ONETENTH;
6086 } else if (!strcasecmp(mult, "one")) {
6087 _mult = AST_AOC_MULT_ONE;
6088 } else if (!strcasecmp(mult, "ten")) {
6089 _mult = AST_AOC_MULT_TEN;
6090 } else if (!strcasecmp(mult, "hundred")) {
6091 _mult = AST_AOC_MULT_HUNDRED;
6092 } else if (!strcasecmp(mult, "thousand")) {
6093 _mult = AST_AOC_MULT_THOUSAND;
6094 } else {
6095 astman_send_error(s, m, "Invalid ChargeMultiplier");
6096 goto aocmessage_cleanup;
6097 }
6098 }
6099
6100 if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
6101 if (ast_strlen_zero(timescale)) {
6102 astman_send_error(s, m, "TimeScale unspecified, TimeScale is required when RateType is Duration.");
6103 goto aocmessage_cleanup;
6104 } else if (!strcasecmp(timescale, "onehundredthsecond")) {
6106 } else if (!strcasecmp(timescale, "onetenthsecond")) {
6108 } else if (!strcasecmp(timescale, "second")) {
6110 } else if (!strcasecmp(timescale, "tenseconds")) {
6112 } else if (!strcasecmp(timescale, "minute")) {
6114 } else if (!strcasecmp(timescale, "hour")) {
6115 _scale = AST_AOC_TIME_SCALE_HOUR;
6116 } else if (!strcasecmp(timescale, "day")) {
6117 _scale = AST_AOC_TIME_SCALE_DAY;
6118 } else {
6119 astman_send_error(s, m, "Invalid TimeScale");
6120 goto aocmessage_cleanup;
6121 }
6122
6123 if (ast_strlen_zero(time) || (sscanf(time, "%30u", &_time) != 1)) {
6124 astman_send_error(s, m, "Invalid Time, Time is a required when RateType is Duration");
6125 goto aocmessage_cleanup;
6126 }
6127
6128 if (!ast_strlen_zero(granularity)) {
6129 if ((sscanf(time, "%30u", &_granularity) != 1)) {
6130 astman_send_error(s, m, "Invalid Granularity");
6131 goto aocmessage_cleanup;
6132 }
6133
6134 if (ast_strlen_zero(granularitytimescale)) {
6135 astman_send_error(s, m, "Invalid GranularityTimeScale, GranularityTimeScale is a required when Granularity is specified");
6136 } else if (!strcasecmp(granularitytimescale, "onehundredthsecond")) {
6137 _granularity_time_scale = AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
6138 } else if (!strcasecmp(granularitytimescale, "onetenthsecond")) {
6139 _granularity_time_scale = AST_AOC_TIME_SCALE_TENTH_SECOND;
6140 } else if (!strcasecmp(granularitytimescale, "second")) {
6141 _granularity_time_scale = AST_AOC_TIME_SCALE_SECOND;
6142 } else if (!strcasecmp(granularitytimescale, "tenseconds")) {
6143 _granularity_time_scale = AST_AOC_TIME_SCALE_TEN_SECOND;
6144 } else if (!strcasecmp(granularitytimescale, "minute")) {
6145 _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
6146 } else if (!strcasecmp(granularitytimescale, "hour")) {
6147 _granularity_time_scale = AST_AOC_TIME_SCALE_HOUR;
6148 } else if (!strcasecmp(granularitytimescale, "day")) {
6149 _granularity_time_scale = AST_AOC_TIME_SCALE_DAY;
6150 } else {
6151 astman_send_error(s, m, "Invalid GranularityTimeScale");
6152 goto aocmessage_cleanup;
6153 }
6154 }
6155
6156 if (ast_strlen_zero(chargingtype) || strcasecmp(chargingtype, "continuouscharging") == 0) {
6157 _step = 0;
6158 } else if (strcasecmp(chargingtype, "stepfunction") == 0 ) {
6159 _step = 1;
6160 } else {
6161 astman_send_error(s, m, "Invalid ChargingType");
6162 goto aocmessage_cleanup;
6163 }
6164 }
6165
6166 if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
6167 if (ast_strlen_zero(volumeunit)) {
6168 astman_send_error(s, m, "VolumeUnit unspecified, VolumeUnit is required when RateType is Volume.");
6169 goto aocmessage_cleanup;
6170 } else if (!strcasecmp(timescale, "octet")) {
6171 _volumeunit = AST_AOC_VOLUME_UNIT_OCTET;
6172 } else if (!strcasecmp(timescale, "segment")) {
6173 _volumeunit = AST_AOC_VOLUME_UNIT_SEGMENT;
6174 } else if (!strcasecmp(timescale, "message")) {
6175 _volumeunit = AST_AOC_VOLUME_UNIT_MESSAGE;
6176 }else {
6177 astman_send_error(s, m, "Invalid VolumeUnit");
6178 goto aocmessage_cleanup;
6179 }
6180 }
6181
6183 || _ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
6184 if (ast_strlen_zero(code) || (sscanf(code, "%30u", &_code) != 1)) {
6185 astman_send_error(s, m, "Invalid Code, Code is a required when ChargedItem is SpecialArrangement and when RateType is SpecialCode");
6186 goto aocmessage_cleanup;
6187 }
6188 }
6189
6190 if (_chargeditem == AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT) {
6191 ast_aoc_s_add_special_arrangement(decoded, _code);
6192 } else if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
6193 ast_aoc_s_add_rate_duration(decoded, _chargeditem, _currencyamount, _mult,
6194 currencyname, _time, _scale, _granularity, _granularity_time_scale, _step);
6195 } else if (_ratetype == AST_AOC_RATE_TYPE_FLAT) {
6196 ast_aoc_s_add_rate_flat(decoded, _chargeditem, _currencyamount, _mult,
6197 currencyname);
6198 } else if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
6199 ast_aoc_s_add_rate_volume(decoded, _chargeditem, _volumeunit, _currencyamount,
6200 _mult, currencyname);
6201 } else if (_ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
6202 ast_aoc_s_add_rate_special_charge_code(decoded, _chargeditem, _code);
6203 } else if (_ratetype == AST_AOC_RATE_TYPE_FREE) {
6204 ast_aoc_s_add_rate_free(decoded, _chargeditem, 0);
6205 } else if (_ratetype == AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
6206 ast_aoc_s_add_rate_free(decoded, _chargeditem, 1);
6207 } else if (_ratetype == AST_AOC_RATE_TYPE_NA) {
6208 ast_aoc_s_add_rate_na(decoded, _chargeditem);
6209 }
6210
6211 return 0;
6212
6213aocmessage_cleanup:
6214
6215 return -1;
6216}
int ast_aoc_s_add_rate_duration(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name, unsigned long time, enum ast_aoc_time_scale time_scale, unsigned long granularity_time, enum ast_aoc_time_scale granularity_time_scale, int step_function)
Add AOC-S duration rate entry.
Definition: aoc.c:770
ast_aoc_s_charged_item
Definition: aoc.h:145
@ AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION
Definition: aoc.h:148
@ AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT
Definition: aoc.h:147
@ AST_AOC_CHARGED_ITEM_NA
Definition: aoc.h:146
@ AST_AOC_CHARGED_ITEM_USER_USER_INFO
Definition: aoc.h:151
@ AST_AOC_CHARGED_ITEM_CALL_SETUP
Definition: aoc.h:150
@ AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE
Definition: aoc.h:152
@ AST_AOC_CHARGED_ITEM_CALL_ATTEMPT
Definition: aoc.h:149
ast_aoc_time_scale
Definition: aoc.h:87
@ AST_AOC_TIME_SCALE_TEN_SECOND
Definition: aoc.h:91
@ AST_AOC_TIME_SCALE_DAY
Definition: aoc.h:94
@ AST_AOC_TIME_SCALE_TENTH_SECOND
Definition: aoc.h:89
@ AST_AOC_TIME_SCALE_MINUTE
Definition: aoc.h:92
@ AST_AOC_TIME_SCALE_SECOND
Definition: aoc.h:90
@ AST_AOC_TIME_SCALE_HOUR
Definition: aoc.h:93
@ AST_AOC_TIME_SCALE_HUNDREDTH_SECOND
Definition: aoc.h:88
ast_aoc_volume_unit
Definition: aoc.h:125
@ AST_AOC_VOLUME_UNIT_OCTET
Definition: aoc.h:126
@ AST_AOC_VOLUME_UNIT_SEGMENT
Definition: aoc.h:127
@ AST_AOC_VOLUME_UNIT_MESSAGE
Definition: aoc.h:128
int ast_aoc_s_add_rate_special_charge_code(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int code)
Add AOC-S special rate entry.
Definition: aoc.c:844
int ast_aoc_s_add_rate_free(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, int from_beginning)
Add AOC-S indicating charge item is free.
Definition: aoc.c:857
int ast_aoc_s_add_special_arrangement(struct ast_aoc_decoded *decoded, unsigned int code)
Add AOC-S special arrangement entry.
Definition: aoc.c:880
int ast_aoc_s_add_rate_flat(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S flat rate entry.
Definition: aoc.c:801
int ast_aoc_s_add_rate_volume(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, enum ast_aoc_volume_unit volume_unit, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S volume rate entry.
Definition: aoc.c:822
int ast_aoc_s_add_rate_na(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item)
Add AOC-S entry indicating charge item is not available.
Definition: aoc.c:869
ast_aoc_s_rate_type
Definition: aoc.h:155
@ AST_AOC_RATE_TYPE_VOLUME
Definition: aoc.h:161
@ AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING
Definition: aoc.h:158
@ AST_AOC_RATE_TYPE_SPECIAL_CODE
Definition: aoc.h:162
@ AST_AOC_RATE_TYPE_NA
Definition: aoc.h:156
@ AST_AOC_RATE_TYPE_DURATION
Definition: aoc.h:159
@ AST_AOC_RATE_TYPE_FLAT
Definition: aoc.h:160
@ AST_AOC_RATE_TYPE_FREE
Definition: aoc.h:157
static const char * __astman_get_header(const struct message *m, char *var, int mode)
Return a matching header value.
Definition: manager.c:3005

References __astman_get_header(), AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION, AST_AOC_CHARGED_ITEM_CALL_ATTEMPT, AST_AOC_CHARGED_ITEM_CALL_SETUP, AST_AOC_CHARGED_ITEM_NA, AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT, AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE, AST_AOC_CHARGED_ITEM_USER_USER_INFO, 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_RATE_TYPE_DURATION, AST_AOC_RATE_TYPE_FLAT, AST_AOC_RATE_TYPE_FREE, AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING, AST_AOC_RATE_TYPE_NA, AST_AOC_RATE_TYPE_SPECIAL_CODE, AST_AOC_RATE_TYPE_VOLUME, ast_aoc_s_add_rate_duration(), ast_aoc_s_add_rate_flat(), ast_aoc_s_add_rate_free(), ast_aoc_s_add_rate_na(), ast_aoc_s_add_rate_special_charge_code(), ast_aoc_s_add_rate_volume(), ast_aoc_s_add_special_arrangement(), AST_AOC_TIME_SCALE_DAY, AST_AOC_TIME_SCALE_HOUR, AST_AOC_TIME_SCALE_HUNDREDTH_SECOND, AST_AOC_TIME_SCALE_MINUTE, AST_AOC_TIME_SCALE_SECOND, AST_AOC_TIME_SCALE_TEN_SECOND, AST_AOC_TIME_SCALE_TENTH_SECOND, AST_AOC_VOLUME_UNIT_MESSAGE, AST_AOC_VOLUME_UNIT_OCTET, AST_AOC_VOLUME_UNIT_SEGMENT, ast_strlen_zero(), astman_send_error(), and GET_HEADER_LAST_MATCH.

Referenced by action_aoc_s_message().

◆ action_aocmessage()

static int action_aocmessage ( struct mansession s,
const struct message m 
)
static

Definition at line 6261 of file manager.c.

6262{
6263 const char *msgtype = astman_get_header(m, "MsgType");
6264 const char *channel = astman_get_header(m, "Channel");
6265 const char *pchannel = astman_get_header(m, "ChannelPrefix");
6266
6267 struct ast_channel *chan = NULL;
6268
6269 struct ast_aoc_decoded *decoded = NULL;
6270 struct ast_aoc_encoded *encoded = NULL;
6271 size_t encoded_size = 0;
6272
6273 if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
6274 astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
6275 goto aocmessage_cleanup;
6276 }
6277
6278 if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
6279 chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
6280 }
6281
6282 if (!chan) {
6283 astman_send_error(s, m, "No such channel");
6284 goto aocmessage_cleanup;
6285 }
6286
6287 if (strcasecmp(msgtype, "d") == 0 || strcasecmp(msgtype, "e") == 0) {
6288 decoded = action_aoc_de_message(s, m);
6289 }
6290 else if (strcasecmp(msgtype, "s") == 0) {
6291 decoded = action_aoc_s_message(s, m);
6292 }
6293 else {
6294 astman_send_error(s, m, "Invalid MsgType");
6295 goto aocmessage_cleanup;
6296 }
6297
6298 if (!decoded) {
6299 goto aocmessage_cleanup;
6300 }
6301
6302 if ((encoded = ast_aoc_encode(decoded, &encoded_size, chan))
6303 && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
6304 astman_send_ack(s, m, "AOC Message successfully queued on channel");
6305 } else {
6306 astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel");
6307 }
6308
6309aocmessage_cleanup:
6310
6311 ast_aoc_destroy_decoded(decoded);
6312 ast_aoc_destroy_encoded(encoded);
6313
6314 if (chan) {
6315 chan = ast_channel_unref(chan);
6316 }
6317 return 0;
6318}
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:313
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
Definition: aoc.c:650
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1434
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4653
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3413
static struct ast_aoc_decoded * action_aoc_s_message(struct mansession *s, const struct message *m)
Definition: manager.c:6218
static struct ast_aoc_decoded * action_aoc_de_message(struct mansession *s, const struct message *m)
Definition: manager.c:5823
@ AST_CONTROL_AOC
Main Channel structure associated with a channel.

References action_aoc_de_message(), action_aoc_s_message(), ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), ast_aoc_encode(), 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(), and NULL.

Referenced by __init_manager().

◆ action_atxfer()

static int action_atxfer ( struct mansession s,
const struct message m 
)
static

Definition at line 5471 of file manager.c.

5472{
5473 const char *name = astman_get_header(m, "Channel");
5474 const char *exten = astman_get_header(m, "Exten");
5475 const char *context = astman_get_header(m, "Context");
5476 struct ast_channel *chan = NULL;
5477 char feature_code[AST_FEATURE_MAX_LEN];
5478 const char *digit;
5479
5480 if (ast_strlen_zero(name)) {
5481 astman_send_error(s, m, "No channel specified");
5482 return 0;
5483 }
5484 if (ast_strlen_zero(exten)) {
5485 astman_send_error(s, m, "No extension specified");
5486 return 0;
5487 }
5488
5489 if (!(chan = ast_channel_get_by_name(name))) {
5490 astman_send_error(s, m, "Channel specified does not exist");
5491 return 0;
5492 }
5493
5494 ast_channel_lock(chan);
5495 if (ast_get_builtin_feature(chan, "atxfer", feature_code, sizeof(feature_code)) ||
5496 ast_strlen_zero(feature_code)) {
5497 ast_channel_unlock(chan);
5498 astman_send_error(s, m, "No attended transfer feature code found");
5499 ast_channel_unref(chan);
5500 return 0;
5501 }
5502 ast_channel_unlock(chan);
5503
5504 if (!ast_strlen_zero(context)) {
5505 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
5506 }
5507
5508 for (digit = feature_code; *digit; ++digit) {
5509 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
5510 ast_queue_frame(chan, &f);
5511 }
5512
5513 for (digit = exten; *digit; ++digit) {
5514 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
5515 ast_queue_frame(chan, &f);
5516 }
5517
5518 chan = ast_channel_unref(chan);
5519
5520 astman_send_ack(s, m, "Atxfer successfully queued");
5521
5522 return 0;
5523}
char digit
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1139
#define ast_channel_unlock(chan)
Definition: channel.h:2923
static const char name[]
Definition: format_mp3.c:68
#define AST_FEATURE_MAX_LEN
int ast_get_builtin_feature(struct ast_channel *chan, const char *feature, char *buf, size_t len)
Get the DTMF code for a builtin feature.
#define AST_FRAME_DTMF
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
char exten[AST_MAX_EXTENSION]
Data structure associated with a single frame of data.

References ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, AST_FEATURE_MAX_LEN, AST_FRAME_DTMF, ast_get_builtin_feature(), ast_queue_frame(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), voicemailpwcheck::context, digit, name, NULL, and pbx_builtin_setvar_helper().

Referenced by __init_manager().

◆ action_blind_transfer()

static int action_blind_transfer ( struct mansession s,
const struct message m 
)
static

Definition at line 5425 of file manager.c.

5426{
5427 const char *name = astman_get_header(m, "Channel");
5428 const char *exten = astman_get_header(m, "Exten");
5429 const char *context = astman_get_header(m, "Context");
5430 struct ast_channel *chan;
5431
5432 if (ast_strlen_zero(name)) {
5433 astman_send_error(s, m, "No channel specified");
5434 return 0;
5435 }
5436
5437 if (ast_strlen_zero(exten)) {
5438 astman_send_error(s, m, "No extension specified");
5439 return 0;
5440 }
5441
5443 if (!chan) {
5444 astman_send_error(s, m, "Channel specified does not exist");
5445 return 0;
5446 }
5447
5448 if (ast_strlen_zero(context)) {
5450 }
5451
5452 switch (ast_bridge_transfer_blind(1, chan, exten, context, NULL, NULL)) {
5454 astman_send_error(s, m, "Transfer not permitted");
5455 break;
5457 astman_send_error(s, m, "Transfer invalid");
5458 break;
5460 astman_send_error(s, m, "Transfer failed");
5461 break;
5463 astman_send_ack(s, m, "Transfer succeeded");
5464 break;
5465 }
5466
5467 ast_channel_unref(chan);
5468 return 0;
5469}
enum ast_transfer_result ast_bridge_transfer_blind(int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
Blind transfer target to the extension and context provided.
Definition: bridge.c:4425
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition: bridge.h:1102
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1100
@ AST_BRIDGE_TRANSFER_INVALID
Definition: bridge.h:1104
@ AST_BRIDGE_TRANSFER_FAIL
Definition: bridge.h:1106
const char * ast_channel_context(const struct ast_channel *chan)

References ast_bridge_transfer_blind(), AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_NOT_PERMITTED, AST_BRIDGE_TRANSFER_SUCCESS, ast_channel_context(), ast_channel_get_by_name(), ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), voicemailpwcheck::context, name, and NULL.

Referenced by __init_manager().

◆ action_cancel_atxfer()

static int action_cancel_atxfer ( struct mansession s,
const struct message m 
)
static

Definition at line 5525 of file manager.c.

5526{
5527 const char *name = astman_get_header(m, "Channel");
5528 struct ast_channel *chan = NULL;
5529 char *feature_code;
5530 const char *digit;
5531
5532 if (ast_strlen_zero(name)) {
5533 astman_send_error(s, m, "No channel specified");
5534 return 0;
5535 }
5536
5537 if (!(chan = ast_channel_get_by_name(name))) {
5538 astman_send_error(s, m, "Channel specified does not exist");
5539 return 0;
5540 }
5541
5542 ast_channel_lock(chan);
5543 feature_code = ast_get_chan_features_atxferabort(chan);
5544 ast_channel_unlock(chan);
5545
5546 if (!feature_code) {
5547 astman_send_error(s, m, "No disconnect feature code found");
5548 ast_channel_unref(chan);
5549 return 0;
5550 }
5551
5552 for (digit = feature_code; *digit; ++digit) {
5553 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
5554 ast_queue_frame(chan, &f);
5555 }
5556 ast_free(feature_code);
5557
5558 chan = ast_channel_unref(chan);
5559
5560 astman_send_ack(s, m, "CancelAtxfer successfully queued");
5561
5562 return 0;
5563}
#define ast_free(a)
Definition: astmm.h:180
char * ast_get_chan_features_atxferabort(struct ast_channel *chan)
Get the transfer configuration option atxferabort.

References ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, AST_FRAME_DTMF, ast_free, ast_get_chan_features_atxferabort(), ast_queue_frame(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), digit, name, and NULL.

Referenced by __init_manager().

◆ action_challenge()

static int action_challenge ( struct mansession s,
const struct message m 
)
static

Definition at line 4736 of file manager.c.

4737{
4738 const char *authtype = astman_get_header(m, "AuthType");
4739
4740 if (!strcasecmp(authtype, "MD5")) {
4742 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
4743 }
4744 mansession_lock(s);
4745 astman_start_ack(s, m);
4746 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
4748 } else {
4749 astman_send_error(s, m, "Must specify AuthType");
4750 }
4751 return 0;
4752}
static void mansession_unlock(struct mansession *s)
Unlock the 'mansession' structure.
Definition: manager.c:3479
static void mansession_lock(struct mansession *s)
Lock the 'mansession' structure.
Definition: manager.c:3473
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:3418
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3302
char challenge[10]
Definition: manager.c:1744
struct mansession_session * session
Definition: manager.c:1778
long int ast_random(void)
Definition: utils.c:2312

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().

◆ action_command()

static int action_command ( struct mansession s,
const struct message m 
)
static

Manager command "command" - execute CLI command.

Definition at line 5602 of file manager.c.

5603{
5604 const char *cmd = astman_get_header(m, "Command");
5605 char *buf = NULL, *final_buf = NULL, *delim, *output;
5606 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */
5607 int fd, ret;
5608 off_t len;
5609
5610 if (ast_strlen_zero(cmd)) {
5611 astman_send_error(s, m, "No command provided");
5612 return 0;
5613 }
5614
5615 if (check_blacklist(cmd)) {
5616 astman_send_error(s, m, "Command blacklisted");
5617 return 0;
5618 }
5619
5620 if ((fd = mkstemp(template)) < 0) {
5621 astman_send_error_va(s, m, "Failed to create temporary file: %s", strerror(errno));
5622 return 0;
5623 }
5624
5625 ret = ast_cli_command(fd, cmd);
5626 astman_send_response_full(s, m, ret == RESULT_SUCCESS ? "Success" : "Error", MSG_MOREDATA, NULL);
5627
5628 /* Determine number of characters available */
5629 if ((len = lseek(fd, 0, SEEK_END)) < 0) {
5630 astman_append(s, "Message: Failed to determine number of characters: %s\r\n", strerror(errno));
5631 goto action_command_cleanup;
5632 }
5633
5634 /* This has a potential to overflow the stack. Hence, use the heap. */
5635 buf = ast_malloc(len + 1);
5636 final_buf = ast_malloc(len + 1);
5637
5638 if (!buf || !final_buf) {
5639 astman_append(s, "Message: Memory allocation failure\r\n");
5640 goto action_command_cleanup;
5641 }
5642
5643 if (lseek(fd, 0, SEEK_SET) < 0) {
5644 astman_append(s, "Message: Failed to set position on temporary file: %s\r\n", strerror(errno));
5645 goto action_command_cleanup;
5646 }
5647
5648 if (read(fd, buf, len) < 0) {
5649 astman_append(s, "Message: Failed to read from temporary file: %s\r\n", strerror(errno));
5650 goto action_command_cleanup;
5651 }
5652
5653 buf[len] = '\0';
5654 term_strip(final_buf, buf, len);
5655 final_buf[len] = '\0';
5656
5657 /* Trim trailing newline */
5658 if (len && final_buf[len - 1] == '\n') {
5659 final_buf[len - 1] = '\0';
5660 }
5661
5662 astman_append(s, "Message: Command output follows\r\n");
5663
5664 delim = final_buf;
5665 while ((output = strsep(&delim, "\n"))) {
5666 astman_append(s, "Output: %s\r\n", output);
5667 }
5668
5669action_command_cleanup:
5670 astman_append(s, "\r\n");
5671
5672 close(fd);
5673 unlink(template);
5674
5675 ast_free(buf);
5676 ast_free(final_buf);
5677
5678 return 0;
5679}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define RESULT_SUCCESS
Definition: cli.h:40
ast_cli_command
calling arguments for new-style handlers.
Definition: cli.h:151
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void astman_send_error_va(struct mansession *s, const struct message *m, const char *fmt,...)
Send error in manager transaction (with va_args support)
Definition: manager.c:3386
static void astman_send_response_full(struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
send a response with an optional message, and terminate it with an empty line. m is used only to grab...
Definition: manager.c:3345
static int check_blacklist(const char *cmd)
Definition: manager.c:5566
#define MSG_MOREDATA
Definition: manager.c:3336
char * strsep(char **str, const char *delims)
int errno
char * term_strip(char *outbuf, const char *inbuf, int maxout)
Remove colorings from a specified string.
Definition: term.c:362

References ast_free, ast_malloc, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_error_va(), astman_send_response_full(), buf, check_blacklist(), errno, len(), MSG_MOREDATA, NULL, RESULT_SUCCESS, strsep(), and term_strip().

Referenced by __init_manager().

◆ action_coresettings()

static int action_coresettings ( struct mansession s,
const struct message m 
)
static

Show PBX core settings information.

Definition at line 6874 of file manager.c.

6875{
6876 const char *actionid = astman_get_header(m, "ActionID");
6877 char idText[150];
6878
6879 if (!ast_strlen_zero(actionid)) {
6880 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6881 } else {
6882 idText[0] = '\0';
6883 }
6884
6885 astman_append(s, "Response: Success\r\n"
6886 "%s"
6887 "AMIversion: %s\r\n"
6888 "AsteriskVersion: %s\r\n"
6889 "SystemName: %s\r\n"
6890 "CoreMaxCalls: %d\r\n"
6891 "CoreMaxLoadAvg: %f\r\n"
6892 "CoreRunUser: %s\r\n"
6893 "CoreRunGroup: %s\r\n"
6894 "CoreMaxFilehandles: %d\r\n"
6895 "CoreRealTimeEnabled: %s\r\n"
6896 "CoreCDRenabled: %s\r\n"
6897 "CoreHTTPenabled: %s\r\n"
6898 "SoundsSearchCustomDir: %s\r\n"
6899 "\r\n",
6900 idText,
6913 );
6914 return 0;
6915}
const char * ast_get_version(void)
Retrieve the Asterisk version string.
int ast_cdr_is_enabled(void)
Return TRUE if CDR subsystem is enabled.
Definition: cdr.c:2923
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
int ast_webmanager_check_enabled(void)
Check if AMI/HTTP is enabled.
Definition: manager.c:2106
int ast_option_maxfiles
Definition: options.c:81
int ast_option_maxcalls
Definition: options.c:79
double ast_option_maxload
Definition: options.c:77
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
Definition: main/config.c:3544
#define AMI_VERSION
Definition: manager.h:57
#define ast_opt_sounds_search_custom
Definition: options.h:138
const char * ast_config_AST_RUN_GROUP
Definition: options.c:169
const char * ast_config_AST_RUN_USER
Definition: options.c:168

References AMI_VERSION, ast_cdr_is_enabled(), AST_CLI_YESNO, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SYSTEM_NAME, ast_get_version(), ast_opt_sounds_search_custom, ast_option_maxcalls, ast_option_maxfiles, ast_option_maxload, ast_realtime_enabled(), ast_strlen_zero(), ast_webmanager_check_enabled(), astman_append(), and astman_get_header().

Referenced by __init_manager().

◆ action_coreshowchannelmap()

static int action_coreshowchannelmap ( struct mansession s,
const struct message m 
)
static

Manager command "CoreShowChannelMap" - Lists all channels connected to the specified channel.

Definition at line 7158 of file manager.c.

7159{
7160 const char *actionid = astman_get_header(m, "ActionID");
7161 const char *channel_name = astman_get_header(m, "Channel");
7162 char *current_channel_name;
7163 char id_text[256];
7164 int total = 0;
7165 struct ao2_container *channel_map;
7166 struct ao2_iterator i;
7167 RAII_VAR(struct ast_bridge_snapshot *, bridge_snapshot, NULL, ao2_cleanup);
7168 RAII_VAR(struct ast_channel_snapshot *, channel_snapshot, NULL, ao2_cleanup);
7169
7170 if (!ast_strlen_zero(actionid)) {
7171 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
7172 } else {
7173 id_text[0] = '\0';
7174 }
7175
7176 if (ast_strlen_zero(channel_name)) {
7177 astman_send_error(s, m, "CoreShowChannelMap requires a channel.\n");
7178 return 0;
7179 }
7180
7181 channel_snapshot = ast_channel_snapshot_get_latest_by_name(channel_name);
7182 if (!channel_snapshot) {
7183 astman_send_error(s, m, "Could not get channel snapshot\n");
7184 return 0;
7185 }
7186
7187 bridge_snapshot = ast_bridge_get_snapshot_by_uniqueid(channel_snapshot->bridge->id);
7188 if (!bridge_snapshot) {
7189 astman_send_listack(s, m, "Channel map will follow", "start");
7190 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", 0);
7192 return 0;
7193 }
7194
7196 if (!channel_map) {
7197 astman_send_error(s, m, "Could not create channel map\n");
7198 return 0;
7199 }
7200
7201 astman_send_listack(s, m, "Channel map will follow", "start");
7202
7203 if (coreshowchannelmap_add_connected_channels(channel_map, channel_snapshot, bridge_snapshot)) {
7204 astman_send_error(s, m, "Could not complete channel map\n");
7205 ao2_ref(channel_map, -1);
7206 return 0;
7207 }
7208
7209 i = ao2_iterator_init(channel_map, 0);
7210 while ((current_channel_name = ao2_iterator_next(&i))) {
7211 astman_append(s,
7212 "Event: CoreShowChannelMap\r\n"
7213 "%s"
7214 "Channel: %s\r\n"
7215 "ConnectedChannel: %s\r\n\n",
7216 id_text,
7217 channel_name,
7218 current_channel_name);
7219 total++;
7220 }
7222
7223 ao2_ref(channel_map, -1);
7224 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", total);
7226
7227 return 0;
7228}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT
Reject duplicate objects in container.
Definition: astobj2.h:1201
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3423
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3459
static int coreshowchannelmap_add_connected_channels(struct ao2_container *channel_map, struct ast_channel_snapshot *channel_snapshot, struct ast_bridge_snapshot *bridge_snapshot)
Recursive function to get all channels in a bridge. Follow local channels as well.
Definition: manager.c:7074
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3467
struct ast_channel_snapshot * ast_channel_snapshot_get_latest_by_name(const char *name)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
static int total
Definition: res_adsi.c:970
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
Definition: strings.c:200
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314
Structure representing a snapshot of channel state.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_bridge_get_snapshot_by_uniqueid(), ast_channel_snapshot_get_latest_by_name(), ast_str_container_alloc_options(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), coreshowchannelmap_add_connected_channels(), NULL, RAII_VAR, and total.

Referenced by __init_manager().

◆ action_coreshowchannels()

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 6990 of file manager.c.

6991{
6992 const char *actionid = astman_get_header(m, "ActionID");
6993 char idText[256];
6994 int numchans = 0;
6995 struct ao2_container *channels;
6996 struct ao2_iterator it_chans;
6997 struct ast_channel_snapshot *cs;
6998
6999 if (!ast_strlen_zero(actionid)) {
7000 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
7001 } else {
7002 idText[0] = '\0';
7003 }
7004
7006
7007 astman_send_listack(s, m, "Channels will follow", "start");
7008
7009 it_chans = ao2_iterator_init(channels, 0);
7010 for (; (cs = ao2_iterator_next(&it_chans)); ao2_ref(cs, -1)) {
7012 char durbuf[16] = "";
7013
7014 if (!built) {
7015 continue;
7016 }
7017
7018 if (!ast_tvzero(cs->base->creationtime)) {
7019 int duration, durh, durm, durs;
7020
7021 duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->base->creationtime) / 1000);
7022 durh = duration / 3600;
7023 durm = (duration % 3600) / 60;
7024 durs = duration % 60;
7025 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
7026 }
7027
7028 astman_append(s,
7029 "Event: CoreShowChannel\r\n"
7030 "%s"
7031 "%s"
7032 "Application: %s\r\n"
7033 "ApplicationData: %s\r\n"
7034 "Duration: %s\r\n"
7035 "BridgeId: %s\r\n"
7036 "\r\n",
7037 idText,
7038 ast_str_buffer(built),
7039 cs->dialplan->appl,
7040 cs->dialplan->data,
7041 durbuf,
7042 cs->bridge->id);
7043
7044 numchans++;
7045
7046 ast_free(built);
7047 }
7048 ao2_iterator_destroy(&it_chans);
7049
7050 astman_send_list_complete(s, m, "CoreShowChannelsComplete", numchans);
7051
7052 ao2_ref(channels, -1);
7053 return 0;
7054}
static struct channel_usage channels
static void astman_send_list_complete(struct mansession *s, const struct message *m, const char *event_name, int count)
Definition: manager.c:3450
struct ao2_container * ast_channel_cache_by_name(void)
Secondary channel cache, indexed by name.
struct ast_str * ast_manager_build_channel_state_string_prefix(const struct ast_channel_snapshot *snapshot, const char *prefix)
Generate the AMI message body from a channel snapshot.
const ast_string_field data
const ast_string_field appl
struct ast_channel_snapshot_dialplan * dialplan
struct ast_channel_snapshot_bridge * bridge
struct ast_channel_snapshot_base * base
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_snapshot_dialplan::appl, ast_channel_cache_by_name(), ast_free, ast_manager_build_channel_state_string_prefix(), ast_str_buffer(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), astman_append(), astman_get_header(), astman_send_list_complete(), astman_send_listack(), ast_channel_snapshot::base, ast_channel_snapshot::bridge, channels, ast_channel_snapshot_base::creationtime, ast_channel_snapshot_dialplan::data, ast_channel_snapshot::dialplan, and ast_channel_snapshot_bridge::id.

Referenced by __init_manager().

◆ action_corestatus()

static int action_corestatus ( struct mansession s,
const struct message m 
)
static

Show PBX core status information.

Definition at line 6918 of file manager.c.

6919{
6920 const char *actionid = astman_get_header(m, "ActionID");
6921 char idText[150];
6922 char startuptime[150], startupdate[150];
6923 char reloadtime[150], reloaddate[150];
6924 struct ast_tm tm;
6925
6926 if (!ast_strlen_zero(actionid)) {
6927 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6928 } else {
6929 idText[0] = '\0';
6930 }
6931
6933 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
6934 ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm);
6936 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
6937 ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm);
6938
6939 astman_append(s, "Response: Success\r\n"
6940 "%s"
6941 "CoreStartupDate: %s\r\n"
6942 "CoreStartupTime: %s\r\n"
6943 "CoreReloadDate: %s\r\n"
6944 "CoreReloadTime: %s\r\n"
6945 "CoreCurrentCalls: %d\r\n"
6946 "\r\n",
6947 idText,
6948 startupdate,
6949 startuptime,
6950 reloaddate,
6951 reloadtime,
6953 );
6954 return 0;
6955}
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:499
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
struct timeval ast_lastreloadtime
Definition: asterisk.c:337
struct timeval ast_startuptime
Definition: asterisk.c:336

References ast_active_channels(), ast_lastreloadtime, ast_localtime(), ast_startuptime, ast_strftime(), ast_strlen_zero(), astman_append(), astman_get_header(), and NULL.

Referenced by __init_manager().

◆ action_createconfig()

static int action_createconfig ( struct mansession s,
const struct message m 
)
static

Definition at line 4482 of file manager.c.

4483{
4484 int fd;
4485 const char *fn = astman_get_header(m, "Filename");
4486 struct ast_str *filepath = ast_str_alloca(PATH_MAX);
4487 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
4488 ast_str_append(&filepath, 0, "%s", fn);
4489
4490 if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
4491 close(fd);
4492 astman_send_ack(s, m, "New configuration file created successfully");
4493 } else {
4494 astman_send_error(s, m, strerror(errno));
4495 }
4496
4497 return 0;
4498}
#define AST_FILE_MODE
Definition: asterisk.h:32
#define PATH_MAX
Definition: asterisk.h:40
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151

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(), errno, and PATH_MAX.

Referenced by __init_manager().

◆ action_destroy()

static void action_destroy ( void *  obj)
static

Definition at line 8153 of file manager.c.

8154{
8155 struct manager_action *doomed = obj;
8156
8157 if (doomed->synopsis) {
8158 /* The string fields were initialized. */
8160 }
8161 ao2_cleanup(doomed->final_response);
8162 ao2_cleanup(doomed->list_responses);
8163}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
struct ast_xml_doc_item * final_response
Definition: manager.h:167
const ast_string_field synopsis
Definition: manager.h:163
struct ast_xml_doc_item * list_responses
Definition: manager.h:165

References ao2_cleanup, ast_string_field_free_memory, manager_action::final_response, manager_action::list_responses, and manager_action::synopsis.

Referenced by ast_manager_register2().

◆ action_events()

static int action_events ( struct mansession s,
const struct message m 
)
static

Definition at line 4637 of file manager.c.

4638{
4639 const char *mask = astman_get_header(m, "EventMask");
4640 int res, x;
4641 const char *id = astman_get_header(m, "ActionID");
4642 char id_text[256];
4643
4644 if (!ast_strlen_zero(id)) {
4645 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
4646 } else {
4647 id_text[0] = '\0';
4648 }
4649
4650 res = set_eventmask(s, mask);
4652 /* if this option is set we should not return a response on
4653 * error, or when all events are set */
4654
4655 if (res > 0) {
4656 for (x = 0; x < ARRAY_LEN(perms); x++) {
4657 if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
4658 return 0;
4659 }
4660 }
4661 astman_append(s, "Response: Success\r\n%s"
4662 "Events: On\r\n\r\n", id_text);
4663 } else if (res == 0)
4664 astman_append(s, "Response: Success\r\n%s"
4665 "Events: Off\r\n\r\n", id_text);
4666 return 0;
4667 }
4668
4669 if (res > 0)
4670 astman_append(s, "Response: Success\r\n%s"
4671 "Events: On\r\n\r\n", id_text);
4672 else if (res == 0)
4673 astman_append(s, "Response: Success\r\n%s"
4674 "Events: Off\r\n\r\n", id_text);
4675 else
4676 astman_send_error(s, m, "Invalid event mask");
4677
4678 return 0;
4679}
static int broken_events_action
Definition: manager.c:1619
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 ',...
Definition: manager.c:3488
static const struct permalias perms[]
int num
Definition: manager.c:2168
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), broken_events_action, permalias::num, perms, and set_eventmask().

Referenced by __init_manager().

◆ action_extensionstate()

static int action_extensionstate ( struct mansession s,
const struct message m 
)
static

Definition at line 6571 of file manager.c.

6572{
6573 const char *exten = astman_get_header(m, "Exten");
6574 const char *context = astman_get_header(m, "Context");
6575 char hint[256];
6576 int status;
6577
6578 if (ast_strlen_zero(exten)) {
6579 astman_send_error(s, m, "Extension not specified");
6580 return 0;
6581 }
6582 if (ast_strlen_zero(context)) {
6583 context = "default";
6584 }
6586 hint[0] = '\0';
6587 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
6588 astman_start_ack(s, m);
6589 astman_append(s, "Message: Extension Status\r\n"
6590 "Exten: %s\r\n"
6591 "Context: %s\r\n"
6592 "Hint: %s\r\n"
6593 "Status: %d\r\n"
6594 "StatusText: %s\r\n"
6595 "\r\n",
6596 exten, context, hint, status,
6598 return 0;
6599}
jack_status_t status
Definition: app_jack.c:146
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition: pbx.c:3126
int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
If an extension hint exists, return non-zero.
Definition: pbx.c:4137
int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
Uses hint and devicestate callback to get the state of an extension.
Definition: pbx.c:3170

References ast_extension_state(), ast_extension_state2str(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), voicemailpwcheck::context, NULL, and status.

Referenced by __init_manager().

◆ action_filter()

static int action_filter ( struct mansession s,
const struct message m 
)
static

Manager command to add an event filter to a manager session.

See also
For more details look at manager_add_filter

Definition at line 6708 of file manager.c.

6709{
6710 const char *filter = astman_get_header(m, "Filter");
6711 const char *operation = astman_get_header(m, "Operation");
6712 int res;
6713
6714 if (!strcasecmp(operation, "Add")) {
6716
6717 if (res != FILTER_SUCCESS) {
6718 if (res == FILTER_ALLOC_FAILED) {
6719 astman_send_error(s, m, "Internal Error. Failed to allocate regex for filter");
6720 return 0;
6721 } else if (res == FILTER_COMPILE_FAIL) {
6722 astman_send_error(s, m, "Filter did not compile. Check the syntax of the filter given.");
6723 return 0;
6724 } else {
6725 astman_send_error(s, m, "Internal Error. Failed adding filter.");
6726 return 0;
6727 }
6728 }
6729
6730 astman_send_ack(s, m, "Success");
6731 return 0;
6732 }
6733
6734 astman_send_error(s, m, "Unknown operation");
6735 return 0;
6736}
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:807
static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters)
Add an event filter to a manager session.
Definition: manager.c:6760
struct ao2_container * whitefilters
Definition: manager.c:1750
struct ao2_container * blackfilters
Definition: manager.c:1751

References astman_get_header(), astman_send_ack(), astman_send_error(), mansession_session::blackfilters, filter(), FILTER_ALLOC_FAILED, FILTER_COMPILE_FAIL, FILTER_SUCCESS, manager_add_filter(), mansession::session, and mansession_session::whitefilters.

Referenced by __init_manager().

◆ action_find()

static struct manager_action * action_find ( const char *  name)
static

Definition at line 1856 of file manager.c.

1857{
1858 struct manager_action *act;
1859
1861 AST_RWLIST_TRAVERSE(&actions, act, list) {
1862 if (!strcasecmp(name, act->action)) {
1863 ao2_t_ref(act, +1, "found action object");
1864 break;
1865 }
1866 }
1868
1869 return act;
1870}
#define ao2_t_ref(o, delta, tag)
Definition: astobj2.h:460
list of actions registered
Definition: manager.c:1817
const char * action
Definition: manager.h:156

References manager_action::action, ao2_t_ref, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and name.

Referenced by ast_hook_send_action(), and process_message().

◆ action_getconfig()

static int action_getconfig ( struct mansession s,
const struct message m 
)
static

Definition at line 3896 of file manager.c.

3897{
3898 struct ast_config *cfg;
3899 const char *fn = astman_get_header(m, "Filename");
3900 const char *category = astman_get_header(m, "Category");
3901 const char *filter = astman_get_header(m, "Filter");
3902 const char *category_name;
3903 int catcount = 0;
3904 int lineno = 0;
3905 int ret = 0;
3906 struct ast_category *cur_category = NULL;
3907 struct ast_variable *v;
3908 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
3909
3910 if (ast_strlen_zero(fn)) {
3911 astman_send_error(s, m, "Filename not specified");
3912 return 0;
3913 }
3914
3915 ret = restrictedFile(fn);
3916 if (ret == 1) {
3917 astman_send_error(s, m, "File requires escalated priveledges");
3918 return 0;
3919 } else if (ret == -1) {
3920 astman_send_error(s, m, "Config file not found");
3921 return 0;
3922 }
3923
3924 cfg = ast_config_load2(fn, "manager", config_flags);
3925 if (cfg == CONFIG_STATUS_FILEMISSING) {
3926 astman_send_error(s, m, "Config file not found");
3927 return 0;
3928 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
3929 astman_send_error(s, m, "Config file has invalid format");
3930 return 0;
3931 }
3932
3933 astman_start_ack(s, m);
3934 while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
3935 struct ast_str *templates;
3936
3937 category_name = ast_category_get_name(cur_category);
3938 lineno = 0;
3939 astman_append(s, "Category-%06d: %s\r\n", catcount, category_name);
3940
3941 if (ast_category_is_template(cur_category)) {
3942 astman_append(s, "IsTemplate-%06d: %d\r\n", catcount, 1);
3943 }
3944
3945 if ((templates = ast_category_get_templates(cur_category))
3946 && ast_str_strlen(templates) > 0) {
3947 astman_append(s, "Templates-%06d: %s\r\n", catcount, ast_str_buffer(templates));
3949 }
3950
3951 for (v = ast_category_first(cur_category); v; v = v->next) {
3952 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
3953 }
3954
3955 catcount++;
3956 }
3957
3958 if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
3959 astman_append(s, "No categories found\r\n");
3960 }
3961
3962 ast_config_destroy(cfg);
3963 astman_append(s, "\r\n");
3964
3965 return 0;
3966}
static int restrictedFile(const char *filename)
Check if a file is restricted or not.
Definition: manager.c:3863
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1117
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3321
#define CONFIG_STATUS_FILEMISSING
struct ast_str * ast_category_get_templates(const struct ast_category *category)
Return the template names this category inherits from.
Definition: main/config.c:1127
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
int ast_category_is_template(const struct ast_category *category)
Check if category is a template.
Definition: main/config.c:1122
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1246
@ CONFIG_FLAG_NOCACHE
@ CONFIG_FLAG_WITHCOMMENTS
struct ast_category * ast_category_browse_filtered(struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
Browse categories with filters.
Definition: main/config.c:1424
static struct templates templates
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
Structure used to handle boolean flags.
Definition: utils.h:199
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next

References ast_category_browse_filtered(), ast_category_first(), ast_category_get_name(), ast_category_get_templates(), ast_category_is_template(), ast_config_destroy(), ast_config_load2(), ast_free, ast_str_buffer(), ast_str_strlen(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, filter(), ast_variable::name, ast_variable::next, NULL, restrictedFile(), templates, and ast_variable::value.

Referenced by __init_manager().

◆ action_getconfigjson()

static int action_getconfigjson ( struct mansession s,
const struct message m 
)
static

Definition at line 4034 of file manager.c.

4035{
4036 struct ast_config *cfg;
4037 const char *fn = astman_get_header(m, "Filename");
4038 const char *filter = astman_get_header(m, "Filter");
4039 const char *category = astman_get_header(m, "Category");
4040 struct ast_category *cur_category = NULL;
4041 const char *category_name;
4042 struct ast_variable *v;
4043 int comma1 = 0;
4044 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
4045
4046 if (ast_strlen_zero(fn)) {
4047 astman_send_error(s, m, "Filename not specified");
4048 return 0;
4049 }
4050
4051 if (restrictedFile(fn)) {
4052 astman_send_error(s, m, "File requires escalated priveledges");
4053 return 0;
4054 }
4055
4056 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
4057 astman_send_error(s, m, "Config file not found");
4058 return 0;
4059 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
4060 astman_send_error(s, m, "Config file has invalid format");
4061 return 0;
4062 }
4063
4064 astman_start_ack(s, m);
4065 astman_append(s, "JSON: {");
4066 while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
4067 int comma2 = 0;
4068 struct ast_str *templates;
4069
4070 category_name = ast_category_get_name(cur_category);
4071 astman_append(s, "%s\"", comma1 ? "," : "");
4072 astman_append_json(s, category_name);
4073 astman_append(s, "\":{");
4074 comma1 = 1;
4075
4076 if (ast_category_is_template(cur_category)) {
4077 astman_append(s, "\"istemplate\":1");
4078 comma2 = 1;
4079 }
4080
4081 if ((templates = ast_category_get_templates(cur_category))
4082 && ast_str_strlen(templates) > 0) {
4083 astman_append(s, "%s", comma2 ? "," : "");
4084 astman_append(s, "\"templates\":\"%s\"", ast_str_buffer(templates));
4086 comma2 = 1;
4087 }
4088
4089 for (v = ast_category_first(cur_category); v; v = v->next) {
4090 astman_append(s, "%s\"", comma2 ? "," : "");
4091 astman_append_json(s, v->name);
4092 astman_append(s, "\":\"");
4094 astman_append(s, "\"");
4095 comma2 = 1;
4096 }
4097
4098 astman_append(s, "}");
4099 }
4100 astman_append(s, "}\r\n\r\n");
4101
4102 ast_config_destroy(cfg);
4103
4104 return 0;
4105}
static void astman_append_json(struct mansession *s, const char *str)
Definition: manager.c:4025

References ast_category_browse_filtered(), ast_category_first(), ast_category_get_name(), ast_category_get_templates(), ast_category_is_template(), ast_config_destroy(), ast_config_load2(), ast_free, ast_str_buffer(), ast_str_strlen(), ast_strlen_zero(), astman_append(), astman_append_json(), astman_get_header(), astman_send_error(), astman_start_ack(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, filter(), ast_variable::name, ast_variable::next, NULL, restrictedFile(), templates, and ast_variable::value.

Referenced by __init_manager().

◆ action_getvar()

static int action_getvar ( struct mansession s,
const struct message m 
)
static

Definition at line 4914 of file manager.c.

4915{
4916 struct ast_channel *c = NULL;
4917 const char *name = astman_get_header(m, "Channel");
4918 const char *varname = astman_get_header(m, "Variable");
4919 char *varval;
4920 char workspace[1024];
4921
4922 if (ast_strlen_zero(varname)) {
4923 astman_send_error(s, m, "No variable specified");
4924 return 0;
4925 }
4926
4927 /* We don't want users with insufficient permissions using certain functions. */
4929 astman_send_error(s, m, "GetVar Access Forbidden: Variable");
4930 return 0;
4931 }
4932
4933 if (!ast_strlen_zero(name)) {
4934 if (!(c = ast_channel_get_by_name(name))) {
4935 astman_send_error(s, m, "No such channel");
4936 return 0;
4937 }
4938 }
4939
4940 workspace[0] = '\0';
4941 if (varname[strlen(varname) - 1] == ')') {
4942 if (!c) {
4944 if (c) {
4945 ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
4946 } else
4947 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
4948 } else {
4949 ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
4950 }
4951 varval = workspace;
4952 } else {
4953 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
4954 }
4955
4956 if (c) {
4958 }
4959
4960 astman_start_ack(s, m);
4961 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, ""));
4962
4963 return 0;
4964}
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1282
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.
Definition: manager.c:2198
#define LOG_ERROR
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
Retrieve the value of a builtin variable or variable from the channel variable stack.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static struct test_val 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(), c, function_capable_string_allowed_with_auths(), LOG_ERROR, name, NULL, pbx_retrieve_variable(), S_OR, mansession::session, and mansession_session::writeperm.

Referenced by __init_manager().

◆ action_hangup()

static int action_hangup ( struct mansession s,
const struct message m 
)
static

Definition at line 4875 of file manager.c.

4876{
4877 return ast_manager_hangup_helper(s, m,
4879}
void ast_channel_softhangup_withcause_locked(struct ast_channel *chan, int causecode)
Lock the given channel, then request softhangup on the channel with the given causecode.
Definition: channel.c:468
int ast_manager_hangup_helper(struct mansession *s, const struct message *m, manager_hangup_handler_t hangup_handler, manager_hangup_cause_validator_t cause_validator)
A manager helper function that hangs up a channel using a supplied channel type specific hangup funct...
Definition: manager.c:4754

References ast_channel_softhangup_withcause_locked(), ast_manager_hangup_helper(), and NULL.

Referenced by __init_manager().

◆ action_listcategories()

static int action_listcategories ( struct mansession s,
const struct message m 
)
static

Definition at line 3968 of file manager.c.

3969{
3970 struct ast_config *cfg;
3971 const char *fn = astman_get_header(m, "Filename");
3972 const char *match = astman_get_header(m, "Match");
3973 struct ast_category *category = NULL;
3974 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
3975 int catcount = 0;
3976
3977 if (ast_strlen_zero(fn)) {
3978 astman_send_error(s, m, "Filename not specified");
3979 return 0;
3980 }
3981
3982 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
3983 astman_send_error(s, m, "Config file not found");
3984 return 0;
3985 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
3986 astman_send_error(s, m, "Config file has invalid format");
3987 return 0;
3988 }
3989
3990 astman_start_ack(s, m);
3991 while ((category = ast_category_browse_filtered(cfg, NULL, category, match))) {
3992 astman_append(s, "Category-%06d: %s\r\n", catcount, ast_category_get_name(category));
3993 catcount++;
3994 }
3995
3996 if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
3997 astman_append(s, "Error: no categories found\r\n");
3998 }
3999
4000 ast_config_destroy(cfg);
4001 astman_append(s, "\r\n");
4002
4003 return 0;
4004}
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2362

References ast_category_browse_filtered(), ast_category_get_name(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, match(), and NULL.

Referenced by __init_manager().

◆ action_listcommands()

static int action_listcommands ( struct mansession s,
const struct message m 
)
static

Definition at line 4618 of file manager.c.

4619{
4620 struct manager_action *cur;
4622
4623 astman_start_ack(s, m);
4625 AST_RWLIST_TRAVERSE(&actions, cur, list) {
4626 if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
4627 astman_append(s, "%s: %s (Priv: %s)\r\n",
4628 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
4629 }
4630 }
4632 astman_append(s, "\r\n");
4633
4634 return 0;
4635}

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(), MAX_AUTH_PERM_STRING, mansession::session, manager_action::synopsis, and mansession_session::writeperm.

Referenced by __init_manager().

◆ action_loggerrotate()

static int action_loggerrotate ( struct mansession s,
const struct message m 
)
static

Manager command "LoggerRotate" - reloads and rotates the logger in the same manner as the CLI command 'logger rotate'.

Definition at line 7232 of file manager.c.

7233{
7234 if (ast_logger_rotate()) {
7235 astman_send_error(s, m, "Failed to reload the logger and rotate log files");
7236 return 0;
7237 }
7238
7239 astman_send_ack(s, m, "Reloaded the logger and rotated log files");
7240 return 0;
7241}
int ast_logger_rotate(void)
Reload logger while rotating log files.
Definition: logger.c:1315

References ast_logger_rotate(), astman_send_ack(), and astman_send_error().

Referenced by __init_manager().

◆ action_login()

static int action_login ( struct mansession s,
const struct message m 
)
static

Definition at line 4687 of file manager.c.

4688{
4689
4690 /* still authenticated - don't process again */
4691 if (s->session->authenticated) {
4692 astman_send_ack(s, m, "Already authenticated");
4693 return 0;
4694 }
4695
4696 if (authenticate(s, m)) {
4697 sleep(1);
4698 astman_send_error(s, m, "Authentication failed");
4699 return -1;
4700 }
4701 s->session->authenticated = 1;
4704 ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_sockaddr_stringify_addr(&s->session->addr));
4705 }
4706 astman_send_ack(s, m, "Authentication accepted");
4711 const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
4712 long uptime = 0;
4713 long lastreloaded = 0;
4714 struct timeval tmp;
4715 struct timeval curtime = ast_tvnow();
4716
4717 if (ast_startuptime.tv_sec) {
4718 tmp = ast_tvsub(curtime, ast_startuptime);
4719 uptime = tmp.tv_sec;
4720 }
4721
4722 if (ast_lastreloadtime.tv_sec) {
4723 tmp = ast_tvsub(curtime, ast_lastreloadtime);
4724 lastreloaded = tmp.tv_sec;
4725 }
4726
4727 astman_append(s, "Event: FullyBooted\r\n"
4728 "Privilege: %s\r\n"
4729 "Uptime: %ld\r\n"
4730 "LastReload: %ld\r\n"
4731 "Status: Fully Booted\r\n\r\n", cat_str, uptime, lastreloaded);
4732 }
4733 return 0;
4734}
static int tmp()
Definition: bt_open.c:389
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:2474
static int unauth_sessions
Definition: manager.c:1632
static int authenticate(struct mansession *s, const struct message *m)
Definition: manager.c:3727
struct ast_flags ast_options
Definition: options.c:61
@ AST_OPT_FLAG_FULLY_BOOTED
Definition: options.h:58
#define ast_verb(level,...)
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:286
struct ast_sockaddr addr
Definition: manager.c:1734
uint32_t managerid
Definition: manager.c:1739
char username[80]
Definition: manager.c:1743
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2297
#define ast_test_flag(p, flag)
Definition: utils.h:63

References mansession_session::addr, ast_atomic_fetchadd_int(), ast_lastreloadtime, AST_OPT_FLAG_FULLY_BOOTED, ast_options, ast_sockaddr_stringify_addr(), ast_startuptime, ast_str_alloca, ast_test_flag, ast_tvnow(), ast_tvsub(), 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, MAX_AUTH_PERM_STRING, mansession_session::readperm, mansession_session::send_events, mansession::session, tmp(), unauth_sessions, and mansession_session::username.

Referenced by __init_manager().

◆ action_logoff()

static int action_logoff ( struct mansession s,
const struct message m 
)
static

Definition at line 4681 of file manager.c.

4682{
4683 astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
4684 return -1;
4685}
void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
Send response in manager transaction.
Definition: manager.c:3376

References astman_send_response().

Referenced by __init_manager().

◆ action_mailboxcount()

static int action_mailboxcount ( struct mansession s,
const struct message m 
)
static

Definition at line 6550 of file manager.c.

6551{
6552 const char *mailbox = astman_get_header(m, "Mailbox");
6553 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
6554
6555 if (ast_strlen_zero(mailbox)) {
6556 astman_send_error(s, m, "Mailbox not specified");
6557 return 0;
6558 }
6559 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
6560 astman_start_ack(s, m);
6561 astman_append(s, "Message: Mailbox Message Count\r\n"
6562 "Mailbox: %s\r\n"
6563 "UrgMessages: %d\r\n"
6564 "NewMessages: %d\r\n"
6565 "OldMessages: %d\r\n"
6566 "\r\n",
6567 mailbox, urgentmsgs, newmsgs, oldmsgs);
6568 return 0;
6569}
int ast_app_inboxcount2(const char *mailboxes, int *urgentmsgs, int *newmsgs, int *oldmsgs)
Determine number of urgent/new/old messages in a mailbox.
Definition: main/app.c:619

References ast_app_inboxcount2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and voicemailpwcheck::mailbox.

Referenced by __init_manager().

◆ action_mailboxstatus()

static int action_mailboxstatus ( struct mansession s,
const struct message m 
)
static

Definition at line 6533 of file manager.c.

6534{
6535 const char *mailbox = astman_get_header(m, "Mailbox");
6536 int ret;
6537
6538 if (ast_strlen_zero(mailbox)) {
6539 astman_send_error(s, m, "Mailbox not specified");
6540 return 0;
6541 }
6543 astman_start_ack(s, m);
6544 astman_append(s, "Message: Mailbox Status\r\n"
6545 "Mailbox: %s\r\n"
6546 "Waiting: %d\r\n\r\n", mailbox, ret);
6547 return 0;
6548}
int ast_app_has_voicemail(const char *mailboxes, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX"....
Definition: main/app.c:582

References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), voicemailpwcheck::mailbox, and NULL.

Referenced by __init_manager().

◆ action_originate()

static int action_originate ( struct mansession s,
const struct message m 
)
static

Definition at line 6320 of file manager.c.

6321{
6322 const char *name = astman_get_header(m, "Channel");
6323 const char *exten = astman_get_header(m, "Exten");
6324 const char *context = astman_get_header(m, "Context");
6325 const char *priority = astman_get_header(m, "Priority");
6326 const char *timeout = astman_get_header(m, "Timeout");
6327 const char *callerid = astman_get_header(m, "CallerID");
6328 const char *account = astman_get_header(m, "Account");
6329 const char *app = astman_get_header(m, "Application");
6330 const char *appdata = astman_get_header(m, "Data");
6331 const char *async = astman_get_header(m, "Async");
6332 const char *id = astman_get_header(m, "ActionID");
6333 const char *codecs = astman_get_header(m, "Codecs");
6334 const char *early_media = astman_get_header(m, "Earlymedia");
6335 struct ast_assigned_ids assignedids = {
6336 .uniqueid = astman_get_header(m, "ChannelId"),
6337 .uniqueid2 = astman_get_header(m, "OtherChannelId"),
6338 };
6339 const char *gosub = astman_get_header(m, "PreDialGoSub");
6340
6341 struct ast_variable *vars = NULL;
6342 char *tech, *data;
6343 char *l = NULL, *n = NULL;
6344 int pi = 0;
6345 int res;
6346 int to = 30000;
6347 int reason = 0;
6348 char tmp[256];
6349 char tmp2[256];
6351 pthread_t th;
6352 int bridge_early = 0;
6353
6354 if (!cap) {
6355 astman_send_error(s, m, "Internal Error. Memory allocation failure.");
6356 return 0;
6357 }
6359
6360 if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
6361 || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
6362 astman_send_error_va(s, m, "Uniqueid length exceeds maximum of %d\n",
6364 res = 0;
6365 goto fast_orig_cleanup;
6366 }
6367
6368 if (ast_strlen_zero(name)) {
6369 astman_send_error(s, m, "Channel not specified");
6370 res = 0;
6371 goto fast_orig_cleanup;
6372 }
6373 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
6374 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
6375 astman_send_error(s, m, "Invalid priority");
6376 res = 0;
6377 goto fast_orig_cleanup;
6378 }
6379 }
6380 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
6381 astman_send_error(s, m, "Invalid timeout");
6382 res = 0;
6383 goto fast_orig_cleanup;
6384 }
6385 ast_copy_string(tmp, name, sizeof(tmp));
6386 tech = tmp;
6387 data = strchr(tmp, '/');
6388 if (!data) {
6389 astman_send_error(s, m, "Invalid channel");
6390 res = 0;
6391 goto fast_orig_cleanup;
6392 }
6393 *data++ = '\0';
6394 ast_copy_string(tmp2, callerid, sizeof(tmp2));
6395 ast_callerid_parse(tmp2, &n, &l);
6396 if (n) {
6397 if (ast_strlen_zero(n)) {
6398 n = NULL;
6399 }
6400 }
6401 if (l) {
6403 if (ast_strlen_zero(l)) {
6404 l = NULL;
6405 }
6406 }
6407 if (!ast_strlen_zero(codecs)) {
6410 }
6411
6412 if (!ast_strlen_zero(app) && s->session) {
6413 int bad_appdata = 0;
6414 /* To run the System application (or anything else that goes to
6415 * shell), you must have the additional System privilege */
6417 && (
6418 strcasestr(app, "system") || /* System(rm -rf /)
6419 TrySystem(rm -rf /) */
6420 strcasestr(app, "exec") || /* Exec(System(rm -rf /))
6421 TryExec(System(rm -rf /)) */
6422 strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /)
6423 EAGI(/bin/rm,-rf /) */
6424 strcasestr(app, "mixmonitor") || /* MixMonitor(blah,,rm -rf) */
6425 strcasestr(app, "externalivr") || /* ExternalIVR(rm -rf) */
6426 strcasestr(app, "originate") || /* Originate(Local/1234,app,System,rm -rf) */
6427 (strstr(appdata, "SHELL") && (bad_appdata = 1)) || /* NoOp(${SHELL(rm -rf /)}) */
6428 (strstr(appdata, "EVAL") && (bad_appdata = 1)) /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
6429 )) {
6430 char error_buf[64];
6431 snprintf(error_buf, sizeof(error_buf), "Originate Access Forbidden: %s", bad_appdata ? "Data" : "Application");
6432 astman_send_error(s, m, error_buf);
6433 res = 0;
6434 goto fast_orig_cleanup;
6435 }
6436 }
6437
6438 /* Check early if the extension exists. If not, we need to bail out here. */
6439 if (exten && context && pi) {
6440 if (! ast_exists_extension(NULL, context, exten, pi, l)) {
6441 /* The extension does not exist. */
6442 astman_send_error(s, m, "Extension does not exist.");
6443 res = 0;
6444 goto fast_orig_cleanup;
6445 }
6446 }
6447
6448 /* Allocate requested channel variables */
6449 vars = astman_get_variables(m);
6450 if (s->session && s->session->chanvars) {
6451 struct ast_variable *v, *old;
6452 old = vars;
6453 vars = NULL;
6454
6455 /* The variables in the AMI originate action are appended at the end of the list, to override any user variables that apply */
6456
6458 if (old) {
6459 for (v = vars; v->next; v = v->next );
6460 v->next = old; /* Append originate variables at end of list */
6461 }
6462 }
6463
6464 /* For originate async - we can bridge in early media stage */
6465 bridge_early = ast_true(early_media);
6466
6467 if (ast_true(async)) {
6468 struct fast_originate_helper *fast;
6469
6470 fast = ast_calloc(1, sizeof(*fast));
6471 if (!fast || ast_string_field_init(fast, 252)) {
6472 ast_free(fast);
6474 res = -1;
6475 } else {
6476 if (!ast_strlen_zero(id)) {
6477 ast_string_field_build(fast, idtext, "ActionID: %s\r\n", id);
6478 }
6483 ast_string_field_set(fast, cid_num, l);
6488 ast_string_field_set(fast, channelid, assignedids.uniqueid);
6489 ast_string_field_set(fast, otherchannelid, assignedids.uniqueid2);
6490 fast->vars = vars;
6491 fast->cap = cap;
6492 cap = NULL; /* transfered originate helper the capabilities structure. It is now responsible for freeing it. */
6493 fast->timeout = to;
6494 fast->early_media = bridge_early;
6495 fast->priority = pi;
6498 res = -1;
6499 } else {
6500 res = 0;
6501 }
6502 }
6503 } else if (!ast_strlen_zero(app)) {
6504 res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason,
6506 assignedids.uniqueid ? &assignedids : NULL);
6508 } else {
6509 if (exten && context && pi) {
6511 context, exten, pi, &reason, AST_OUTGOING_WAIT,
6512 l, n, vars, account, NULL, bridge_early,
6513 assignedids.uniqueid ? &assignedids : NULL , gosub);
6515 } else {
6516 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
6518 res = 0;
6519 goto fast_orig_cleanup;
6520 }
6521 }
6522 if (!res) {
6523 astman_send_ack(s, m, "Originate successfully queued");
6524 } else {
6525 astman_send_error(s, m, "Originate failed");
6526 }
6527
6528fast_orig_cleanup:
6530 return 0;
6531}
static const char app[]
Definition: app_adsiprog.c:56
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1162
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
Definition: callerid.c:1101
static int priority
#define AST_MAX_PUBLIC_UNIQUEID
Definition: channel.h:147
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:523
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
static void destroy_fast_originate_helper(struct fast_originate_helper *doomed)
Definition: manager.c:5710
struct ast_variable * astman_get_variables(const struct message *m)
Get a linked list of the Variable: headers.
Definition: manager.c:3128
static void * fast_originate(void *data)
Definition: manager.c:5718
char * strcasestr(const char *, const char *)
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:543
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
Find the priority of an extension that has the specified label.
Definition: pbx.c:4180
int ast_pbx_outgoing_exten_predial(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, int early_media, const struct ast_assigned_ids *assignedids, const char *predial_callee)
Definition: pbx.c:7926
@ AST_OUTGOING_WAIT
Definition: pbx.h:1141
int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, const struct ast_assigned_ids *assignedids)
Synchronously or asynchronously make an outbound call and execute an application on the channel.
Definition: pbx.c:7980
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:604
const char * uniqueid2
Definition: channel.h:606
const char * uniqueid
Definition: channel.h:605
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
helper function for originate
Definition: manager.c:5682
const ast_string_field appdata
Definition: manager.c:5700
struct ast_variable * vars
Definition: manager.c:5702
const ast_string_field cid_num
Definition: manager.c:5700
const ast_string_field account
Definition: manager.c:5700
const ast_string_field tech
Definition: manager.c:5700
const ast_string_field data
Definition: manager.c:5700
const ast_string_field channelid
Definition: manager.c:5700
const ast_string_field otherchannelid
Definition: manager.c:5700
struct ast_format_cap * cap
Definition: manager.c:5684
const ast_string_field exten
Definition: manager.c:5700
const ast_string_field idtext
Definition: manager.c:5700
const ast_string_field cid_name
Definition: manager.c:5700
struct ast_variable * chanvars
Definition: manager.c:1752
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:588

References ao2_cleanup, app, ast_callerid_parse(), ast_calloc, ast_copy_string(), ast_exists_extension(), ast_findlabel_extension(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_remove_by_type(), ast_format_cap_update_by_allow_disallow(), ast_format_slin, ast_free, AST_MAX_PUBLIC_UNIQUEID, AST_MEDIA_TYPE_UNKNOWN, AST_OUTGOING_WAIT, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten_predial(), ast_pthread_create_detached, ast_shrink_phone_number(), ast_string_field_build, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_true(), ast_variables_destroy(), ast_variables_dup(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), astman_send_error_va(), fast_originate_helper::cap, mansession_session::chanvars, codecs, voicemailpwcheck::context, destroy_fast_originate_helper(), fast_originate_helper::early_media, EVENT_FLAG_SYSTEM, fast_originate(), name, ast_variable::next, NULL, priority, fast_originate_helper::priority, mansession::session, strcasestr(), fast_originate_helper::timeout, tmp(), ast_assigned_ids::uniqueid, ast_assigned_ids::uniqueid2, fast_originate_helper::vars, and mansession_session::writeperm.

Referenced by __init_manager().

◆ action_ping()

static int action_ping ( struct mansession s,
const struct message m 
)
static

Definition at line 3824 of file manager.c.

3825{
3826 const char *actionid = astman_get_header(m, "ActionID");
3827 struct timeval now = ast_tvnow();
3828
3829 astman_append(s, "Response: Success\r\n");
3830 if (!ast_strlen_zero(actionid)){
3831 astman_append(s, "ActionID: %s\r\n", actionid);
3832 }
3834 s,
3835 "Ping: Pong\r\n"
3836 "Timestamp: %ld.%06lu\r\n"
3837 "\r\n",
3838 (long) now.tv_sec, (unsigned long) now.tv_usec);
3839 return 0;
3840}

References ast_strlen_zero(), ast_tvnow(), astman_append(), and astman_get_header().

Referenced by __init_manager().

◆ action_presencestate()

static int action_presencestate ( struct mansession s,
const struct message m 
)
static

Definition at line 6601 of file manager.c.

6602{
6603 const char *provider = astman_get_header(m, "Provider");
6605 char *subtype;
6606 char *message;
6607
6609 astman_send_error(s, m, "No provider specified");
6610 return 0;
6611 }
6612
6614 if (state == AST_PRESENCE_INVALID) {
6615 astman_send_error_va(s, m, "Invalid provider %s or provider in invalid state", provider);
6616 return 0;
6617 }
6618
6619 astman_start_ack(s, m);
6620 astman_append(s, "Message: Presence State\r\n"
6621 "State: %s\r\n", ast_presence_state2str(state));
6622
6623 if (!ast_strlen_zero(subtype)) {
6624 astman_append(s, "Subtype: %s\r\n", subtype);
6625 }
6626
6627 if (!ast_strlen_zero(message)) {
6628 /* XXX The Message header here is deprecated as it
6629 * duplicates the action response header 'Message'.
6630 * Remove it in the next major revision of AMI.
6631 */
6632 astman_append(s, "Message: %s\r\n"
6633 "PresenceMessage: %s\r\n",
6634 message, message);
6635 }
6636 astman_append(s, "\r\n");
6637
6638 return 0;
6639}
static struct prometheus_metrics_provider provider
Definition: bridges.c:201
enum cc_state state
Definition: ccss.c:393
ast_presence_state
Definition: presencestate.h:26
@ AST_PRESENCE_INVALID
Definition: presencestate.h:39
const char * ast_presence_state2str(enum ast_presence_state state)
Convert presence state to text string for output.

References AST_PRESENCE_INVALID, ast_presence_state2str(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_error_va(), astman_start_ack(), provider, and state.

Referenced by __init_manager().

◆ action_redirect()

static int action_redirect ( struct mansession s,
const struct message m 
)
static

action_redirect: The redirect manager command

Definition at line 5280 of file manager.c.

5281{
5282 char buf[256];
5283 const char *name = astman_get_header(m, "Channel");
5284 const char *name2 = astman_get_header(m, "ExtraChannel");
5285 const char *exten = astman_get_header(m, "Exten");
5286 const char *exten2 = astman_get_header(m, "ExtraExten");
5287 const char *context = astman_get_header(m, "Context");
5288 const char *context2 = astman_get_header(m, "ExtraContext");
5289 const char *priority = astman_get_header(m, "Priority");
5290 const char *priority2 = astman_get_header(m, "ExtraPriority");
5291 struct ast_channel *chan;
5292 struct ast_channel *chan2;
5293 int pi = 0;
5294 int pi2 = 0;
5295 int res;
5296 int chan1_wait = 0;
5297 int chan2_wait = 0;
5298
5299 if (ast_strlen_zero(name)) {
5300 astman_send_error(s, m, "Channel not specified");
5301 return 0;
5302 }
5303
5304 if (ast_strlen_zero(context)) {
5305 astman_send_error(s, m, "Context not specified");
5306 return 0;
5307 }
5308 if (ast_strlen_zero(exten)) {
5309 astman_send_error(s, m, "Exten not specified");
5310 return 0;
5311 }
5313 astman_send_error(s, m, "Priority not specified");
5314 return 0;
5315 }
5316 if (sscanf(priority, "%30d", &pi) != 1) {
5318 }
5319 if (pi < 1) {
5320 astman_send_error(s, m, "Priority is invalid");
5321 return 0;
5322 }
5323
5324 if (!ast_strlen_zero(name2) && !ast_strlen_zero(context2)) {
5325 /* We have an ExtraChannel and an ExtraContext */
5326 if (ast_strlen_zero(exten2)) {
5327 astman_send_error(s, m, "ExtraExten not specified");
5328 return 0;
5329 }
5330 if (ast_strlen_zero(priority2)) {
5331 astman_send_error(s, m, "ExtraPriority not specified");
5332 return 0;
5333 }
5334 if (sscanf(priority2, "%30d", &pi2) != 1) {
5335 pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL);
5336 }
5337 if (pi2 < 1) {
5338 astman_send_error(s, m, "ExtraPriority is invalid");
5339 return 0;
5340 }
5341 }
5342
5344 if (!chan) {
5345 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
5346 astman_send_error(s, m, buf);
5347 return 0;
5348 }
5349 if (ast_check_hangup_locked(chan)) {
5350 astman_send_error(s, m, "Redirect failed, channel not up.");
5351 chan = ast_channel_unref(chan);
5352 return 0;
5353 }
5354
5355 if (ast_strlen_zero(name2)) {
5356 /* Single channel redirect in progress. */
5357 res = ast_async_goto(chan, context, exten, pi);
5358 if (!res) {
5359 astman_send_ack(s, m, "Redirect successful");
5360 } else {
5361 astman_send_error(s, m, "Redirect failed");
5362 }
5363 chan = ast_channel_unref(chan);
5364 return 0;
5365 }
5366
5367 chan2 = ast_channel_get_by_name(name2);
5368 if (!chan2) {
5369 snprintf(buf, sizeof(buf), "ExtraChannel does not exist: %s", name2);
5370 astman_send_error(s, m, buf);
5371 chan = ast_channel_unref(chan);
5372 return 0;
5373 }
5374 if (ast_check_hangup_locked(chan2)) {
5375 astman_send_error(s, m, "Redirect failed, extra channel not up.");
5376 chan2 = ast_channel_unref(chan2);
5377 chan = ast_channel_unref(chan);
5378 return 0;
5379 }
5380
5381 /* Dual channel redirect in progress. */
5382 ast_channel_lock(chan);
5383 if (ast_channel_is_bridged(chan)) {
5385 chan1_wait = 1;
5386 }
5387 ast_channel_unlock(chan);
5388
5389 ast_channel_lock(chan2);
5390 if (ast_channel_is_bridged(chan2)) {
5392 chan2_wait = 1;
5393 }
5394 ast_channel_unlock(chan2);
5395
5396 res = ast_async_goto(chan, context, exten, pi);
5397 if (!res) {
5398 if (!ast_strlen_zero(context2)) {
5399 res = ast_async_goto(chan2, context2, exten2, pi2);
5400 } else {
5401 res = ast_async_goto(chan2, context, exten, pi);
5402 }
5403 if (!res) {
5404 astman_send_ack(s, m, "Dual Redirect successful");
5405 } else {
5406 astman_send_error(s, m, "Secondary redirect failed");
5407 }
5408 } else {
5409 astman_send_error(s, m, "Redirect failed");
5410 }
5411
5412 /* Release the bridge wait. */
5413 if (chan1_wait) {
5415 }
5416 if (chan2_wait) {
5418 }
5419
5420 chan2 = ast_channel_unref(chan2);
5421 chan = ast_channel_unref(chan);
5422 return 0;
5423}
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11034
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10545
@ AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT
Definition: channel.h:1035
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:6969
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ast_async_goto(), ast_channel_clear_flag(), ast_channel_flags(), ast_channel_get_by_name(), ast_channel_is_bridged(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_check_hangup_locked(), ast_findlabel_extension(), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT, ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), buf, voicemailpwcheck::context, name, NULL, and priority.

Referenced by __init_manager().

◆ action_reload()

static int action_reload ( struct mansession s,
const struct message m 
)
static

Send a reload event.

Definition at line 6958 of file manager.c.

6959{
6960 const char *module = astman_get_header(m, "Module");
6962
6963 switch (res) {
6965 astman_send_error(s, m, "No such module");
6966 break;
6968 astman_send_error(s, m, "Module does not support reload");
6969 break;
6971 astman_send_error(s, m, "An unknown error occurred");
6972 break;
6974 astman_send_error(s, m, "A reload is in progress");
6975 break;
6977 astman_send_error(s, m, "Module not initialized");
6978 break;
6981 /* Treat a queued request as success */
6982 astman_send_ack(s, m, "Module Reloaded");
6983 break;
6984 }
6985 return 0;
6986}
ast_module_reload_result
Possible return types for ast_module_reload.
Definition: module.h:109
@ AST_MODULE_RELOAD_IN_PROGRESS
Definition: module.h:114
@ AST_MODULE_RELOAD_QUEUED
Definition: module.h:111
@ AST_MODULE_RELOAD_SUCCESS
Definition: module.h:110
@ AST_MODULE_RELOAD_ERROR
Definition: module.h:113
@ AST_MODULE_RELOAD_NOT_IMPLEMENTED
Definition: module.h:116
@ AST_MODULE_RELOAD_NOT_FOUND
Definition: module.h:112
@ AST_MODULE_RELOAD_UNINITIALIZED
Definition: module.h:115
enum ast_module_reload_result ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:1567

References ast_module_reload(), AST_MODULE_RELOAD_ERROR, AST_MODULE_RELOAD_IN_PROGRESS, AST_MODULE_RELOAD_NOT_FOUND, AST_MODULE_RELOAD_NOT_IMPLEMENTED, AST_MODULE_RELOAD_QUEUED, AST_MODULE_RELOAD_SUCCESS, AST_MODULE_RELOAD_UNINITIALIZED, astman_get_header(), astman_send_ack(), astman_send_error(), NULL, and S_OR.

Referenced by __init_manager().

◆ action_sendtext()

static int action_sendtext ( struct mansession s,
const struct message m 
)
static

Definition at line 5237 of file manager.c.

5238{
5239 struct ast_channel *c;
5240 const char *name = astman_get_header(m, "Channel");
5241 const char *textmsg = astman_get_header(m, "Message");
5242 const char *content_type = astman_get_header(m, "Content-Type");
5243 int res;
5244
5245 if (ast_strlen_zero(name)) {
5246 astman_send_error(s, m, "No channel specified");
5247 return 0;
5248 }
5249
5250 if (ast_strlen_zero(textmsg)) {
5251 astman_send_error(s, m, "No Message specified");
5252 return 0;
5253 }
5254
5256 if (!c) {
5257 astman_send_error(s, m, "No such channel");
5258 return 0;
5259 }
5260
5261 /*
5262 * If the "extra" data is not available, then send using "string" only.
5263 * Doing such maintains backward compatibilities.
5264 */
5265 res = ast_strlen_zero(content_type) ? queue_sendtext(c, textmsg) :
5266 queue_sendtext_data(c, textmsg, content_type);
5267
5269
5270 if (res >= 0) {
5271 astman_send_ack(s, m, "Success");
5272 } else {
5273 astman_send_error(s, m, "Failure");
5274 }
5275
5276 return 0;
5277}
static int queue_sendtext_data(struct ast_channel *chan, const char *body, const char *content_type)
Queue a read action to send a text data message.
Definition: manager.c:5218
static int queue_sendtext(struct ast_channel *chan, const char *body)
Queue a read action to send a text message.
Definition: manager.c:5202

References ast_channel_get_by_name(), ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), c, name, queue_sendtext(), and queue_sendtext_data().

Referenced by __init_manager().

◆ action_setvar()

static int action_setvar ( struct mansession s,
const struct message m 
)
static

Definition at line 4881 of file manager.c.

4882{
4883 struct ast_channel *c = NULL;
4884 const char *name = astman_get_header(m, "Channel");
4885 const char *varname = astman_get_header(m, "Variable");
4886 const char *varval = astman_get_header(m, "Value");
4887 int res = 0;
4888
4889 if (ast_strlen_zero(varname)) {
4890 astman_send_error(s, m, "No variable specified");
4891 return 0;
4892 }
4893
4894 if (!ast_strlen_zero(name)) {
4895 if (!(c = ast_channel_get_by_name(name))) {
4896 astman_send_error(s, m, "No such channel");
4897 return 0;
4898 }
4899 }
4900
4901 res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
4902
4903 if (c) {
4905 }
4906 if (res == 0) {
4907 astman_send_ack(s, m, "Variable Set");
4908 } else {
4909 astman_send_error(s, m, "Variable not set");
4910 }
4911 return 0;
4912}

References ast_channel_get_by_name(), ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), c, name, NULL, pbx_builtin_setvar_helper(), and S_OR.

Referenced by __init_manager().

◆ action_status()

static int action_status ( struct mansession s,
const struct message m 
)
static

Manager "status" command to show channels.

Definition at line 5081 of file manager.c.

5082{
5083 const char *name = astman_get_header(m, "Channel");
5084 const char *chan_variables = astman_get_header(m, "Variables");
5085 const char *all_chan_variables = astman_get_header(m, "AllVariables");
5086 int all_variables = 0;
5087 const char *id = astman_get_header(m, "ActionID");
5088 char *variables = ast_strdupa(S_OR(chan_variables, ""));
5089 struct ast_channel *chan;
5090 int channels = 0;
5091 int all = ast_strlen_zero(name); /* set if we want all channels */
5092 char id_text[256];
5093 struct ast_channel_iterator *it_chans = NULL;
5095 AST_APP_ARG(name)[100];
5096 );
5097
5098 if (!ast_strlen_zero(all_chan_variables)) {
5099 all_variables = ast_true(all_chan_variables);
5100 }
5101
5103 astman_send_error(s, m, "Status Access Forbidden: Variables");
5104 return 0;
5105 }
5106
5107 if (all) {
5108 if (!(it_chans = ast_channel_iterator_all_new())) {
5109 astman_send_error(s, m, "Memory Allocation Failure");
5110 return 1;
5111 }
5112 chan = ast_channel_iterator_next(it_chans);
5113 } else {
5115 if (!chan) {
5116 astman_send_error(s, m, "No such channel");
5117 return 0;
5118 }
5119 }
5120
5121 astman_send_listack(s, m, "Channel status will follow", "start");
5122
5123 if (!ast_strlen_zero(id)) {
5124 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
5125 } else {
5126 id_text[0] = '\0';
5127 }
5128
5129 if (!ast_strlen_zero(chan_variables)) {
5130 AST_STANDARD_APP_ARGS(vars, variables);
5131 }
5132
5133 /* if we look by name, we break after the first iteration */
5134 for (; chan; all ? chan = ast_channel_iterator_next(it_chans) : 0) {
5135 ast_channel_lock(chan);
5136
5137 generate_status(s, chan, vars.name, vars.argc, all_variables, id_text, &channels);
5138
5139 ast_channel_unlock(chan);
5140 chan = ast_channel_unref(chan);
5141 }
5142
5143 if (it_chans) {
5145 }
5146
5147 astman_send_list_complete_start(s, m, "StatusComplete", channels);
5148 astman_append(s, "Items: %d\r\n", channels);
5150
5151 return 0;
5152}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1360
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1422
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1408
static void generate_status(struct mansession *s, struct ast_channel *chan, char **vars, int varc, int all_variables, char *id_text, int *count)
Definition: manager.c:4966
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.

References AST_APP_ARG, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_true(), astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), channels, function_capable_string_allowed_with_auths(), generate_status(), name, ast_channel::name, NULL, S_OR, mansession::session, and mansession_session::writeperm.

Referenced by __init_manager().

◆ action_timeout()

static int action_timeout ( struct mansession s,
const struct message m 
)
static

Definition at line 6641 of file manager.c.

6642{
6643 struct ast_channel *c;
6644 const char *name = astman_get_header(m, "Channel");
6645 double timeout = atof(astman_get_header(m, "Timeout"));
6646 struct timeval when = { timeout, 0 };
6647
6648 if (ast_strlen_zero(name)) {
6649 astman_send_error(s, m, "No channel specified");
6650 return 0;
6651 }
6652
6653 if (!timeout || timeout < 0) {
6654 astman_send_error(s, m, "No timeout specified");
6655 return 0;
6656 }
6657
6658 if (!(c = ast_channel_get_by_name(name))) {
6659 astman_send_error(s, m, "No such channel");
6660 return 0;
6661 }
6662
6663 when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
6664
6669
6670 astman_send_ack(s, m, "Timeout Set");
6671
6672 return 0;
6673}
void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
Set when to hang a channel up.
Definition: channel.c:510

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(), c, and name.

Referenced by __init_manager().

◆ action_updateconfig()

static int action_updateconfig ( struct mansession s,
const struct message m 
)
static

Definition at line 4391 of file manager.c.

4392{
4393 struct ast_config *cfg;
4394 const char *sfn = astman_get_header(m, "SrcFilename");
4395 const char *dfn = astman_get_header(m, "DstFilename");
4396 int res;
4397 const char *rld = astman_get_header(m, "Reload");
4398 int preserve_effective_context = CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT;
4399 const char *preserve_effective_context_string = astman_get_header(m, "PreserveEffectiveContext");
4400 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
4401 enum error_type result;
4402
4403 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
4404 astman_send_error(s, m, "Filename not specified");
4405 return 0;
4406 }
4407 if (restrictedFile(sfn) || restrictedFile(dfn)) {
4408 astman_send_error(s, m, "File requires escalated priveledges");
4409 return 0;
4410 }
4411 if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
4412 astman_send_error(s, m, "Config file not found");
4413 return 0;
4414 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
4415 astman_send_error(s, m, "Config file has invalid format");
4416 return 0;
4417 }
4418 result = handle_updates(s, m, cfg, dfn);
4419 if (!result) {
4420 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
4421 if (!ast_strlen_zero(preserve_effective_context_string) && !ast_true(preserve_effective_context_string)) {
4422 preserve_effective_context = CONFIG_SAVE_FLAG_NONE;
4423 }
4424 res = ast_config_text_file_save2(dfn, cfg, "Manager", preserve_effective_context);
4425 ast_config_destroy(cfg);
4426 if (res) {
4427 astman_send_error(s, m, "Save of config failed");
4428 return 0;
4429 }
4430 astman_send_ack(s, m, NULL);
4431 if (!ast_strlen_zero(rld)) {
4432 if (ast_true(rld)) {
4433 ast_module_reload(NULL); /* Reload everything */
4434 } else if (!ast_false(rld)) {
4435 ast_module_reload(rld); /* Reload the specific module */
4436 }
4437 }
4438 } else {
4439 ast_config_destroy(cfg);
4440 switch(result) {
4441 case UNKNOWN_ACTION:
4442 astman_send_error(s, m, "Unknown action command");
4443 break;
4444 case UNKNOWN_CATEGORY:
4445 astman_send_error(s, m, "Given category does not exist");
4446 break;
4448 astman_send_error(s, m, "Category not specified");
4449 break;
4451 astman_send_error(s, m, "Problem with category, value, or line (if required)");
4452 break;
4453 case FAILURE_ALLOCATION:
4454 astman_send_error(s, m, "Memory allocation failure, this should not happen");
4455 break;
4456 case FAILURE_NEWCAT:
4457 astman_send_error(s, m, "Create category did not complete successfully");
4458 break;
4459 case FAILURE_DELCAT:
4460 astman_send_error(s, m, "Delete category did not complete successfully");
4461 break;
4462 case FAILURE_EMPTYCAT:
4463 astman_send_error(s, m, "Empty category did not complete successfully");
4464 break;
4465 case FAILURE_UPDATE:
4466 astman_send_error(s, m, "Update did not complete successfully");
4467 break;
4468 case FAILURE_DELETE:
4469 astman_send_error(s, m, "Delete did not complete successfully");
4470 break;
4471 case FAILURE_APPEND:
4472 astman_send_error(s, m, "Append did not complete successfully");
4473 break;
4474 case FAILURE_TEMPLATE:
4475 astman_send_error(s, m, "Template category not found");
4476 break;
4477 }
4478 }
4479 return 0;
4480}
static enum error_type handle_updates(struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
helper function for action_updateconfig
Definition: manager.c:4108
error_type
Definition: manager.c:1564
void ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
Definition: main/config.c:383
int ast_config_text_file_save2(const char *filename, const struct ast_config *cfg, const char *generator, uint32_t flags)
Save a config text file.
Definition: main/config.c:2725
@ CONFIG_SAVE_FLAG_NONE
@ CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
Definition: utils.c:2216

References ast_config_destroy(), ast_config_load2(), ast_config_text_file_save2(), ast_false(), 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_SAVE_FLAG_NONE, CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT, CONFIG_STATUS_FILEINVALID, FAILURE_ALLOCATION, FAILURE_APPEND, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_TEMPLATE, FAILURE_UPDATE, handle_updates(), NULL, restrictedFile(), result, UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.

Referenced by __init_manager().

◆ action_userevent()

static int action_userevent ( struct mansession s,
const struct message m 
)
static

Definition at line 6853 of file manager.c.

6854{
6855 const char *event = astman_get_header(m, "UserEvent");
6856 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
6857 int x;
6858
6859 ast_str_reset(body);
6860
6861 for (x = 0; x < m->hdrcount; x++) {
6862 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:")) &&
6863 strncasecmp("Action:", m->headers[x], strlen("Action:"))) {
6864 ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
6865 }
6866 }
6867
6868 astman_send_ack(s, m, "Event Sent");
6869 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
6870 return 0;
6871}
static struct ast_threadstorage userevent_buf
Definition: manager.c:3285
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:253
#define EVENT_FLAG_USER
Definition: manager.h:81
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693

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().

◆ action_waitevent()

static int action_waitevent ( struct mansession s,
const struct message m 
)
static

Definition at line 4500 of file manager.c.

4501{
4502 const char *timeouts = astman_get_header(m, "Timeout");
4503 int timeout = -1;
4504 int x;
4505 int needexit = 0;
4506 const char *id = astman_get_header(m, "ActionID");
4507 char idText[256];
4508
4509 if (!ast_strlen_zero(id)) {
4510 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
4511 } else {
4512 idText[0] = '\0';
4513 }
4514
4515 if (!ast_strlen_zero(timeouts)) {
4516 sscanf(timeouts, "%30i", &timeout);
4517 if (timeout < -1) {
4518 timeout = -1;
4519 }
4520 /* XXX maybe put an upper bound, or prevent the use of 0 ? */
4521 }
4522
4525 pthread_kill(s->session->waiting_thread, SIGURG);
4526 }
4528
4529 ao2_lock(s->session);
4530
4531 if (s->session->managerid) { /* AMI-over-HTTP session */
4532 /*
4533 * Make sure the timeout is within the expire time of the session,
4534 * as the client will likely abort the request if it does not see
4535 * data coming after some amount of time.
4536 */
4537 time_t now = time(NULL);
4538 int max = s->session->sessiontimeout - now - 10;
4539
4540 if (max < 0) { /* We are already late. Strange but possible. */
4541 max = 0;
4542 }
4543 if (timeout < 0 || timeout > max) {
4544 timeout = max;
4545 }
4546 if (!s->session->send_events) { /* make sure we record events */
4547 s->session->send_events = -1;
4548 }
4549 }
4550 ao2_unlock(s->session);
4551
4553 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
4555 ast_debug(1, "Starting waiting for an event!\n");
4556
4557 for (x = 0; x < timeout || timeout < 0; x++) {
4558 ao2_lock(s->session);
4559 if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
4560 needexit = 1;
4561 }
4562 if (s->session->needdestroy) {
4563 needexit = 1;
4564 }
4565 ao2_unlock(s->session);
4566 /* We can have multiple HTTP session point to the same mansession entry.
4567 * The way we deal with it is not very nice: newcomers kick out the previous
4568 * HTTP session. XXX this needs to be improved.
4569 */
4571 if (s->session->waiting_thread != pthread_self()) {
4572 needexit = 1;
4573 }
4575 if (needexit) {
4576 break;
4577 }
4578 if (s->session->managerid == 0) { /* AMI session */
4580 break;
4581 }
4582 } else { /* HTTP session */
4583 sleep(1);
4584 }
4585 }
4586 ast_debug(1, "Finished waiting for an event!\n");
4587
4589 if (s->session->waiting_thread == pthread_self()) {
4590 struct eventqent *eqe = s->session->last_ev;
4591
4594
4595 ao2_lock(s->session);
4596 astman_send_response(s, m, "Success", "Waiting for Event completed.");
4597 while ((eqe = advance_event(eqe))) {
4598 if (((s->session->readperm & eqe->category) == eqe->category)
4599 && ((s->session->send_events & eqe->category) == eqe->category)
4600 && match_filter(s, eqe->eventdata)) {
4601 astman_append(s, "%s", eqe->eventdata);
4602 }
4603 s->session->last_ev = eqe;
4604 }
4605 astman_append(s,
4606 "Event: WaitEventComplete\r\n"
4607 "%s"
4608 "\r\n", idText);
4609 ao2_unlock(s->session);
4610 } else {
4612 ast_debug(1, "Abandoning event request!\n");
4613 }
4614
4615 return 0;
4616}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define max(a, b)
Definition: f2c.h:198
static struct eventqent * advance_event(struct eventqent *e)
Definition: manager.c:2975
static int match_filter(struct mansession *s, char *eventdata)
Definition: manager.c:6791
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
Definition: iostream.c:84
#define AST_RWLIST_NEXT
Definition: linkedlists.h:441
int category
Definition: manager.c:1606
ast_mutex_t notify_lock
Definition: manager.c:1762
pthread_t waiting_thread
Definition: manager.c:1738
struct ast_iostream * stream
Definition: manager.c:1735
struct eventqent * last_ev
Definition: manager.c:1754
time_t sessiontimeout
Definition: manager.c:1742
int ast_wait_for_input(int fd, int ms)
Definition: utils.c:1698

References advance_event(), ao2_lock, ao2_unlock, ast_debug, ast_iostream_get_fd(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_RWLIST_NEXT, ast_strlen_zero(), ast_wait_for_input(), astman_append(), astman_get_header(), astman_send_response(), eventqent::category, mansession_session::last_ev, mansession_session::managerid, match_filter(), max, mansession_session::needdestroy, mansession_session::notify_lock, NULL, mansession_session::readperm, mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, mansession_session::stream, and mansession_session::waiting_thread.

Referenced by __init_manager().

◆ advance_event()

static struct eventqent * advance_event ( struct eventqent e)
static

Definition at line 2975 of file manager.c.

2976{
2977 struct eventqent *next;
2978
2980 if ((next = AST_RWLIST_NEXT(e, eq_next))) {
2983 }
2985 return next;
2986}
int usecount
Definition: manager.c:1605

References ast_atomic_fetchadd_int(), AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and eventqent::usecount.

Referenced by action_waitevent(), and process_events().

◆ AO2_GLOBAL_OBJ_STATIC() [1/2]

static AO2_GLOBAL_OBJ_STATIC ( event_docs  )
static

A container of event documentation nodes.

◆ AO2_GLOBAL_OBJ_STATIC() [2/2]

static AO2_GLOBAL_OBJ_STATIC ( mgr_sessions  )
static

Active manager connection sessions container.

◆ aocmessage_get_unit_entry()

static int aocmessage_get_unit_entry ( const struct message m,
struct ast_aoc_unit_entry entry,
unsigned int  entry_num 
)
static

Definition at line 5798 of file manager.c.

5799{
5800 const char *unitamount;
5801 const char *unittype;
5802 struct ast_str *str = ast_str_alloca(32);
5803
5804 memset(entry, 0, sizeof(*entry));
5805
5806 ast_str_set(&str, 0, "UnitAmount(%u)", entry_num);
5807 unitamount = astman_get_header(m, ast_str_buffer(str));
5808
5809 ast_str_set(&str, 0, "UnitType(%u)", entry_num);
5810 unittype = astman_get_header(m, ast_str_buffer(str));
5811
5812 if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) {
5813 entry->valid_amount = 1;
5814 }
5815
5816 if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) {
5817 entry->valid_type = 1;
5818 }
5819
5820 return 0;
5821}
const char * str
Definition: app_jack.c:147

References ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), astman_get_header(), and str.

Referenced by action_aoc_de_message().

◆ append_channel_vars()

static void append_channel_vars ( struct ast_str **  pbuf,
struct ast_channel chan 
)
static

Definition at line 7867 of file manager.c.

7868{
7869 struct varshead *vars;
7870 struct ast_var_t *var;
7871
7872 vars = ast_channel_get_manager_vars(chan);
7873 if (!vars) {
7874 return;
7875 }
7876
7877 AST_LIST_TRAVERSE(vars, var, entries) {
7878 ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", ast_channel_name(chan), var->name, var->value);
7879 }
7880 ao2_ref(vars, -1);
7881}
struct varshead * ast_channel_get_manager_vars(struct ast_channel *chan)
Gets the variables for a given channel, as specified by ast_channel_set_manager_vars().
Definition: channel.c:7983
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
struct ast_var_t::@211 entries

References ao2_ref, ast_channel_get_manager_vars(), ast_channel_name(), AST_LIST_TRAVERSE, ast_str_append(), and var.

Referenced by __manager_event_sessions_va().

◆ append_event()

static int append_event ( const char *  str,
int  category 
)
static

events are appended to a queue from where they can be dispatched to clients.

Definition at line 7843 of file manager.c.

7844{
7845 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
7846 static int seq; /* sequence number */
7847
7848 if (!tmp) {
7849 return -1;
7850 }
7851
7852 /* need to init all fields, because ast_malloc() does not */
7853 tmp->usecount = 0;
7854 tmp->category = category;
7855 tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
7856 tmp->tv = ast_tvnow();
7857 AST_RWLIST_NEXT(tmp, eq_next) = NULL;
7858 strcpy(tmp->eventdata, str);
7859
7863
7864 return 0;
7865}
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741

References ast_atomic_fetchadd_int(), ast_malloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_NEXT, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tvnow(), NULL, seq, str, and tmp().

Referenced by __init_manager(), and __manager_event_sessions_va().

◆ ast_hook_send_action()

int ast_hook_send_action ( struct manager_custom_hook hook,
const char *  msg 
)

access for hooks to send action messages to ami

Registered hooks can call this function to invoke actions and they will receive responses through registered callback.

Definition at line 3159 of file manager.c.

3160{
3161 const char *action;
3162 int ret = 0;
3163 struct manager_action *act_found;
3164 struct mansession s = {.session = NULL, };
3165 struct message m = { 0 };
3166 char *dup_str;
3167 char *src;
3168 int x = 0;
3169 int curlen;
3170
3171 if (hook == NULL) {
3172 return -1;
3173 }
3174
3175 /* Create our own copy of the AMI action msg string. */
3176 src = dup_str = ast_strdup(msg);
3177 if (!dup_str) {
3178 return -1;
3179 }
3180
3181 /* convert msg string to message struct */
3182 curlen = strlen(src);
3183 for (x = 0; x < curlen; x++) {
3184 int cr; /* set if we have \r */
3185 if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n')
3186 cr = 2; /* Found. Update length to include \r\n */
3187 else if (src[x] == '\n')
3188 cr = 1; /* also accept \n only */
3189 else
3190 continue;
3191 /* don't keep empty lines */
3192 if (x && m.hdrcount < ARRAY_LEN(m.headers)) {
3193 /* ... but trim \r\n and terminate the header string */
3194 src[x] = '\0';
3195 m.headers[m.hdrcount++] = src;
3196 }
3197 x += cr;
3198 curlen -= x; /* remaining size */
3199 src += x; /* update pointer */
3200 x = -1; /* reset loop */
3201 }
3202
3203 action = astman_get_header(&m, "Action");
3204
3205 do {
3206 if (!strcasecmp(action, "login")) {
3207 break;
3208 }
3209
3210 act_found = action_find(action);
3211 if (!act_found) {
3212 break;
3213 }
3214
3215 /*
3216 * we have to simulate a session for this action request
3217 * to be able to pass it down for processing
3218 * This is necessary to meet the previous design of manager.c
3219 */
3220 s.hook = hook;
3221
3222 ret = -1;
3223 ao2_lock(act_found);
3224 if (act_found->registered && act_found->func) {
3225 struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
3226
3227 ao2_unlock(act_found);
3228 /* If the action is in a module it must be running. */
3229 if (!act_found->module || mod_ref) {
3230 ret = act_found->func(&s, &m);
3231 ast_module_unref(mod_ref);
3232 }
3233 } else {
3234 ao2_unlock(act_found);
3235 }
3236 ao2_t_ref(act_found, -1, "done with found action object");
3237 } while (0);
3238
3239 ast_free(dup_str);
3240 return ret;
3241}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
static struct manager_action * action_find(const char *name)
Definition: manager.c:1856
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455
struct ast_module * module
Definition: manager.h:172
int(* func)(struct mansession *s, const struct message *m)
Definition: manager.h:171
unsigned int registered
TRUE if the AMI action is registered and the callback can be called.
Definition: manager.h:183
In case you didn't read that giant block of text above the mansession_session struct,...
Definition: manager.c:1777
struct manager_custom_hook * hook
Definition: manager.c:1783

References action_find(), ao2_lock, ao2_t_ref, ao2_unlock, ARRAY_LEN, ast_free, ast_module_running_ref, ast_module_unref, ast_strdup, astman_get_header(), manager_action::func, message::hdrcount, message::headers, mansession::hook, manager_action::module, NULL, manager_action::registered, and mansession::session.

Referenced by hook_send().

◆ ast_instring()

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 2264 of file manager.c.

2265{
2266 const char *val = bigstr, *next;
2267
2268 do {
2269 if ((next = strchr(val, delim))) {
2270 if (!strncmp(val, smallstr, (next - val))) {
2271 return 1;
2272 } else {
2273 continue;
2274 }
2275 } else {
2276 return !strcmp(smallstr, val);
2277 }
2278 } while (*(val = (next + 1)));
2279
2280 return 0;
2281}
Definition: ast_expr2.c:325

Referenced by get_perm().

◆ ast_manager_check_enabled()

int ast_manager_check_enabled ( void  )

Check if AMI is enabled.

Definition at line 2101 of file manager.c.

2102{
2103 return manager_enabled;
2104}
static int manager_enabled
Definition: manager.c:1620

References manager_enabled.

Referenced by handle_show_settings().

◆ ast_manager_get_message_router()

struct stasis_message_router * ast_manager_get_message_router ( void  )

Get the stasis_message_router for AMI.

Since
12
Returns
The stasis_message_router for AMI
Return values
NULLon error

Definition at line 1877 of file manager.c.

1878{
1879 return stasis_router;
1880}
static struct stasis_message_router * stasis_router
The stasis_message_router for all Stasis Message Bus API messages.
Definition: manager.c:1639

References stasis_router.

Referenced by manager_bridging_init(), manager_channels_init(), manager_mwi_init(), and manager_system_init().

◆ ast_manager_get_topic()

struct stasis_topic * ast_manager_get_topic ( void  )

Get the Stasis Message Bus API topic for AMI.

Since
12
Returns
The Stasis Message Bus API topic for AMI
Return values
NULLon error

Definition at line 1872 of file manager.c.

1873{
1874 return manager_topic;
1875}
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1636

References manager_topic.

Referenced by aoc_publish_blob(), ast_manager_publish_event(), endpoint_state_cb(), load_module(), manager_bridging_init(), manager_channels_init(), manager_mwi_init(), manager_system_init(), pbx_load_users(), publish_load_message_type(), queue_publish_member_blob(), and stasis_app_user_event().

◆ ast_manager_hangup_helper()

int ast_manager_hangup_helper ( struct mansession s,
const struct message m,
manager_hangup_handler_t  handler,
manager_hangup_cause_validator_t  cause_validator 
)

A manager helper function that hangs up a channel using a supplied channel type specific hangup function and cause code validator.

This function handles the lookup of channel(s) and the AMI interaction but uses the supplied callbacks to actually perform the hangup. It can be used to implement a custom AMI 'Hangup' action without having to duplicate all the code in the standard Hangup action.

Parameters
sSession
mMessage
handlerFunction that actually performs the hangup
cause_validatorFunction that validates the cause code
Return values
0on success.
non-zeroon error.

Definition at line 4754 of file manager.c.

4757{
4758 struct ast_channel *c = NULL;
4759 int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */
4760 const char *id = astman_get_header(m, "ActionID");
4761 const char *name_or_regex = astman_get_header(m, "Channel");
4762 const char *cause = astman_get_header(m, "Cause");
4763 char idText[256];
4764 regex_t regexbuf;
4765 struct ast_channel_iterator *iter = NULL;
4766 struct ast_str *regex_string;
4767 int channels_matched = 0;
4768
4769 if (ast_strlen_zero(name_or_regex)) {
4770 astman_send_error(s, m, "No channel specified");
4771 return 0;
4772 }
4773
4774 if (!ast_strlen_zero(id)) {
4775 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
4776 } else {
4777 idText[0] = '\0';
4778 }
4779
4780 if (cause_validator) {
4781 causecode = cause_validator(name_or_regex, cause);
4782 } else if (!ast_strlen_zero(cause)) {
4783 char *endptr;
4784 causecode = strtol(cause, &endptr, 10);
4785 if (causecode < 0 || causecode > 127 || *endptr != '\0') {
4786 ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause);
4787 /* keep going, better to hangup without cause than to not hang up at all */
4788 causecode = 0; /* do not set channel's hangupcause */
4789 }
4790 }
4791
4792 /************************************************/
4793 /* Regular explicit match channel byname hangup */
4794
4795 if (name_or_regex[0] != '/') {
4796 if (!(c = ast_channel_get_by_name(name_or_regex))) {
4797 ast_log(LOG_NOTICE, "Request to hangup non-existent channel: %s\n",
4798 name_or_regex);
4799 astman_send_error(s, m, "No such channel");
4800 return 0;
4801 }
4802
4803 ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
4804 (s->session->managerid ? "HTTP " : ""),
4805 s->session->username,
4808
4809 hangup_handler(c, causecode);
4811
4812 astman_send_ack(s, m, "Channel Hungup");
4813
4814 return 0;
4815 }
4816
4817 /***********************************************/
4818 /* find and hangup any channels matching regex */
4819
4820 regex_string = ast_str_create(strlen(name_or_regex));
4821 if (!regex_string) {
4822 astman_send_error(s, m, "Memory Allocation Failure");
4823 return 0;
4824 }
4825
4826 /* Make "/regex/" into "regex" */
4827 if (ast_regex_string_to_regex_pattern(name_or_regex, &regex_string) != 0) {
4828 astman_send_error(s, m, "Regex format invalid, Channel param should be /regex/");
4829 ast_free(regex_string);
4830 return 0;
4831 }
4832
4833 /* if regex compilation fails, hangup fails */
4834 if (regcomp(&regexbuf, ast_str_buffer(regex_string), REG_EXTENDED | REG_NOSUB)) {
4835 astman_send_error_va(s, m, "Regex compile failed on: %s", name_or_regex);
4836 ast_free(regex_string);
4837 return 0;
4838 }
4839
4840 astman_send_listack(s, m, "Channels hung up will follow", "start");
4841
4843 if (iter) {
4844 for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
4845 if (regexec(&regexbuf, ast_channel_name(c), 0, NULL, 0)) {
4846 continue;
4847 }
4848
4849 ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
4850 (s->session->managerid ? "HTTP " : ""),
4851 s->session->username,
4854
4855 hangup_handler(c, causecode);
4856 channels_matched++;
4857
4858 astman_append(s,
4859 "Event: ChannelHungup\r\n"
4860 "Channel: %s\r\n"
4861 "%s"
4862 "\r\n", ast_channel_name(c), idText);
4863 }
4865 }
4866
4867 regfree(&regexbuf);
4868 ast_free(regex_string);
4869
4870 astman_send_list_complete(s, m, "ChannelsHungupListComplete", channels_matched);
4871
4872 return 0;
4873}
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str **regex_pattern)
Given a string regex_string in the form of "/regex/", convert it into the form of "regex".
Definition: utils.c:2179

References mansession_session::addr, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_name(), ast_channel_unref, ast_free, ast_log, ast_regex_string_to_regex_pattern(), ast_sockaddr_stringify_addr(), ast_str_buffer(), ast_str_create, ast_strlen_zero(), ast_verb, astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), astman_send_error_va(), astman_send_list_complete(), astman_send_listack(), c, LOG_NOTICE, mansession_session::managerid, NULL, mansession::session, and mansession_session::username.

Referenced by action_hangup(), and pjsip_action_hangup().

◆ ast_manager_publish_event()

void ast_manager_publish_event ( const char *  type,
int  class_type,
struct ast_json obj 
)

Publish an event to AMI.

Since
12
Parameters
typeThe type of AMI event to publish
class_typeThe class on which to publish the event
objThe event data to be published.

Publishes a message to the Stasis Message Bus API message bus solely for the consumption of AMI. The message will be of the type provided by ast_manager_get_generic_type, and will be published to the topic provided by ast_manager_get_topic. As such, the JSON must be constructed as defined by the ast_manager_get_generic_type message.

Definition at line 2055 of file manager.c.

2056{
2057 RAII_VAR(struct ast_json *, event_info, NULL, ast_json_unref);
2058 RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
2060
2061 if (!obj || !ast_manager_get_generic_type()) {
2062 return;
2063 }
2064
2065 ast_json_ref(obj);
2066 event_info = ast_json_pack("{s: s, s: i, s: o}",
2067 "type", type,
2068 "class_type", class_type,
2069 "event", obj);
2070 if (!event_info) {
2071 return;
2072 }
2073
2074 payload = ast_json_payload_create(event_info);
2075 if (!payload) {
2076 return;
2077 }
2079 if (!message) {
2080 return;
2081 }
2083}
static const char type[]
Definition: chan_ooh323.c:109
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
Definition: manager.c:1872
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json_payload * ast_json_payload_create(struct ast_json *json)
Create an ao2 object to pass json blobs as data payloads for stasis.
Definition: json.c:756
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511
Abstract JSON element (object, array, string, int, ...).

References ao2_cleanup, ast_json_pack(), ast_json_payload_create(), ast_json_ref(), ast_json_unref(), ast_manager_get_generic_type(), ast_manager_get_topic(), NULL, RAII_VAR, stasis_message_create(), stasis_publish(), and type.

Referenced by analog_publish_channel_alarm_clear(), analog_publish_dnd_state(), publish_channel_alarm(), publish_channel_alarm_clear(), publish_dnd_state(), publish_fully_booted(), publish_span_alarm(), publish_span_alarm_clear(), really_quit(), and reset_user_pw().

◆ ast_manager_register2()

int ast_manager_register2 ( const char *  action,
int  auth,
int(*)(struct mansession *s, const struct message *m)  func,
struct ast_module module,
const char *  synopsis,
const char *  description 
)

register a new command with manager, including online help. This is the preferred way to register a manager command

Register a manager command with the manager interface.

Definition at line 8167 of file manager.c.

8168{
8169 struct manager_action *cur;
8170
8171 cur = ao2_t_alloc(sizeof(*cur), action_destroy, action);
8172 if (!cur) {
8173 return -1;
8174 }
8175 if (ast_string_field_init(cur, 128)) {
8176 ao2_t_ref(cur, -1, "action object creation failed");
8177 return -1;
8178 }
8179
8180 cur->action = action;
8181 cur->authority = auth;
8182 cur->func = func;
8183 cur->module = module;
8184#ifdef AST_XML_DOCS
8186 char *tmpxml;
8187
8188 tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
8189 ast_string_field_set(cur, synopsis, tmpxml);
8190 ast_free(tmpxml);
8191
8192 tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
8193 ast_string_field_set(cur, syntax, tmpxml);
8194 ast_free(tmpxml);
8195
8196 tmpxml = ast_xmldoc_build_description("manager", action, NULL);
8197 ast_string_field_set(cur, description, tmpxml);
8198 ast_free(tmpxml);
8199
8200 tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
8201 ast_string_field_set(cur, seealso, tmpxml);
8202 ast_free(tmpxml);
8203
8204 tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
8205 ast_string_field_set(cur, arguments, tmpxml);
8206 ast_free(tmpxml);
8207
8210
8211 cur->docsrc = AST_XML_DOC;
8212 } else
8213#endif
8214 {
8217#ifdef AST_XML_DOCS
8218 cur->docsrc = AST_STATIC_DOC;
8219#endif
8220 }
8221 if (ast_manager_register_struct(cur)) {
8222 ao2_t_ref(cur, -1, "action object registration failed");
8223 return -1;
8224 }
8225
8226 ao2_t_ref(cur, -1, "action object registration successful");
8227 return 0;
8228}
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:407
static char * synopsis
Definition: func_enum.c:154
static int ast_manager_register_struct(struct manager_action *act)
Definition: manager.c:8112
static void action_destroy(void *obj)
Definition: manager.c:8153
const ast_string_field description
Definition: manager.h:163
enum ast_doc_src docsrc
Definition: manager.h:174
const ast_string_field seealso
Definition: manager.h:163
const ast_string_field syntax
Definition: manager.h:163
const ast_string_field arguments
Definition: manager.h:163
struct ast_xml_doc_item * ast_xmldoc_build_list_responses(const char *type, const char *name, const char *module)
Generate the [list responses] tag based on type of node ('application', 'function' or 'agi') and name...
Definition: xmldoc.c:2484
char * ast_xmldoc_build_description(const char *type, const char *name, const char *module)
Generate description documentation from XML.
Definition: xmldoc.c:2271
char * ast_xmldoc_build_syntax(const char *type, const char *name, const char *module)
Get the syntax for a specified application or function.
Definition: xmldoc.c:1252
char * ast_xmldoc_build_arguments(const char *type, const char *name, const char *module)
Generate the [arguments] tag based on type of node ('application', 'function' or 'agi') and name.
Definition: xmldoc.c:2084
char * ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
Generate synopsis documentation from XML.
Definition: xmldoc.c:2248
@ AST_XML_DOC
Definition: xmldoc.h:31
@ AST_STATIC_DOC
Definition: xmldoc.h:32
char * ast_xmldoc_build_seealso(const char *type, const char *name, const char *module)
Parse the <see-also> node content.
Definition: xmldoc.c:1702
struct ast_xml_doc_item * ast_xmldoc_build_final_response(const char *type, const char *name, const char *module)
Generate the [final response] tag based on type of node ('application', 'function' or 'agi') and name...
Definition: xmldoc.c:2554

References manager_action::action, action_destroy(), ao2_t_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_final_response(), ast_xmldoc_build_list_responses(), ast_xmldoc_build_seealso(), ast_xmldoc_build_synopsis(), ast_xmldoc_build_syntax(), manager_action::authority, manager_action::docsrc, manager_action::final_response, manager_action::func, manager_action::list_responses, manager_action::module, NULL, and synopsis.

◆ ast_manager_register_hook()

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

Parameters
hookstruct manager_custom_hook object to add

Definition at line 2086 of file manager.c.

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by create_test_dialplan(), and register_hook().

◆ ast_manager_register_struct()

static int ast_manager_register_struct ( struct manager_action act)
static

Definition at line 8112 of file manager.c.

8113{
8114 struct manager_action *cur, *prev = NULL;
8115
8117 AST_RWLIST_TRAVERSE(&actions, cur, list) {
8118 int ret;
8119
8120 ret = strcasecmp(cur->action, act->action);
8121 if (ret == 0) {
8122 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
8124 return -1;
8125 }
8126 if (ret > 0) { /* Insert these alphabetically */
8127 break;
8128 }
8129 prev = cur;
8130 }
8131
8132 ao2_t_ref(act, +1, "action object added to list");
8133 act->registered = 1;
8134 if (prev) {
8135 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
8136 } else {
8137 AST_RWLIST_INSERT_HEAD(&actions, act, list);
8138 }
8139
8140 ast_verb(5, "Manager registered action %s\n", act->action);
8141
8143
8144 return 0;
8145}
#define LOG_WARNING
#define AST_RWLIST_INSERT_AFTER
Definition: linkedlists.h:702
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:718

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, NULL, ast_category::prev, and manager_action::registered.

Referenced by ast_manager_register2().

◆ ast_manager_str_from_json_object()

struct ast_str * ast_manager_str_from_json_object ( struct ast_json blob,
key_exclusion_cb  exclusion_cb 
)

Convert a JSON object into an AMI compatible string.

Since
12
Parameters
blobThe JSON blob containing key/value pairs to convert
exclusion_cbA key_exclusion_cb pointer to a function that will exclude keys from the final AMI string
Returns
A malloc'd ast_str object. Callers of this function should free the returned ast_str object
Return values
NULLon error

Definition at line 1973 of file manager.c.

1974{
1975 struct ast_str *res = ast_str_create(1024);
1976
1977 if (!ast_json_is_null(blob)) {
1978 manager_json_to_ast_str(blob, NULL, &res, exclusion_cb);
1979 }
1980
1981 return res;
1982}
static void manager_json_to_ast_str(struct ast_json *obj, const char *key, struct ast_str **res, key_exclusion_cb exclusion_cb)
Definition: manager.c:1932
int ast_json_is_null(const struct ast_json *value)
Check if value is JSON null.
Definition: json.c:273

References ast_json_is_null(), ast_str_create, manager_json_to_ast_str(), and NULL.

Referenced by agi_channel_to_ami(), aoc_to_ami(), manager_generic_msg_cb(), multi_user_event_to_ami(), mwi_app_event_cb(), queue_channel_to_ami(), queue_member_to_ami(), and queue_multi_channel_to_ami().

◆ ast_manager_unregister()

int ast_manager_unregister ( const char *  action)

support functions to register/unregister AMI action handlers,

Unregister a registered manager command.

Definition at line 8041 of file manager.c.

8042{
8043 struct manager_action *cur;
8044
8047 if (!strcasecmp(action, cur->action)) {
8049 break;
8050 }
8051 }
8054
8055 if (cur) {
8056 /*
8057 * We have removed the action object from the container so we
8058 * are no longer in a hurry.
8059 */
8060 ao2_lock(cur);
8061 cur->registered = 0;
8062 ao2_unlock(cur);
8063
8064 ao2_t_ref(cur, -1, "action object removed from list");
8065 ast_verb(5, "Manager unregistered action %s\n", action);
8066 }
8067
8068 return 0;
8069}
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617

References manager_action::action, ao2_lock, ao2_t_ref, ao2_unlock, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and manager_action::registered.

Referenced by __unload_module(), ast_res_pjsip_cleanup_options_handling(), ast_res_pjsip_destroy_configuration(), ast_sip_destroy_sorcery_auth(), ast_sip_destroy_sorcery_location(), astdb_atexit(), bridge_cleanup(), load_module(), local_shutdown(), manager_bridging_cleanup(), manager_shutdown(), message_shutdown(), unload_module(), unload_parking_manager(), and unload_pbx().

◆ ast_manager_unregister_hook()

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

Parameters
hookstruct manager_custom_hook object to delete

Definition at line 2094 of file manager.c.

2095{
2097 AST_RWLIST_REMOVE(&manager_hooks, hook, list);
2099}
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:885

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by register_hook(), unload_module(), and unregister_hook().

◆ ast_webmanager_check_enabled()

int ast_webmanager_check_enabled ( void  )

Check if AMI/HTTP is enabled.

Definition at line 2106 of file manager.c.

2107{
2109}
static int webmanager_enabled
Definition: manager.c:1622

References manager_enabled, and webmanager_enabled.

Referenced by action_coresettings(), and handle_show_settings().

◆ astman_append()

void astman_append ( struct mansession s,
const char *  fmt,
  ... 
)

utility functions for creating AMI replies

Definition at line 3302 of file manager.c.

3303{
3304 int res;
3305 va_list ap;
3306 struct ast_str *buf;
3307
3309 return;
3310 }
3311
3312 va_start(ap, fmt);
3313 res = ast_str_set_va(&buf, 0, fmt, ap);
3314 va_end(ap);
3315 if (res == AST_DYNSTR_BUILD_FAILED) {
3316 return;
3317 }
3318
3319 if (s->hook || (s->tcptls_session != NULL && s->tcptls_session->stream != NULL)) {
3321 } else {
3322 ast_verbose("No connection stream in astman_append, should not happen\n");
3323 }
3324}
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2206
#define ASTMAN_APPEND_BUF_INITSIZE
initial allocated size for the astman_append_buf and astman_send_*_va
Definition: manager.c:3288
static struct ast_threadstorage astman_append_buf
Definition: manager.c:3283
static int send_string(struct mansession *s, char *string)
Definition: manager.c:3247
@ AST_DYNSTR_BUILD_FAILED
Definition: strings.h:943
int ast_str_set_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Set a dynamic string from a va_list.
Definition: strings.h:1030
struct ast_iostream * stream
Definition: tcptls.h:161
struct ast_tcptls_session_instance * tcptls_session
Definition: manager.c:1780

References AST_DYNSTR_BUILD_FAILED, ast_str_buffer(), ast_str_set_va(), ast_str_thread_get(), ast_verbose(), astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, buf, mansession::hook, NULL, send_string(), ast_tcptls_session_instance::stream, and mansession::tcptls_session.

Referenced by _iax2_show_peers_one(), action_agents(), action_challenge(), action_command(), action_confbridgelist_item(), action_confbridgelistrooms(), action_coresettings(), action_coreshowchannelmap(), action_coreshowchannels(), action_corestatus(), action_dahdishowchannels(), action_dahdishowstatus(), action_devicestatelist(), action_events(), action_extensionstate(), action_extensionstatelist(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_meetmelistrooms(), action_ping(), action_presencestate(), action_presencestatelist(), action_status(), action_waitevent(), ami_outbound_registration_task(), ami_registrations_aor(), ami_show_outbound_registrations(), ami_subscription_detail(), append_vmbox_info_astman(), append_vmu_info_astman(), ast_cli_netstats(), ast_manager_hangup_helper(), ast_sip_format_contact_ami(), astman_append_json(), astman_send_list_complete_end(), do_print(), format_ami_aor_handler(), format_ami_aorlist_handler(), format_ami_auth_handler(), format_ami_authlist_handler(), format_ami_contactlist_handler(), format_ami_endpoint(), format_ami_endpoint_transport(), format_ami_endpoints(), format_ami_resource_lists(), generate_status(), manager_append_event_parking_lot_data_cb(), manager_bridge_info(), manager_bridge_tech_list(), manager_db_tree_get(), manager_dbget(), manager_fax_sessions(), manager_fax_sessions_entry(), manager_fax_stats(), manager_iax2_show_netstats(), manager_iax2_show_registry(), manager_jabber_send(), manager_mixmonitor(), manager_modulecheck(), manager_mute_mixmonitor(), manager_mutestream(), manager_parking_status_all_lots(), manager_parking_status_single_lot(), manager_queue_rule_show(), manager_queues_status(), manager_queues_summary(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_stop_mixmonitor(), mwi_mailbox_get(), send_bridge_info_item_cb(), send_bridge_list_item_cb(), send_identify_ami_event(), session_do(), and spandsp_manager_fax_session().

◆ astman_append_headers()

static void astman_append_headers ( struct message m,
const struct ast_variable params 
)
static

Append additional headers into the message structure from params.

Note
You likely want to initialize m->hdrcount to 0 before calling this.

Definition at line 3052 of file manager.c.

3053{
3054 const struct ast_variable *v;
3055
3056 for (v = params; v && m->hdrcount < ARRAY_LEN(m->headers); v = v->next) {
3057 if (ast_asprintf((char**)&m->headers[m->hdrcount], "%s: %s", v->name, v->value) > -1) {
3058 ++m->hdrcount;
3059 }
3060 }
3061}
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267

References ARRAY_LEN, ast_asprintf, message::hdrcount, message::headers, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by auth_http_callback(), and generic_http_callback().

◆ astman_append_json()

static void astman_append_json ( struct mansession s,
const char *  str 
)
static

Definition at line 4025 of file manager.c.

4026{
4027 char *buf;
4028
4029 buf = ast_alloca(2 * strlen(str) + 1);
4031 astman_append(s, "%s", buf);
4032}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
static void json_escape(char *out, const char *in)
Definition: manager.c:4007

References ast_alloca, astman_append(), buf, json_escape(), and str.

Referenced by action_getconfigjson().

◆ astman_flush()

static void astman_flush ( struct mansession s,
struct ast_str buf 
)
static

Definition at line 3290 of file manager.c.

3291{
3292 if (s->hook || (s->tcptls_session && s->tcptls_session->stream)) {
3294 } else {
3295 ast_verbose("No connection stream in astman_append, should not happen\n");
3296 }
3297}

References ast_str_buffer(), ast_verbose(), buf, mansession::hook, send_string(), ast_tcptls_session_instance::stream, and mansession::tcptls_session.

Referenced by astman_send_list_complete(), astman_send_list_complete_start(), and astman_send_response_full().

◆ astman_free_headers()

static void astman_free_headers ( struct message m)
static

Free headers inside message structure, but not the message structure itself.

Definition at line 3066 of file manager.c.

3067{
3068 while (m->hdrcount) {
3069 --m->hdrcount;
3070 ast_free((void *) m->headers[m->hdrcount]);
3071 m->headers[m->hdrcount] = NULL;
3072 }
3073}

References ast_free, message::hdrcount, message::headers, and NULL.

Referenced by auth_http_callback(), do_message(), and generic_http_callback().

◆ astman_get_header()

const char * astman_get_header ( const struct message m,
char *  var 
)

Return the first matching variable from an array.

Get header from manager transaction.

Note
This is the legacy function and is implemented in therms of __astman_get_header().
Never returns NULL.

Definition at line 3042 of file manager.c.

3043{
3045}
#define GET_HEADER_FIRST_MATCH
Definition: manager.c:2988

References __astman_get_header(), GET_HEADER_FIRST_MATCH, and var.

Referenced by action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_aoc_de_message(), action_aocmessage(), action_atxfer(), action_blind_transfer(), action_bridge(), action_cancel_atxfer(), action_challenge(), action_command(), action_confbridgekick(), action_confbridgelist(), action_confbridgelistrooms(), action_confbridgesetsinglevideosrc(), action_confbridgestartrecord(), action_confbridgestoprecord(), action_coresettings(), action_coreshowchannelmap(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), action_dahdishowstatus(), action_devicestatelist(), action_events(), action_extensionstate(), action_extensionstatelist(), action_filter(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_lock_unlock_helper(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_meetmelistrooms(), action_messagesend(), action_mute_unmute_helper(), action_originate(), action_ping(), action_presencestate(), action_presencestatelist(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), ami_register(), ami_show_aors(), ami_show_auths(), ami_show_contacts(), ami_show_endpoint(), ami_show_endpoints(), ami_show_outbound_registrations(), ami_show_registration_contact_statuses(), ami_show_registrations(), ami_show_resource_lists(), ami_show_subscriptions_inbound(), ami_show_subscriptions_outbound(), ami_sip_qualify(), ami_unregister(), aocmessage_get_unit_entry(), ast_hook_send_action(), ast_manager_hangup_helper(), astman_send_list_complete_start_common(), astman_send_response_full(), authenticate(), controlplayback_manager(), handle_manager_bridge_tech_suspend(), handle_updates(), manager_add_queue_member(), manager_bridge_destroy(), manager_bridge_info(), manager_bridge_kick(), manager_bridge_tech_list(), manager_bridges_list(), manager_change_priority_caller_on_queue(), manager_db_tree_get(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_dialplan_extension_add(), manager_dialplan_extension_remove(), manager_fax_session(), manager_fax_sessions(), manager_fax_stats(), manager_get_mailbox_summary(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_jabber_send(), manager_list_voicemail_users(), manager_match_mailbox(), manager_mixmonitor(), manager_modulecheck(), manager_moduleload(), manager_mute_mixmonitor(), manager_mutestream(), manager_notify(), manager_notify_endpoint(), manager_notify_uri(), manager_optimize_away(), manager_park(), manager_parking_lot_list(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_play_mf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_member_ringinuse(), manager_queue_reload(), manager_queue_reset(), manager_queue_rule_show(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_request_withdraw_caller_from_queue(), manager_send_flash(), manager_show_dialplan(), manager_status_voicemail_user(), manager_stop_mixmonitor(), manager_voicemail_forward(), manager_voicemail_move(), manager_voicemail_remove(), meetmemute(), mwi_mailbox_delete(), mwi_mailbox_get(), mwi_mailbox_update(), process_message(), sorcery_memory_cache_ami_expire(), sorcery_memory_cache_ami_expire_object(), sorcery_memory_cache_ami_populate(), sorcery_memory_cache_ami_stale(), and sorcery_memory_cache_ami_stale_object().

◆ astman_get_variables()

struct ast_variable * astman_get_variables ( const struct message m)

Get a linked list of the Variable: headers.

Note
Order of variables is reversed from the order they are specified in the manager message

Definition at line 3128 of file manager.c.

3129{
3131}
struct ast_variable * astman_get_variables_order(const struct message *m, enum variable_orders order)
Get a linked list of the Variable: headers with order specified.
Definition: manager.c:3133
@ ORDER_REVERSE
Definition: manager.h:289

References astman_get_variables_order(), and ORDER_REVERSE.

Referenced by action_originate().

◆ astman_get_variables_order()

struct ast_variable * astman_get_variables_order ( const struct message m,
enum variable_orders  order 
)

Get a linked list of the Variable: headers with order specified.

Definition at line 3133 of file manager.c.

3135{
3136 int varlen;
3137 int x;
3138 struct ast_variable *head = NULL;
3139
3140 static const char var_hdr[] = "Variable:";
3141
3142 /* Process all "Variable:" headers. */
3143 varlen = strlen(var_hdr);
3144 for (x = 0; x < m->hdrcount; x++) {
3145 if (strncasecmp(var_hdr, m->headers[x], varlen)) {
3146 continue;
3147 }
3148 head = man_do_variable_value(head, m->headers[x] + varlen);
3149 }
3150
3151 if (order == ORDER_NATURAL) {
3152 head = ast_variables_reverse(head);
3153 }
3154
3155 return head;
3156}
integer order
Definition: analys.c:66
static struct ast_variable * man_do_variable_value(struct ast_variable *head, const char *hdr_val)
Definition: manager.c:3084
struct ast_variable * ast_variables_reverse(struct ast_variable *var)
Reverse a variable list.
Definition: main/config.c:565
@ ORDER_NATURAL
Definition: manager.h:288

References ast_variables_reverse(), message::hdrcount, message::headers, man_do_variable_value(), NULL, order, and ORDER_NATURAL.

Referenced by action_messagesend(), astman_get_variables(), manager_notify_channel(), manager_notify_endpoint(), and manager_notify_uri().

◆ astman_live_dangerously()

void astman_live_dangerously ( int  new_live_dangerously)

Enable/disable the inclusion of 'dangerous' configurations outside of the ast_config_AST_CONFIG_DIR.

This function can globally enable/disable the loading of configuration files outside of ast_config_AST_CONFIG_DIR.

Parameters
new_live_dangerouslyIf true, enable the access of files outside ast_config_AST_CONFIG_DIR from astman.

Definition at line 3842 of file manager.c.

3843{
3844 if (new_live_dangerously && !live_dangerously)
3845 {
3846 ast_log(LOG_WARNING, "Manager Configuration load protection disabled.\n");
3847 }
3848
3849 if (!new_live_dangerously && live_dangerously)
3850 {
3851 ast_log(LOG_NOTICE, "Manager Configuration load protection enabled.\n");
3852 }
3853 live_dangerously = new_live_dangerously;
3854}
static int live_dangerously
Set to true (non-zero) to globally allow all dangerous AMI actions to run.
Definition: manager.c:1650

References ast_log, live_dangerously, LOG_NOTICE, and LOG_WARNING.

Referenced by load_asterisk_conf().

◆ astman_send_ack()

void astman_send_ack ( struct mansession s,
const struct message m,
char *  msg 
)

Send ack in manager transaction.

Definition at line 3413 of file manager.c.

3414{
3415 astman_send_response_full(s, m, "Success", msg, NULL);
3416}

References astman_send_response_full(), and NULL.

Referenced by action_add_agi_cmd(), action_agent_logoff(), action_aocmessage(), action_atxfer(), action_blind_transfer(), action_bridge(), action_cancel_atxfer(), action_confbridgekick(), action_confbridgesetsinglevideosrc(), action_confbridgestartrecord(), action_confbridgestoprecord(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_filter(), action_lock_unlock_helper(), action_loggerrotate(), action_login(), action_messagesend(), action_mute_unmute_helper(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), ami_register(), ami_sip_qualify(), ami_unregister(), ast_manager_hangup_helper(), controlplayback_manager(), handle_manager_bridge_tech_suspend(), manager_add_queue_member(), manager_bridge_destroy(), manager_bridge_kick(), manager_change_priority_caller_on_queue(), manager_dbdel(), manager_dbdeltree(), manager_dbput(), manager_dialplan_extension_add(), manager_dialplan_extension_remove(), manager_fax_session(), manager_fax_stats(), manager_get_mailbox_summary(), manager_jabber_send(), manager_list_voicemail_users(), manager_moduleload(), manager_optimize_away(), manager_park_bridged(), manager_park_unbridged(), manager_pause_queue_member(), manager_play_dtmf(), manager_play_mf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_member_ringinuse(), manager_queue_reload(), manager_queue_reset(), manager_remove_queue_member(), manager_request_withdraw_caller_from_queue(), manager_send_flash(), manager_send_response(), manager_status_voicemail_user(), manager_voicemail_forward(), manager_voicemail_move(), manager_voicemail_refresh(), manager_voicemail_remove(), meetmemute(), mwi_mailbox_delete(), mwi_mailbox_update(), sorcery_memory_cache_ami_expire(), sorcery_memory_cache_ami_expire_object(), sorcery_memory_cache_ami_populate(), sorcery_memory_cache_ami_stale(), and sorcery_memory_cache_ami_stale_object().

◆ astman_send_error()

void astman_send_error ( struct mansession s,
const struct message m,
char *  error 
)

Send error in manager transaction.

Definition at line 3381 of file manager.c.

3382{
3383 astman_send_response_full(s, m, "Error", error, NULL);
3384}
int error(const char *format,...)
Definition: utils/frame.c:999

References astman_send_response_full(), error(), and NULL.

Referenced by action_add_agi_cmd(), action_agent_logoff(), action_aoc_de_message(), action_aoc_s_message(), action_aoc_s_submessage(), action_aocmessage(), action_atxfer(), action_blind_transfer(), action_bridge(), action_cancel_atxfer(), action_challenge(), action_command(), action_confbridgekick(), action_confbridgelist(), action_confbridgelistrooms(), action_confbridgesetsinglevideosrc(), action_confbridgestartrecord(), action_confbridgestoprecord(), action_coreshowchannelmap(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_dahdishowstatus(), action_devicestatelist(), action_events(), action_extensionstate(), action_extensionstatelist(), action_filter(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_lock_unlock_helper(), action_loggerrotate(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_meetmelistrooms(), action_messagesend(), action_mute_unmute_helper(), action_originate(), action_presencestate(), action_presencestatelist(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), ami_register(), ami_show_aors(), ami_show_auths(), ami_show_contacts(), ami_show_endpoints(), ami_show_outbound_registrations(), ami_show_resource_lists(), ami_sip_qualify(), ami_unregister(), ast_manager_hangup_helper(), controlplayback_manager(), do_message(), handle_manager_bridge_tech_suspend(), handle_parse_error(), manager_add_queue_member(), manager_bridge_destroy(), manager_bridge_info(), manager_bridge_kick(), manager_bridge_tech_list(), manager_bridges_list(), manager_change_priority_caller_on_queue(), manager_db_tree_get(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_dialplan_extension_add(), manager_dialplan_extension_remove(), manager_fax_session(), manager_get_mailbox_summary(), manager_jabber_send(), manager_mixmonitor(), manager_modulecheck(), manager_moduleload(), manager_mute_mixmonitor(), manager_mutestream(), manager_notify(), manager_optimize_away(), manager_park(), manager_park_bridged(), manager_park_unbridged(), manager_parking_lot_list(), manager_parking_status_all_lots(), manager_parking_status_single_lot(), manager_pause_queue_member(), manager_play_dtmf(), manager_play_mf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_member_ringinuse(), manager_queue_reload(), manager_queue_reset(), manager_remove_queue_member(), manager_request_withdraw_caller_from_queue(), manager_send_flash(), manager_send_response(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_status_voicemail_user(), manager_stop_mixmonitor(), manager_voicemail_forward(), manager_voicemail_move(), manager_voicemail_remove(), meetmemute(), mwi_mailbox_delete(), mwi_mailbox_get(), mwi_mailbox_update(), process_message(), sorcery_memory_cache_ami_expire(), sorcery_memory_cache_ami_expire_object(), sorcery_memory_cache_ami_populate(), sorcery_memory_cache_ami_stale(), and sorcery_memory_cache_ami_stale_object().

◆ astman_send_error_va()

void astman_send_error_va ( struct mansession s,
const struct message m,
const char *  fmt,
  ... 
)

Send error in manager transaction (with va_args support)

Definition at line 3386 of file manager.c.

3387{
3388 int res;
3389 va_list ap;
3390 struct ast_str *buf;
3391 char *msg;
3392
3394 return;
3395 }
3396
3397 va_start(ap, fmt);
3398 res = ast_str_set_va(&buf, 0, fmt, ap);
3399 va_end(ap);
3400 if (res == AST_DYNSTR_BUILD_FAILED) {
3401 return;
3402 }
3403
3404 /* astman_append will use the same underlying buffer, so copy the message out
3405 * before sending the response */
3406 msg = ast_str_buffer(buf);
3407 if (msg) {
3408 msg = ast_strdupa(msg);
3409 }
3410 astman_send_response_full(s, m, "Error", msg, NULL);
3411}

References AST_DYNSTR_BUILD_FAILED, ast_str_buffer(), ast_str_set_va(), ast_str_thread_get(), ast_strdupa, astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, astman_send_response_full(), buf, and NULL.

Referenced by action_command(), action_originate(), action_presencestate(), ami_show_endpoint(), ast_manager_hangup_helper(), ast_sip_create_ami_event(), format_ami_endpoint_transport(), manager_notify_endpoint(), manager_notify_uri(), manager_send_response(), mwi_mailbox_delete(), mwi_mailbox_get(), and mwi_mailbox_update().

◆ astman_send_list_complete()

static void astman_send_list_complete ( struct mansession s,
const struct message m,
const char *  event_name,
int  count 
)
static

Definition at line 3450 of file manager.c.

3451{
3452 struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
3453 if (buf) {
3454 ast_str_append(&buf, 0, "\r\n");
3455 astman_flush(s, buf);
3456 }
3457}
static void astman_flush(struct mansession *s, struct ast_str *buf)
Definition: manager.c:3290
static struct ast_str * astman_send_list_complete_start_common(struct mansession *s, const struct message *m, const char *event_name, int count)
Definition: manager.c:3428

References ast_str_append(), astman_flush(), astman_send_list_complete_start_common(), and buf.

Referenced by action_coreshowchannels(), and ast_manager_hangup_helper().

◆ astman_send_list_complete_end()

void astman_send_list_complete_end ( struct mansession s)

End the list complete event.

Since
13.2.0
Parameters
s- AMI session control struct.
Note
You need to call astman_send_list_complete_start() to start the AMI list completion event.
Between calling astman_send_list_complete_start() and astman_send_list_complete_end() you can add additonal headers using astman_append().

Definition at line 3467 of file manager.c.

3468{
3469 astman_append(s, "\r\n");
3470}

References astman_append().

Referenced by action_agents(), action_confbridgelist(), action_confbridgelistrooms(), action_coreshowchannelmap(), action_dahdishowchannels(), action_dahdishowstatus(), action_devicestatelist(), action_extensionstatelist(), action_meetmelist(), action_meetmelistrooms(), action_presencestatelist(), action_status(), ami_show_aors(), ami_show_auths(), ami_show_contacts(), ami_show_endpoint(), ami_show_endpoints(), ami_show_outbound_registrations(), ami_show_registration_contact_statuses(), ami_show_registrations(), ami_show_resource_lists(), ami_show_subscriptions_inbound(), ami_show_subscriptions_outbound(), append_vmbox_info_astman(), manager_bridge_info(), manager_bridge_tech_list(), manager_bridges_list(), manager_db_tree_get(), manager_dbget(), manager_fax_sessions(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_list_voicemail_users(), manager_parking_lot_list(), manager_parking_status_all_lots(), manager_parking_status_single_lot(), manager_queues_status(), manager_queues_summary(), manager_show_dialplan(), manager_status_voicemail_user(), and mwi_mailbox_get().

◆ astman_send_list_complete_start()

void astman_send_list_complete_start ( struct mansession s,
const struct message m,
const char *  event_name,
int  count 
)

Start the list complete event.

Since
13.2.0
Parameters
s- AMI session control struct.
m- AMI action request that started the list.
event_name- AMI list complete event name.
count- Number of items in the list.
Note
You need to call astman_send_list_complete_end() to end the AMI list completion event.
Between calling astman_send_list_complete_start() and astman_send_list_complete_end() you can add additonal headers using astman_append().

Definition at line 3459 of file manager.c.

3460{
3461 struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
3462 if (buf) {
3463 astman_flush(s, buf);
3464 }
3465}

References astman_flush(), astman_send_list_complete_start_common(), and buf.

Referenced by action_agents(), action_confbridgelist(), action_confbridgelistrooms(), action_coreshowchannelmap(), action_dahdishowchannels(), action_dahdishowstatus(), action_devicestatelist(), action_extensionstatelist(), action_meetmelist(), action_meetmelistrooms(), action_presencestatelist(), action_status(), ami_show_aors(), ami_show_auths(), ami_show_contacts(), ami_show_endpoint(), ami_show_endpoints(), ami_show_outbound_registrations(), ami_show_registration_contact_statuses(), ami_show_registrations(), ami_show_resource_lists(), ami_show_subscriptions_inbound(), ami_show_subscriptions_outbound(), append_vmbox_info_astman(), manager_bridge_info(), manager_bridge_tech_list(), manager_bridges_list(), manager_db_tree_get(), manager_dbget(), manager_fax_sessions(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_list_voicemail_users(), manager_parking_lot_list(), manager_parking_status_all_lots(), manager_parking_status_single_lot(), manager_queues_status(), manager_queues_summary(), manager_show_dialplan(), manager_status_voicemail_user(), and mwi_mailbox_get().

◆ astman_send_list_complete_start_common()

static struct ast_str * astman_send_list_complete_start_common ( struct mansession s,
const struct message m,
const char *  event_name,
int  count 
)
static

Definition at line 3428 of file manager.c.

3429{
3430 const char *id = astman_get_header(m, "ActionID");
3431 struct ast_str *buf;
3432
3434 if (!buf) {
3435 return NULL;
3436 }
3437
3438 ast_str_set(&buf, 0, "Event: %s\r\n", event_name);
3439 if (!ast_strlen_zero(id)) {
3440 ast_str_append(&buf, 0, "ActionID: %s\r\n", id);
3441 }
3442 ast_str_append(&buf, 0,
3443 "EventList: Complete\r\n"
3444 "ListItems: %d\r\n",
3445 count);
3446
3447 return buf;
3448}

References ast_str_append(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, astman_get_header(), buf, and NULL.

Referenced by astman_send_list_complete(), and astman_send_list_complete_start().

◆ astman_send_listack()

void astman_send_listack ( struct mansession s,
const struct message m,
char *  msg,
char *  listflag 
)

Send ack in manager transaction to begin a list.

Parameters
s- AMI session control struct.
m- AMI action request that started the list.
msg- Message contents describing the list to follow.
listflag- Should always be set to "start".
Note
You need to call astman_send_list_complete_start() and astman_send_list_complete_end() to send the AMI list completion event.

Definition at line 3423 of file manager.c.

3424{
3425 astman_send_response_full(s, m, "Success", msg, listflag);
3426}

References astman_send_response_full().

Referenced by action_agents(), action_confbridgelist(), action_confbridgelistrooms(), action_coreshowchannelmap(), action_coreshowchannels(), action_dahdishowchannels(), action_dahdishowstatus(), action_devicestatelist(), action_extensionstatelist(), action_meetmelist(), action_meetmelistrooms(), action_presencestatelist(), action_status(), ami_show_aors(), ami_show_auths(), ami_show_contacts(), ami_show_endpoint(), ami_show_endpoints(), ami_show_outbound_registrations(), ami_show_registration_contact_statuses(), ami_show_registrations(), ami_show_resource_lists(), ami_show_subscriptions_inbound(), ami_show_subscriptions_outbound(), append_vmbox_info_astman(), ast_manager_hangup_helper(), manager_bridge_info(), manager_bridge_tech_list(), manager_bridges_list(), manager_db_tree_get(), manager_dbget(), manager_dpsendack(), manager_fax_sessions(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_list_voicemail_users(), manager_parking_lot_list(), manager_parking_status_all_lots(), manager_parking_status_single_lot(), manager_queues_status(), manager_queues_summary(), manager_status_voicemail_user(), and mwi_mailbox_get().

◆ astman_send_response()

void astman_send_response ( struct mansession s,
const struct message m,
char *  resp,
char *  msg 
)

Send response in manager transaction.

Definition at line 3376 of file manager.c.

3377{
3378 astman_send_response_full(s, m, resp, msg, NULL);
3379}

References astman_send_response_full(), and NULL.

Referenced by action_logoff(), and action_waitevent().

◆ astman_send_response_full()

static void astman_send_response_full ( struct mansession s,
const struct message m,
char *  resp,
char *  msg,
char *  listflag 
)
static

send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field.

Use the explicit constant MSG_MOREDATA to remove the empty line. XXX MSG_MOREDATA should go to a header file.

Definition at line 3345 of file manager.c.

3346{
3347 const char *id = astman_get_header(m, "ActionID");
3348 struct ast_str *buf;
3349
3351 if (!buf) {
3352 return;
3353 }
3354
3355 ast_str_set(&buf, 0, "Response: %s\r\n", resp);
3356
3357 if (!ast_strlen_zero(id)) {
3358 ast_str_append(&buf, 0, "ActionID: %s\r\n", id);
3359 }
3360
3361 if (listflag) {
3362 /* Start, complete, cancelled */
3363 ast_str_append(&buf, 0, "EventList: %s\r\n", listflag);
3364 }
3365
3366 if (msg != MSG_MOREDATA) {
3367 if (msg) {
3368 ast_str_append(&buf, 0, "Message: %s\r\n", msg);
3369 }
3370 ast_str_append(&buf, 0, "\r\n");
3371 }
3372
3373 astman_flush(s, buf);
3374}

References ast_str_append(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, astman_flush(), astman_get_header(), buf, and MSG_MOREDATA.

Referenced by action_command(), astman_send_ack(), astman_send_error(), astman_send_error_va(), astman_send_listack(), astman_send_response(), and astman_start_ack().

◆ astman_start_ack()

static void astman_start_ack ( struct mansession s,
const struct message m 
)
static

◆ authenticate()

static int authenticate ( struct mansession s,
const struct message m 
)
static

Definition at line 3727 of file manager.c.

3728{
3729 const char *username = astman_get_header(m, "Username");
3730 const char *password = astman_get_header(m, "Secret");
3731 int error = -1;
3732 struct ast_manager_user *user = NULL;
3733 regex_t *regex_filter;
3734 struct ao2_iterator filter_iter;
3735
3736 if (ast_strlen_zero(username)) { /* missing username */
3737 return -1;
3738 }
3739
3740 /* locate user in locked state */
3742
3743 if (!(user = get_manager_by_name_locked(username))) {
3744 report_invalid_user(s, username);
3745 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
3746 } else if (user->acl && (ast_apply_acl(user->acl, &s->session->addr, "Manager User ACL: ") == AST_SENSE_DENY)) {
3747 report_failed_acl(s, username);
3748 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
3749 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
3750 const char *key = astman_get_header(m, "Key");
3751 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
3752 int x;
3753 int len = 0;
3754 char md5key[256] = "";
3755 struct MD5Context md5;
3756 unsigned char digest[16];
3757
3758 MD5Init(&md5);
3759 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
3760 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
3761 MD5Final(digest, &md5);
3762 for (x = 0; x < 16; x++)
3763 len += sprintf(md5key + len, "%02hhx", digest[x]);
3764 if (!strcmp(md5key, key)) {
3765 error = 0;
3766 } else {
3767 report_failed_challenge_response(s, key, md5key);
3768 }
3769 } else {
3770 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n",
3771 S_OR(s->session->challenge, ""));
3772 }
3773 } else if (user->secret) {
3774 if (!strcmp(password, user->secret)) {
3775 error = 0;
3776 } else {
3777 report_inval_password(s, username);
3778 }
3779 }
3780
3781 if (error) {
3782 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
3784 return -1;
3785 }
3786
3787 /* auth complete */
3788
3789 /* All of the user parameters are copied to the session so that in the event
3790 * of a reload and a configuration change, the session parameters are not
3791 * changed. */
3792 ast_copy_string(s->session->username, username, sizeof(s->session->username));
3793 s->session->readperm = user->readperm;
3794 s->session->writeperm = user->writeperm;
3795 s->session->writetimeout = user->writetimeout;
3796 if (user->chanvars) {
3797 s->session->chanvars = ast_variables_dup(user->chanvars);
3798 }
3799
3800 filter_iter = ao2_iterator_init(user->whitefilters, 0);
3801 while ((regex_filter = ao2_iterator_next(&filter_iter))) {
3802 ao2_t_link(s->session->whitefilters, regex_filter, "add white user filter to session");
3803 ao2_t_ref(regex_filter, -1, "remove iterator ref");
3804 }
3805 ao2_iterator_destroy(&filter_iter);
3806
3807 filter_iter = ao2_iterator_init(user->blackfilters, 0);
3808 while ((regex_filter = ao2_iterator_next(&filter_iter))) {
3809 ao2_t_link(s->session->blackfilters, regex_filter, "add black user filter to session");
3810 ao2_t_ref(regex_filter, -1, "remove iterator ref");
3811 }
3812 ao2_iterator_destroy(&filter_iter);
3813
3814 s->session->sessionstart = time(NULL);
3816 set_eventmask(s, astman_get_header(m, "Events"));
3817
3819
3821 return 0;
3822}
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition: acl.c:799
@ AST_SENSE_DENY
Definition: acl.h:37
#define ao2_t_link(container, obj, tag)
Definition: astobj2.h:1534
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_md5.c:52
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:2457
static void report_invalid_user(const struct mansession *s, const char *username)
Definition: manager.c:3507
static void report_failed_acl(const struct mansession *s, const char *username)
Definition: manager.c:3532
static void report_failed_challenge_response(const struct mansession *s, const char *response, const char *expected_response)
Definition: manager.c:3665
static void report_inval_password(const struct mansession *s, const char *username)
Definition: manager.c:3557
static void report_auth_success(const struct mansession *s)
Definition: manager.c:3582
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
Definition: md5.c:72
void MD5Init(struct MD5Context *context)
Definition: md5.c:57
void MD5Final(unsigned char digest[16], struct MD5Context *context)
Definition: md5.c:120
Definition: md5.h:26
user descriptor, as read from the config file.
Definition: manager.c:1796
struct timeval sessionstart_tv
Definition: manager.c:1741
time_t sessionstart
Definition: manager.c:1740
structure to hold users read from users.conf
list of users found in the config file

References mansession_session::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_t_link, ao2_t_ref, ast_apply_acl(), ast_copy_string(), ast_debug, ast_log, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, AST_SENSE_DENY, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_tvnow(), ast_variables_dup(), astman_get_header(), mansession_session::blackfilters, mansession_session::challenge, mansession_session::chanvars, error(), get_manager_by_name_locked(), len(), LOG_NOTICE, md5(), MD5Final(), MD5Init(), MD5Update(), NULL, 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::username, mansession_session::whitefilters, mansession_session::writeperm, and mansession_session::writetimeout.

Referenced by action_login().

◆ authority_to_str()

static const char * authority_to_str ( int  authority,
struct ast_str **  res 
)
static

Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be returned.

Definition at line 2236 of file manager.c.

2237{
2238 int i;
2239 char *sep = "";
2240
2241 ast_str_reset(*res);
2242 if (authority != EVENT_FLAG_SHUTDOWN) {
2243 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
2244 if (authority & perms[i].num) {
2245 ast_str_append(res, 0, "%s%s", sep, perms[i].label);
2246 sep = ",";
2247 }
2248 }
2249 }
2250
2251 if (ast_str_strlen(*res) == 0) {
2252 /* replace empty string with something sensible */
2253 ast_str_append(res, 0, "<none>");
2254 }
2255
2256 return ast_str_buffer(*res);
2257}

References ARRAY_LEN, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), EVENT_FLAG_SHUTDOWN, and perms.

Referenced by __manager_event_sessions_va(), action_listcommands(), action_login(), and handle_showmancmd().

◆ blackfilter_cmp_fn()

static int blackfilter_cmp_fn ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 6689 of file manager.c.

6690{
6691 regex_t *regex_filter = obj;
6692 const char *eventdata = arg;
6693 int *result = data;
6694
6695 if (!regexec(regex_filter, eventdata, 0, NULL, 0)) {
6696 *result = 0;
6697 return (CMP_MATCH | CMP_STOP);
6698 }
6699
6700 *result = 1;
6701 return 0;
6702}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028

References CMP_MATCH, CMP_STOP, NULL, and result.

Referenced by match_filter().

◆ build_mansession()

static struct mansession_session * build_mansession ( const struct ast_sockaddr addr)
static

Allocate manager session structure and add it to the list of sessions.

Definition at line 2381 of file manager.c.

2382{
2383 struct ao2_container *sessions;
2384 struct mansession_session *newsession;
2385
2386 newsession = ao2_alloc(sizeof(*newsession), session_destructor);
2387 if (!newsession) {
2388 return NULL;
2389 }
2390
2393 if (!newsession->whitefilters || !newsession->blackfilters) {
2394 ao2_ref(newsession, -1);
2395 return NULL;
2396 }
2397
2398 newsession->waiting_thread = AST_PTHREADT_NULL;
2399 newsession->writetimeout = 100;
2400 newsession->send_events = -1;
2401 ast_sockaddr_copy(&newsession->addr, addr);
2402
2403 ast_mutex_init(&newsession->notify_lock);
2404
2405 sessions = ao2_global_obj_ref(mgr_sessions);
2406 if (sessions) {
2407 ao2_link(sessions, newsession);
2408 ao2_ref(sessions, -1);
2409 }
2410
2411 return newsession;
2412}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void session_destructor(void *obj)
Definition: manager.c:2350
#define ast_mutex_init(pmutex)
Definition: lock.h:186
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167

References mansession_session::addr, ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, ao2_global_obj_ref, ao2_link, ao2_ref, ast_mutex_init, AST_PTHREADT_NULL, ast_sockaddr_copy(), mansession_session::blackfilters, mansession_session::notify_lock, NULL, mansession_session::send_events, session_destructor(), sessions, mansession_session::waiting_thread, mansession_session::whitefilters, and mansession_session::writetimeout.

Referenced by auth_http_callback(), generic_http_callback(), and session_do().

◆ check_blacklist()

static int check_blacklist ( const char *  cmd)
static

Definition at line 5566 of file manager.c.

5567{
5568 char *cmd_copy, *cur_cmd;
5569 char *cmd_words[AST_MAX_CMD_LEN] = { NULL, };
5570 int i;
5571
5572 cmd_copy = ast_strdupa(cmd);
5573 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
5574 cur_cmd = ast_strip(cur_cmd);
5575 if (ast_strlen_zero(cur_cmd)) {
5576 i--;
5577 continue;
5578 }
5579
5580 cmd_words[i] = cur_cmd;
5581 }
5582
5583 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
5584 int j, match = 1;
5585
5586 for (j = 0; command_blacklist[i].words[j]; j++) {
5587 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
5588 match = 0;
5589 break;
5590 }
5591 }
5592
5593 if (match) {
5594 return 1;
5595 }
5596 }
5597
5598 return 0;
5599}
#define AST_MAX_CMD_LEN
Definition: cli.h:48
static const struct @371 command_blacklist[]
#define MAX_BLACKLIST_CMD_LEN
Descriptor for a manager session, either on the AMI socket or over HTTP.
Definition: manager.c:1674
const char * words[AST_MAX_CMD_LEN]
Definition: manager.c:1676
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223

References ARRAY_LEN, AST_MAX_CMD_LEN, ast_strdupa, ast_strip(), ast_strlen_zero(), command_blacklist, match(), MAX_BLACKLIST_CMD_LEN, NULL, strsep(), and words.

Referenced by action_command().

◆ check_manager_session_inuse()

static int check_manager_session_inuse ( const char *  name)
static

Definition at line 2434 of file manager.c.

2435{
2436 struct ao2_container *sessions;
2438 int inuse = 0;
2439
2440 sessions = ao2_global_obj_ref(mgr_sessions);
2441 if (sessions) {
2442 session = ao2_find(sessions, (char *) name, 0);
2443 ao2_ref(sessions, -1);
2444 if (session) {
2446 inuse = 1;
2447 }
2448 }
2449 return inuse;
2450}
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736

References ao2_find, ao2_global_obj_ref, ao2_ref, mansession_session::inuse, name, session, sessions, and unref_mansession().

Referenced by process_message().

◆ coreshowchannelmap_add_connected_channels()

static int coreshowchannelmap_add_connected_channels ( struct ao2_container channel_map,
struct ast_channel_snapshot channel_snapshot,
struct ast_bridge_snapshot bridge_snapshot 
)
static

Recursive function to get all channels in a bridge. Follow local channels as well.

Definition at line 7074 of file manager.c.

7076{
7077 int res = 0;
7078 struct ao2_iterator iter;
7079 char *current_channel_uid;
7080
7081 iter = ao2_iterator_init(bridge_snapshot->channels, 0);
7082 while ((current_channel_uid = ao2_iterator_next(&iter))) {
7083 struct ast_channel_snapshot *current_channel_snapshot;
7084 int add_channel_res;
7085
7086 /* Don't add the original channel to the list - it's either already in there,
7087 * or it's the channel we want the map for */
7088 if (!strcmp(current_channel_uid, channel_snapshot->base->uniqueid)) {
7089 ao2_ref(current_channel_uid, -1);
7090 continue;
7091 }
7092
7093 current_channel_snapshot = ast_channel_snapshot_get_latest(current_channel_uid);
7094 if (!current_channel_snapshot) {
7095 ast_debug(5, "Unable to get channel snapshot\n");
7096 ao2_ref(current_channel_uid, -1);
7097 continue;
7098 }
7099
7100 add_channel_res = coreshowchannelmap_add_to_map(channel_map, current_channel_snapshot->base->name);
7101 if (add_channel_res) {
7102 res = 1;
7103 ao2_ref(current_channel_snapshot, -1);
7104 ao2_ref(current_channel_uid, -1);
7105 break;
7106 }
7107
7108 /* If this is a local channel that we haven't seen yet, let's go ahead and find out what else is connected to it */
7109 if (ast_begins_with(current_channel_snapshot->base->name, "Local")) {
7110 struct ast_channel_snapshot *other_local_snapshot;
7111 struct ast_bridge_snapshot *other_bridge_snapshot;
7112 int size = strlen(current_channel_snapshot->base->name);
7113 char other_local[size + 1];
7114
7115 /* Don't copy the trailing number - set it to 1 or 2, whichever one it currently is not */
7116 ast_copy_string(other_local, current_channel_snapshot->base->name, size);
7117 other_local[size - 1] = ast_ends_with(current_channel_snapshot->base->name, "1") ? '2' : '1';
7118 other_local[size] = '\0';
7119
7120 other_local_snapshot = ast_channel_snapshot_get_latest_by_name(other_local);
7121 if (!other_local_snapshot) {
7122 ast_debug(5, "Unable to get other local channel snapshot\n");
7123 ao2_ref(current_channel_snapshot, -1);
7124 ao2_ref(current_channel_uid, -1);
7125 continue;
7126 }
7127
7128 if (coreshowchannelmap_add_to_map(channel_map, other_local_snapshot->base->name)) {
7129 res = 1;
7130 ao2_ref(current_channel_snapshot, -1);
7131 ao2_ref(current_channel_uid, -1);
7132 ao2_ref(other_local_snapshot, -1);
7133 break;
7134 }
7135
7136 other_bridge_snapshot = ast_bridge_get_snapshot_by_uniqueid(other_local_snapshot->bridge->id);
7137 if (other_bridge_snapshot) {
7138 res = coreshowchannelmap_add_connected_channels(channel_map, other_local_snapshot, other_bridge_snapshot);
7139 }
7140
7141 ao2_ref(current_channel_snapshot, -1);
7142 ao2_ref(current_channel_uid, -1);
7143 ao2_ref(other_local_snapshot, -1);
7144 ao2_ref(other_bridge_snapshot, -1);
7145
7146 if (res) {
7147 break;
7148 }
7149 }
7150 }
7151 ao2_iterator_destroy(&iter);
7152
7153 return res;
7154}
static int coreshowchannelmap_add_to_map(struct ao2_container *c, const char *s)
Helper function to add a channel name to the vector.
Definition: manager.c:7057
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
static int force_inline attribute_pure ast_ends_with(const char *str, const char *suffix)
Checks whether a string ends with another.
Definition: strings.h:116
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition: strings.h:97
struct ao2_container * channels
Definition: bridge.h:331
const ast_string_field uniqueid
const ast_string_field name

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_begins_with(), ast_bridge_get_snapshot_by_uniqueid(), ast_channel_snapshot_get_latest(), ast_channel_snapshot_get_latest_by_name(), ast_copy_string(), ast_debug, ast_ends_with(), ast_channel_snapshot::base, ast_channel_snapshot::bridge, ast_bridge_snapshot::channels, coreshowchannelmap_add_connected_channels(), coreshowchannelmap_add_to_map(), ast_channel_snapshot_bridge::id, ast_channel_snapshot_base::name, and ast_channel_snapshot_base::uniqueid.

Referenced by action_coreshowchannelmap(), and coreshowchannelmap_add_connected_channels().

◆ coreshowchannelmap_add_to_map()

static int coreshowchannelmap_add_to_map ( struct ao2_container c,
const char *  s 
)
static

Helper function to add a channel name to the vector.

Definition at line 7057 of file manager.c.

7058{
7059 char *str;
7060
7061 str = ast_strdup(s);
7062 if (!str) {
7063 ast_log(LOG_ERROR, "Unable to append channel to channel map\n");
7064 return 1;
7065 }
7066
7067 /* If this is a duplicate, it will be ignored */
7069
7070 return 0;
7071}
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
Definition: strings.c:205

References ast_log, ast_str_container_add(), ast_strdup, c, LOG_ERROR, and str.

Referenced by coreshowchannelmap_add_connected_channels().

◆ destroy_fast_originate_helper()

static void destroy_fast_originate_helper ( struct fast_originate_helper doomed)
static

◆ do_message()

static int do_message ( struct mansession s)
static

Definition at line 7624 of file manager.c.

7625{
7626 struct message m = { 0 };
7627 char header_buf[sizeof(s->session->inbuf)] = { '\0' };
7628 int res;
7629 int hdr_loss;
7630 time_t now;
7631
7632 hdr_loss = 0;
7633 for (;;) {
7634 /* Check if any events are pending and do them if needed */
7635 if (process_events(s)) {
7636 res = -1;
7637 break;
7638 }
7639 res = get_input(s, header_buf);
7640 if (res == 0) {
7641 /* No input line received. */
7642 if (!s->session->authenticated) {
7643 if (time(&now) == -1) {
7644 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
7645 res = -1;
7646 break;
7647 }
7648
7649 if (now - s->session->authstart > authtimeout) {
7650 if (displayconnects) {
7651 ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_sockaddr_stringify_addr(&s->session->addr), authtimeout);
7652 }
7653 res = -1;
7654 break;
7655 }
7656 }
7657 continue;
7658 } else if (res > 0) {
7659 /* Input line received. */
7660 if (ast_strlen_zero(header_buf)) {
7661 if (hdr_loss) {
7662 mansession_lock(s);
7663 astman_send_error(s, &m, "Too many lines in message or allocation failure");
7665 res = 0;
7666 } else {
7667 switch (s->parsing) {
7668 case MESSAGE_OKAY:
7669 res = process_message(s, &m) ? -1 : 0;
7670 break;
7672 handle_parse_error(s, &m, "Failed to parse message: line too long");
7673 res = 0;
7674 break;
7675 }
7676 }
7677 break;
7678 } else if (m.hdrcount < ARRAY_LEN(m.headers)) {
7679 m.headers[m.hdrcount] = ast_strdup(header_buf);
7680 if (!m.headers[m.hdrcount]) {
7681 /* Allocation failure. */
7682 hdr_loss = 1;
7683 } else {
7684 ++m.hdrcount;
7685 }
7686 } else {
7687 /* Too many lines in message. */
7688 hdr_loss = 1;
7689 }
7690 } else {
7691 /* Input error. */
7692 break;
7693 }
7694 }
7695
7697
7698 return res;
7699}
static int process_message(struct mansession *s, const struct message *m)
Process an AMI message, performing desired action. Return 0 on success, -1 on error that require the ...
Definition: manager.c:7375
static void astman_free_headers(struct message *m)
Free headers inside message structure, but not the message structure itself.
Definition: manager.c:3066
static int displayconnects
Definition: manager.c:1615
static int get_input(struct mansession *s, char *output)
Definition: manager.c:7503
static void handle_parse_error(struct mansession *s, struct message *m, char *error)
Definition: manager.c:7607
static int process_events(struct mansession *s)
Definition: manager.c:6825
static int authtimeout
Definition: manager.c:1624
char inbuf[1025]
Definition: manager.c:1748
enum mansession_message_parsing parsing
Definition: manager.c:1781

References mansession_session::addr, ARRAY_LEN, ast_log, ast_sockaddr_stringify_addr(), ast_strdup, ast_strlen_zero(), ast_verb, astman_free_headers(), astman_send_error(), mansession_session::authenticated, mansession_session::authstart, authtimeout, displayconnects, errno, get_input(), handle_parse_error(), message::hdrcount, message::headers, mansession_session::inbuf, LOG_ERROR, mansession_lock(), mansession_unlock(), MESSAGE_LINE_TOO_LONG, MESSAGE_OKAY, mansession::parsing, process_events(), process_message(), and mansession::session.

Referenced by session_do().

◆ event_filter_destructor()

static void event_filter_destructor ( void *  obj)
static

Definition at line 2344 of file manager.c.

2345{
2346 regex_t *regex_filter = obj;
2347 regfree(regex_filter);
2348}

Referenced by manager_add_filter().

◆ fast_originate()

static void * fast_originate ( void *  data)
static

Definition at line 5718 of file manager.c.

5719{
5720 struct fast_originate_helper *in = data;
5721 int res;
5722 int reason = 0;
5723 struct ast_channel *chan = NULL, *chans[1];
5724 char requested_channel[AST_CHANNEL_NAME];
5725 struct ast_assigned_ids assignedids = {
5726 .uniqueid = in->channelid,
5727 .uniqueid2 = in->otherchannelid
5728 };
5729
5730 if (!ast_strlen_zero(in->app)) {
5731 res = ast_pbx_outgoing_app(in->tech, in->cap, in->data,
5732 in->timeout, in->app, in->appdata, &reason,
5734 S_OR(in->cid_num, NULL),
5735 S_OR(in->cid_name, NULL),
5736 in->vars, in->account, &chan, &assignedids);
5737 } else {
5738 res = ast_pbx_outgoing_exten(in->tech, in->cap, in->data,
5739 in->timeout, in->context, in->exten, in->priority, &reason,
5741 S_OR(in->cid_num, NULL),
5742 S_OR(in->cid_name, NULL),
5743 in->vars, in->account, &chan, in->early_media, &assignedids);
5744 }
5745
5746 if (!chan) {
5747 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);
5748 }
5749 /* Tell the manager what happened with the channel */
5750 chans[0] = chan;
5751 if (!ast_strlen_zero(in->app)) {
5752 ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
5753 "%s"
5754 "Response: %s\r\n"
5755 "Channel: %s\r\n"
5756 "Application: %s\r\n"
5757 "Data: %s\r\n"
5758 "Reason: %d\r\n"
5759 "Uniqueid: %s\r\n"
5760 "CallerIDNum: %s\r\n"
5761 "CallerIDName: %s\r\n",
5762 in->idtext, res ? "Failure" : "Success",
5763 chan ? ast_channel_name(chan) : requested_channel,
5764 in->app, in->appdata, reason,
5765 chan ? ast_channel_uniqueid(chan) : S_OR(in->channelid, "<unknown>"),
5766 S_OR(in->cid_num, "<unknown>"),
5767 S_OR(in->cid_name, "<unknown>")
5768 );
5769 } else {
5770 ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
5771 "%s"
5772 "Response: %s\r\n"
5773 "Channel: %s\r\n"
5774 "Context: %s\r\n"
5775 "Exten: %s\r\n"
5776 "Reason: %d\r\n"
5777 "Uniqueid: %s\r\n"
5778 "CallerIDNum: %s\r\n"
5779 "CallerIDName: %s\r\n",
5780 in->idtext, res ? "Failure" : "Success",
5781 chan ? ast_channel_name(chan) : requested_channel,
5782 in->context, in->exten, reason,
5783 chan ? ast_channel_uniqueid(chan) : S_OR(in->channelid, "<unknown>"),
5784 S_OR(in->cid_num, "<unknown>"),
5785 S_OR(in->cid_name, "<unknown>")
5786 );
5787 }
5788
5789 /* Locked and ref'd by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
5790 if (chan) {
5791 ast_channel_unlock(chan);
5792 ast_channel_unref(chan);
5793 }
5795 return NULL;
5796}
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define AST_CHANNEL_NAME
Definition: channel.h:171
#define ast_manager_event_multichan(category, event, nchans, chans, contents,...)
Definition: manager.h:260
#define EVENT_FLAG_CALL
Definition: manager.h:76
int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, int early_media, const struct ast_assigned_ids *assignedids)
Synchronously or asynchronously make an outbound call and send it to a particular extension.
Definition: pbx.c:7916
FILE * in
Definition: utils/frame.c:33

References AST_CHANNEL_NAME, ast_channel_name(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_manager_event_multichan, AST_OUTGOING_WAIT, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), destroy_fast_originate_helper(), EVENT_FLAG_CALL, in, NULL, S_OR, and ast_assigned_ids::uniqueid.

Referenced by action_originate().

◆ function_capable_string_allowed_with_auths()

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 2198 of file manager.c.

2199{
2200 if (!(writepermlist & EVENT_FLAG_SYSTEM)
2201 && (
2202 strstr(evaluating, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */
2203 strstr(evaluating, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
2204 )) {
2205 return 0;
2206 }
2207 return 1;
2208}

References EVENT_FLAG_SYSTEM.

Referenced by action_getvar(), and action_status().

◆ generate_status()

static void generate_status ( struct mansession s,
struct ast_channel chan,
char **  vars,
int  varc,
int  all_variables,
char *  id_text,
int *  count 
)
static

Definition at line 4966 of file manager.c.

4967{
4968 struct timeval now;
4969 long elapsed_seconds;
4970 struct ast_bridge *bridge;
4971 RAII_VAR(struct ast_str *, variable_str, NULL, ast_free);
4972 struct ast_str *write_transpath = ast_str_alloca(256);
4973 struct ast_str *read_transpath = ast_str_alloca(256);
4974 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
4975 struct ast_party_id effective_id;
4976 int i;
4977 RAII_VAR(struct ast_channel_snapshot *, snapshot,
4979 ao2_cleanup);
4980 RAII_VAR(struct ast_str *, snapshot_str, NULL, ast_free);
4981
4982 if (!snapshot) {
4983 return;
4984 }
4985
4986 snapshot_str = ast_manager_build_channel_state_string(snapshot);
4987 if (!snapshot_str) {
4988 return;
4989 }
4990
4991 if (all_variables) {
4992 variable_str = ast_str_create(2048);
4993 } else {
4994 variable_str = ast_str_create(1024);
4995 }
4996 if (!variable_str) {
4997 return;
4998 }
4999
5000 now = ast_tvnow();
5001 elapsed_seconds = ast_tvdiff_sec(now, ast_channel_creationtime(chan));
5002
5003 /* Even if all_variables has been specified, explicitly requested variables
5004 * may be global variables or dialplan functions */
5005 for (i = 0; i < varc; i++) {
5006 char valbuf[512], *ret = NULL;
5007
5008 if (vars[i][strlen(vars[i]) - 1] == ')') {
5009 if (ast_func_read(chan, vars[i], valbuf, sizeof(valbuf)) < 0) {
5010 valbuf[0] = '\0';
5011 }
5012 ret = valbuf;
5013 } else {
5014 pbx_retrieve_variable(chan, vars[i], &ret, valbuf, sizeof(valbuf), NULL);
5015 }
5016
5017 ast_str_append(&variable_str, 0, "Variable: %s=%s\r\n", vars[i], ret);
5018 }
5019
5020 /* Walk all channel variables and add them */
5021 if (all_variables) {
5022 struct ast_var_t *variables;
5023
5025 ast_str_append(&variable_str, 0, "Variable: %s=%s\r\n",
5026 ast_var_name(variables), ast_var_value(variables));
5027 }
5028 }
5029
5030 bridge = ast_channel_get_bridge(chan);
5031 effective_id = ast_channel_connected_effective_id(chan);
5032
5033 astman_append(s,
5034 "Event: Status\r\n"
5035 "Privilege: Call\r\n"
5036 "%s"
5037 "Type: %s\r\n"
5038 "DNID: %s\r\n"
5039 "EffectiveConnectedLineNum: %s\r\n"
5040 "EffectiveConnectedLineName: %s\r\n"
5041 "TimeToHangup: %ld\r\n"
5042 "BridgeID: %s\r\n"
5043 "Application: %s\r\n"
5044 "Data: %s\r\n"
5045 "Nativeformats: %s\r\n"
5046 "Readformat: %s\r\n"
5047 "Readtrans: %s\r\n"
5048 "Writeformat: %s\r\n"
5049 "Writetrans: %s\r\n"
5050 "Callgroup: %llu\r\n"
5051 "Pickupgroup: %llu\r\n"
5052 "Seconds: %ld\r\n"
5053 "%s"
5054 "%s"
5055 "\r\n",
5056 ast_str_buffer(snapshot_str),
5057 ast_channel_tech(chan)->type,
5058 S_OR(ast_channel_dialed(chan)->number.str, ""),
5059 S_COR(effective_id.number.valid, effective_id.number.str, "<unknown>"),
5060 S_COR(effective_id.name.valid, effective_id.name.str, "<unknown>"),
5061 (long)ast_channel_whentohangup(chan)->tv_sec,
5062 bridge ? bridge->uniqueid : "",
5063 ast_channel_appl(chan),
5064 ast_channel_data(chan),
5067 ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath),
5069 ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath),
5072 (long)elapsed_seconds,
5073 ast_str_buffer(variable_str),
5074 id_text);
5075 ++*count;
5076
5077 ao2_cleanup(bridge);
5078}
const char * ast_channel_data(const struct ast_channel *chan)
struct varshead * ast_channel_varshead(struct ast_channel *chan)
struct ast_trans_pvt * ast_channel_readtrans(const struct ast_channel *chan)
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_trans_pvt * ast_channel_writetrans(const struct ast_channel *chan)
ast_group_t ast_channel_pickupgroup(const struct ast_channel *chan)
const char * ast_channel_appl(const struct ast_channel *chan)
struct timeval ast_channel_creationtime(struct ast_channel *chan)
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10534
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
ast_group_t ast_channel_callgroup(const struct ast_channel *chan)
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
Structure that contains information about a bridge.
Definition: bridge.h:349
const ast_string_field uniqueid
Definition: bridge.h:401
Information needed to identify an endpoint in a call.
Definition: channel.h:338
Number structure.
Definition: app_followme.c:154
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:73
const char * ast_translate_path_to_str(struct ast_trans_pvt *t, struct ast_str **str)
Puts a string representation of the translation path into outbuf.
Definition: translate.c:930

References ao2_cleanup, ast_channel_appl(), ast_channel_callgroup(), ast_channel_connected_effective_id(), ast_channel_creationtime(), ast_channel_data(), ast_channel_dialed(), ast_channel_get_bridge(), ast_channel_nativeformats(), ast_channel_pickupgroup(), ast_channel_readformat(), ast_channel_readtrans(), ast_channel_snapshot_get_latest(), ast_channel_tech(), ast_channel_uniqueid(), ast_channel_varshead(), ast_channel_whentohangup(), ast_channel_writeformat(), ast_channel_writetrans(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_format_get_name(), ast_free, ast_func_read(), AST_LIST_TRAVERSE, ast_manager_build_channel_state_string(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_create, ast_translate_path_to_str(), ast_tvdiff_sec(), ast_tvnow(), ast_var_name(), ast_var_value(), astman_append(), ast_party_id::name, NULL, ast_party_id::number, pbx_retrieve_variable(), RAII_VAR, S_COR, S_OR, ast_party_name::str, ast_party_number::str, type, ast_bridge::uniqueid, ast_party_name::valid, and ast_party_number::valid.

Referenced by action_status().

◆ get_input()

static int get_input ( struct mansession s,
char *  output 
)
static

Read one full line (including crlf) from the manager socket.

Note
* \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 7503 of file manager.c.

7504{
7505 int res, x;
7506 int maxlen = sizeof(s->session->inbuf) - 1;
7507 char *src = s->session->inbuf;
7508 int timeout = -1;
7509 time_t now;
7510
7511 /*
7512 * Look for \r\n within the buffer. If found, copy to the output
7513 * buffer and return, trimming the \r\n (not used afterwards).
7514 */
7515 for (x = 0; x < s->session->inlen; x++) {
7516 int cr; /* set if we have \r */
7517 if (src[x] == '\r' && x+1 < s->session->inlen && src[x + 1] == '\n') {
7518 cr = 2; /* Found. Update length to include \r\n */
7519 } else if (src[x] == '\n') {
7520 cr = 1; /* also accept \n only */
7521 } else {
7522 continue;
7523 }
7524 memmove(output, src, x); /*... but trim \r\n */
7525 output[x] = '\0'; /* terminate the string */
7526 x += cr; /* number of bytes used */
7527 s->session->inlen -= x; /* remaining size */
7528 memmove(src, src + x, s->session->inlen); /* remove used bytes */
7529 return 1;
7530 }
7531 if (s->session->inlen >= maxlen) {
7532 /* no crlf found, and buffer full - sorry, too long for us
7533 * keep the last character in case we are in the middle of a CRLF. */
7534 ast_log(LOG_WARNING, "Discarding message from %s. Line too long: %.25s...\n", ast_sockaddr_stringify_addr(&s->session->addr), src);
7535 src[0] = src[s->session->inlen - 1];
7536 s->session->inlen = 1;
7538 }
7539 res = 0;
7540 while (res == 0) {
7541 /* calculate a timeout if we are not authenticated */
7542 if (!s->session->authenticated) {
7543 if(time(&now) == -1) {
7544 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
7545 return -1;
7546 }
7547
7548 timeout = (authtimeout - (now - s->session->authstart)) * 1000;
7549 if (timeout < 0) {
7550 /* we have timed out */
7551 return 0;
7552 }
7553 }
7554
7556 if (s->session->pending_event) {
7557 s->session->pending_event = 0;
7559 return 0;
7560 }
7561 s->session->waiting_thread = pthread_self();
7563
7565
7569 }
7570 if (res < 0) {
7571 if (s->session->kicked) {
7572 ast_debug(1, "Manager session has been kicked\n");
7573 return -1;
7574 }
7575 /* If we get a signal from some other thread (typically because
7576 * there are new events queued), return 0 to notify the caller.
7577 */
7578 if (errno == EINTR || errno == EAGAIN) {
7579 return 0;
7580 }
7581 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
7582 return -1;
7583 }
7584
7585 ao2_lock(s->session);
7586 res = ast_iostream_read(s->session->stream, src + s->session->inlen, maxlen - s->session->inlen);
7587 if (res < 1) {
7588 res = -1; /* error return */
7589 } else {
7590 s->session->inlen += res;
7591 src[s->session->inlen] = '\0';
7592 res = 0;
7593 }
7594 ao2_unlock(s->session);
7595 return res;
7596}
ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count)
Read data from an iostream.
Definition: iostream.c:273
unsigned int kicked
Definition: manager.c:1761

References mansession_session::addr, ao2_lock, ao2_unlock, ast_debug, ast_iostream_get_fd(), ast_iostream_read(), ast_log, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, ast_sockaddr_stringify_addr(), ast_wait_for_input(), mansession_session::authenticated, mansession_session::authstart, authtimeout, errno, mansession_session::inbuf, mansession_session::inlen, mansession_session::kicked, LOG_ERROR, LOG_WARNING, MESSAGE_LINE_TOO_LONG, mansession_session::notify_lock, mansession::parsing, mansession_session::pending_event, mansession::session, mansession_session::stream, and mansession_session::waiting_thread.

Referenced by do_message().

◆ get_manager_by_name_locked()

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 2457 of file manager.c.

2458{
2459 struct ast_manager_user *user = NULL;
2460
2461 AST_RWLIST_TRAVERSE(&users, user, list) {
2462 if (!strcasecmp(user->username, name)) {
2463 break;
2464 }
2465 }
2466
2467 return user;
2468}
static char user[512]

References AST_RWLIST_TRAVERSE, name, NULL, and user.

Referenced by __init_manager(), auth_http_callback(), authenticate(), function_amiclient(), handle_showmanager(), manager_displayconnects(), and process_message().

◆ get_perm()

static int get_perm ( const char *  instr)
static

Definition at line 2283 of file manager.c.

2284{
2285 int x = 0, ret = 0;
2286
2287 if (!instr) {
2288 return 0;
2289 }
2290
2291 for (x = 0; x < ARRAY_LEN(perms); x++) {
2292 if (ast_instring(instr, perms[x].label, ',')) {
2293 ret |= perms[x].num;
2294 }
2295 }
2296
2297 return ret;
2298}
static int ast_instring(const char *bigstr, const char *smallstr, const char delim)
Definition: manager.c:2264

References ARRAY_LEN, ast_instring(), permalias::num, and perms.

Referenced by __init_manager(), and strings_to_mask().

◆ grab_last()

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 2115 of file manager.c.

2116{
2117 struct eventqent *ret;
2118
2121 /* the list is never empty now, but may become so when
2122 * we optimize it in the future, so be prepared.
2123 */
2124 if (ret) {
2126 }
2128 return ret;
2129}
#define AST_RWLIST_LAST
Definition: linkedlists.h:431

References ast_atomic_fetchadd_int(), AST_RWLIST_LAST, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and eventqent::usecount.

Referenced by auth_http_callback(), generic_http_callback(), and session_do().

◆ handle_kickmanconn()

static char * handle_kickmanconn ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

CLI command manager kick session.

Definition at line 2807 of file manager.c.

2808{
2809 struct ao2_container *sessions;
2811 struct ao2_iterator i;
2812 int fd = -1;
2813 int found = 0;
2814
2815 switch (cmd) {
2816 case CLI_INIT:
2817 e->command = "manager kick session";
2818 e->usage =
2819 "Usage: manager kick session <file descriptor>\n"
2820 " Kick an active Asterisk Manager Interface session\n";
2821 return NULL;
2822 case CLI_GENERATE:
2823 return NULL;
2824 }
2825
2826 if (a->argc != 4) {
2827 return CLI_SHOWUSAGE;
2828 }
2829
2830 fd = atoi(a->argv[3]);
2831 if (fd <= 0) { /* STDOUT won't be a valid AMI fd either */
2832 ast_cli(a->fd, "Invalid AMI file descriptor: %s\n", a->argv[3]);
2833 return CLI_FAILURE;
2834 }
2835
2836 sessions = ao2_global_obj_ref(mgr_sessions);
2837 if (sessions) {
2839 ao2_ref(sessions, -1);
2840 while ((session = ao2_iterator_next(&i))) {
2842 if (session->stream) {
2843 if (ast_iostream_get_fd(session->stream) == fd) {
2844 if (session->kicked) {
2845 ast_cli(a->fd, "Manager session using file descriptor %d has already been kicked\n", fd);
2848 break;
2849 }
2850 fd = ast_iostream_get_fd(session->stream);
2851 found = fd;
2852 ast_cli(a->fd, "Kicking manager session connected using file descriptor %d\n", fd);
2853 ast_mutex_lock(&session->notify_lock);
2854 session->kicked = 1;
2855 if (session->waiting_thread != AST_PTHREADT_NULL) {
2856 pthread_kill(session->waiting_thread, SIGURG);
2857 }
2858 ast_mutex_unlock(&session->notify_lock);
2861 break;
2862 }
2863 }
2866 }
2868 }
2869
2870 if (!found) {
2871 ast_cli(a->fd, "No manager session found using file descriptor %d\n", fd);
2872 }
2873 return CLI_SUCCESS;
2874}
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

References a, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli(), ast_iostream_get_fd(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, session, sessions, unref_mansession(), and ast_cli_entry::usage.

◆ handle_manager_reload()

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 2956 of file manager.c.

2957{
2958 switch (cmd) {
2959 case CLI_INIT:
2960 e->command = "manager reload";
2961 e->usage =
2962 "Usage: manager reload\n"
2963 " Reloads the manager configuration.\n";
2964 return NULL;
2965 case CLI_GENERATE:
2966 return NULL;
2967 }
2968 if (a->argc > 2) {
2969 return CLI_SHOWUSAGE;
2970 }
2971 reload_module();
2972 return CLI_SUCCESS;
2973}
static int reload_module(void)
Definition: manager.c:10482

References a, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, reload_module(), and ast_cli_entry::usage.

◆ handle_mandebug()

static char * handle_mandebug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 2624 of file manager.c.

2625{
2626 switch (cmd) {
2627 case CLI_INIT:
2628 e->command = "manager set debug [on|off]";
2629 e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n";
2630 return NULL;
2631 case CLI_GENERATE:
2632 return NULL;
2633 }
2634
2635 if (a->argc == 3) {
2636 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
2637 } else if (a->argc == 4) {
2638 if (!strcasecmp(a->argv[3], "on")) {
2639 manager_debug = 1;
2640 } else if (!strcasecmp(a->argv[3], "off")) {
2641 manager_debug = 0;
2642 } else {
2643 return CLI_SHOWUSAGE;
2644 }
2645 }
2646 return CLI_SUCCESS;
2647}

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, manager_debug, NULL, and ast_cli_entry::usage.

◆ handle_parse_error()

static void handle_parse_error ( struct mansession s,
struct message m,
char *  error 
)
static

Definition at line 7607 of file manager.c.

7608{
7609 mansession_lock(s);
7610 astman_send_error(s, m, error);
7611 s->parsing = MESSAGE_OKAY;
7613}

References astman_send_error(), error(), mansession_lock(), mansession_unlock(), MESSAGE_OKAY, and mansession::parsing.

Referenced by do_message().

◆ handle_showmanager()

static char * handle_showmanager ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 2649 of file manager.c.

2650{
2651 struct ast_manager_user *user = NULL;
2652 int l;
2653 struct ast_str *rauthority = ast_str_alloca(MAX_AUTH_PERM_STRING);
2654 struct ast_str *wauthority = ast_str_alloca(MAX_AUTH_PERM_STRING);
2655 struct ast_variable *v;
2656
2657 switch (cmd) {
2658 case CLI_INIT:
2659 e->command = "manager show user";
2660 e->usage =
2661 " Usage: manager show user <user>\n"
2662 " Display all information related to the manager user specified.\n";
2663 return NULL;
2664 case CLI_GENERATE:
2665 l = strlen(a->word);
2666 if (a->pos != 3) {
2667 return NULL;
2668 }
2670 AST_RWLIST_TRAVERSE(&users, user, list) {
2671 if (!strncasecmp(a->word, user->username, l)) {
2672 if (ast_cli_completion_add(ast_strdup(user->username))) {
2673 break;
2674 }
2675 }
2676 }
2678 return NULL;
2679 }
2680
2681 if (a->argc != 4) {
2682 return CLI_SHOWUSAGE;
2683 }
2684
2686
2687 if (!(user = get_manager_by_name_locked(a->argv[3]))) {
2688 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
2690 return CLI_SUCCESS;
2691 }
2692
2693 ast_cli(a->fd, "\n");
2694 ast_cli(a->fd,
2695 " username: %s\n"
2696 " secret: %s\n"
2697 " ACL: %s\n"
2698 " read perm: %s\n"
2699 " write perm: %s\n"
2700 " displayconnects: %s\n"
2701 "allowmultiplelogin: %s\n",
2702 S_OR(user->username, "(N/A)"),
2703 (user->secret ? "<Set>" : "(N/A)"),
2704 ((user->acl && !ast_acl_list_is_empty(user->acl)) ? "yes" : "no"),
2705 user_authority_to_str(user->readperm, &rauthority),
2706 user_authority_to_str(user->writeperm, &wauthority),
2707 (user->displayconnects ? "yes" : "no"),
2708 (user->allowmultiplelogin ? "yes" : "no"));
2709 ast_cli(a->fd, " Variables: \n");
2710 for (v = user->chanvars ; v ; v = v->next) {
2711 ast_cli(a->fd, " %s = %s\n", v->name, v->value);
2712 }
2713 if (!ast_acl_list_is_empty(user->acl)) {
2714 ast_acl_output(a->fd, user->acl, NULL);
2715 }
2716
2718
2719 return CLI_SUCCESS;
2720}
void ast_acl_output(int fd, struct ast_acl_list *acl, const char *prefix)
output an ACL to the provided fd
Definition: acl.c:1098
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Definition: acl.c:540
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2756
static const char * user_authority_to_str(int authority, struct ast_str **res)
Convert authority code to a list of options for a user. This will only display those authority codes ...
Definition: manager.c:2212

References a, ast_acl_list_is_empty(), ast_acl_output(), ast_cli(), ast_cli_completion_add(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, get_manager_by_name_locked(), MAX_AUTH_PERM_STRING, ast_variable::name, ast_variable::next, NULL, S_OR, ast_cli_entry::usage, user_authority_to_str(), and ast_variable::value.

◆ handle_showmanagers()

static char * handle_showmanagers ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 2722 of file manager.c.

2723{
2724 struct ast_manager_user *user = NULL;
2725 int count_amu = 0;
2726 switch (cmd) {
2727 case CLI_INIT:
2728 e->command = "manager show users";
2729 e->usage =
2730 "Usage: manager show users\n"
2731 " Prints a listing of all managers that are currently configured on that\n"
2732 " system.\n";
2733 return NULL;
2734 case CLI_GENERATE:
2735 return NULL;
2736 }
2737 if (a->argc != 3) {
2738 return CLI_SHOWUSAGE;
2739 }
2740
2742
2743 /* If there are no users, print out something along those lines */
2744 if (AST_RWLIST_EMPTY(&users)) {
2745 ast_cli(a->fd, "There are no manager users.\n");
2747 return CLI_SUCCESS;
2748 }
2749
2750 ast_cli(a->fd, "\nusername\n--------\n");
2751
2752 AST_RWLIST_TRAVERSE(&users, user, list) {
2753 ast_cli(a->fd, "%s\n", user->username);
2754 count_amu++;
2755 }
2756
2758
2759 ast_cli(a->fd,"-------------------\n"
2760 "%d manager users configured.\n", count_amu);
2761 return CLI_SUCCESS;
2762}

References a, 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, NULL, and ast_cli_entry::usage.

◆ handle_showmancmd()

static char * handle_showmancmd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 2492 of file manager.c.

2493{
2494 struct manager_action *cur;
2495 struct ast_str *authority;
2496 int num;
2497 int l;
2498 const char *auth_str;
2499#ifdef AST_XML_DOCS
2500 char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64];
2501 char arguments_title[64], privilege_title[64], final_response_title[64], list_responses_title[64];
2502#endif
2503
2504 switch (cmd) {
2505 case CLI_INIT:
2506 e->command = "manager show command";
2507 e->usage =
2508 "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
2509 " Shows the detailed description for a specific Asterisk manager interface command.\n";
2510 return NULL;
2511 case CLI_GENERATE:
2512 l = strlen(a->word);
2514 AST_RWLIST_TRAVERSE(&actions, cur, list) {
2515 if (!strncasecmp(a->word, cur->action, l)) {
2517 break;
2518 }
2519 }
2520 }
2522 return NULL;
2523 }
2524 if (a->argc < 4) {
2525 return CLI_SHOWUSAGE;
2526 }
2527
2529
2530#ifdef AST_XML_DOCS
2531 /* setup the titles */
2532 term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
2533 term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40);
2534 term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
2535 term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
2536 term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
2537 term_color(privilege_title, "[Privilege]\n", COLOR_MAGENTA, 0, 40);
2538 term_color(final_response_title, "[Final Response]\n", COLOR_MAGENTA, 0, 40);
2539 term_color(list_responses_title, "[List Responses]\n", COLOR_MAGENTA, 0, 40);
2540#endif
2541
2543 AST_RWLIST_TRAVERSE(&actions, cur, list) {
2544 for (num = 3; num < a->argc; num++) {
2545 if (!strcasecmp(cur->action, a->argv[num])) {
2546 auth_str = authority_to_str(cur->authority, &authority);
2547
2548#ifdef AST_XML_DOCS
2549 if (cur->docsrc == AST_XML_DOC) {
2550 char *syntax = ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1);
2551 char *synopsis = ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1);
2552 char *description = ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1);
2553 char *arguments = ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1);
2554 char *seealso = ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1);
2555 char *privilege = ast_xmldoc_printable(S_OR(auth_str, "Not available"), 1);
2556 char *responses = ast_xmldoc_printable("None", 1);
2557
2558 if (!syntax || !synopsis || !description || !arguments
2559 || !seealso || !privilege || !responses) {
2560 ast_free(syntax);
2562 ast_free(description);
2563 ast_free(arguments);
2564 ast_free(seealso);
2565 ast_free(privilege);
2566 ast_free(responses);
2567 ast_cli(a->fd, "Allocation failure.\n");
2569
2570 return CLI_FAILURE;
2571 }
2572
2573 ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s",
2574 syntax_title, syntax,
2575 synopsis_title, synopsis,
2576 description_title, description,
2577 arguments_title, arguments,
2578 seealso_title, seealso,
2579 privilege_title, privilege,
2580 list_responses_title);
2581
2582 if (!cur->list_responses) {
2583 ast_cli(a->fd, "%s\n\n", responses);
2584 } else {
2585 struct ast_xml_doc_item *temp;
2586 for (temp = cur->list_responses; temp; temp = AST_LIST_NEXT(temp, next)) {
2587 ast_cli(a->fd, "Event: %s\n", temp->name);
2588 print_event_instance(a, temp);
2589 }
2590 }
2591
2592 ast_cli(a->fd, "%s", final_response_title);
2593
2594 if (!cur->final_response) {
2595 ast_cli(a->fd, "%s\n\n", responses);
2596 } else {
2597 ast_cli(a->fd, "Event: %s\n", cur->final_response->name);
2599 }
2600
2606 ast_free(privilege);
2607 ast_free(responses);
2608 } else
2609#endif
2610 {
2611 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
2612 cur->action, cur->synopsis,
2613 auth_str,
2614 S_OR(cur->description, ""));
2615 }
2616 }
2617 }
2618 }
2620
2621 return CLI_SUCCESS;
2622}
static void print_event_instance(struct ast_cli_args *a, struct ast_xml_doc_item *instance)
Definition: manager.c:9598
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
Struct that contains the XML documentation for a particular item. Note that this is an ao2 ref counte...
Definition: xmldoc.h:56
struct ast_str * syntax
Definition: xmldoc.h:58
struct ast_xml_doc_item * next
Definition: xmldoc.h:80
struct ast_str * arguments
Definition: xmldoc.h:62
struct ast_str * description
Definition: xmldoc.h:66
const ast_string_field name
Definition: xmldoc.h:74
struct ast_str * seealso
Definition: xmldoc.h:60
#define COLOR_MAGENTA
Definition: term.h:60
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
Definition: term.c:235
char * ast_xmldoc_printable(const char *bwinput, int withcolors)
Colorize and put delimiters (instead of tags) to the xmldoc output.
Definition: xmldoc.c:241

References a, manager_action::action, manager_action::arguments, ast_xml_doc_item::arguments, ast_cli(), ast_cli_completion_add(), ast_free, AST_LIST_NEXT, 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_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, COLOR_MAGENTA, ast_cli_entry::command, manager_action::description, ast_xml_doc_item::description, manager_action::docsrc, manager_action::final_response, manager_action::list_responses, MAX_AUTH_PERM_STRING, ast_xml_doc_item::name, ast_xml_doc_item::next, NULL, print_event_instance(), S_OR, manager_action::seealso, ast_xml_doc_item::seealso, synopsis, manager_action::synopsis, manager_action::syntax, ast_xml_doc_item::syntax, term_color(), and ast_cli_entry::usage.

◆ handle_showmancmds()

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 2765 of file manager.c.

2766{
2767 struct manager_action *cur;
2768 int name_len = 1;
2769 int space_remaining;
2770#define HSMC_FORMAT " %-*.*s %-.*s\n"
2771 switch (cmd) {
2772 case CLI_INIT:
2773 e->command = "manager show commands";
2774 e->usage =
2775 "Usage: manager show commands\n"
2776 " Prints a listing of all the available Asterisk manager interface commands.\n";
2777 return NULL;
2778 case CLI_GENERATE:
2779 return NULL;
2780 }
2781
2783 AST_RWLIST_TRAVERSE(&actions, cur, list) {
2784 int incoming_len = strlen(cur->action);
2785 if (incoming_len > name_len) {
2786 name_len = incoming_len;
2787 }
2788 }
2789
2790 space_remaining = MGR_SHOW_TERMINAL_WIDTH - name_len - 4;
2791 if (space_remaining < 0) {
2792 space_remaining = 0;
2793 }
2794
2795 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, "Action", space_remaining, "Synopsis");
2796 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, "------", space_remaining, "--------");
2797
2798 AST_RWLIST_TRAVERSE(&actions, cur, list) {
2799 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, cur->action, space_remaining, cur->synopsis);
2800 }
2802
2803 return CLI_SUCCESS;
2804}
#define MGR_SHOW_TERMINAL_WIDTH
Definition: manager.c:1657
#define HSMC_FORMAT

References a, manager_action::action, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, HSMC_FORMAT, MGR_SHOW_TERMINAL_WIDTH, NULL, manager_action::synopsis, and ast_cli_entry::usage.

◆ handle_showmanconn()

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 2877 of file manager.c.

2878{
2879 struct ao2_container *sessions;
2881 time_t now = time(NULL);
2882#define HSMCONN_FORMAT1 " %-15.15s %-55.55s %-10.10s %-10.10s %-8.8s %-8.8s %-10.10s %-10.10s\n"
2883#define HSMCONN_FORMAT2 " %-15.15s %-55.55s %-10d %-10d %-8d %-8d %-10.10d %-10.10d\n"
2884 int count = 0;
2885 struct ao2_iterator i;
2886
2887 switch (cmd) {
2888 case CLI_INIT:
2889 e->command = "manager show connected";
2890 e->usage =
2891 "Usage: manager show connected\n"
2892 " Prints a listing of the users that are currently connected to the\n"
2893 "Asterisk manager interface.\n";
2894 return NULL;
2895 case CLI_GENERATE:
2896 return NULL;
2897 }
2898
2899 ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "ReadPerms", "WritePerms");
2900
2901 sessions = ao2_global_obj_ref(mgr_sessions);
2902 if (sessions) {
2904 ao2_ref(sessions, -1);
2905 while ((session = ao2_iterator_next(&i))) {
2907 ast_cli(a->fd, HSMCONN_FORMAT2, session->username,
2909 (int) (session->sessionstart),
2910 (int) (now - session->sessionstart),
2911 session->stream ? ast_iostream_get_fd(session->stream) : -1,
2912 session->inuse,
2913 session->readperm,
2914 session->writeperm);
2915 count++;
2918 }
2920 }
2921 ast_cli(a->fd, "%d users connected.\n", count);
2922
2923 return CLI_SUCCESS;
2924}
#define HSMCONN_FORMAT1
#define HSMCONN_FORMAT2

References a, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli(), ast_iostream_get_fd(), ast_sockaddr_stringify_addr(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, HSMCONN_FORMAT1, HSMCONN_FORMAT2, NULL, session, sessions, unref_mansession(), and ast_cli_entry::usage.

◆ handle_showmaneventq()

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 2928 of file manager.c.

2929{
2930 struct eventqent *s;
2931 switch (cmd) {
2932 case CLI_INIT:
2933 e->command = "manager show eventq";
2934 e->usage =
2935 "Usage: manager show eventq\n"
2936 " Prints a listing of all events pending in the Asterisk manger\n"
2937 "event queue.\n";
2938 return NULL;
2939 case CLI_GENERATE:
2940 return NULL;
2941 }
2943 AST_RWLIST_TRAVERSE(&all_events, s, eq_next) {
2944 ast_cli(a->fd, "Usecount: %d\n", s->usecount);
2945 ast_cli(a->fd, "Category: %d\n", s->category);
2946 ast_cli(a->fd, "Event:\n%s", s->eventdata);
2947 }
2949
2950 return CLI_SUCCESS;
2951}

References a, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, eventqent::category, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, NULL, ast_cli_entry::usage, and eventqent::usecount.

◆ handle_updates()

static enum error_type handle_updates ( struct mansession s,
const struct message m,
struct ast_config cfg,
const char *  dfn 
)
static

helper function for action_updateconfig

Definition at line 4108 of file manager.c.

4109{
4110 int x;
4111 char hdr[40];
4112 const char *action, *cat, *var, *value, *match, *line, *options;
4113 struct ast_variable *v;
4114 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
4115 enum error_type result = 0;
4116
4117 for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */
4118 unsigned int object = 0;
4119 char *dupoptions;
4120 int allowdups = 0;
4121 int istemplate = 0;
4122 int ignoreerror = 0;
4123 RAII_VAR(char *, inherit, NULL, ast_free);
4124 RAII_VAR(char *, catfilter, NULL, ast_free);
4125 char *token;
4126 int foundvar = 0;
4127 int foundcat = 0;
4128 struct ast_category *category = NULL;
4129
4130 snprintf(hdr, sizeof(hdr), "Action-%06d", x);
4131 action = astman_get_header(m, hdr);
4132 if (ast_strlen_zero(action)) /* breaks the for loop if no action header */
4133 break; /* this could cause problems if actions come in misnumbered */
4134
4135 snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
4136 cat = astman_get_header(m, hdr);
4137 if (ast_strlen_zero(cat)) { /* every action needs a category */
4139 break;
4140 }
4141
4142 snprintf(hdr, sizeof(hdr), "Var-%06d", x);
4143 var = astman_get_header(m, hdr);
4144
4145 snprintf(hdr, sizeof(hdr), "Value-%06d", x);
4146 value = astman_get_header(m, hdr);
4147
4148 if (!ast_strlen_zero(value) && *value == '>') {
4149 object = 1;
4150 value++;
4151 }
4152
4153 snprintf(hdr, sizeof(hdr), "Match-%06d", x);
4154 match = astman_get_header(m, hdr);
4155
4156 snprintf(hdr, sizeof(hdr), "Line-%06d", x);
4157 line = astman_get_header(m, hdr);
4158
4159 snprintf(hdr, sizeof(hdr), "Options-%06d", x);
4160 options = astman_get_header(m, hdr);
4161 if (!ast_strlen_zero(options)) {
4162 char copy[strlen(options) + 1];
4163 strcpy(copy, options); /* safe */
4164 dupoptions = copy;
4165 while ((token = ast_strsep(&dupoptions, ',', AST_STRSEP_STRIP))) {
4166 if (!strcasecmp("allowdups", token)) {
4167 allowdups = 1;
4168 continue;
4169 }
4170 if (!strcasecmp("template", token)) {
4171 istemplate = 1;
4172 continue;
4173 }
4174 if (!strcasecmp("ignoreerror", token)) {
4175 ignoreerror = 1;
4176 continue;
4177 }
4178 if (ast_begins_with(token, "inherit")) {
4179 char *c = ast_strsep(&token, '=', AST_STRSEP_STRIP);
4180 c = ast_strsep(&token, '=', AST_STRSEP_STRIP);
4181 if (c) {
4182 inherit = ast_strdup(c);
4183 }
4184 continue;
4185 }
4186 if (ast_begins_with(token, "catfilter")) {
4187 char *c = ast_strsep(&token, '=', AST_STRSEP_STRIP);
4188 c = ast_strsep(&token, '=', AST_STRSEP_STRIP);
4189 if (c) {
4190 catfilter = ast_strdup(c);
4191 }
4192 continue;
4193 }
4194 }
4195 }
4196
4197 if (!strcasecmp(action, "newcat")) {
4198 struct ast_category *template;
4199 char *tmpl_name = NULL;
4200
4201 if (!allowdups) {
4202 if (ast_category_get(cfg, cat, "TEMPLATES=include")) {
4203 if (ignoreerror) {
4204 continue;
4205 } else {
4206 result = FAILURE_NEWCAT; /* already exist */
4207 break;
4208 }
4209 }
4210 }
4211
4212 if (istemplate) {
4213 category = ast_category_new_template(cat, dfn, -1);
4214 } else {
4215 category = ast_category_new(cat, dfn, -1);
4216 }
4217
4218 if (!category) {
4220 break;
4221 }
4222
4223 if (inherit) {
4224 while ((tmpl_name = ast_strsep(&inherit, ',', AST_STRSEP_STRIP))) {
4225 if ((template = ast_category_get(cfg, tmpl_name, "TEMPLATES=restrict"))) {
4226 if (ast_category_inherit(category, template)) {
4228 break;
4229 }
4230 } else {
4231 ast_category_destroy(category);
4232 category = NULL;
4233 result = FAILURE_TEMPLATE; /* template not found */
4234 break;
4235 }
4236 }
4237 }
4238
4239 if (category != NULL) {
4240 if (ast_strlen_zero(match)) {
4241 ast_category_append(cfg, category);
4242 } else {
4243 if (ast_category_insert(cfg, category, match)) {
4244 ast_category_destroy(category);
4246 break;
4247 }
4248 }
4249 }
4250 } else if (!strcasecmp(action, "renamecat")) {
4251 if (ast_strlen_zero(value)) {
4253 break;
4254 }
4255
4256 foundcat = 0;
4257 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
4258 ast_category_rename(category, value);
4259 foundcat = 1;
4260 }
4261
4262 if (!foundcat) {
4264 break;
4265 }
4266 } else if (!strcasecmp(action, "delcat")) {
4267 foundcat = 0;
4268 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
4269 category = ast_category_delete(cfg, category);
4270 foundcat = 1;
4271 }
4272
4273 if (!foundcat && !ignoreerror) {
4275 break;
4276 }
4277 } else if (!strcasecmp(action, "emptycat")) {
4278 foundcat = 0;
4279 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
4280 ast_category_empty(category);
4281 foundcat = 1;
4282 }
4283
4284 if (!foundcat) {
4286 break;
4287 }
4288 } else if (!strcasecmp(action, "update")) {
4289 if (ast_strlen_zero(var)) {
4291 break;
4292 }
4293
4294 foundcat = 0;
4295 foundvar = 0;
4296 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
4297 if (!ast_variable_update(category, var, value, match, object)) {
4298 foundvar = 1;
4299 }
4300 foundcat = 1;
4301 }
4302
4303 if (!foundcat) {
4305 break;
4306 }
4307
4308 if (!foundvar) {
4310 break;
4311 }
4312 } else if (!strcasecmp(action, "delete")) {
4313 if ((ast_strlen_zero(var) && ast_strlen_zero(line))) {
4315 break;
4316 }
4317
4318 foundcat = 0;
4319 foundvar = 0;
4320 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
4321 if (!ast_variable_delete(category, var, match, line)) {
4322 foundvar = 1;
4323 }
4324 foundcat = 1;
4325 }
4326
4327 if (!foundcat) {
4329 break;
4330 }
4331
4332 if (!foundvar && !ignoreerror) {
4334 break;
4335 }
4336 } else if (!strcasecmp(action, "append")) {
4337 if (ast_strlen_zero(var)) {
4339 break;
4340 }
4341
4342 foundcat = 0;
4343 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
4344 if (!(v = ast_variable_new(var, value, dfn))) {
4346 break;
4347 }
4348 if (object || (match && !strcasecmp(match, "object"))) {
4349 v->object = 1;
4350 }
4351 ast_variable_append(category, v);
4352 foundcat = 1;
4353 }
4354
4355 if (!foundcat) {
4357 break;
4358 }
4359 } else if (!strcasecmp(action, "insert")) {
4360 if (ast_strlen_zero(var) || ast_strlen_zero(line)) {
4362 break;
4363 }
4364
4365 foundcat = 0;
4366 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
4367 if (!(v = ast_variable_new(var, value, dfn))) {
4369 break;
4370 }
4371 ast_variable_insert(category, v, line);
4372 foundcat = 1;
4373 }
4374
4375 if (!foundcat) {
4377 break;
4378 }
4379 }
4380 else {
4381 ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action);
4383 break;
4384 }
4385 }
4386 ast_free(str1);
4387 ast_free(str2);
4388 return result;
4389}
static int copy(char *infile, char *outfile)
Utility function to copy a file.
int ast_category_inherit(struct ast_category *existing, const struct ast_category *base)
Applies base (template) to category.
Definition: main/config.c:1456
struct ast_category * ast_category_new_template(const char *name, const char *in_file, int lineno)
Create a category making it a template.
Definition: main/config.c:1084
struct ast_category * ast_category_delete(struct ast_config *cfg, struct ast_category *cat)
Delete a category.
Definition: main/config.c:1567
void ast_category_rename(struct ast_category *cat, const char *name)
Definition: main/config.c:1451
int ast_variable_delete(struct ast_category *category, const char *variable, const char *match, const char *line)
Definition: main/config.c:1488
int ast_category_insert(struct ast_config *config, struct ast_category *cat, const char *match)
Inserts new category.
Definition: main/config.c:1172
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
Definition: extconf.c:2833
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: extconf.c:1177
int ast_variable_update(struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object)
Update variable value within a config.
Definition: main/config.c:1533
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category.
Definition: extconf.c:2788
#define ast_variable_new(name, value, filename)
void ast_category_destroy(struct ast_category *cat)
Definition: extconf.c:2845
int ast_category_empty(struct ast_category *category)
Removes and destroys all variables in a category.
Definition: main/config.c:1599
void ast_variable_insert(struct ast_category *category, struct ast_variable *variable, const char *line)
Definition: main/config.c:499
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
Definition: main/config.c:1111
@ AST_STRSEP_STRIP
Definition: strings.h:255
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835
static struct test_options options

References ast_begins_with(), ast_category_append(), ast_category_browse_filtered(), ast_category_delete(), ast_category_destroy(), ast_category_empty(), ast_category_get(), ast_category_inherit(), ast_category_insert(), ast_category_new(), ast_category_new_template(), ast_category_rename(), ast_free, ast_log, ast_str_create, ast_strdup, ast_strlen_zero(), ast_strsep(), AST_STRSEP_STRIP, ast_variable_append(), ast_variable_delete(), ast_variable_insert(), ast_variable_new, ast_variable_update(), astman_get_header(), c, copy(), FAILURE_ALLOCATION, FAILURE_NEWCAT, FAILURE_TEMPLATE, FAILURE_UPDATE, LOG_WARNING, match(), NULL, ast_variable::object, options, RAII_VAR, result, UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, UNSPECIFIED_CATEGORY, value, and var.

Referenced by action_updateconfig().

◆ json_escape()

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 4007 of file manager.c.

4008{
4009 for (; *in; in++) {
4010 if (*in == '\\' || *in == '\"') {
4011 *out++ = '\\';
4012 }
4013 *out++ = *in;
4014 }
4015 *out = '\0';
4016}
FILE * out
Definition: utils/frame.c:33

References in, and out.

Referenced by astman_append_json().

◆ log_action()

static void log_action ( const struct message m,
const char *  action 
)
static

Definition at line 7336 of file manager.c.

7337{
7338 struct ast_str *buf;
7339 int x;
7340
7341 if (!manager_debug) {
7342 return;
7343 }
7344
7345 buf = ast_str_create(256);
7346 if (!buf) {
7347 return;
7348 }
7349
7350 for (x = 0; x < m->hdrcount; ++x) {
7351 if (!strncasecmp(m->headers[x], "Secret", 6)) {
7352 ast_str_append(&buf, 0, "Secret: <redacted from logging>\n");
7353 } else {
7354 ast_str_append(&buf, 0, "%s\n", m->headers[x]);
7355 }
7356 }
7357
7358 ast_verbose("<--- Examining AMI action: -->\n%s\n", ast_str_buffer(buf));
7359 ast_free(buf);
7360}

References ast_free, ast_str_append(), ast_str_buffer(), ast_str_create, ast_verbose(), buf, message::hdrcount, message::headers, and manager_debug.

Referenced by process_message().

◆ man_do_variable_value()

static struct ast_variable * man_do_variable_value ( struct ast_variable head,
const char *  hdr_val 
)
static

Definition at line 3084 of file manager.c.

3085{
3086 char *parse;
3088 AST_APP_ARG(vars)[64];
3089 );
3090
3091 hdr_val = ast_skip_blanks(hdr_val); /* ignore leading spaces in the value */
3092 parse = ast_strdupa(hdr_val);
3093
3094 /* Break the header value string into name=val pair items. */
3096 if (args.argc) {
3097 int y;
3098
3099 /* Process each name=val pair item. */
3100 for (y = 0; y < args.argc; y++) {
3101 struct ast_variable *cur;
3102 char *var;
3103 char *val;
3104
3105 if (!args.vars[y]) {
3106 continue;
3107 }
3108 var = val = args.vars[y];
3109 strsep(&val, "=");
3110
3111 /* XXX We may wish to trim whitespace from the strings. */
3112 if (!val || ast_strlen_zero(var)) {
3113 continue;
3114 }
3115
3116 /* Create new variable list node and prepend it to the list. */
3117 cur = ast_variable_new(var, val, "");
3118 if (cur) {
3119 cur->next = head;
3120 head = cur;
3121 }
3122 }
3123 }
3124
3125 return head;
3126}
const char * args

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_skip_blanks(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_variable_new, ast_variable::next, strsep(), and var.

Referenced by astman_get_variables_order().

◆ manager_add_filter()

static enum add_filter_result manager_add_filter ( const char *  filter_pattern,
struct ao2_container whitefilters,
struct ao2_container blackfilters 
)
static

Add an event filter to a manager session.

Parameters
filter_patternFilter syntax to add, see below for syntax
whitefilters,blackfilters
Returns
FILTER_ALLOC_FAILED Memory allocation failure
FILTER_COMPILE_FAIL If the filter did not compile
FILTER_SUCCESS Success

Filter will be used to match against each line of a manager event Filter can be any valid regular expression Filter can be a valid regular expression prefixed with !, which will add the filter as a black filter

Examples:

filter_pattern = "Event: Newchannel"
filter_pattern = "Event: New.*"
filter_pattern = "!Channel: DAHDI.*"

Definition at line 6760 of file manager.c.

6760 {
6761 regex_t *new_filter = ao2_t_alloc(sizeof(*new_filter), event_filter_destructor, "event_filter allocation");
6762 int is_blackfilter;
6763
6764 if (!new_filter) {
6765 return FILTER_ALLOC_FAILED;
6766 }
6767
6768 if (filter_pattern[0] == '!') {
6769 is_blackfilter = 1;
6770 filter_pattern++;
6771 } else {
6772 is_blackfilter = 0;
6773 }
6774
6775 if (regcomp(new_filter, filter_pattern, REG_EXTENDED | REG_NOSUB)) {
6776 ao2_t_ref(new_filter, -1, "failed to make regex");
6777 return FILTER_COMPILE_FAIL;
6778 }
6779
6780 if (is_blackfilter) {
6781 ao2_t_link(blackfilters, new_filter, "link new filter into black user container");
6782 } else {
6783 ao2_t_link(whitefilters, new_filter, "link new filter into white user container");
6784 }
6785
6786 ao2_ref(new_filter, -1);
6787
6788 return FILTER_SUCCESS;
6789}
static void event_filter_destructor(void *obj)
Definition: manager.c:2344

References ao2_ref, ao2_t_alloc, ao2_t_link, ao2_t_ref, event_filter_destructor(), FILTER_ALLOC_FAILED, FILTER_COMPILE_FAIL, and FILTER_SUCCESS.

Referenced by __init_manager(), and action_filter().

◆ manager_default_msg_cb()

static void manager_default_msg_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1990 of file manager.c.

1992{
1993 struct ao2_container *sessions;
1994 struct ast_manager_event_blob *ev;
1995
1997 /* Not an AMI message; disregard */
1998 return;
1999 }
2000
2001 sessions = ao2_global_obj_ref(mgr_sessions);
2003 /* Nobody is listening */
2005 return;
2006 }
2007
2009 if (!ev) {
2010 /* Conversion failure */
2012 return;
2013 }
2014
2016 "%s", ev->extra_fields);
2017 ao2_ref(ev, -1);
2019}
#define manager_event_sessions(sessions, category, event, contents,...)
Definition: manager.c:1984
struct ast_manager_event_blob * stasis_message_to_ami(struct stasis_message *msg)
Build the AMI representation of the message.
int stasis_message_can_be_ami(struct stasis_message *msg)
Determine if the given message can be converted to AMI.
Struct containing info for an AMI event to send out.
Definition: manager.h:502
const ast_string_field extra_fields
Definition: manager.h:507
const char * manager_event
Definition: manager.h:504

References any_manager_listeners, ao2_cleanup, ao2_global_obj_ref, ao2_ref, ast_manager_event_blob::event_flags, ast_manager_event_blob::extra_fields, ast_manager_event_blob::manager_event, manager_event_sessions, sessions, stasis_message_can_be_ami(), and stasis_message_to_ami().

Referenced by manager_subscriptions_init().

◆ manager_displayconnects()

static int manager_displayconnects ( struct mansession_session session)
static

Get displayconnects config option.

Parameters
sessionmanager session to get parameter from.
Returns
displayconnects config option value.

Definition at line 2474 of file manager.c.

2475{
2476 struct ast_manager_user *user = NULL;
2477 int ret = 0;
2478
2480 if ((user = get_manager_by_name_locked(session->username))) {
2481 ret = user->displayconnects;
2482 }
2484
2485 return ret;
2486}

References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, get_manager_by_name_locked(), NULL, and session.

Referenced by action_login(), generic_http_callback(), purge_sessions(), and session_do().

◆ manager_generic_msg_cb()

static void manager_generic_msg_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 2021 of file manager.c.

2023{
2024 struct ast_json_payload *payload;
2025 int class_type;
2026 const char *type;
2027 struct ast_json *event;
2028 struct ast_str *event_buffer;
2029 struct ao2_container *sessions;
2030
2031 sessions = ao2_global_obj_ref(mgr_sessions);
2033 /* Nobody is listening */
2035 return;
2036 }
2037
2038 payload = stasis_message_data(message);
2039 class_type = ast_json_integer_get(ast_json_object_get(payload->json, "class_type"));
2040 type = ast_json_string_get(ast_json_object_get(payload->json, "type"));
2041 event = ast_json_object_get(payload->json, "event");
2042
2044 if (!event_buffer) {
2045 ast_log(AST_LOG_WARNING, "Error while creating payload for event %s\n", type);
2047 return;
2048 }
2050 "%s", ast_str_buffer(event_buffer));
2051 ast_free(event_buffer);
2053}
struct ast_str * ast_manager_str_from_json_object(struct ast_json *blob, key_exclusion_cb exclusion_cb)
Convert a JSON object into an AMI compatible string.
Definition: manager.c:1973
#define AST_LOG_WARNING
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:332
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct ast_json * json
Definition: json.h:1083

References any_manager_listeners, ao2_cleanup, ao2_global_obj_ref, ast_free, ast_json_integer_get(), ast_json_object_get(), ast_json_string_get(), ast_log, AST_LOG_WARNING, ast_manager_str_from_json_object(), ast_str_buffer(), ast_json_payload::json, manager_event_sessions, NULL, sessions, stasis_message_data(), and type.

Referenced by manager_subscriptions_init().

◆ manager_json_array_with_key()

static void manager_json_array_with_key ( struct ast_json obj,
const char *  key,
size_t  index,
struct ast_str **  res,
key_exclusion_cb  exclusion_cb 
)
static

Definition at line 1907 of file manager.c.

1910{
1911 struct ast_str *key_str = ast_str_alloca(64);
1912 ast_str_set(&key_str, 0, "%s(%zu)", key, index);
1914 res, exclusion_cb);
1915}

References ast_str_alloca, ast_str_buffer(), ast_str_set(), and manager_json_to_ast_str().

Referenced by manager_json_to_ast_str().

◆ manager_json_obj_with_key()

static void manager_json_obj_with_key ( struct ast_json obj,
const char *  key,
const char *  parent_key,
struct ast_str **  res,
key_exclusion_cb  exclusion_cb 
)
static

Definition at line 1917 of file manager.c.

1920{
1921 if (parent_key) {
1922 struct ast_str *key_str = ast_str_alloca(64);
1923 ast_str_set(&key_str, 0, "%s/%s", parent_key, key);
1925 res, exclusion_cb);
1926 return;
1927 }
1928
1929 manager_json_to_ast_str(obj, key, res, exclusion_cb);
1930}

References ast_str_alloca, ast_str_buffer(), ast_str_set(), and manager_json_to_ast_str().

Referenced by manager_json_to_ast_str().

◆ manager_json_to_ast_str()

void manager_json_to_ast_str ( struct ast_json obj,
const char *  key,
struct ast_str **  res,
key_exclusion_cb  exclusion_cb 
)
static

Definition at line 1932 of file manager.c.

1934{
1935 struct ast_json_iter *i;
1936
1937 /* If obj or res is not given, just return */
1938 if (!obj || !res) {
1939 return;
1940 }
1941
1942 if (!*res && !(*res = ast_str_create(1024))) {
1943 return;
1944 }
1945
1946 if (exclusion_cb && key && exclusion_cb(key)) {
1947 return;
1948 }
1949
1950 if (ast_json_typeof(obj) != AST_JSON_OBJECT &&
1952 manager_json_value_str_append(obj, key, res);
1953 return;
1954 }
1955
1956 if (ast_json_typeof(obj) == AST_JSON_ARRAY) {
1957 size_t j;
1958 for (j = 0; j < ast_json_array_size(obj); ++j) {
1960 key, j, res, exclusion_cb);
1961 }
1962 return;
1963 }
1964
1965 for (i = ast_json_object_iter(obj); i;
1966 i = ast_json_object_iter_next(obj, i)) {
1969 key, res, exclusion_cb);
1970 }
1971}
static void manager_json_array_with_key(struct ast_json *obj, const char *key, size_t index, struct ast_str **res, key_exclusion_cb exclusion_cb)
Definition: manager.c:1907
static void manager_json_value_str_append(struct ast_json *value, const char *key, struct ast_str **res)
Definition: manager.c:1882
static void manager_json_obj_with_key(struct ast_json *obj, const char *key, const char *parent_key, struct ast_str **res, key_exclusion_cb exclusion_cb)
Definition: manager.c:1917
struct ast_json * ast_json_object_iter_value(struct ast_json_iter *iter)
Get the value from an iterator.
Definition: json.c:455
enum ast_json_type ast_json_typeof(const struct ast_json *value)
Get the type of value.
Definition: json.c:78
struct ast_json_iter * ast_json_object_iter_next(struct ast_json *object, struct ast_json_iter *iter)
Get the next iterator.
Definition: json.c:447
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
Definition: json.c:370
struct ast_json_iter * ast_json_object_iter(struct ast_json *object)
Get an iterator pointing to the first field in a JSON object.
Definition: json.c:439
@ AST_JSON_ARRAY
Definition: json.h:165
@ AST_JSON_OBJECT
Definition: json.h:164
const char * ast_json_object_iter_key(struct ast_json_iter *iter)
Get the key from an iterator.
Definition: json.c:451
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
Definition: json.c:366
Iterator for JSON object key/values.

References AST_JSON_ARRAY, ast_json_array_get(), ast_json_array_size(), AST_JSON_OBJECT, ast_json_object_iter(), ast_json_object_iter_key(), ast_json_object_iter_next(), ast_json_object_iter_value(), ast_json_typeof(), ast_str_create, manager_json_array_with_key(), manager_json_obj_with_key(), and manager_json_value_str_append().

Referenced by ast_manager_str_from_json_object(), manager_json_array_with_key(), and manager_json_obj_with_key().

◆ manager_json_value_str_append()

static void manager_json_value_str_append ( struct ast_json value,
const char *  key,
struct ast_str **  res 
)
static

Definition at line 1882 of file manager.c.

1884{
1885 switch (ast_json_typeof(value)) {
1886 case AST_JSON_STRING:
1887 ast_str_append(res, 0, "%s: %s\r\n", key, ast_json_string_get(value));
1888 break;
1889 case AST_JSON_INTEGER:
1890 ast_str_append(res, 0, "%s: %jd\r\n", key, ast_json_integer_get(value));
1891 break;
1892 case AST_JSON_TRUE:
1893 ast_str_append(res, 0, "%s: True\r\n", key);
1894 break;
1895 case AST_JSON_FALSE:
1896 ast_str_append(res, 0, "%s: False\r\n", key);
1897 break;
1898 default:
1899 ast_str_append(res, 0, "%s: \r\n", key);
1900 break;
1901 }
1902}
@ AST_JSON_STRING
Definition: json.h:166
@ AST_JSON_FALSE
Definition: json.h:170
@ AST_JSON_INTEGER
Definition: json.h:167
@ AST_JSON_TRUE
Definition: json.h:169

References AST_JSON_FALSE, AST_JSON_INTEGER, ast_json_integer_get(), AST_JSON_STRING, ast_json_string_get(), AST_JSON_TRUE, ast_json_typeof(), ast_str_append(), and value.

Referenced by manager_json_to_ast_str().

◆ manager_modulecheck()

static int manager_modulecheck ( struct mansession s,
const struct message m 
)
static

Manager function to check if module is loaded.

Definition at line 7244 of file manager.c.

7245{
7246 const char *module = astman_get_header(m, "Module");
7247 const char *id = astman_get_header(m, "ActionID");
7248
7249 ast_debug(1, "**** ModuleCheck .so file %s\n", module);
7250 if (!ast_module_check(module)) {
7251 astman_send_error(s, m, "Module not loaded");
7252 return 0;
7253 }
7254
7255 astman_append(s, "Response: Success\r\n");
7256
7257 if (!ast_strlen_zero(id)) {
7258 astman_append(s, "ActionID: %s\r\n", id);
7259 }
7260
7261#if !defined(LOW_MEMORY)
7262 /* When we switched from subversion to git we lost the ability to
7263 * retrieve the 'ASTERISK_FILE_VERSION' from that file, but we retain
7264 * the response header here for backwards compatibility. */
7265 astman_append(s, "Version: \r\n");
7266#endif
7267
7268 astman_append(s, "\r\n");
7269
7270 return 0;
7271}
int ast_module_check(const char *name)
Check if module with the name given is loaded.
Definition: loader.c:2669

References ast_debug, ast_module_check(), ast_strlen_zero(), astman_append(), astman_get_header(), and astman_send_error().

Referenced by __init_manager().

◆ manager_moduleload()

static int manager_moduleload ( struct mansession s,
const struct message m 
)
static

Definition at line 7273 of file manager.c.

7274{
7275 int res;
7276 const char *module = astman_get_header(m, "Module");
7277 const char *loadtype = astman_get_header(m, "LoadType");
7278
7279 if (!loadtype || strlen(loadtype) == 0) {
7280 astman_send_error(s, m, "Incomplete ModuleLoad action.");
7281 }
7282 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) {
7283 astman_send_error(s, m, "Need module name");
7284 }
7285
7286 if (!strcasecmp(loadtype, "load")) {
7287 res = ast_load_resource(module);
7288 if (res) {
7289 astman_send_error(s, m, "Could not load module.");
7290 } else {
7291 astman_send_ack(s, m, "Module loaded.");
7292 }
7293 } else if (!strcasecmp(loadtype, "unload")) {
7294 res = ast_unload_resource(module, AST_FORCE_SOFT);
7295 if (res) {
7296 astman_send_error(s, m, "Could not unload module.");
7297 } else {
7298 astman_send_ack(s, m, "Module unloaded.");
7299 }
7300 } else if (!strcasecmp(loadtype, "reload")) {
7301 /* TODO: Unify the ack/error messages here with action_reload */
7302 if (!ast_strlen_zero(module)) {
7303 enum ast_module_reload_result reload_res = ast_module_reload(module);
7304
7305 switch (reload_res) {
7307 astman_send_error(s, m, "No such module.");
7308 break;
7310 astman_send_error(s, m, "Module does not support reload action.");
7311 break;
7313 astman_send_error(s, m, "An unknown error occurred");
7314 break;
7316 astman_send_error(s, m, "A reload is in progress");
7317 break;
7319 astman_send_error(s, m, "Module not initialized");
7320 break;
7323 /* Treat a queued request as success */
7324 astman_send_ack(s, m, "Module reloaded.");
7325 break;
7326 }
7327 } else {
7328 ast_module_reload(NULL); /* Reload all modules */
7329 astman_send_ack(s, m, "All modules reloaded");
7330 }
7331 } else
7332 astman_send_error(s, m, "Incomplete ModuleLoad action.");
7333 return 0;
7334}
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition: loader.c:1219
enum ast_module_load_result ast_load_resource(const char *resource_name)
Load a module.
Definition: loader.c:1824
@ AST_FORCE_SOFT
Definition: module.h:62

References AST_FORCE_SOFT, ast_load_resource(), ast_module_reload(), AST_MODULE_RELOAD_ERROR, AST_MODULE_RELOAD_IN_PROGRESS, AST_MODULE_RELOAD_NOT_FOUND, AST_MODULE_RELOAD_NOT_IMPLEMENTED, AST_MODULE_RELOAD_QUEUED, AST_MODULE_RELOAD_SUCCESS, AST_MODULE_RELOAD_UNINITIALIZED, ast_strlen_zero(), ast_unload_resource(), astman_get_header(), astman_send_ack(), astman_send_error(), and NULL.

Referenced by __init_manager().

◆ manager_state_cb()

static int manager_state_cb ( const char *  context,
const char *  exten,
struct ast_state_cb_info info,
void *  data 
)
static

Definition at line 8071 of file manager.c.

8072{
8073 /* Notify managers of change */
8074 char hint[512];
8075
8076 hint[0] = '\0';
8077 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
8078
8079 switch(info->reason) {
8081 manager_event(EVENT_FLAG_CALL, "ExtensionStatus",
8082 "Exten: %s\r\n"
8083 "Context: %s\r\n"
8084 "Hint: %s\r\n"
8085 "Status: %d\r\n"
8086 "StatusText: %s\r\n",
8087 exten,
8088 context,
8089 hint,
8090 info->exten_state,
8091 ast_extension_state2str(info->exten_state));
8092 break;
8094 manager_event(EVENT_FLAG_CALL, "PresenceStatus",
8095 "Exten: %s\r\n"
8096 "Context: %s\r\n"
8097 "Hint: %s\r\n"
8098 "Status: %s\r\n"
8099 "Subtype: %s\r\n"
8100 "Message: %s\r\n",
8101 exten,
8102 context,
8103 hint,
8104 ast_presence_state2str(info->presence_state),
8105 info->presence_subtype,
8106 info->presence_message);
8107 break;
8108 }
8109 return 0;
8110}
def info(msg)
@ AST_HINT_UPDATE_DEVICE
Definition: pbx.h:91
@ AST_HINT_UPDATE_PRESENCE
Definition: pbx.h:93

References ast_extension_state2str(), ast_get_hint(), AST_HINT_UPDATE_DEVICE, AST_HINT_UPDATE_PRESENCE, ast_presence_state2str(), voicemailpwcheck::context, EVENT_FLAG_CALL, sip_to_pjsip::info(), manager_event, and NULL.

Referenced by __init_manager().

◆ mansession_cmp_fn()

static int mansession_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 2414 of file manager.c.

2415{
2416 struct mansession_session *s = obj;
2417 char *str = arg;
2418 return !strcasecmp(s->username, str) ? CMP_MATCH : 0;
2419}

References CMP_MATCH, str, and mansession_session::username.

Referenced by __init_manager().

◆ mansession_get_transport()

static enum ast_transport mansession_get_transport ( const struct mansession s)
static

◆ mansession_lock()

static void mansession_lock ( struct mansession s)
static

Lock the 'mansession' structure.

Definition at line 3473 of file manager.c.

3474{
3475 ast_mutex_lock(&s->lock);
3476}
ast_mutex_t lock
Definition: manager.c:1784

References ast_mutex_lock, and mansession::lock.

Referenced by action_challenge(), do_message(), handle_parse_error(), and process_message().

◆ mansession_unlock()

static void mansession_unlock ( struct mansession s)
static

Unlock the 'mansession' structure.

Definition at line 3479 of file manager.c.

3480{
3482}

References ast_mutex_unlock, and mansession::lock.

Referenced by action_challenge(), do_message(), handle_parse_error(), and process_message().

◆ match_filter()

static int match_filter ( struct mansession s,
char *  eventdata 
)
static

Definition at line 6791 of file manager.c.

6792{
6793 int result = 0;
6794
6795 if (manager_debug) {
6796 ast_verbose("<-- Examining AMI event: -->\n%s\n", eventdata);
6797 } else {
6798 ast_debug(4, "Examining AMI event:\n%s\n", eventdata);
6799 }
6801 return 1; /* no filtering means match all */
6803 /* white filters only: implied black all filter processed first, then white filters */
6804 ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container");
6806 /* black filters only: implied white all filter processed first, then black filters */
6807 ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container");
6808 } else {
6809 /* white and black filters: implied black all filter processed first, then white filters, and lastly black filters */
6810 ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container");
6811 if (result) {
6812 result = 0;
6813 ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container");
6814 }
6815 }
6816
6817 return result;
6818}
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag)
ao2_callback_data() is a generic function that applies cb_fn() to all objects in a container....
Definition: astobj2.h:1721
@ OBJ_NODATA
Definition: astobj2.h:1044
static int blackfilter_cmp_fn(void *obj, void *arg, void *data, int flags)
Definition: manager.c:6689
static int whitefilter_cmp_fn(void *obj, void *arg, void *data, int flags)
Definition: manager.c:6675

References ao2_container_count(), ao2_t_callback_data, ast_debug, ast_verbose(), blackfilter_cmp_fn(), mansession_session::blackfilters, manager_debug, OBJ_NODATA, result, mansession::session, whitefilter_cmp_fn(), and mansession_session::whitefilters.

Referenced by action_waitevent(), and process_events().

◆ print_event_instance()

static void print_event_instance ( struct ast_cli_args a,
struct ast_xml_doc_item instance 
)
static

Definition at line 9598 of file manager.c.

9599{
9600 char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64];
9601
9602 term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
9603 term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40);
9604 term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
9605 term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
9606 term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
9607
9608 if (!ast_strlen_zero(ast_str_buffer(instance->synopsis))) {
9610 ast_cli(a->fd, "%s%s\n\n", synopsis_title, synopsis);
9612 }
9613 if (!ast_strlen_zero(ast_str_buffer(instance->syntax))) {
9614 char *syntax = ast_xmldoc_printable(ast_str_buffer(instance->syntax), 1);
9615 ast_cli(a->fd, "%s%s\n\n", syntax_title, syntax);
9616 ast_free(syntax);
9617 }
9618 if (!ast_strlen_zero(ast_str_buffer(instance->description))) {
9619 char *description = ast_xmldoc_printable(ast_str_buffer(instance->description), 1);
9620 ast_cli(a->fd, "%s%s\n\n", description_title, description);
9621 ast_free(description);
9622 }
9623 if (!ast_strlen_zero(ast_str_buffer(instance->arguments))) {
9624 char *arguments = ast_xmldoc_printable(ast_str_buffer(instance->arguments), 1);
9625 ast_cli(a->fd, "%s%s\n\n", arguments_title, arguments);
9626 ast_free(arguments);
9627 }
9628 if (!ast_strlen_zero(ast_str_buffer(instance->seealso))) {
9629 char *seealso = ast_xmldoc_printable(ast_str_buffer(instance->seealso), 1);
9630 ast_cli(a->fd, "%s%s\n\n", seealso_title, seealso);
9631 ast_free(seealso);
9632 }
9633}
struct ast_str * synopsis
Definition: xmldoc.h:64

References a, ast_xml_doc_item::arguments, ast_cli(), ast_free, ast_str_buffer(), ast_strlen_zero(), ast_xmldoc_printable(), COLOR_MAGENTA, ast_xml_doc_item::description, ast_xml_doc_item::seealso, synopsis, ast_xml_doc_item::synopsis, ast_xml_doc_item::syntax, and term_color().

Referenced by handle_manager_show_event(), and handle_showmancmd().

◆ process_events()

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 6825 of file manager.c.

6826{
6827 int ret = 0;
6828
6829 ao2_lock(s->session);
6830 if (s->session->stream != NULL) {
6831 struct eventqent *eqe = s->session->last_ev;
6832
6833 while ((eqe = advance_event(eqe))) {
6834 if (eqe->category == EVENT_FLAG_SHUTDOWN) {
6835 ast_debug(3, "Received CloseSession event\n");
6836 ret = -1;
6837 }
6838 if (!ret && s->session->authenticated &&
6839 (s->session->readperm & eqe->category) == eqe->category &&
6840 (s->session->send_events & eqe->category) == eqe->category) {
6841 if (match_filter(s, eqe->eventdata)) {
6842 if (send_string(s, eqe->eventdata) < 0 || s->write_error)
6843 ret = -1; /* don't send more */
6844 }
6845 }
6846 s->session->last_ev = eqe;
6847 }
6848 }
6849 ao2_unlock(s->session);
6850 return ret;
6851}
unsigned int write_error
Definition: manager.c:1782

References advance_event(), ao2_lock, ao2_unlock, ast_debug, mansession_session::authenticated, eventqent::category, EVENT_FLAG_SHUTDOWN, mansession_session::last_ev, match_filter(), NULL, mansession_session::readperm, mansession_session::send_events, send_string(), mansession::session, mansession_session::stream, and mansession::write_error.

Referenced by do_message(), and process_message().

◆ process_message()

static int process_message ( struct mansession s,
const struct message m 
)
static

Process an AMI message, performing desired action. Return 0 on success, -1 on error that require the session to be destroyed.

Definition at line 7375 of file manager.c.

7376{
7377 int ret = 0;
7378 struct manager_action *act_found;
7379 struct ast_manager_user *user = NULL;
7380 const char *username;
7381 const char *action;
7382
7383 action = __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY);
7384 if (ast_strlen_zero(action)) {
7385 report_req_bad_format(s, "NONE");
7386 mansession_lock(s);
7387 astman_send_error(s, m, "Missing action in request");
7389 return 0;
7390 }
7391
7392 log_action(m, action);
7393
7394 if (ast_shutting_down()) {
7395 ast_log(LOG_ERROR, "Unable to process manager action '%s'. Asterisk is shutting down.\n", action);
7396 mansession_lock(s);
7397 astman_send_error(s, m, "Asterisk is shutting down");
7399 return 0;
7400 }
7401
7402 if (!s->session->authenticated
7403 && strcasecmp(action, "Login")
7404 && strcasecmp(action, "Logoff")
7405 && strcasecmp(action, "Challenge")) {
7406 if (!s->session->authenticated) {
7407 report_req_not_allowed(s, action);
7408 }
7409 mansession_lock(s);
7410 astman_send_error(s, m, "Permission denied");
7412 return 0;
7413 }
7414
7415 if (!s->session->authenticated
7416 && (!strcasecmp(action, "Login")
7417 || !strcasecmp(action, "Challenge"))) {
7418 username = astman_get_header(m, "Username");
7419
7423 if (user && !user->allowmultiplelogin) {
7426 sleep(1);
7427 mansession_lock(s);
7428 astman_send_error(s, m, "Login Already In Use");
7430 return -1;
7431 }
7433 }
7434 }
7435
7436 act_found = action_find(action);
7437 if (act_found) {
7438 /* Found the requested AMI action. */
7439 int acted = 0;
7440
7441 if ((s->session->writeperm & act_found->authority)
7442 || act_found->authority == 0) {
7443 /* We have the authority to execute the action. */
7444 ret = -1;
7445 ao2_lock(act_found);
7446 if (act_found->registered && act_found->func) {
7447 struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
7448
7449 ao2_unlock(act_found);
7450 if (mod_ref || !act_found->module) {
7451 ast_debug(1, "Running action '%s'\n", act_found->action);
7452 ret = act_found->func(s, m);
7453 acted = 1;
7454 ast_module_unref(mod_ref);
7455 }
7456 } else {
7457 ao2_unlock(act_found);
7458 }
7459 }
7460 if (!acted) {
7461 /*
7462 * We did not execute the action because access was denied, it
7463 * was no longer registered, or no action was really registered.
7464 * Complain about it and leave.
7465 */
7466 report_req_not_allowed(s, action);
7467 mansession_lock(s);
7468 astman_send_error(s, m, "Permission denied");
7470 }
7471 ao2_t_ref(act_found, -1, "done with found action object");
7472 } else {
7473 char buf[512];
7474
7475 report_req_bad_format(s, action);
7476 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
7477 mansession_lock(s);
7478 astman_send_error(s, m, buf);
7480 }
7481 if (ret) {
7482 return ret;
7483 }
7484 /* Once done with our message, deliver any pending events unless the
7485 requester doesn't want them as part of this response.
7486 */
7487 if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) {
7488 return process_events(s);
7489 } else {
7490 return ret;
7491 }
7492}
int ast_shutting_down(void)
Definition: asterisk.c:1872
static void log_action(const struct message *m, const char *action)
Definition: manager.c:7336
static int check_manager_session_inuse(const char *name)
Definition: manager.c:2434
static void report_req_not_allowed(const struct mansession *s, const char *action)
Definition: manager.c:3607
static void report_session_limit(const struct mansession *s)
Definition: manager.c:3695
static void report_req_bad_format(const struct mansession *s, const char *action)
Definition: manager.c:3636
char username[80]
Definition: manager.c:1797

References __astman_get_header(), manager_action::action, action_find(), ao2_lock, ao2_t_ref, ao2_unlock, ast_debug, ast_log, ast_module_running_ref, ast_module_unref, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_shutting_down(), ast_strlen_zero(), astman_get_header(), astman_send_error(), mansession_session::authenticated, manager_action::authority, buf, check_manager_session_inuse(), manager_action::func, GET_HEADER_SKIP_EMPTY, get_manager_by_name_locked(), log_action(), LOG_ERROR, mansession_lock(), mansession_unlock(), manager_action::module, NULL, process_events(), manager_action::registered, report_req_bad_format(), report_req_not_allowed(), report_session_limit(), mansession::session, and mansession_session::writeperm.

Referenced by auth_http_callback(), do_message(), and generic_http_callback().

◆ purge_events()

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 2135 of file manager.c.

2136{
2137 struct eventqent *ev;
2138 struct timeval now = ast_tvnow();
2139
2141 while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
2142 ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
2144 ast_free(ev);
2145 }
2146
2148 /* Never release the last event */
2149 if (!AST_RWLIST_NEXT(ev, eq_next)) {
2150 break;
2151 }
2152
2153 /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
2154 if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
2156 ast_free(ev);
2157 }
2158 }
2161}
static int httptimeout
Definition: manager.c:1618
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:844
#define AST_RWLIST_FIRST
Definition: linkedlists.h:423
struct timeval tv
Definition: manager.c:1608

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(), httptimeout, eventqent::tv, and eventqent::usecount.

Referenced by purge_old_stuff().

◆ purge_sessions()

static int purge_sessions ( int  n_max)
static

remove at most n_max stale session from the list.

Definition at line 7803 of file manager.c.

7804{
7805 struct ao2_container *sessions;
7807 time_t now = time(NULL);
7808 struct ao2_iterator i;
7809 int purged = 0;
7810
7811 sessions = ao2_global_obj_ref(mgr_sessions);
7812 if (!sessions) {
7813 return 0;
7814 }
7816 ao2_ref(sessions, -1);
7817 while ((session = ao2_iterator_next(&i)) && n_max > 0) {
7819 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
7820 if (session->authenticated
7821 && VERBOSITY_ATLEAST(2)
7823 ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
7824 session->username, ast_sockaddr_stringify_addr(&session->addr));
7825 }
7828 n_max--;
7829 purged++;
7830 } else {
7833 }
7834 }
7836 return purged;
7837}
static void session_destroy(struct mansession_session *s)
Definition: manager.c:2421
#define VERBOSITY_ATLEAST(level)

References ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_sockaddr_stringify_addr(), ast_verb, manager_displayconnects(), NULL, session, session_destroy(), sessions, unref_mansession(), and VERBOSITY_ATLEAST.

Referenced by purge_old_stuff().

◆ queue_read_action_payload()

static int queue_read_action_payload ( struct ast_channel chan,
const unsigned char *  payload,
size_t  payload_size,
enum ast_frame_read_action  action 
)
static

Queue a given read action containing a payload onto a channel.

This queues a READ_ACTION control frame that contains a given "payload", or data to be triggered and handled on the channel's read side. This ensures the "action" is handled by the channel's media reading thread.

Parameters
chanThe channel to queue the action on
payloadThe read action's payload
payload_sizeThe size of the given payload
actionThe type of read action to queue
Return values
-1on error
0on success

Definition at line 5169 of file manager.c.

5171{
5173 size_t obj_size;
5174 int res;
5175
5176 obj_size = payload_size + sizeof(*obj);
5177
5178 obj = ast_malloc(obj_size);
5179 if (!obj) {
5180 return -1;
5181 }
5182
5183 obj->action = action;
5185 memcpy(obj->payload, payload, payload_size);
5186
5187 res = ast_queue_control_data(chan, AST_CONTROL_READ_ACTION, obj, obj_size);
5188
5189 ast_free(obj);
5190 return res;
5191}
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
@ AST_CONTROL_READ_ACTION
enum ast_frame_read_action action

References ast_control_read_action_payload::action, AST_CONTROL_READ_ACTION, ast_free, ast_malloc, ast_queue_control_data(), ast_control_read_action_payload::payload, and ast_control_read_action_payload::payload_size.

Referenced by queue_sendtext(), and queue_sendtext_data().

◆ queue_sendtext()

static int queue_sendtext ( struct ast_channel chan,
const char *  body 
)
static

Queue a read action to send a text message.

Parameters
chanThe channel to queue the action on
bodyThe body of the message
Return values
-1on error
0on success

Definition at line 5202 of file manager.c.

5203{
5204 return queue_read_action_payload(chan, (const unsigned char *)body,
5205 strlen(body) + 1, AST_FRAME_READ_ACTION_SEND_TEXT);
5206}
static int queue_read_action_payload(struct ast_channel *chan, const unsigned char *payload, size_t payload_size, enum ast_frame_read_action action)
Queue a given read action containing a payload onto a channel.
Definition: manager.c:5169
@ AST_FRAME_READ_ACTION_SEND_TEXT

References AST_FRAME_READ_ACTION_SEND_TEXT, and queue_read_action_payload().

Referenced by action_sendtext().

◆ queue_sendtext_data()

static int queue_sendtext_data ( struct ast_channel chan,
const char *  body,
const char *  content_type 
)
static

Queue a read action to send a text data message.

Parameters
chanThe channel to queue the action on
bodyThe body of the message
content_typeThe message's content type
Return values
-1on error
0on success

Definition at line 5218 of file manager.c.

5220{
5221 int res;
5222 struct ast_msg_data *obj;
5223
5225 NULL, NULL, content_type, body);
5226 if (!obj) {
5227 return -1;
5228 }
5229
5230 res = queue_read_action_payload(chan, (const unsigned char *)obj,
5232
5233 ast_free(obj);
5234 return res;
5235}
struct ast_msg_data * ast_msg_data_alloc2(enum ast_msg_data_source_type source_type, const char *to, const char *from, const char *content_type, const char *body)
Allocates an ast_msg_data structure.
size_t ast_msg_data_get_length(struct ast_msg_data *msg)
Get length of the structure.
@ AST_MSG_DATA_SOURCE_TYPE_UNKNOWN
Definition: message.h:447
@ AST_FRAME_READ_ACTION_SEND_TEXT_DATA
Structure used to transport a message through the frame core.

References AST_FRAME_READ_ACTION_SEND_TEXT_DATA, ast_free, ast_msg_data_alloc2(), ast_msg_data_get_length(), AST_MSG_DATA_SOURCE_TYPE_UNKNOWN, NULL, and queue_read_action_payload().

Referenced by action_sendtext().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 10482 of file manager.c.

10483{
10484 return __init_manager(1, 0);
10485}

References __init_manager().

Referenced by handle_manager_reload().

◆ report_auth_success()

static void report_auth_success ( const struct mansession s)
static

Definition at line 3582 of file manager.c.

3583{
3584 char session_id[32];
3585 struct ast_security_event_successful_auth successful_auth = {
3588 .common.service = "AMI",
3589 .common.account_id = s->session->username,
3590 .common.session_tv = &s->session->sessionstart_tv,
3591 .common.local_addr = {
3592 .addr = &s->tcptls_session->parent->local_address,
3593 .transport = mansession_get_transport(s),
3594 },
3595 .common.remote_addr = {
3596 .addr = &s->session->addr,
3597 .transport = mansession_get_transport(s),
3598 },
3599 .common.session_id = session_id,
3600 };
3601
3602 snprintf(session_id, sizeof(session_id), "%p", s->session);
3603
3604 ast_security_event_report(AST_SEC_EVT(&successful_auth));
3605}
static enum ast_transport mansession_get_transport(const struct mansession *s)
Definition: manager.c:3501
int ast_security_event_report(const struct ast_security_event_common *sec)
Report a security event.
@ AST_SECURITY_EVENT_SUCCESSFUL_AUTH
FYI FWIW, Successful authentication has occurred.
#define AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION
Event descriptor version.
#define AST_SEC_EVT(e)
enum ast_security_event_type event_type
The security event sub-type.
struct ast_security_event_common common
Common security event descriptor elements.
struct ast_sockaddr local_address
Definition: tcptls.h:131

References mansession_session::addr, AST_SEC_EVT, ast_security_event_report(), AST_SECURITY_EVENT_SUCCESSFUL_AUTH, AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION, ast_security_event_successful_auth::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, mansession::session, mansession_session::sessionstart_tv, mansession::tcptls_session, and mansession_session::username.

Referenced by authenticate().

◆ report_failed_acl()

static void report_failed_acl ( const struct mansession s,
const char *  username 
)
static

Definition at line 3532 of file manager.c.

3533{
3534 char session_id[32];
3535 struct ast_security_event_failed_acl failed_acl_event = {
3537 .common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
3538 .common.service = "AMI",
3539 .common.account_id = username,
3540 .common.session_tv = &s->session->sessionstart_tv,
3541 .common.local_addr = {
3542 .addr = &s->tcptls_session->parent->local_address,
3543 .transport = mansession_get_transport(s),
3544 },
3545 .common.remote_addr = {
3546 .addr = &s->session->addr,
3547 .transport = mansession_get_transport(s),
3548 },
3549 .common.session_id = session_id,
3550 };
3551
3552 snprintf(session_id, sizeof(session_id), "%p", s->session);
3553
3554 ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
3555}
#define AST_SECURITY_EVENT_FAILED_ACL_VERSION
Event descriptor version.
@ AST_SECURITY_EVENT_FAILED_ACL
Failed ACL.
Checking against an IP access control list failed.
struct ast_security_event_common common
Common security event descriptor elements.

References mansession_session::addr, AST_SEC_EVT, AST_SECURITY_EVENT_FAILED_ACL, AST_SECURITY_EVENT_FAILED_ACL_VERSION, ast_security_event_report(), ast_security_event_failed_acl::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, mansession::session, mansession_session::sessionstart_tv, and mansession::tcptls_session.

Referenced by authenticate().

◆ report_failed_challenge_response()

static void report_failed_challenge_response ( const struct mansession s,
const char *  response,
const char *  expected_response 
)
static

Definition at line 3665 of file manager.c.

3667{
3668 char session_id[32];
3669 struct ast_security_event_chal_resp_failed chal_resp_failed = {
3672 .common.service = "AMI",
3673 .common.account_id = s->session->username,
3674 .common.session_tv = &s->session->sessionstart_tv,
3675 .common.local_addr = {
3676 .addr = &s->tcptls_session->parent->local_address,
3677 .transport = mansession_get_transport(s),
3678 },
3679 .common.remote_addr = {
3680 .addr = &s->session->addr,
3681 .transport = mansession_get_transport(s),
3682 },
3683 .common.session_id = session_id,
3684
3685 .challenge = s->session->challenge,
3686 .response = response,
3687 .expected_response = expected_response,
3688 };
3689
3690 snprintf(session_id, sizeof(session_id), "%p", s->session);
3691
3692 ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
3693}
#define AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION
Event descriptor version.
@ AST_SECURITY_EVENT_CHAL_RESP_FAILED
An attempt at challenge/response authentication failed.
An attempt at challenge/response auth failed.
const char * response
Response received.
struct ast_security_event_common common
Common security event descriptor elements.
const char * expected_response
Response expected to be received.

References mansession_session::addr, AST_SEC_EVT, AST_SECURITY_EVENT_CHAL_RESP_FAILED, AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION, ast_security_event_report(), mansession_session::challenge, ast_security_event_chal_resp_failed::common, ast_security_event_common::event_type, ast_security_event_chal_resp_failed::expected_response, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, ast_security_event_chal_resp_failed::response, mansession::session, mansession_session::sessionstart_tv, mansession::tcptls_session, and mansession_session::username.

Referenced by authenticate().

◆ report_inval_password()

static void report_inval_password ( const struct mansession s,
const char *  username 
)
static

Definition at line 3557 of file manager.c.

3558{
3559 char session_id[32];
3560 struct ast_security_event_inval_password inval_password = {
3563 .common.service = "AMI",
3564 .common.account_id = username,
3565 .common.session_tv = &s->session->sessionstart_tv,
3566 .common.local_addr = {
3567 .addr = &s->tcptls_session->parent->local_address,
3568 .transport = mansession_get_transport(s),
3569 },
3570 .common.remote_addr = {
3571 .addr = &s->session->addr,
3572 .transport = mansession_get_transport(s),
3573 },
3574 .common.session_id = session_id,
3575 };
3576
3577 snprintf(session_id, sizeof(session_id), "%p", s->session);
3578
3579 ast_security_event_report(AST_SEC_EVT(&inval_password));
3580}
#define AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION
Event descriptor version.
@ AST_SECURITY_EVENT_INVAL_PASSWORD
An attempt at basic password authentication failed.
An attempt at basic password auth failed.
struct ast_security_event_common common
Common security event descriptor elements.

References mansession_session::addr, AST_SEC_EVT, AST_SECURITY_EVENT_INVAL_PASSWORD, AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION, ast_security_event_report(), ast_security_event_inval_password::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, mansession::session, mansession_session::sessionstart_tv, and mansession::tcptls_session.

Referenced by authenticate().

◆ report_invalid_user()

static void report_invalid_user ( const struct mansession s,
const char *  username 
)
static

Definition at line 3507 of file manager.c.

3508{
3509 char session_id[32];
3510 struct ast_security_event_inval_acct_id inval_acct_id = {
3513 .common.service = "AMI",
3514 .common.account_id = username,
3515 .common.session_tv = &s->session->sessionstart_tv,
3516 .common.local_addr = {
3517 .addr = &s->tcptls_session->parent->local_address,
3518 .transport = mansession_get_transport(s),
3519 },
3520 .common.remote_addr = {
3521 .addr = &s->session->addr,
3522 .transport = mansession_get_transport(s),
3523 },
3524 .common.session_id = session_id,
3525 };
3526
3527 snprintf(session_id, sizeof(session_id), "%p", s);
3528
3529 ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
3530}
#define AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION
Event descriptor version.
@ AST_SECURITY_EVENT_INVAL_ACCT_ID
Invalid Account ID.
Invalid account ID specified (invalid username, for example)
struct ast_security_event_common common
Common security event descriptor elements.

References mansession_session::addr, AST_SEC_EVT, AST_SECURITY_EVENT_INVAL_ACCT_ID, AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION, ast_security_event_report(), ast_security_event_inval_acct_id::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, mansession::session, mansession_session::sessionstart_tv, and mansession::tcptls_session.

Referenced by authenticate().

◆ report_req_bad_format()

static void report_req_bad_format ( const struct mansession s,
const char *  action 
)
static

Definition at line 3636 of file manager.c.

3637{
3638 char session_id[32];
3639 char request_type[64];
3640 struct ast_security_event_req_bad_format req_bad_format = {
3643 .common.service = "AMI",
3644 .common.account_id = s->session->username,
3645 .common.session_tv = &s->session->sessionstart_tv,
3646 .common.local_addr = {
3647 .addr = &s->tcptls_session->parent->local_address,
3648 .transport = mansession_get_transport(s),
3649 },
3650 .common.remote_addr = {
3651 .addr = &s->session->addr,
3652 .transport = mansession_get_transport(s),
3653 },
3654 .common.session_id = session_id,
3655
3656 .request_type = request_type,
3657 };
3658
3659 snprintf(session_id, sizeof(session_id), "%p", s->session);
3660 snprintf(request_type, sizeof(request_type), "Action: %s", action);
3661
3662 ast_security_event_report(AST_SEC_EVT(&req_bad_format));
3663}
#define AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION
Event descriptor version.
@ AST_SECURITY_EVENT_REQ_BAD_FORMAT
Request received with bad formatting.
Invalid formatting of request.
struct ast_security_event_common common
Common security event descriptor elements.
const char * request_type
Request type that was made.

References mansession_session::addr, AST_SEC_EVT, ast_security_event_report(), AST_SECURITY_EVENT_REQ_BAD_FORMAT, AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION, ast_security_event_req_bad_format::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, ast_security_event_req_not_allowed::request_type, ast_security_event_req_bad_format::request_type, mansession::session, mansession_session::sessionstart_tv, mansession::tcptls_session, and mansession_session::username.

Referenced by process_message().

◆ report_req_not_allowed()

static void report_req_not_allowed ( const struct mansession s,
const char *  action 
)
static

Definition at line 3607 of file manager.c.

3608{
3609 char session_id[32];
3610 char request_type[64];
3611 struct ast_security_event_req_not_allowed req_not_allowed = {
3614 .common.service = "AMI",
3615 .common.account_id = s->session->username,
3616 .common.session_tv = &s->session->sessionstart_tv,
3617 .common.local_addr = {
3618 .addr = &s->tcptls_session->parent->local_address,
3619 .transport = mansession_get_transport(s),
3620 },
3621 .common.remote_addr = {
3622 .addr = &s->session->addr,
3623 .transport = mansession_get_transport(s),
3624 },
3625 .common.session_id = session_id,
3626
3627 .request_type = request_type,
3628 };
3629
3630 snprintf(session_id, sizeof(session_id), "%p", s->session);
3631 snprintf(request_type, sizeof(request_type), "Action: %s", action);
3632
3633 ast_security_event_report(AST_SEC_EVT(&req_not_allowed));
3634}
#define AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION
Event descriptor version.
@ AST_SECURITY_EVENT_REQ_NOT_ALLOWED
A request was made that is not allowed.
Request denied because it's not allowed.
struct ast_security_event_common common
Common security event descriptor elements.
const char * request_type
Request type that was made.

References mansession_session::addr, AST_SEC_EVT, ast_security_event_report(), AST_SECURITY_EVENT_REQ_NOT_ALLOWED, AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION, ast_security_event_req_not_allowed::common, ast_security_event_common::event_type, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, ast_security_event_req_not_allowed::request_type, mansession::session, mansession_session::sessionstart_tv, mansession::tcptls_session, and mansession_session::username.

Referenced by process_message().

◆ report_session_limit()

static void report_session_limit ( const struct mansession s)
static

Definition at line 3695 of file manager.c.

3696{
3697 char session_id[32];
3699 .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
3701 .common.service = "AMI",
3702 .common.account_id = s->session->username,
3703 .common.session_tv = &s->session->sessionstart_tv,
3704 .common.local_addr = {
3705 .addr = &s->tcptls_session->parent->local_address,
3706 .transport = mansession_get_transport(s),
3707 },
3708 .common.remote_addr = {
3709 .addr = &s->session->addr,
3710 .transport = mansession_get_transport(s),
3711 },
3712 .common.session_id = session_id,
3713 };
3714
3715 snprintf(session_id, sizeof(session_id), "%p", s->session);
3716
3718}
static int session_limit
Definition: http.c:106
#define AST_SECURITY_EVENT_SESSION_LIMIT_VERSION
Event descriptor version.
@ AST_SECURITY_EVENT_SESSION_LIMIT
Session limit reached.
Request denied because of a session limit.

References mansession_session::addr, AST_SEC_EVT, ast_security_event_report(), AST_SECURITY_EVENT_SESSION_LIMIT, AST_SECURITY_EVENT_SESSION_LIMIT_VERSION, ast_tcptls_session_args::local_address, mansession_get_transport(), ast_tcptls_session_instance::parent, mansession::session, session_limit, mansession_session::sessionstart_tv, mansession::tcptls_session, and mansession_session::username.

Referenced by process_message().

◆ restrictedFile()

static int restrictedFile ( const char *  filename)
static

Check if a file is restricted or not.

Returns
0 on success
1 on restricted file
-1 on failure

Definition at line 3863 of file manager.c.

3864{
3865 char *stripped_filename;
3866 RAII_VAR(char *, path, NULL, ast_free);
3867 RAII_VAR(char *, real_path, NULL, ast_std_free);
3868
3869 if (live_dangerously) {
3870 return 0;
3871 }
3872
3873 stripped_filename = ast_strip(ast_strdupa(filename));
3874
3875 /* If the file path starts with '/', don't prepend ast_config_AST_CONFIG_DIR */
3876 if (stripped_filename[0] == '/') {
3877 real_path = realpath(stripped_filename, NULL);
3878 } else {
3879 if (ast_asprintf(&path, "%s/%s", ast_config_AST_CONFIG_DIR, stripped_filename) == -1) {
3880 return -1;
3881 }
3882 real_path = realpath(path, NULL);
3883 }
3884
3885 if (!real_path) {
3886 return -1;
3887 }
3888
3889 if (!ast_begins_with(real_path, ast_config_AST_CONFIG_DIR)) {
3890 return 1;
3891 }
3892
3893 return 0;
3894}
void ast_std_free(void *ptr)
Definition: astmm.c:1734

References ast_asprintf, ast_begins_with(), ast_config_AST_CONFIG_DIR, ast_free, ast_std_free(), ast_strdupa, ast_strip(), live_dangerously, NULL, and RAII_VAR.

Referenced by action_getconfig(), action_getconfigjson(), and action_updateconfig().

◆ send_string()

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 3247 of file manager.c.

3248{
3249 struct ast_iostream *stream;
3250 int len, res;
3251
3252 /* It's a result from one of the hook's action invocation */
3253 if (s->hook) {
3254 /*
3255 * to send responses, we're using the same function
3256 * as for receiving events. We call the event "HookResponse"
3257 */
3258 s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string);
3259 return 0;
3260 }
3261
3262 stream = s->stream ? s->stream : s->session->stream;
3263
3264 len = strlen(string);
3266 res = ast_iostream_write(stream, string, len);
3268
3269 if (res < len) {
3270 s->write_error = 1;
3271 }
3272
3273 return res;
3274}
void ast_iostream_set_timeout_inactivity(struct ast_iostream *stream, int timeout)
Set the iostream inactivity timeout timer.
Definition: iostream.c:121
ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t count)
Write data to an iostream.
Definition: iostream.c:374
void ast_iostream_set_timeout_disable(struct ast_iostream *stream)
Disable the iostream timeout timer.
Definition: iostream.c:113
#define EVENT_FLAG_HOOKRESPONSE
Definition: manager.h:89
struct ast_iostream * stream
Definition: manager.c:1779

References ast_iostream_set_timeout_disable(), ast_iostream_set_timeout_inactivity(), ast_iostream_write(), EVENT_FLAG_HOOKRESPONSE, manager_custom_hook::helper, mansession::hook, len(), mansession::session, mansession_session::stream, mansession::stream, mansession::write_error, and mansession_session::writetimeout.

Referenced by astman_append(), astman_flush(), and process_events().

◆ session_destroy()

static void session_destroy ( struct mansession_session s)
static

Definition at line 2421 of file manager.c.

2422{
2423 struct ao2_container *sessions;
2424
2425 sessions = ao2_global_obj_ref(mgr_sessions);
2426 if (sessions) {
2427 ao2_unlink(sessions, s);
2428 ao2_ref(sessions, -1);
2429 }
2431}
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578

References ao2_global_obj_ref, ao2_ref, ao2_unlink, sessions, and unref_mansession().

Referenced by auth_http_callback(), generic_http_callback(), purge_sessions(), and session_do().

◆ session_destructor()

static void session_destructor ( void *  obj)
static

Definition at line 2350 of file manager.c.

2351{
2352 struct mansession_session *session = obj;
2353 struct eventqent *eqe = session->last_ev;
2354 struct ast_datastore *datastore;
2355
2356 /* Get rid of each of the data stores on the session */
2357 while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
2358 /* Free the data store */
2359 ast_datastore_free(datastore);
2360 }
2361
2362 if (eqe) {
2364 }
2365 if (session->chanvars) {
2366 ast_variables_destroy(session->chanvars);
2367 }
2368
2369 if (session->whitefilters) {
2370 ao2_t_ref(session->whitefilters, -1, "decrement ref for white container, should be last one");
2371 }
2372
2373 if (session->blackfilters) {
2374 ao2_t_ref(session->blackfilters, -1, "decrement ref for black container, should be last one");
2375 }
2376
2377 ast_mutex_destroy(&session->notify_lock);
2378}
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define ast_mutex_destroy(a)
Definition: lock.h:188
Structure for a data store object.
Definition: datastore.h:64

References ao2_t_ref, ast_atomic_fetchadd_int(), ast_datastore_free(), AST_LIST_REMOVE_HEAD, ast_mutex_destroy, ast_variables_destroy(), session, and eventqent::usecount.

Referenced by build_mansession().

◆ session_do()

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 7709 of file manager.c.

7710{
7711 struct ast_tcptls_session_instance *ser = data;
7713 struct mansession s = {
7714 .tcptls_session = data,
7715 };
7716 int res;
7717 int arg = 1;
7718 struct ast_sockaddr ser_remote_address_tmp;
7719
7722 goto done;
7723 }
7724
7725 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
7726 session = build_mansession(&ser_remote_address_tmp);
7727
7728 if (session == NULL) {
7730 goto done;
7731 }
7732
7733 /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
7734 * This is necessary to prevent delays (caused by buffering) as we
7735 * write to the socket in bits and pieces. */
7736 if (setsockopt(ast_iostream_get_fd(ser->stream), IPPROTO_TCP, TCP_NODELAY, (char *) &arg, sizeof(arg)) < 0) {
7737 ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on manager connection: %s\n", strerror(errno));
7738 }
7740
7742 /* Hook to the tail of the event queue */
7743 session->last_ev = grab_last();
7744
7745 ast_mutex_init(&s.lock);
7746
7747 /* these fields duplicate those in the 'ser' structure */
7748 session->stream = s.stream = ser->stream;
7749 ast_sockaddr_copy(&session->addr, &ser_remote_address_tmp);
7750 s.session = session;
7751
7752 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
7753
7754 if(time(&session->authstart) == -1) {
7755 ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
7759 goto done;
7760 }
7762
7763 /*
7764 * We cannot let the stream exclusively wait for data to arrive.
7765 * We have to wake up the task to send async events.
7766 */
7768
7770 ast_tvnow(), authtimeout * 1000);
7771
7772 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */
7773 for (;;) {
7774 if ((res = do_message(&s)) < 0 || s.write_error || session->kicked) {
7775 break;
7776 }
7777 if (session->authenticated) {
7779 }
7780 }
7781 /* session is over, explain why and terminate */
7782 if (session->authenticated) {
7784 ast_verb(2, "Manager '%s' %s from %s\n", session->username, session->kicked ? "kicked" : "logged off", ast_sockaddr_stringify_addr(&session->addr));
7785 }
7786 } else {
7788 if (displayconnects) {
7789 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
7790 }
7791 }
7792
7794
7796done:
7797 ao2_ref(ser, -1);
7798 ser = NULL;
7799 return NULL;
7800}
static struct mansession_session * build_mansession(const struct ast_sockaddr *addr)
Allocate manager session structure and add it to the list of sessions.
Definition: manager.c:2381
static int do_message(struct mansession *s)
Definition: manager.c:7624
static struct eventqent * grab_last(void)
Definition: manager.c:2115
static int authlimit
Definition: manager.c:1625
void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive_input)
Set the iostream if it can exclusively depend upon the set timeouts.
Definition: iostream.c:148
void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timeval start, int timeout)
Set the iostream I/O sequence timeout timer.
Definition: iostream.c:139
void ast_iostream_nonblock(struct ast_iostream *stream)
Make an iostream non-blocking.
Definition: iostream.c:103
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
Socket address structure.
Definition: netsock2.h:97
describes a server instance
Definition: tcptls.h:150
struct ast_sockaddr remote_address
Definition: tcptls.h:152
int done
Definition: test_amihooks.c:48

References AMI_VERSION, ao2_lock, ao2_ref, ao2_unlock, ast_atomic_fetchadd_int(), ast_iostream_get_fd(), ast_iostream_nonblock(), ast_iostream_set_exclusive_input(), ast_iostream_set_timeout_disable(), ast_iostream_set_timeout_sequence(), AST_LIST_HEAD_INIT_NOLOCK, ast_log, ast_mutex_destroy, ast_mutex_init, ast_sockaddr_copy(), ast_sockaddr_stringify_addr(), ast_tvnow(), ast_verb, astman_append(), authlimit, authtimeout, build_mansession(), displayconnects, do_message(), done, errno, grab_last(), mansession::lock, LOG_ERROR, LOG_WARNING, manager_displayconnects(), NULL, ast_tcptls_session_instance::remote_address, mansession::session, session, session_destroy(), ast_tcptls_session_instance::stream, mansession::stream, mansession::tcptls_session, unauth_sessions, and mansession::write_error.

◆ set_eventmask()

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 3488 of file manager.c.

3489{
3490 int maskint = strings_to_mask(eventmask);
3491
3492 ao2_lock(s->session);
3493 if (maskint >= 0) {
3494 s->session->send_events = maskint;
3495 }
3496 ao2_unlock(s->session);
3497
3498 return maskint;
3499}
static int strings_to_mask(const char *string)
Definition: manager.c:2304

References ao2_lock, ao2_unlock, mansession_session::send_events, mansession::session, and strings_to_mask().

Referenced by action_events(), and authenticate().

◆ STASIS_MESSAGE_TYPE_DEFN()

STASIS_MESSAGE_TYPE_DEFN ( ast_manager_get_generic_type  )

Define AMI message types.

◆ strings_to_mask()

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 2304 of file manager.c.

2305{
2306 const char *p;
2307
2308 if (ast_strlen_zero(string)) {
2309 return -1;
2310 }
2311
2312 for (p = string; *p; p++) {
2313 if (*p < '0' || *p > '9') {
2314 break;
2315 }
2316 }
2317 if (!*p) { /* all digits */
2318 return atoi(string);
2319 }
2320 if (ast_false(string)) {
2321 return 0;
2322 }
2323 if (ast_true(string)) { /* all permissions */
2324 int x, ret = 0;
2325 for (x = 0; x < ARRAY_LEN(perms); x++) {
2326 ret |= perms[x].num;
2327 }
2328 return ret;
2329 }
2330 return get_perm(string);
2331}
static int get_perm(const char *instr)
Definition: manager.c:2283

References ARRAY_LEN, ast_false(), ast_strlen_zero(), ast_true(), get_perm(), permalias::num, and perms.

Referenced by set_eventmask().

◆ unref_mansession()

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 2335 of file manager.c.

2336{
2337 int refcount = ao2_ref(s, -1);
2338 if (manager_debug) {
2339 ast_debug(1, "Mansession: %p refcount now %d\n", s, refcount - 1);
2340 }
2341 return NULL;
2342}

References ao2_ref, ast_debug, manager_debug, and NULL.

Referenced by __manager_event_sessions_va(), astman_is_authed(), astman_verify_session_readpermissions(), astman_verify_session_writepermissions(), check_manager_session_inuse(), find_session(), find_session_by_nonce(), generic_http_callback(), handle_kickmanconn(), handle_showmanconn(), purge_sessions(), and session_destroy().

◆ user_authority_to_str()

static const char * user_authority_to_str ( int  authority,
struct ast_str **  res 
)
static

Convert authority code to a list of options for a user. This will only display those authority codes that have an explicit match on authority.

Definition at line 2212 of file manager.c.

2213{
2214 int i;
2215 char *sep = "";
2216
2217 ast_str_reset(*res);
2218 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
2219 if ((authority & perms[i].num) == perms[i].num) {
2220 ast_str_append(res, 0, "%s%s", sep, perms[i].label);
2221 sep = ",";
2222 }
2223 }
2224
2225 if (ast_str_strlen(*res) == 0) {
2226 /* replace empty string with something sensible */
2227 ast_str_append(res, 0, "<none>");
2228 }
2229
2230 return ast_str_buffer(*res);
2231}

References ARRAY_LEN, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), permalias::num, and perms.

Referenced by handle_showmanager().

◆ whitefilter_cmp_fn()

static int whitefilter_cmp_fn ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 6675 of file manager.c.

6676{
6677 regex_t *regex_filter = obj;
6678 const char *eventdata = arg;
6679 int *result = data;
6680
6681 if (!regexec(regex_filter, eventdata, 0, NULL, 0)) {
6682 *result = 1;
6683 return (CMP_MATCH | CMP_STOP);
6684 }
6685
6686 return 0;
6687}

References CMP_MATCH, CMP_STOP, NULL, and result.

Referenced by match_filter().

Variable Documentation

◆ acl_change_sub

struct stasis_subscription* acl_change_sub
static

Definition at line 1633 of file manager.c.

Referenced by acl_change_stasis_subscribe(), and acl_change_stasis_unsubscribe().

◆ actions

struct actions actions = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

◆ all_events

struct all_events all_events = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

◆ allowmultiplelogin

int allowmultiplelogin = 1
static

Definition at line 1616 of file manager.c.

Referenced by __init_manager(), and handle_manager_show_settings().

◆ astman_append_buf

struct ast_threadstorage astman_append_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_astman_append_buf , .custom_init = NULL , }
static

◆ authlimit

int authlimit
static

Definition at line 1625 of file manager.c.

Referenced by __init_manager(), manager_set_defaults(), and session_do().

◆ authtimeout

int authtimeout
static

Definition at line 1624 of file manager.c.

Referenced by __init_manager(), do_message(), get_input(), manager_set_defaults(), and session_do().

◆ broken_events_action

int broken_events_action = 0
static

Definition at line 1619 of file manager.c.

Referenced by __init_manager(), action_events(), and manager_set_defaults().

◆ 

const struct { ... } command_blacklist[]
Initial value:
= {
{{ "module", "load", NULL }},
{{ "module", "unload", NULL }},
{{ "restart", "gracefully", NULL }},
}

Referenced by check_blacklist().

◆ displayconnects

int displayconnects = 1
static

◆ global_realm

char global_realm[MAXHOSTNAMELEN]
static

Default realm

Definition at line 1630 of file manager.c.

Referenced by __init_manager(), auth_http_callback(), and manager_set_defaults().

◆ httptimeout

int httptimeout = 60
static

◆ live_dangerously

int live_dangerously
static

Set to true (non-zero) to globally allow all dangerous AMI actions to run.

Definition at line 1650 of file manager.c.

Referenced by astman_live_dangerously(), load_asterisk_conf(), and restrictedFile().

◆ manager_channelvars

char* manager_channelvars
static

Definition at line 1626 of file manager.c.

Referenced by handle_manager_show_settings(), load_channelvars(), and manager_shutdown().

◆ manager_debug

int manager_debug = 0
static

◆ manager_disabledevents

char* manager_disabledevents
static

◆ manager_enabled

int manager_enabled = 0
static

◆ manager_event_buf

struct ast_threadstorage manager_event_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_buf , .custom_init = NULL , }
static

Definition at line 7884 of file manager.c.

Referenced by __manager_event_sessions_va().

◆ manager_hooks

struct manager_hooks manager_hooks = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

◆ manager_topic

struct stasis_topic* manager_topic
static

◆ perms

const struct permalias perms[]
static

◆ rtp_topic_forwarder

struct stasis_forward* rtp_topic_forwarder
static

The stasis_subscription for forwarding the RTP topic to the AMI topic.

Definition at line 1642 of file manager.c.

Referenced by manager_shutdown(), and manager_subscriptions_init().

◆ security_topic_forwarder

struct stasis_forward* security_topic_forwarder
static

The stasis_subscription for forwarding the Security topic to the AMI topic.

Definition at line 1645 of file manager.c.

Referenced by manager_shutdown(), and manager_subscriptions_init().

◆ stasis_router

struct stasis_message_router* stasis_router
static

◆ subscribed

int subscribed = 0
static

◆ timestampevents

int timestampevents
static

◆ unauth_sessions

int unauth_sessions = 0
static

Definition at line 1632 of file manager.c.

Referenced by action_login(), and session_do().

◆ userevent_buf

struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , }
static

Definition at line 3285 of file manager.c.

Referenced by action_userevent().

◆ users

struct users users = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

◆ webmanager_enabled

int webmanager_enabled = 0
static

◆ words

const char* words[AST_MAX_CMD_LEN]

Definition at line 1676 of file manager.c.